[R]特異値分解を行う
svd関数を使う。特異値分解の等式は以下のとおり。
A = U D V^T
UとVは直交行列。DはAの特異値を対角成分にもつ対角行列。
> a <- matrix(1:9, 3, 3)
> a
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
> r <- svd(a)
> r
$d
[1] 1.684810e+01 1.068370e+00 5.543107e-16
$u
[,1] [,2] [,3]
[1,] -0.4796712 0.77669099 0.4082483
[2,] -0.5723678 0.07568647 -0.8164966
[3,] -0.6650644 -0.62531805 0.4082483
$v
[,1] [,2] [,3]
[1,] -0.2148372 -0.8872307 0.4082483
[2,] -0.5205874 -0.2496440 -0.8164966
[3,] -0.8263375 0.3879428 0.4082483
svd関数の戻り値はリストで、要素dに特異値が代入されている。
> r$d
[1] 1.684810e+01 1.068370e+00 5.543107e-16
上記の恒等式における、行列U(戻り値では要素u)と行列V(戻り値では要素v)が直交行列であることを確認する。
> t(r$u) %*% r$u
[,1] [,2] [,3]
[1,] 1.000000e+00 1.110223e-16 5.551115e-17
[2,] 1.110223e-16 1.000000e+00 -1.110223e-16
[3,] 5.551115e-17 -1.110223e-16 1.000000e+00
> t(r$v) %*% r$v
[,1] [,2] [,3]
[1,] 1.000000e+00 0.000000e+00 -1.110223e-16
[2,] 0.000000e+00 1.000000e+00 1.110223e-16
[3,] -1.110223e-16 1.110223e-16 1.000000e+00
上記の恒等式が成り立っているか確認する。
> r$u %*% diag(r$d) %*% t(r$v)
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
行列Aの特異値は、A^T Aの正の固有値の兵の平方根でも求められる。
> sqrt(eigen(t(a) %*% a)$values)
[1] 1.684810e+01 1.068370e+00 7.942757e-08
3つ目は、実質0ということだが、高精度に計算されていないことがわかる。
