如何在涉及matrix_power的matplotlib中绘制矩阵的标量函数?

时间:2019-03-04 01:43:57

标签: python numpy matplotlib numpy-ndarray

我有以下代码来绘制标量x与标量f(x),其中函数内部存在一些矩阵乘法:

import numpy as np
import matplotlib.pyplot as plt
from numpy.linalg import matrix_power
P=np.array([\
 [0,0,0.5,0,0.5],\
 [0,0,1,0,0], \
 [.25,.25,0,.25,.25], \
 [0,0,.5,0,.5], \
 [0,0,0,0,1], \
 ])
t=np.array([0,1,0,0,0])
ones=np.array([1,1,1,1,0])

def f(x):
    return t.dot(matrix_power(P,x)).dot(ones)
x=np.arange(1,20)
plt.plot(x, f(x))

现在,该功能本身可以正常工作。

>>> f(1)
1.0
>>> f(2)
0.75 

但是绘图会引起错误exponent must be an integer

换句话说,如何在数组上评估此函数?例如

f(np.array([1,2]))

我尝试用 plt.plot(x, map(f,x))

但这没有帮助。

我该如何解决?

1 个答案:

答案 0 :(得分:2)

In [1]: P=np.array([\ 
   ...:  [0,0,0.5,0,0.5],\ 
   ...:  [0,0,1,0,0], \ 
   ...:  [.25,.25,0,.25,.25], \ 
   ...:  [0,0,.5,0,.5], \ 
   ...:  [0,0,0,0,1], \ 
   ...:  ])                                                                     
In [2]:                                                                         
In [2]: P                                                                       
Out[2]: 
array([[0.  , 0.  , 0.5 , 0.  , 0.5 ],
       [0.  , 0.  , 1.  , 0.  , 0.  ],
       [0.25, 0.25, 0.  , 0.25, 0.25],
       [0.  , 0.  , 0.5 , 0.  , 0.5 ],
       [0.  , 0.  , 0.  , 0.  , 1.  ]])

In [4]: np.linalg.matrix_power(P,3)                                             
Out[4]: 
array([[0.   , 0.   , 0.25 , 0.   , 0.75 ],
       [0.   , 0.   , 0.5  , 0.   , 0.5  ],
       [0.125, 0.125, 0.   , 0.125, 0.625],
       [0.   , 0.   , 0.25 , 0.   , 0.75 ],
       [0.   , 0.   , 0.   , 0.   , 1.   ]])

In [5]: np.linalg.matrix_power(P,np.arange(0,4))                                
---------------------------------------------------------------------------    
TypeError: exponent must be an integer

因此,只需为其提供所需的整数即可:

In [10]: [f(i) for i in range(4)]                                               
Out[10]: [1.0, 1.0, 0.75, 0.5]

pylab.plot(np.arange(25), [f(i) for i in np.arange(25)]) 

通过matrix_power代码:

a = asanyarray(a)
_assertRankAtLeast2(a)
_assertNdSquareness(a)

try:
    n = operator.index(n)
except TypeError:
    raise TypeError("exponent must be an integer")
....

这是n=3的作用:

In [5]: x = np.arange(9).reshape(3,3)                                           
In [6]: np.linalg.matrix_power(x,3)                                             
Out[6]: 
array([[ 180,  234,  288],
       [ 558,  720,  882],
       [ 936, 1206, 1476]])
In [7]: x@x@x                                                                   
Out[7]: 
array([[ 180,  234,  288],
       [ 558,  720,  882],
       [ 936, 1206, 1476]])

您可以定义一个matrix_power函数,该函数接受一系列幂:

def matrix_power(P,x):
    return np.array([np.linalg.matrix_power(P,i) for i in x])

使用此matrix_power(P,np.arange(25))将产生(25,5,5)数组。而您的f(x)实际上可以解决此问题,并返回一个(25,)形状数组。但是我想知道,这是偶然的还是故意的?您在编写f时考虑了3d功率阵列吗?

t.dot(matrix_power(P,x)).dot(ones)