简体   繁体   English

Numpy 旋转矩阵乘法

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM