アダマール積

アダマール積

アダマール積

 同じサイズの行列 $A,\ B$ に対して、成分ごとの積をとる演算を アダマール積 (Hadamard product) または シューア積 (Schur product) とよび、$A\circ B$ で表します。
 
\[\begin{bmatrix}
a_{11}&a_{12} &a_{13}\\
a_{21}&a_{22} &a_{23}\\
a_{31}&a_{32} &a_{33}\end{bmatrix}
\begin{bmatrix}
b_{11}&b_{12}&b_{13}\\
b_{21}&b_{22}&b_{23}\\
b_{31}&b_{32}&b_{33}\end{bmatrix}
=\begin{bmatrix}
a_{11}b_{11}&a_{12}b_{12}&a_{13}b_{13}\\
a_{21}b_{21}&a_{22}b_{22}&a_{23}b_{23}\\
a_{31}b_{31}&a_{32}b_{32}&a_{33}b_{33}
\end{bmatrix}\tag{1}\]

アダマール積の性質

 アダマール積は交換則と分配則
 
\[\begin{align*}
&A\circ B=B\circ A\tag{2}\\[6pt]
&A\circ (B\circ C)=(A\circ B)\circ C\tag{3}\\[6pt]
&A\circ (B+C)=A\circ B+A\circ C\tag{4}\end{align*}\]
を満たす演算です。 (参考文献:フリー百科事典 Wikipedia
 

NumPyのアダマール積

 NumPy の配列に対して * 演算子を適用すると、成分ごとの積、すなわち アダマール積 を実行します(行列積ではありません)。

# SLA_101-1

import numpy as np

a = np.array([[3, 1, 7],
              [0, 2, 5],
              [9, 4, 3]])

b = np.array([[2, 2, 6],
              [9, 6, 2],
              [8, 1, 4]])

# aとbのアダマール積
print(a*b)
[[ 6  2 42]
 [ 0 12 10]
 [72  4 12]]

 アダマール積を使うと、$a_{ij}b_{ij}$ の総和
 
\[a_{11}b_{11}+a_{12}b_{12}+\ \cdots+\ a_{nn}b_{nn}\]
を簡潔なコードで実装できます。すなわち行列 $a_{ij}$ と $b_{ij}$ を用意しておいて、アダマール積をとってから、numpy.sum() ですべての成分の和をとります。たとえば、コード SLA_101-1 で定義した行列 a, b の成分ごとの積の和は以下のように計算できます。

# SLA_101-2

# 行列 a, b の成分ごとの積の和
s = np.sum(a*b)

print(s)
160

 これは機械学習などでも用いられる実践的な手法です。
 

sympy.matrices.dense.matrix_multiply_elementwise()

 SymPy では * 演算子は行列積を実行します。
 アダマール積は matrix_multiply_elementwise() を使って計算します。

# SLA_102

from sympy import Symbol, var, init_printing
from sympy.matrices import Matrix
from sympy.matrices import matrix_multiply_elementwise

init_printing()

# 一般表記の行列生成関数
def general_matrix(m, n, s):
    Symbol(s)
    elements = lambda i,j : var('{}{}{}'.format(s, i+1, j+1))
    return Matrix(m, n, elements)

a = general_matrix(3, 3, "a")
b = general_matrix(3, 3, "b")

# aとbのアダマール積を計算
aob = matrix_multiply_elementwise(a, b)

# a,b,aobを表示
display(a, b, aob)
\begin{align*}
&\left[\begin{matrix}a_{11} & a_{12} & a_{13}\\a_{21} & a_{22} &a_{23}\\a_{31} & a_{32} & a_{33}\end{matrix}\right]\\[6pt]
&\left[\begin{matrix}b_{11} & b_{12} & b_{13}\\b_{21} & b_{22} &b_{23}\\b_{31} & b_{32} & b_{33}\end{matrix}\right]\\[6pt]
&\left[\begin{matrix}a_{11} b_{11} & a_{12} b_{12} & a_{13} b_{13}\\a_{21} b_{21} & a_{22} b_{22} & a_{23} b_{23}\\a_{31} b_{31} & a_{32} b_{32} & a_{33} b_{33}\end{matrix}\right]\end{align*}