版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_38918949/article/details/82217702
R语言:SVD分解求解线性方程组AX=b
当 是方阵时,可以直接用内置函数解,当 不是方阵时,只能求得最小二乘解。
函数svd的用法
svd分解X,使用函数svd,返回一个列表T,顺序是d, u, v。
T <- svd(X)
U <- T$u
D <- T$d
V <- T$v
这里T是list,注意这里的U和V是矩阵,D是向量,想要恢复原矩阵X,需要:
Y <- U %*% diag(D) %*% t(V)
求解方法
问题:求 使得(最小二乘解):
线性方程组形式
对 进行SVD分解:
的广义逆矩阵 :
其中 是 的广义逆:
广义逆的定义是:
数值分析书上讲,是非零元的逆的转置。但此时计算时出现问题:
> A <- matrix(rep(1,18),nrow = 3)
#### A的秩为1
> T <- svd(A)
#### 对A进行svd分解
> A2 <- T$u %*% diag(T$d) %*% t(T$v)
#### 利用svd分解恢复A
> diag(T$d)
# [,1] [,2] [,3]
# [1,] 4.242641 0.000000e+00 0.000000e+00
# [2,] 0.000000 8.107923e-16 0.000000e+00
# [3,] 0.000000 0.000000e+00 6.972611e-32
这里就出现问题了,虽然A的秩为1,但是计算得到的奇异值,由于精度原因,后两个为很接近于0的数。
所以要利用svd算A的广义逆,需要忽略后两项。取diag(T$d)的前r项,这个r就是A的rank。求A的rank可以用qr分解
r <- qr(A)$rank
在数值计算中,太小的奇异值会被忽略,这就成为低秩分解。
还有一种方法,直接设置阈值 ,小于 的都记为0,但是这个 的取法我还没有查到文献记载。
那么:
矩阵形式
则
系数矩阵为右乘
对上式求转置即可:
对 进行SVD分解,按照上面计算得到 ,再转置得到 。