R语言:SVD分解求解线性方程组AX=b

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_38918949/article/details/82217702

R语言:SVD分解求解线性方程组AX=b

A 是方阵时,可以直接用内置函数解,当 A 不是方阵时,只能求得最小二乘解。

函数svd的用法

svd分解X,使用函数svd,返回一个列表T,顺序是d, u, v。

X = U D 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)

求解方法

问题:求 x 使得(最小二乘解):

线性方程组形式

A x = b

A 进行SVD分解:
A = U D V

A 的广义逆矩阵 A +
A + = V D + U

其中 D + D 的广义逆:
广义逆的定义是:
D + = ( D D ) 1 D

数值分析书上讲,是非零元的逆的转置。但此时计算时出现问题:

> 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,但是这个 θ 的取法我还没有查到文献记载。

那么:

x = A + b

矩阵形式

A X = B


X = A + B

系数矩阵为右乘

X A = B

对上式求转置即可:
A X = B

A 进行SVD分解,按照上面计算得到 X ,再转置得到 X

猜你喜欢

转载自blog.csdn.net/sinat_38918949/article/details/82217702