Ví dụ thực tế về lý do tại sao đảo ngược ma trận là không tốt


16

Tôi biết rằng việc đảo ngược một ma trận để giải quyết một hệ thống tuyến tính không phải là một ý tưởng tốt, vì nó không chính xác và hiệu quả như giải quyết trực tiếp hệ thống hoặc sử dụng phân tách LU, Cholesky hoặc QR.

Tuy nhiên, tôi đã không thể kiểm tra điều này với một ví dụ thực tế. Tôi đã thử mã này (trong 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))

và phần dư luôn theo cùng một thứ tự (10 ^ -13).

Ai đó có thể cung cấp một ví dụ thực tế trong đó inv (A) * b ít chính xác hơn A \ b không?

------ Cập nhật câu hỏi ------

Cảm ơn bạn cho câu trả lời của bạn. Tuy nhiên, giả sử rằng chúng ta phải giải lần một hệ thống A x = b , trong đó A luôn là cùng một ma trận. Xem xét điều đónAx=bA

- là đầy đủ, và do đó A - 1 đòi hỏi bộ nhớ lưu trữ cùng hơn Một .AA1A

-Số điều kiện của nhỏ, do đó A - 1 có thể được tính toán với độ chính xác.AA1

Trong trường hợp đó, sẽ không hiệu quả hơn khi tính thay vì sử dụng phân tách LU? Ví dụ: tôi đã thử mã Matlab này: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))

Đối với một ma trận có số điều kiện khoảng 450, phần dư là trong cả hai trường hợp, nhưng phải mất 19 giây để giải hệ thống n lần bằng cách sử dụng phân tách LU, trong khi sử dụng nghịch đảo A chỉ mất 9 giây.O(1011)


8
trang trợ giúp MATLAB cho inv đưa ra một ví dụ hay. Xem dưới phần có tiêu đề Hệ thống tuyến tính giải quyết .
GoHokies 17/03/2017

1
A

2
2n323n3

3
Kích thước ma trận của bạn là quá nhỏ và có điều kiện để so sánh này. Không phải là không có vấn đề liên quan khi bạn có ma trận như vậy, nhưng ý kiến ​​nhận được rằng bạn không nên đảo ngược có nghĩa là cho một cài đặt khác (ví dụ: câu hỏi được đề cập bởi Chris Rackauckas trong câu trả lời của anh ấy). Trong thực tế, đối với các ma trận nhỏ và - chắc chắn - được điều hòa tốt, tính toán nghịch đảo thực sự có thể là lựa chọn tốt hơn. Một trường hợp cực đoan sẽ là ma trận xoay 3x3 (hoặc, thực tế hơn, biến đổi affine).
Christian Clason

1
Nếu bạn cần liên tục giải quyết Ax=btương tự Avà nó đủ nhỏ để thực hiện nghịch đảo, thay vào đó bạn có thể lưu hệ số LU và sử dụng lại điều đó.
Chris Rackauckas

Câu trả lời:


11

Thông thường có một số lý do chính để giải quyết sự tôn trọng hệ thống tuyến tính để sử dụng nghịch đảo. Tóm tắt:

  • vấn đề với số có điều kiện (bình luận @GoHokies)
  • vấn đề trong trường hợp thưa thớt (câu trả lời @ChrisRackauckas)
  • hiệu quả (bình luận @Kirill)

Dù sao, như @ChristianClason đã nhận xét trong các bình luận, có thể là một số trường hợp trong đó việc sử dụng nghịch đảo là một lựa chọn tốt.

Trong ghi chú / bài viết của Alex Druinsky, Sivan Toledo, Làm thế nào chính xác là inv (A) * b? có một số xem xét về vấn đề này.

x

inverse||xVx||O(κ2(A)ϵmachine) backward stable (LU, QR,...)||xbackwardstablex||O(κ(A)ϵmachine)

xV

V

V

V||xV||||x||

bA

Vì vậy, cơ hội sử dụng hay không phụ thuộc vào ứng dụng, bạn có thể kiểm tra bài viết xem liệu trường hợp của bạn có thỏa mãn điều kiện để có được sự ổn định ngược hay nếu bạn không cần nó.

Nói chung, theo tôi, là an toàn hơn giải quyết hệ thống tuyến tính.


12

Δu

ut=Δu+f(t,u).

A

ut=Au+f(t,u)

AIγASpecialMatrices.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

nO(3n)O(1)

Tuy nhiên, giả sử chúng ta muốn đảo ngược ma trận.

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

O(n2)

\IterativeSolvers.jlAx=bA1A

Như những người khác đã đề cập, số điều kiện và lỗi số là một lý do khác, nhưng thực tế là nghịch đảo của một ma trận thưa thớt dày đặc cho thấy rất rõ "đây là một ý tưởng tồi".

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.