Pythonにおける行列の固有値問題の解法、行列の対角化

今日は行列の固有値問題を解いて、さらに行列の対角化をしてみます。

固有値問題

まずは固有値問題から。固有値問題とはAx=λxを満たすような固有ベクトルxと固有値λを求めるような問題のことです。
他のプログラムでは面倒くさいですがPythonなら簡単に求まります。

import numpy as np
list_a = (0,14,2)
list_b = (-1,9,-1)
list_c = (-2,4,8)
mat_a = np.array([list_a,list_b,list_c])
eigv_a,eigm_a=np.linalg.eig(mat_a)
print(eigv_a)
print(eigm_a)
[4. 6. 7.] 
[[ 9.42809042e-01 -9.12870929e-01 -8.94427191e-01]
 [ 2.35702260e-01 -3.65148372e-01 -4.47213595e-01]
 [ 2.35702260e-01 -1.82574186e-01 -5.57327535e-16]]

固有値固有ベクトルの順番は同じです。そして固有ベクトルは1に規格化されています。
すなわち
固有値4のとき固有ベクトル(9.42809042e-01,2.35702260e-01,2.35702260e-01)
人間にわかりやすくすれば(4,1,1)
固有値6のとき固有ベクトル(-9.12870929e-01,-3.65148372e-01,-1.82574186e-01)
人間にわかりやすくすれば(5,2,1)
固有値6のとき固有ベクトル(-8.94427191e-01,-4.47213595e-01,-5.57327535e-16)
人間にわかりやすくすれば(2,1,0)です。
そしてP-1AP=BのPがeigm_aになっています。

固有ベクトルpythonで出す場合は

eigm_a = np.transpose(eigm_a) 

np.transposeで転置行列を求めましょう。

[[ 9.42809042e-01  2.35702260e-01  2.35702260e-01]
 [-9.12870929e-01 -3.65148372e-01 -1.82574186e-01]
 [-8.94427191e-01 -4.47213595e-01 -5.57327535e-16]]

最初から綺麗に出したいときは

import numpy as np
list_a = (0,14,2)
list_b = (-1,9,-1)
list_c = (-2,4,8)
mat_a = np.array([list_a,list_b,list_c])
eigv_a,eigm_a = np.linalg.eig(mat_a)
eigm_a[np.abs(eigm_a) <= 1.0e-10] = 0.0 #端数を削除するため10^-10以下は0とみなす
eigm_a = np.transpose(eigm_a) 
eigm_abs = np.abs(eigm_a) #行列の絶対値を求める
eigmin = eigm_abs.min(axis=1) #行列の絶対値の各行の最小値を求める
for i in range (0,3):
    if eigmin[i] == 0.0:
        eigmin[i] = eigm_abs[i,0] #各行の最小値が0の場合はとりあえず1番目
for i in range (0,3):
    eigm_a[i,] = eigm_a[i,]/eigmin[i] #規格化する
print(eigm_a)

というのを考えました。汚いコードになってしまったので、もっと綺麗なプログラムがあるはずです。みなさんで作ってください。

[[ 4.   1.   1. ]
 [-5.  -2.  -1. ]
 [-1.  -0.5  0. ]]

今日はここまで。