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になっています。
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. ]]
今日はここまで。