固有値・固有ベクトルを求める簡単な方法としてはパワー法がある(パワー法は,あくまでも簡便法である。より一般的で精度も十分で計算速度も速いアルゴリズムは数多くある)。
例題:
「行列 $\mathbf{A}$ の,固有値と固有ベクトルを求めなさい。」
\[ \mathbf{A} = \left ( \begin{array}{rrr} 1.0 & 0.5 & 0.3 \\ 0.5 & 1.0 & 0.6 \\ 0.3 & 0.6 & 1.0 \end{array} \right ) \]
> ( A <- matrix(c(1, 0.5, 0.3, 0.5, 1.0, 0.6, 0.3, 0.6, 1.0), byrow=TRUE, ncol=3) ) [,1] [,2] [,3] [1,] 1.0 0.5 0.3 [2,] 0.5 1.0 0.6 [3,] 0.3 0.6 1.0 > eigen(A) # 固有値・固有ベクトルを求める関数 $values [1] 1.9437808 0.7068785 0.3493407 $vectors [,1] [,2] [,3] [1,] -0.5187544 0.78724483 0.3333758 [2,] -0.6371903 -0.09604819 -0.7646982 [3,] -0.5699846 -0.60911437 0.5514502
\[ \mathbf{u}_1 = \left ( \begin{array}{rrr} 1.0 \\ 0.0 \\ 0.0 \end{array} \right ) \]
> ( u <- c(1, 0, 0) ) [1] 1 0 0
\[ \mathbf{A}\ \mathbf{u}_{1} = \left ( \begin{array}{rrr} 1.0 & 0.5 & 0.3 \\ 0.5 & 1.0 & 0.6 \\ 0.3 & 0.6 & 1.0 \end{array} \right )\ \left ( \begin{array}{rrr} 1.0 \\ 0.0 \\ 0.0 \end{array} \right ) = \left ( \begin{array}{rrr} 1.0 \\ 0.5 \\ 0.3 \end{array} \right ) \]
> ( Au <- A %*% u ) [,1] [1,] 1.0 [2,] 0.5 [3,] 0.3
\[ ノルム = 1.0^{2} + 0.5^{2} + 0.3^{2} = 1.34 \]
> ( norm <- sum(Au^2) ) [1] 1.34
\[ 固有値 = \sqrt{1.34} = 1.158 \]
> ( lambda <- sqrt(norm) ) [1] 1.157584
\[ \mathbf{u}_2 = \left ( \begin{array}{rrr} 1.0\ /\ 1.158 \\ 0.5\ /\ 1.158 \\ 0.3\ /\ 1.158 \end{array} \right ) = \left ( \begin{array}{rrr} 0.864 \\ 0.432 \\ 0.259 \end{array} \right ) \]
> ( u <- Au/lambda ) [,1] [1,] 0.8638684 [2,] 0.4319342 [3,] 0.2591605
例えば 0.001 以下の誤差範囲内の解は,数回の繰り返しで求められ,
固有値 = 1.944,固有ベクトル = ( 0.519, 0.637, 0.570 )' となる。
> repeat { + Au <- A %*% u + lambda2 <- sqrt(sum(Au^2)) + u <- Au/lambda2 + if (abs(lambda2-lambda) < 0.00001) break + lambda <- lambda2 + } > lambda [1] 1.94377 > u [,1] [1,] 0.5191201 [2,] 0.6371451 [3,] 0.5697021
$n \times n$ 行列の固有値・固有ベクトルは $n$ 対得られるので,次に,2 番目の固有値・固有ベクトルを求める。
このためには,元の行列 $\mathbf{A}$ の各要素に対して,以下の演算を行った新たな行列(残差行列)に対して上述の手続きを繰り返す。
\[ A_{ij} - 固有値 \times u_i \times u_j \rightarrow A_{ij} \] $u_i$,$u_j$ は固有ベクトルの第 $i$ 要素,第 $j$ 要素。
2 番目の固有値・固有ベクトルは 0.707,( 0.787,-0.0961, -0.609 )'> ( A <- A-lambda * (u %*% t(u)) ) [,1] [,2] [,3] [1,] 0.4761817 -0.1429114 -0.2748581 [2,] -0.1429114 0.2109189 -0.1055554 [3,] -0.2748581 -0.1055554 0.3691289
3 番目の固有値・固有ベクトルは 0.349,( 0.333,-0.765, 0.551 )'> ( u <- c(1, 0, 0) ) [1] 1 0 0 > repeat { + Au <- A %*% u + lambda2 <- sqrt(sum(Au^2)) + u <- Au/lambda2 + if (abs(lambda2-lambda) < 0.00001) break + lambda <- lambda2 + } > lambda [1] 0.706869 > u [,1] [1,] 0.78708384 [2,] -0.09801462 [3,] -0.60900917
全ての固有値・固有ベクトルを求めた後,最後の残差行列の各要素は 0 に近い値になっているはずである。> ( A <- A-lambda * (u %*% t(u)) ) [,1] [,2] [,3] [1,] 0.03827570 -0.08837948 0.06397343 [2,] -0.08837948 0.20412812 -0.14774970 [3,] 0.06397343 -0.14774970 0.10695672 > ( u <- c(1, 0, 0) ) [1] 1 0 0 > repeat { + Au <- A %*% u + lambda2 <- sqrt(sum(Au^2)) + u <- Au/lambda2 + if (abs(lambda2-lambda) < 0.00001) break + lambda <- lambda2 + } > lambda [1] 0.3493423 > u [,1] [1,] 0.3309719 [2,] -0.7644015 [3,] 0.5533063
> ( A <- A-lambda * (u %*% t(u)) ) [,1] [,2] [,3] [1,] 7.905913e-06 2.530936e-06 -1.232010e-06 [2,] 2.530936e-06 4.004597e-06 4.017210e-06 [3,] -1.232010e-06 4.017210e-06 6.287713e-06
演習問題:
応用問題: