NumPyで対称行列を生成・判定
対称行列を表すNumPy配列ndarray
を生成したり、あるndarray
が対称行列であるかを判定する方法について、以下の内容を説明する。
- NumPy配列
ndarray
を元に対称行列を生成 - NumPy配列
ndarray
が対称行列であるか判定 - 歪対称行列(交代行列)の場合
なお、対称行列の定義は以下の通り。
線型代数学における対称行列(たいしょうぎょうれつ、英: symmetric matrix)は、自身の転置行列と一致するような正方行列を言う。 対称行列 - Wikipedia
NumPyの行列演算についての詳細は以下の記事を参照。
NumPy配列ndarrayを元に対称行列を生成
正方行列を表す任意のNumPy配列ndarray
を元に対称行列を生成する方法について説明する。
以下のndarray
を例とする。
import numpy as np
a = np.arange(16).reshape(4, 4)
print(a)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]
# [12 13 14 15]]
関数np.tril()
, np.triu()
でndarray
から下三角成分・上三角成分を抽出できる。
print(np.tril(a))
# [[ 0 0 0 0]
# [ 4 5 0 0]
# [ 8 9 10 0]
# [12 13 14 15]]
print(np.triu(a))
# [[ 0 1 2 3]
# [ 0 5 6 7]
# [ 0 0 10 11]
# [ 0 0 0 15]]
以降はnp.tril()
によって生成した下三角行列を使って例を示すが、考え方はnp.triu()
による上三角行列でも同じ。
T
で転置行列を取得できる。
三角行列とその転置行列を足し合わせると対角成分以外は所望の対称行列となるが、対角成分は重複するため2倍の値になってしまう。
print(np.tril(a).T)
# [[ 0 4 8 12]
# [ 0 5 9 13]
# [ 0 0 10 14]
# [ 0 0 0 15]]
print(np.tril(a) + np.tril(a).T)
# [[ 0 4 8 12]
# [ 4 10 9 13]
# [ 8 9 20 14]
# [12 13 14 30]]
diagonal()
メソッドとnp.diag()
関数を利用すると対角行列を生成できる。
print(a.diagonal())
# [ 0 5 10 15]
print(np.diag(a.diagonal()))
# [[ 0 0 0 0]
# [ 0 5 0 0]
# [ 0 0 10 0]
# [ 0 0 0 15]]
三角行列とその転置行列を足し合わせたものから対角行列を引くと所望の対称行列が得られる。
print(np.tril(a) + np.tril(a).T - np.diag(a.diagonal()))
# [[ 0 4 8 12]
# [ 4 5 9 13]
# [ 8 9 10 14]
# [12 13 14 15]]
これを関数にすると以下のようになる。対象のndarray
が正方行列ではない場合の例外処理は省略しているので注意。
def get_symmetric(a, use_tril=True):
if use_tril:
a = np.tril(a)
else:
a = np.triu(a)
return a + a.T - np.diag(a.diagonal())
第二引数use_tril
で元のndarray
の下三角成分を使うか上三角成分を使うかを選択できるようにしている。使用例は以下の通り。
print(get_symmetric(a))
# [[ 0 4 8 12]
# [ 4 5 9 13]
# [ 8 9 10 14]
# [12 13 14 15]]
print(get_symmetric(a, False))
# [[ 0 1 2 3]
# [ 1 5 6 7]
# [ 2 6 10 11]
# [ 3 7 11 15]]
NumPy配列ndarrayが対称行列であるか判定
ndarray
が対称行列であるかどうかは、元のndarray
とその転置が一致するかで判定できる。
np.array_equal()
を使うと簡単。
def is_symmetric(a):
return np.array_equal(a, a.T)
a_sym = get_symmetric(a)
print(a_sym)
# [[ 0 4 8 12]
# [ 4 5 9 13]
# [ 8 9 10 14]
# [12 13 14 15]]
print(is_symmetric(a_sym))
# True
print(is_symmetric(a))
# False
歪対称行列(交代行列)の場合
対称行列と同様の考え方で、歪対称行列(交代行列)を生成したり判定したりすることもできる。
歪対称行列(交代行列)の定義は以下の通り。
線型代数学において、交代行列(こうたいぎょうれつ、英: alternating matrix)、歪対称行列(わいたいしょうぎょうれつ、英: skew-symmetric matrix)または反対称行列(はんたいしょうぎょうれつ、英: antisymmetric matrix, antimetric matrix; 反称行列)は、正方行列 A であってその転置 A⊤ が自身の −1 倍となるものをいう。 交代行列 - Wikipedia
対称行列の場合と同様に、元のndarray
の下三角成分または上三角成分から生成できる。
def get_skew_symmetric(a, use_tril=True):
if use_tril:
a = np.tril(a)
else:
a = np.triu(a)
return a - a.T
print(get_skew_symmetric(a))
# [[ 0 -4 -8 -12]
# [ 4 0 -9 -13]
# [ 8 9 0 -14]
# [ 12 13 14 0]]
print(get_skew_symmetric(a, False))
# [[ 0 1 2 3]
# [ -1 0 6 7]
# [ -2 -6 0 11]
# [ -3 -7 -11 0]]
判定も対称行列の場合と同様。
def is_skew_symmetric(a):
return np.array_equal(a, -a.T)
a_sk_sym = get_skew_symmetric(a)
print(a_sk_sym)
# [[ 0 -4 -8 -12]
# [ 4 0 -9 -13]
# [ 8 9 0 -14]
# [ 12 13 14 0]]
print(is_skew_symmetric(a_sk_sym))
# True
print(is_skew_symmetric(a))
# False