2016-12-06 15 views
2

3つの行列に配列を掛ける必要がある数値計算を高速化しようとしています。問題の構造は以下である:Numpy Tensordotを使用する行列配列の乗算を変更する

  • (N、10)の形状として配列
  • 第1の行列は、アレイの動的寸法に沿って一定であり(10、10の形状を有しています)
  • 他の二つの行列は、アレイの第一の次元に沿って変化し、(N、10、10を有する)(N、形状)を持つ配列であるべきである
  • 計算の結果を形作る

forループを使用してソリューションを実装しました。私はnumpyの機能を使用しようとしているので、私はより良いパフォーマンスを持っていると思います。

:私は以下の通りであるforループ

Iはnumpy.tensordotを使用して試みたが、アレイを有するダイナミック行列を乗算するときに私の代わりに(N、10)の(N 10、N)の形状を得ます
res = np.zeros(temp_rho.shape, dtype=np.complex128) 
for i in range(temp_rho.shape[0]): 
    res[i] = np.dot(self.constMatrix, temp_rho[i]) 
    res[i] += np.dot(self.dinMat1[i], temp_rho[i]) 
    res[i] += np.dot(self.dinMat2[i], np.conj(temp_rho[i])) 
#temp_rho.shape = (N, 10) 
#res.shape = (N, 10) 
#self.constMatrix.shape = (10, 10) 
#self.dinMat1.shape = (N, 10, 10) 
#self.dinMat2.shape = (N, 10, 10) 

このコードをnumpyのドットプロダクトに実装するには、正しいディメンションを返す必要がありますか?

答えて

2

ここnp.dotnp.einsumの組み合わせ使用したアプローチだ - 後で2用

parte1 = np.tensordot(temp_rho, constMatrix, axes=([1],[1])) 

しないのはなぜnumpy.tensordot仕事 - parte1を取得する別の方法はnp.tensordotとなり

parte1 = constMatrix.dot(temp_rho.T).T 
parte2 = np.einsum('ijk,ik->ij',dinMat1, temp_rho) 
parte3 = np.einsum('ijk,ik->ij',dinMat2, np.conj(temp_rho)) 
out = parte1 + parte2 + parte3 

を減額?

まあ、我々はsum-reducedでない軸を要素ごと二つの別々の軸に沿って掛けているようtensordotでは不可能であるtemp_rho/np.conj(temp_rho)の第一の軸、に対して整列dinMat1/dinMat2の間の第一の軸を維持する必要があります。したがって、np.tensordotと一緒に使用すると、2つの入力からそれぞれ第1の軸に対応する長さの軸がNになります。