固有値と固有ベクトル
固有分解/スペクトル分解
実対称行列Aの固有分解(岡本安晴、2019、pp. 61-67;岡本安晴、2009、pp.41-45)は、numpy.linalg.eigh(A)で簡単に求めることができる。正値実対称行列、正値でない実対称行列の簡単な例を用意したが、関数eighはエルミート行列の固有分解も行えるのでエルミート行列の簡単な場合も用意した。
正値実対称行列
の固有値と固有ベクトルを求める(固有分解)プログラムをリスト1のように作成してみた。
リスト1
import numpy as np
a = np.array([[1,0],[0,2]])
print('a =\n', a)
vals, vecs = np.linalg.eigh(a)
print('eigen values =\n', vals)
print('eigen vectors =\n', vecs)
#
# 固有値の降順に並べ換える。
#
idx = np.argsort(-vals)
vals = vals[idx]
vecs = vecs[:,idx]
print('vals =\n', vals)
print('vecs =\n', vecs)
a_ck = vecs @ np.diag(vals) @ vecs.T
print('a_ck =\n', a_ck)
固有値は昇順で返されるので、リスト1では降順に並べ替えている。
リスト1を実行すると、以下の出力を得る。
a =
[[1 0]
[0 2]]
eigen values =
[1. 2.]
eigen vectors =
[[1. 0.]
[0. 1.]]
vals =
[2. 1.]
vecs =
[[0. 1.]
[1. 0.]]
a_ck =
[[1. 0.]
[0. 2.]]
すなわち、固有値の大きさで並べ換える前:
固有値
固有ベクトル
Pythonのprint文print('eigen vectors =\n', vecs)による出力では、vecsは行単位にまとめられて出力されているが、固有ベクトルはvecsに列単位にまとめられている。
参照:
https://numpy.org/doc/stable/reference/generated/numpy.linalg.eigh.html
正定値ではない実対称行列
の固有分解を行うスクリプトをリスト2のように作成した。
リスト2
import numpy as np
a = np.array([[1,0],[0,-2]])
print('a =\n', a)
vals, vecs = np.linalg.eigh(a)
print('eigen values =\n', vals)
print('eigen vectors =\n', vecs)
a_ck = vecs @ np.diag(vals) @ vecs.T
print('a_ck =\n', a_ck)
リスト2を実行すると、以下の出力を得る。
a =
[[ 1
0]
[ 0 -2]]
eigen values =
[-2.
1.]
eigen vectors =
[[0. 1.]
[1. 0.]]
a_ck =
[[ 1. 0.]
[ 0. -2.]]
エルミート行列
の固有分解を行うスクリプトをリスト3のように用意した。
リスト3
import numpy as np
h = np.array([[1,1j],[-1j,-1]])
print('h =\n', h)
vals, vecs = np.linalg.eigh(h)
print('eigen values =\n', vals)
print('eigen vectors =\n', vecs)
h_ck = vecs @ np.diag(vals) @
np.conjugate(vecs).T
print('h_ck =\n', h_ck)
リスト3を実行すると、以下の出力を得る。
h =
[[ 1.+0.j 0.+1.j]
[-0.-1.j -1.+0.j]]
eigen values =
[-1.41421356 1.41421356]
eigen vectors =
[[ 0.38268343+0.j
-0.92387953+0.j ]
[ 0.
+0.92387953j 0.
+0.38268343j]]
h_ck =
[[ 1.+0.j 0.+1.j]
[ 0.-1.j -1.+0.j]]
すなわち、
である。