2016/11/03

固有値問題

固有値問題


$n$ 次正方行列 $A$ に対して、 \[ \bm{Ax} = \lambda \bm{x} \] を満たすベクトル $\bm{x} \neq \bm{0}$ と、スカラー $\lambda$ をそれぞれ固有ベクトル、固有値と呼びます。

固有値分解


一般に $\bm{A}$ の成分が全て実数、すなわち実行列であっても、その固有値は虚数になることがあります。 $\bm{A}$ が実対称行列であれば、固有値は実数になります。また、そのときの異なる固有ベクトルは互いに直交します。以下では $\bm{A}$ は対称行列とします。 対称行列 $\bm{A}$ の固有値、固有ベクトルを $\lambda_i, \bm{u}_i, i=1,\dots,n$とします。 ここで固有ベクトルは正規直交になるようにとります。$\bm{Au}_i = \lambda_i \bm{u}_i$ より、 \[ \bm{A} [ \bm{u}_1, \dots, \bm{u}_n ] = [ \bm{u}_1, \dots, \bm{u}_n ] \text{diag}[\lambda_1, \dots, \lambda_n] \] となります。 直交行列 $\bm{U} = [ \bm{u}_1, \dots, \bm{u}_n ]$、 対角行列 $\bm{\Lambda} = \text{diag}[\lambda_1, \dots, \lambda_n] $ を用いると、 \[ \bm{A} \bm{U} = \bm{U} \bm{\Lambda} \] と書けます。$\bm{U}$ は直交行列で、$\bm{U}^{-1} = \bm{U}^\top$ となるので、 $\bm{A}$ の固有値分解は次のように書けます。 \[ \bm{A} = \bm{U} \bm{\Lambda} \bm{U}^\top \]

一般化固有値問題


\[ \bm{Ax} = \lambda \bm{B} \bm{x} \] の $\bm{x}$ と $\lambda$ を求めることは一般化固有値問題と呼ばれます。 一般化固有値問題はレイリー商 $\frac{\bm{x}^\top \bm{Ax}}{\bm{x}^\top \bm{Bx}}$ の最大化などに用いられます。 $\bm{B}$ が正則であれば \[\bm{B}^{-1} \bm{Ax} = \lambda {x}\] から通常の固有値問題に帰結することできます。

Pythonでの固有値問題


NumPy/SciPyで固有値問題を解くには、
  • np.linalg.eig・・・一般の行列の固有値問題
  • np.linalg.eigh ・・・対称行列の場合
  • sp.linalg.eig・・・一般化固有値問題
  • sp.linalg.eigh・・・対称行列の一般化固有値問題
などを用います。

参考


対称行列の固有値分解をnp.linalg.eigで行います。

A = np.array([[1, 2], [2, 1]])
w, v = np.linalg.eig(A)
A_ = v @ np.diag(w) @ v.T
A_は np.array([[ 1., 2.], [ 2., 1.]]) となり、行列が元に戻せていることがわかります。 np.linalg.eighは行列の上三角部か下三角部のどちらかを使います。オプション引数がUPLO='U'だと上三角、UPLO='O'だと下三角になります。

B = np.array([[1, 2], [3, 1]])
w, v = np.linalg.eigh(B, UPLO='U')
B_ = v @ np.diag(w) @ v.T
BとAは異なる行列ですが、Bの上三角部分がAと同じなので、オプション'U'を使った場合は復元後のB_とA_は同じになります。