[英]Numpy rotation matrix multiplication
I want to calculate and multply a sequence of rotation matrix using numpy.我想使用 numpy 计算并乘以一系列旋转矩阵。 I've written this code to do my job,我写了这段代码来完成我的工作,
def npmat(angle_list):
aa = np.full((nn, n, n),np.eye(n))
c=0
for j in range(1,n):
for i in range(j):
th = angle_list[c]
aa[c,i,i]=aa[c,j,j] = np.cos(th)
aa[c,i,j]= np.sin(th)
aa[c,j,i]= -np.sin(th)
c+=1
return np.linalg.multi_dot(aa)
n,nn=3,3
#nn=n*(n-1)/2
angle_list= array([1.06426904, 0.27106789, 0.56149785])
npmat(angle_list)=
array([[ 0.46742875, 0.6710055 , 0.57555363],
[-0.84250501, 0.53532228, 0.06012796],
[-0.26776049, -0.51301235, 0.81555052]])
But I've to apply this function over 10K times and this is very slow and feels like not using numpy to its full potential.但是我必须应用这个函数超过 10K 次,这非常慢,感觉就像没有充分利用 numpy。 Is there a more efficient a do this in numpy?在 numpy 中有更有效的方法吗?
EDIT: Since it seems like you are looking for the product of these matrices, you can apply the matrices without constructing them.编辑:由于您似乎正在寻找这些矩阵的乘积,因此您可以在不构造它们的情况下应用这些矩阵。 It might also make sense to just compute the cosine and sine without having vectorized that first.只计算余弦和正弦而不先进行矢量化也可能是有意义的。
n=3
nn= n*(n-1)//2
theta_list = np.array([1.06426904, 0.27106789, 0.56149785])
sin_list = np.sin(theta_list)
cos_list = np.cos(theta_list)
A = np.eye(n)
c=0
for i in range(1,n):
for j in range(i):
ri = np.copy(A[i])
rj = np.copy(A[j])
A[i] = cos_list[c]*ri + sin_list[c]*rj
A[j] = -sin_list[c]*ri + cos_list[c]*rj
c+=1
print(A.T) // transpose at end because its faster to update A[i] than A[:,i]
If you want to compute each of the matrices explicitly here is a vectorized version of some of your original code.如果您想显式计算每个矩阵,这里是一些原始代码的矢量化版本。
n=4
nn= n*(n-1)//2
theta_list = np.random.rand(nn)*2*np.pi
sin_list = np.sin(theta_list)
cos_list = np.cos(theta_list)
aa = np.full((nn, n, n),np.eye(n))
ii,jj = np.tril_indices(n,k=-1)
cc = np.arange(nn)
aa[cc,ii,ii] = cos_list[cc]
aa[cc,jj,jj] = cos_list[cc]
aa[cc,ii,jj] = -sin_list[cc]
aa[cc,jj,ii] = sin_list[cc]
A solutions with more vectorisation levels :具有更多矢量化级别的解决方案:
def npmats(angle):
a,b = angle.shape
aa = np.full((a,b, n,n),np.eye(n))
for j in range(1,n):
for i in range(j):
aa[:,:,i,i]=aa[:,:,j,j] = np.cos(angle)
sinangle=np.sin(angle)
aa[:,:,i,j]= sinangle
aa[:,:,j,i]= -sinangle
bb=np.empty((a,n,n))
for i in range(a):
bb[i]=np.linalg.multi_dot(aa[i])
return bb
It seems reasonably fast:看起来相当快:
In [9]: angle= np.random.rand(10000,nn)
In [10]: %time res = npmats(angle)
Wall time: 205 ms
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.