2016-07-26 6 views
2

2つの並列配列、1つは回転行列の配列、もう1つは3D点のグループの配列を与えられています。対応する行列。numpyでのポイントマトリックス乗算の処理グループ

numpy.einsumで各グループをループすることで、私が望むことを達成できました。私はループなしでこれを行う方法があると期待しています。

import numpy as np 
N_GROUPS = 10 
N_SUBGROUPS = 4 

p = np.random.random((N_SUBGROUPS,N_GROUPS,3,)) # N_GROUPS of N_SUBGROUPS of 3D points 
M = np.random.random((N_GROUPS,3,3,))   # N_GROUPS of rotation matrices 
I = np.linalg.inv(M)       # Inverse of M for testing purposes 

# Use a loop to transform every subgroup. 
for i in xrange(N_SUBGROUPS): 
    p_ = np.einsum('ij,ijk->ik', p[i], M) 

    # test 
    p__= np.einsum('ij,ijk->ik', p_, I) 
    print np.allclose(p[i],p__)# Returns True 

私の状況に対処するためのeinsum表現を書き換えるすべてのヘルプ、または別の方法を使用する方法についての提案をいただければ幸いです:これは、これまで私が持っているコードです。

+0

は、ディメンションの結果の配列を探しているが、 '(N_SUBGROUPS、N_GROUPS、3)'? – Praveen

答えて

1

これは本当に簡単です。自分で仕事のほとんどをやったことがあります。

サブグループに対応するインデックスを取得し、それをeinsum方程式の両辺に置きます。これは、次元(N_SUBGROUPS, N_GROUPS, 3)の希望の配列を与えます。

は、我々はその後、サブグループインデックスl、呼び出したとします

p_ = np.einsum('lij,ijk->lik', p, M) 

# I've changed the subgroup range index for clarity 
for l in range(N_SUBGROUPS): 
    # test 
    p__= np.einsum('ij,ijk->ik', p_[l], I) 
    print(np.allclose(p[l],p__)) # Returns True 
+1

私はとても馬鹿だと感じています、ありがとう!私は打ち切りを使用して終わったので、私はそれに投げることができるすべてのバンドルの変形を扱うことができます: 'np.einsum( '... ij、ijk - > ... ik'、p、M)' – Fnord