簡単な例を見てみましょう。
定義すると:
import numpy as np
N = 5
A = np.arange(N)
X = np.arange(N*N).reshape(N,N)
B = np.arange(N)
W = np.arange(N*N).reshape(N,N)
G = np.arange(N)
Zij = np.arange(N)
次に、最初の合計は次のSum_v(Av * Xi_v)
ように計算できますnp.dot
。
In [54]: X
Out[54]:
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19],
[20, 21, 22, 23, 24]])
In [55]: A
Out[55]: array([0, 1, 2, 3, 4])
In [56]: np.dot(X, A)
Out[56]: array([ 30, 80, 130, 180, 230])
同様に、2 番目の合計は次のSum_v(Bv * Wj_v)
ように計算できます。
In [58]: np.dot(W,B)
Out[58]: array([ 30, 80, 130, 180, 230])
ただし、最初の合計の結果がi
-index に沿って変化するベクトルになるようにし、2 番目の合計の結果がj
-index に沿って変化するベクトルになるようにします。それを numpy に配置するには、ブロードキャストを使用します。
In [59]: np.dot(X,A) + np.dot(W,B)[:,None]
Out[59]:
array([[ 60, 110, 160, 210, 260],
[110, 160, 210, 260, 310],
[160, 210, 260, 310, 360],
[210, 260, 310, 360, 410],
[260, 310, 360, 410, 460]])
3 番目の合計は、2 つの 1 次元配列間の単純な内積です。
In [60]: np.dot(Zij, G)
Out[60]: 30
それで、すべてをまとめると、
In [61]: M = np.dot(X,A) + np.dot(W,B)[:,None] + np.dot(Zij, G)
In [62]: M
Out[62]:
array([[ 90, 140, 190, 240, 290],
[140, 190, 240, 290, 340],
[190, 240, 290, 340, 390],
[240, 290, 340, 390, 440],
[290, 340, 390, 440, 490]])
の意味を誤解している可能性があることに注意してくださいZij
。1次元配列だとおっしゃっていますが、おそらくそれぞれ i,j
が1次元配列ということでしょうか。するとZ
三次元になります。
具体的に言うと、 の最初の 2 つの軸がインデックスとインデックスをZ
表し、の最後の軸が合計したい軸であるとします。i
j
Z
この場合、最後の項を次のようにする必要がありますnp.dot(Z, G)
。
In [13]: Z = np.arange(N**3).reshape(N,N,-1)
In [14]: np.dot(X,A) + np.dot(W,B)[:,None] + np.dot(Z, G)
Out[14]:
array([[ 90, 190, 290, 390, 490],
[ 390, 490, 590, 690, 790],
[ 690, 790, 890, 990, 1090],
[ 990, 1090, 1190, 1290, 1390],
[1290, 1390, 1490, 1590, 1690]])