『Python数値計算ノート』ではアフィリエイトプログラムを利用して商品を紹介しています。

アダマール積

アダマール積(シューア積)

同じサイズの行列 A, B に対して、成分ごとの積をとる演算をアダマール積(Hadamard product)またはシューア積(Schur product)とよび、AB で表します。名称はフランスの数学者ジャック・サロモン・アダマール(Jacques Salomon Hadamard)、ドイツ・イスラエルの数学者イサイ・シューア(Issai Schur)らに由来します。
 
たとえば、3×3サイズの行列同士のアダマール積は次のように表されます。
 (1)[a11a12a13a21a22a23a31a32a33][b11b12b13b21b22b23b31b32b33]=[a11b11a12b12a13b13a21b21a22b22a23b23a31b31a32b32a33b33]
ほぼ自明のことですが、アダマール積は交換則と分配則
 (2)AB=BA(3)A(BC)=(AB)C(4)A(B+C)=AB+AC
を満たす演算です。

【NumPy】アダマール積

NumPy の配列に対して * 演算子を適用すると、成分ごとの積、すなわちアダマール積を計算します(行列積ではありません)。3×3サイズの配列を用意して、配列積 (アダマール積) を計算させてみましょう。

# NumPy_Hadamard_product

# In[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]]

アダマール積を使うと、aijbij の総和
 a11b11+a12b12+ + annbnn
を簡潔なコードで実装できます。すなわち行列 aijbij を用意しておいて、アダマール積をとってから、numpy.sum() ですべての成分の和をとります。たとえば、In[1] で定義した行列 a, b の成分ごとの積の和は以下のように計算できます。

# In[2]

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

print(s)
# 160

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

sympy.matrix_multiply_elementwise()

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

# SymPy_Hadamard_product

# In[1]

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)
[a11a12a13a21a22a23a31a32a33][b11b12b13b21b22b23b31b32b33][a11b11a12b12a13b13a21b21a22b22a23b23a31b31a32b32a33b33]

コメント