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

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

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

函数svd的用法

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

X=UDV 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 x 使得(最小二乘解):

线性方程组形式

Ax=b A x = b

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

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

其中 D+ D + D D 的广义逆:
广义逆的定义是:
D+=(DD)1D 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 x = A + b

矩阵形式

AX=B A X = B


X=A+B X = A + B

系数矩阵为右乘

XA=B X A = B

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

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

你可能感兴趣的:(计算数学)