これまで無意識で使っていたのですが、NumPy
、固有ベクトルを正規化している らしいです。
(たしかに、複数の行列の固有ベクトルを比較するとき、統一的な出力にした方が解釈しやすい、、)と思いつつ、
実際に確かめてみたいと思います。
本記事では↓の例題を考えます。
例題
行列 A = \left(\begin{matrix} 4 & 1 \\ -2 & 1 \end{matrix}\right)の固有値と固有ベクトルを求めよ。
これを素直に解くと、λ をAの固有値(=定数)として、
(※手計算の過程を飛ばして先へ進む。)
\begin{align}
\det\left(\begin{matrix} 4 - \lambda & 1 \\ -2 & 1 - \lambda \end{matrix}\right) = 0 \\
\iff (4 - \lambda)(1 - \lambda) - (-2) = 0 \\
\iff \lambda^2 -5\lambda + 6 = 0 \\
\iff \lambda = 2, 3
\end{align}
と固有値が求まりました。
それぞれの固有値に対する固有ベクトルは、
\begin{align}
\lambda = 2 の時、\boldsymbol{x_1}\ = \left(\begin{matrix} 1 \\ -2\\
\end{matrix}\right) \\
\lambda = 3 の時、\boldsymbol{x_2}\ = \left(\begin{matrix} 1 \\ -1 \end{matrix}\right) \\
\end{align}
となりました。
コーディングしてみましょう。
numpy
を使って解く
by_numpy
import numpy as np
A = np.array([[4, 1],
[-2, 1]])
eigenvalues_A, eigenvectors_A = np.linalg.eig(A)
eigenvalues_A, eigenvectors_A
とすると、出力は
出力_by_numpy
(array([3., 2.]),
array([[ 0.70710678, -0.4472136 ],
[-0.70710678, 0.89442719]]))
となりました。
ここで、numpy
\begin{align}
\lambda = 2 \text{ の時 }、\boldsymbol{x_1}\ = \left(\begin{matrix} -0.4472... \\ 0.8944...\end{matrix}\right) \\
\lambda = 3 \text{ の時 }、\boldsymbol{x_2}\ = \left(\begin{matrix} 0.7071... \\ 0.7071...\end{matrix}\right) \\
\end{align}
となります。
ここで、手計算で出した固有ベクトルを正規化してみましょう。
\begin{align}
\lambda = 2 の時、\boldsymbol{x_1}\ = \left(\begin{matrix} 1 \\ -2\\
\end{matrix}\right) \\
\text{を正規化すると、} \\
x_{11} = \frac{1}{\sqrt{1^2 + (-2)^2}} = \frac{1}{\sqrt{5}} = 0.4472... \\
x_{21} = \frac{-2}{\sqrt{1^2 + (-2)^2}} = \frac{-2}{\sqrt{5}} = - 0.8944... \\
\end{align}
よって、NumPyが固有ベクトルを正規化して出力していることを確かめることができました。
scipy
を使って解く
scipy
を使っても解けます。
by_scipy
from scipy.linalg import eig
eigenvalues, eigenvectors = eig(A)
eigenvalues, eigenvectors
_by_scipy
(array([3.+0.j, 2.+0.j]),
array([[ 0.70710678, -0.4472136 ],
[-0.70710678, 0.89442719]]))
ちなみに、ここでの.j
は虚部が0であることを表してます。