为何不反转矩阵的实际示例


16

我知道将矩阵求逆来求解线性系统不是一个好主意,因为它不如直接求解该系统或使用LU,Cholesky或QR分解那样准确和有效。

但是,我无法通过一个实际的例子进行验证。我已经尝试过此代码(在MATLAB中)

M   = 500;    
A   = rand(M,M);
A   = real(expm(1i*(A+A.')));
b   = rand(M,1);

x1  = A\b;
x2  = inv(A)*b;

disp(norm(b-A*x1))
disp(norm(b-A*x2))

并且残差总是相同的阶数(10 ^ -13)。

有人可以提供一个实际的例子,其中inv(A)* b的准确度远小于A \ b吗?

------问题更新------

谢谢您的回答。但是,假设我们必须求解次系统,其中始终是相同的矩阵。考虑一下A x = b AnAx=bA

-已满,因此需要存储器存储比相同。AA1A

条件数较小,因此可以精确计算。AA1

在那种情况下,计算比使用LU分解会更有效吗?例如,我已经尝试过以下Matlab代码:A1

%Set A and b:
M           = 1000; 
A           = rand(M,M);
A           = real(expm(1i*(A+A.')));
b           = rand(M,1);

%Times we solve the system:
n           = 3000;

%Performing LU decomposition:
disp('Performing LU decomposition')
tic
[L,U,P]     = lu(A);
toc
fprintf('\n')

%Solving the system n times with LU decomposition:
optsL.LT    = true;   %Options for linsolve
optsU.UT    = true;
disp('Solving the system n times using LU decomposition')
tic
for ii=1:n
    x1      = linsolve(U, linsolve(L,P*b,optsL) , optsU);
end
toc
fprintf('\n')

%Computing inverse of A:
disp('Computing inverse of A')
tic
Ainv        = inv(A);
toc
fprintf('\n')

%Solving the system n times with Ainv:
disp('Solving the system n times with A inv')
tic
for ii=1:n
    x2  = Ainv*b;
end
toc
fprintf('\n')

disp('Residuals')
disp(norm(b-A*x1))
disp(norm(b-A*x2))

disp('Condition number of A')
disp(cond(A))

对于条件数约为450的矩阵,两种情况下的残差均为,但是使用LU分解将系统求解n次需要19秒,而使用A的逆仅需9秒。O(1011)


8
MATLAB inv帮助页面提供了一个很好的示例。查看标题为“ 求解线性系统 ”的部分。
GoHokies

1
顺便说一句,您的矩阵的条件数是多少?我的PC上没有MATLAB,因此无法检查,但我认为它很小,可以让您获得准确的逆数...A
GoHokies

2
我看了Trefethen和Bau(练习21.4),他们纯粹用计算成本来描述它,即触发器与触发器。因此,即使您发现残差相似(您是否尝试过检查条件更差的矩阵,如GoHokies的评论?),仅是不必要的计算成本就值得考虑。22n323n3
基里尔

3
您的矩阵大小太小,无法进行比较。并不是说您拥有这样的矩阵并不存在相关的问题,但是您收到的您不应该求逆的观点是针对另一种设置的(例如,克里斯·拉卡卡斯(Chris Rackauckas)在回答中提到的一种设置)。实际上,对于条件良好的小型矩阵(确实是条件良好的矩阵),计算逆数确实是更好的选择。极端情况是3x3旋转(或更实际地,仿射变换)矩阵。
Christian Clason

1
如果您需要Ax=b用相同的方法反复求解,A并且它足够小以求逆,则可以保存LU分解并重复使用。
克里斯·拉科卡斯

Answers:


11

通常,出于某些原因,倾向于使用线性方程组来求解线性系统。简要地:

  • 条件编号有问题(@GoHokies评论)
  • 稀疏情况下的问题(@ChrisRackauckas答案)
  • 效率(@Kirill评论)

无论如何,正如@ChristianClason在评论中指出的那样,在某些情况下,使用反函数是一个不错的选择。

在Sivan Toledo的Alex Druinsky的注释/文章中,inv(A)* b的精确度如何?关于这个问题有一些考虑。

根据本文,普遍偏爱使用线性系统的主要原因是在这两个估计值之内(是真实解): X

||XV-X||Øκ2一种ϵ一种CH一世ñË 向后稳定(LU,QR等)||Xb一种Cķw一种[Rd-sŤ一种bË-X||Øκ一种ϵ一种CH一世ñË

现在,在一定条件下可以提高逆估计值,请参见本文中的定理1,但可以有条件地精确且不向后稳定。XV

本文显示了发生这种情况的情况(为倒数)V

(1)不是一个好的右逆,或V

(2)如此差的左逆,所以| | x V | | |小得多 | x | | , 要么V||XV||||X||

(3)在与小奇异值关联的A的左奇异矢量上的投影很小。b一种

因此,是否有可能使用反函数取决于应用程序,您可以查看文章并确定是否满足获得向后稳定性的条件,或者是否不需要它。

总的来说,我认为,线性系统更安全。


12

Δü

üŤ=Δü+FŤü

一种

üŤ=一种ü+FŤü

一种一世-γ一种SpecialMatrices.jl

julia> using SpecialMatrices
julia> Strang(5)
5×5 SpecialMatrices.Strang{Float64}:
 2.0  -1.0   0.0   0.0   0.0
-1.0   2.0  -1.0   0.0   0.0
 0.0  -1.0   2.0  -1.0   0.0
 0.0   0.0  -1.0   2.0  -1.0
 0.0   0.0   0.0  -1.0   2.0

ñØ3ñØ1个

但是,假设我们要反转矩阵。

julia> inv(collect(Strang(5)))
5×5 Array{Float64,2}:
 0.833333  0.666667  0.5  0.333333  0.166667
 0.666667  1.33333   1.0  0.666667  0.333333
 0.5       1.0       1.5  1.0       0.5
 0.333333  0.666667  1.0  1.33333   0.666667
 0.166667  0.333333  0.5  0.666667  0.833333

Øñ2

\IterativeSolvers.jl一种X=b一种-1个一种

正如其他人提到的那样,条件数和数值误差是另一个原因,但是稀疏矩阵的逆是密集的这一事实非常清楚地表明“这是一个坏主意”。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.