私は 2 つの多次元 NumPy 配列A
とB
を持っA.shape = (K, d, N)
ていB.shape = (K, N, d)
ます。軸 0 ( ) に対して要素ごとの操作を実行したいと思います。その操作は、軸 1 と 2 (および)K
に対する行列乗算です。したがって、結果は の多次元配列になるはずです。単純な実装は次のようになります。d, N
N, d
C
C.shape = (K, d, d)
C[k] = np.dot(A[k], B[k])
C = np.vstack([np.dot(A[k], B[k])[np.newaxis, :, :] for k in xrange(K)])
しかし、この実装は遅いです。少し速いアプローチは次のようになります。
C = np.dot(A, B)[:, :, 0, :]
これは、多次元配列のデフォルトの動作を使用し、np.dot
shape の配列を提供します(K, d, K, d)
。ただし、このアプローチでは必要な応答時間が計算されますK
(軸 2 に沿った各エントリは同じです)。漸近的には、最初のアプローチよりも遅くなりますが、オーバーヘッドははるかに少なくなります。また、次のアプローチも認識しています。
from numpy.core.umath_tests import matrix_multiply
C = matrix_multiply(A, B)
ただし、この機能が利用できることを保証するものではありません。したがって、私の質問は、NumPy はこれを効率的に行う標準的な方法を提供していますか? 一般に多次元配列に適用される答えは完璧ですが、この場合のみに固有の答えも素晴らしいでしょう。
編集: @Juh_ が指摘したように、2 番目のアプローチは正しくありません。正しいバージョンは次のとおりです。
C = np.dot(A, B).diagonal(axis1=0, axis2=2).transpose(2, 0, 1)
ただし、オーバーヘッドが追加されるため、小さな行列であっても、最初のアプローチよりも遅くなります。最後のアプローチは、小さな行列と大きな行列のすべてのタイミング テストでロング ショットで勝つことです。より良い解決策が見つからない場合は、numpy.core.umath_tests
ライブラリ (C で記述) をプロジェクトにコピーすることになるとしても、これを使用することを強く検討しています。