密行列Aとベクトルe、fのA * diag(e)* A^T * fの高速乗算の提案はありませんか?連結行列の乗算
これは私が今持っているものです。
v[:] = 0
for i in range(N):
for j in range(N):
v[i] = v[i]+A[i,j]*e[j]*np.dot(A[:,j],f)
おかげで、@rubenvbによって作ら
密行列Aとベクトルe、fのA * diag(e)* A^T * fの高速乗算の提案はありませんか?連結行列の乗算
これは私が今持っているものです。
v[:] = 0
for i in range(N):
for j in range(N):
v[i] = v[i]+A[i,j]*e[j]*np.dot(A[:,j],f)
おかげで、@rubenvbによって作ら
の提案は、おそらくそれを行うための最も簡単な方法です。別の方法はeinsum
を使用することです。
例を示します。私はa
、e
とf
次使用します:
In [95]: a
Out[95]:
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
In [96]: e
Out[96]: array([-1, 2, 3])
In [97]: f
Out[97]: array([5, 4, 1])
これはnumpyのコードにあなたの式の直接翻訳したものです。それは基本的にrubenvbの提案@と同じです:
In [99]: np.einsum('ij,j,jk,k', a, e, a.T, f)
Out[99]: array([ 556, 1132, 1708])
あなたはその引数に関連付けられたインデックスラベルを交換することによりa
を移調する必要性を排除することができます:
In [98]: a.dot(np.diag(e)).dot(a.T).dot(f)
Out[98]: array([ 556, 1132, 1708])
ここeinsum
バージョンです
In [100]: np.einsum('ij,j,kj,k', a, e, a, f)
Out[100]: array([ 556, 1132, 1708])
@ rubenvbのコメントでは、A.dot(np.diag(e)).dot(A.transpose()).dot(f)
を使用することが推奨されていました。しかし、実際には2D
の配列をdiag(e)
にする必要はないので、1つの行列乗算をスキップします。また、A.T
とf
の場所を入れ替えることもできます。転置も避けてください。このように、単純化されたとはるかに効率的なソリューションはそうのように、進化するだろう - numpyの内積を使用しないのはなぜ
In [226]: # Setup inputs
...: N = 200
...: A = np.random.rand(N,N)
...: e = np.random.rand(N,)
...: f = np.random.rand(N,)
...:
In [227]: %timeit np.einsum('ij,j,kj,k', A, e, A, f) # @Warren Weckesser's soln
10 loops, best of 3: 77.6 ms per loop
In [228]: %timeit A.dot(np.diag(e)).dot(A.transpose()).dot(f) # @rubenvb's soln
10 loops, best of 3: 18.6 ms per loop
In [229]: %timeit A.dot(e*f.dot(A)) # Proposed here
10000 loops, best of 3: 100 µs per loop
-
をここで提案されたすべてのアプローチにまともなサイズの配列の迅速な実行時のテストです? A.ドット(diag(e))のようなものdot(A.tranpose()).dot(f)? – rubenvb