【发布时间】:2017-02-11 22:26:11
【问题描述】:
我正在尝试在 Python 中编写一个函数,该函数将参数列表 a 作为输入并返回依赖于这些参数的向量列表 u。然后我希望能够使用标准向量运算(例如标量积)对u 进行操作。在下面的示例中(灵感来自this post 的第二个答案),该函数返回两个初始向量v 和w 的组合:
import numpy as np
v = np.array([1,0,0])
w = np.array([0,1,0])
a = np.linspace(0,np.pi,4)
def u(a):
u = np.cos(a)*v + np.sin(a)*w
return u
uvec = np.vectorize(u, otypes=[np.ndarray])
ufin = np.array(uvec(a).tolist())
print "ufin =", ufin
print "ufin.v =", np.dot(ufin,v)
这会返回:
ufin = [[ 1.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 5.00000000e-01 8.66025404e-01 0.00000000e+00]
[ -5.00000000e-01 8.66025404e-01 0.00000000e+00]
[ -1.00000000e+00 1.22464680e-16 0.00000000e+00]]
ufin.v = [ 1. 0.5 -0.5 -1. ]
这是我想要获得的,因为ufin 的行为就像一个向量。你能告诉我是否还有其他更简单的方法来实现这一点?我需要编写一个代码,其中必须定义大量向量和向量操作,并希望它尽可能紧凑。
提前谢谢你!
编辑:
我根据this post 的最后一个答案找到了另一个(显然更紧凑)解决方案。这个想法是将参数列表重塑为列数组,以便函数的输出自动(无需向量化)返回向量列表作为二维数组。这是通过这种方式完成的:
import numpy as np
from numpy.core.umath_tests import inner1d
v = np.array([1,0,0])
w = np.array([0,1,0])
a = np.linspace(0,np.pi,4).reshape((4,1))
b = np.linspace(0,np.pi/2,4).reshape((4,1))
def u(a):
u = np.cos(a)*v + np.sin(a)*w
return u
print "u(a) =",u(a)
print "u(b) =",u(b)
print "u(a).v =",np.dot(u(a),v)
print "u(a)^v =",np.cross(u(a),v)
# print "u(a).u(b) =",np.dot(u(a),u(b)) # does not work
print "u(a).u(b) =",inner1d(u(a),u(b)) # works
print "u(a)^u(b) =",np.cross(u(a),u(b))
这会返回:
u(a) = [[ 1.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 5.00000000e-01 8.66025404e-01 0.00000000e+00]
[ -5.00000000e-01 8.66025404e-01 0.00000000e+00]
[ -1.00000000e+00 1.22464680e-16 0.00000000e+00]]
u(b) = [[ 1.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 8.66025404e-01 5.00000000e-01 0.00000000e+00]
[ 5.00000000e-01 8.66025404e-01 0.00000000e+00]
[ 6.12323400e-17 1.00000000e+00 0.00000000e+00]]
u(a).v = [ 1. 0.5 -0.5 -1. ]
u(a)^v = [[ 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 -8.66025404e-01]
[ 0.00000000e+00 0.00000000e+00 -8.66025404e-01]
[ 0.00000000e+00 0.00000000e+00 -1.22464680e-16]]
u(a).u(b) = [ 1.00000000e+00 8.66025404e-01 5.00000000e-01 6.12323400e-17]
u(a)^u(b) = [[ 0. 0. 0. ]
[ 0. 0. -0.5 ]
[ 0. 0. -0.8660254]
[ 0. 0. -1. ]]
对于涉及初始(u 和 v)和向量输出列表(u(a) 和 u(b))的操作以及涉及向量的两个输出列表的操作,这都是正确的行为。唯一需要注意的是(对于向量输出列表之间的操作)是必须使用inner1d 函数而不是标准np.dot,因为后者被解释为由于两个矩阵不一致而无法完成的矩阵乘积尺寸。
【问题讨论】:
标签: python numpy vectorization