inv(A)*B*inv(A) or A\B/A, which is more accurate for a full rank A and half rank B
7 views (last 30 days)
Show older comments
My matrices are
A = [0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 2 0 0
0 0 0 0 0 0 6 0 0 0
0 0 0 0 0 24 0 0 0 0
1953050.78182336 390611.805629631 78122.6909803108 15624.6041672176 3124.93402773033 624.989444414569 124.998416658843 24.9997888874000 4.99997888869543 1
3515506.25066668 624981.527842487 109372.229170523 18749.6041663820 3124.94722207284 499.993666635371 74.9993666622000 9.99995777739086 1 0
5624833.75058238 874977.833364188 131247.229164674 18749.6833324371 2499.96833317685 299.997466648800 29.9998733321726 2 0 0
7874800.50027769 1049977.83331739 131247.783327059 14999.8099990611 1499.98733324400 119.999493328690 6 0 0 0
9449800.49985652 1049982.26661648 104998.669993428 8999.92399946400 599.997466643452 24 0 0 0 0];
B=[0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
3515506.25066668 624981.527842487 109372.229170523 18749.6041663820 3124.94722207284 499.993666635371 74.9993666622000 9.99995777739086 1 0
5624833.75058238 874977.833364188 131247.229164674 18749.6833324371 2499.96833317685 299.997466648800 29.9998733321726 2 0 0
7874800.50027769 1049977.83331739 131247.783327059 14999.8099990611 1499.98733324400 119.999493328690 6 0 0 0
9449800.49985652 1049982.26661648 104998.669993428 8999.92399946400 599.997466643452 24 0 0 0 0
9449840.39954828 839989.359947423 62999.4679962480 3599.98479986071 120 0 0 0 0 0];
I tried both inv(A)*B*inv(A) or A\B/A, resulting in very different results for a gradient descent algorithm.
So, which is more accurate?
2 Comments
Torsten
on 11 Jun 2024
Did you think about why you get different results ? Is your matrix A near to singular and badly conditioned ? What do you get with
cond(A)
?
Can you include the matrix here for testing ?
Accepted Answer
John D'Errico
on 11 Jun 2024
Edited: John D'Errico
on 11 Jun 2024
Why would you want to compute the inverse of A TWICE ANYWAY? Even using both slash and backslash is arguably a bad idea, since again, you are doing way more work than you need.
Instead, decompose A. For example, you might decide to compute a QR factorization for A. Or perhaps an LU. Even then, the condition number of A is large enough that when you do two solves, it still inflates any noise in the system by the SQUARE of the condition number. And since you have given us only numbers to 14 significant digits, that means anything you get will probably be complete crap, no matter what you do.
A = [0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 2 0 0
0 0 0 0 0 0 6 0 0 0
0 0 0 0 0 24 0 0 0 0
1953050.78182336 390611.805629631 78122.6909803108 15624.6041672176 3124.93402773033 624.989444414569 124.998416658843 24.9997888874000 4.99997888869543 1
3515506.25066668 624981.527842487 109372.229170523 18749.6041663820 3124.94722207284 499.993666635371 74.9993666622000 9.99995777739086 1 0
5624833.75058238 874977.833364188 131247.229164674 18749.6833324371 2499.96833317685 299.997466648800 29.9998733321726 2 0 0
7874800.50027769 1049977.83331739 131247.783327059 14999.8099990611 1499.98733324400 119.999493328690 6 0 0 0
9449800.49985652 1049982.26661648 104998.669993428 8999.92399946400 599.997466643452 24 0 0 0 0];
cond(A)
cond(A)^2
Do you see that any noise in the least significant digits of B will potentially be amplified by the SQUARE of the condition number here, and that means, since you have only 14 significant digits in both A and B, the result may be meaningless?
B=[0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
3515506.25066668 624981.527842487 109372.229170523 18749.6041663820 3124.94722207284 499.993666635371 74.9993666622000 9.99995777739086 1 0
5624833.75058238 874977.833364188 131247.229164674 18749.6833324371 2499.96833317685 299.997466648800 29.9998733321726 2 0 0
7874800.50027769 1049977.83331739 131247.783327059 14999.8099990611 1499.98733324400 119.999493328690 6 0 0 0
9449800.49985652 1049982.26661648 104998.669993428 8999.92399946400 599.997466643452 24 0 0 0 0
9449840.39954828 839989.359947423 62999.4679962480 3599.98479986071 120 0 0 0 0 0];
Even so, we might try a QR or an LU. Simplest would be to do this:
Afac = decomposition(A)
As you can see, it chose an LU by default.
Afac\B/Afac
That requires MATLAB to perform only one operation in the form of a decomposition. As such, it will be considerably more efficient to perform. It will be a far better solution that using the inverse matrix almost always.
My real question is, can you improve the condition of A? If I look at the last 5 rows of A, it looks like a Vandermonde matrix. That would suggest re-scaling the polynomial variable to be on the order of 1, instead of going out as far as 5. All it is is a variable re-scaling, but it would improve the problem dramatically. For example...
Ahat = [A(1:5,:);A(6:10,:)*diag(5.^(-9:1:0))]
cond(Ahat)
9 Comments
More Answers (2)
See Also
Categories
Find more on Spline Postprocessing in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!