我有以下代码来绘制标量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))
但这没有帮助。
我该如何解决?
答案 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)