>>> a = np.arange(1,5).reshape(2,2) >>> a array([[1, 2], [3, 4]]) >>> b = np.arange(-5,-1).reshape(2,2) >>> b array([[-5, -4], [-3, -2]])
を使ったすこぶる分かりにくい挙動を見てみよう。
>>> np.einsum('ij,ij->ij', a, b) array([[-5, -8], [-9, -8]]) >>> np.einsum('ij,ij->ji', a, b) array([[-5, -9], [-8, -8]])
を考えてみたい。最初の例はいわゆるアダマール積であり、次の例はその転置行列である。
最初の例は数式で書くと
\begin{align*}
(c_{ij}) = (a_{ij} b_{ij}) = \begin{pmatrix} 1 \times (-5) & 2 \times (-4) \\ 3 \times (-3) & 4 \times (-2) \end{pmatrix} = \begin{pmatrix} -5 & -8 \\ -9 & -8 \end{pmatrix}
\end{align*}
であり、次の例は添字を逆にして、${c_{ij}^\prime} = (c_{ji})$ を考えたものである。
どちらの例でも和はとらないので、これもまた分かりにくい部分がある。「アインシュタインの規約」という響きに惑わされずに、そういう API なのだと理解するしかないだろう。