inv(matrix) takes shorter time than \ operator
Mostra commenti meno recenti
A=magic(5)
A =
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
>> tic
inv(A)
toc
ans =
-0.0049 0.0512 -0.0354 0.0012 0.0034
0.0431 -0.0373 -0.0046 0.0127 0.0015
-0.0303 0.0031 0.0031 0.0031 0.0364
0.0047 -0.0065 0.0108 0.0435 -0.0370
0.0028 0.0050 0.0415 -0.0450 0.0111
Elapsed time is 0.006097 seconds.
>> tic
B=eye(5);
A\B
toc
ans =
-0.0049 0.0512 -0.0354 0.0012 0.0034
0.0431 -0.0373 -0.0046 0.0127 0.0015
-0.0303 0.0031 0.0031 0.0031 0.0364
0.0047 -0.0065 0.0108 0.0435 -0.0370
0.0028 0.0050 0.0415 -0.0450 0.0111
Elapsed time is 0.008993 seconds.
Just a general question, shouldn't have been the other way round? inv(matrix) is supposed to be more computationally intensive than the \ operation.
6 Commenti
Jan
il 8 Feb 2013
This is an basic and important problem in the field of numerical linear algebra. +1
Matt J
il 30 Lug 2020
Armin Schmidt's comments moved here:
Hey, I know this discussion is already a little bit older, but I have a similar question to inv and \, but in relation with the mahalanobis-distance. I can get from an other class the covariance-matrices of each cluster. Now I want to calculate the mahalanobis-distance: (x-mu)*cov^(-1)*(x-mu)', where mu is the centroid of each cluster and x the current feature-vector to measure the distance to my clusters (classes). Now to write A*inv(cov)*A' (for A=(x-mu)) would be numerically instable. what would be the best way to calculate the mahalanobis-distance in this case? Could I write something like A * cov\A' and would that be numerically more stable?
Matt J
il 30 Lug 2020
@Armin,
Yes, you could do that. I don't know about stability improvements, but it would definitely be faster.
Bruno Luong
il 30 Lug 2020
Modificato: Bruno Luong
il 30 Lug 2020
But here A is a vector isn't it?
So when we discuss of advantage/disadvantage of
inv(C)
vs
C\eye(size(C))
they are no longer apply to
inv(C)*A
vs
C\A
For vector C\A win hand down, period.
Matt J
il 30 Lug 2020
We can only assume it is a vector, based on where Armin wrote: "where mu is the centroid of each cluster and x the current feature-vector"
Christine Tobler
il 31 Lug 2020
Based on the formula (x-mu)*cov^(-1)*(x-mu)', you'd expect the output here to be symmetric positive (semi-)definite. If cov is numerically full rank, you can use the following to compute this matrix in a way that will keep it symmetric positive semi-definite.
R = chol(cov);
A = (x-mu)/R;
A = A*A';
If cov is low-rank (positive semi-definite), you could consider doing the same using the ldl function instead of chol.
Risposta accettata
Più risposte (2)
James Tursa
il 8 Feb 2013
5 voti
1) Your example is so small as to make the timing irrelevant
2) You burden the \ method with creating another variable, B
3) The \ operation doesn't know ahead of time that B is the identity matrix, so it may not be able to take computational advantage of that fact.
4) Why do you think inv is more computationally intensive than \ ?
2 Commenti
5) Omitting semicolons and displaying to the screen is also adding unnecessary overhead.
6) You have to re-run the code multiple times, preferably inside a function to see a fully optimized execution. There is no way inv(A) on a 5x5 matrix takes 0.006097 seconds on any reasonable machine.
the cyclist
il 8 Feb 2013
Modificato: the cyclist
il 8 Feb 2013
Regarding James' point #4, he may have gotten the idea from the documentation of the inv() function:
"In practice, it is seldom necessary to form the explicit inverse of a matrix. A frequent misuse of inv arises when solving the system of linear equations Ax = b. One way to solve this is with x = inv(A)*b. A better way, from both an execution time and numerical accuracy standpoint, is to use the matrix division operator x = A\b."
@Bramen, I think the larger worry with inv() is actually the numerical stability for arrays that are nearly singular. See, for example, this old blog post:
Matt J
il 8 Feb 2013
It's not that inv(A) is supposed to be more computationally intensive than \. It's that A\b is faster than inv(A)*b, as demonstrated below.
N=2000;
A=rand(N);
b=rand(N,1);
tic;
inv(A)*b;
toc
Elapsed time is 0.509519 seconds.
tic
A\b;
toc
Elapsed time is 0.195016 seconds.
4 Commenti
Daniel
il 4 Nov 2015
The least squares estimate in statistics is a very common use of inv(X'*X) and there the size of (X'X) is usually somewhere between 2x2 and 10x10. For those cases inv() appears much faster, as you can see here:
X = normrnd(0,1,100,4);
beta=[1 2 3 4]';
y = X*beta;
tic;
for i=1:10000
inv(X'*X)*X'*y;
end
toc;
tic;
for i=1:10000
(X'*X)\X'*y;
end
toc;
Elapsed time is 0.144074 seconds.
Elapsed time is 0.236353 seconds.
I have to do this operation literally one billion times, so changing the code reduces the time from 3 days to 2 days which is nice... And the constant change recommendation from Matlab is annyoing.
And btw the QR method is the slowest:
tic;
for i=1:n
[Q,R] = qr(X,0);
inv(R)*inv(R)'*X'*y;
end
toc;
Elapsed time is 0.375314 seconds.
You shouldn't be comparing with (X'*X)\X'*y nor with an explicit call to qr(). You should be comparing with X\y, which is equivalent (in this case) to the QR method.
tic;
for i=1:10000
inv(X'*X)*X'*y;
end
toc;
tic;
for i=1:10000
(X'*X)\X'*y;
end
toc;
tic;
for i=1:10000
X\y;
end
toc;
Elapsed time is 0.082173 seconds.
Elapsed time is 0.157320 seconds.
Elapsed time is 0.086341 seconds.
That said, when you have a very tall X matrix, then using the normal equations directly can be faster, and also save memory. However, since X'*X has a higher condition number than X, it will also be less stable numerically and amplify noise, as demonstrated in the example below. So you need to be sure you have a well-conditioned X in order for this to be a good compromise.
d=30;
N=1e5;
X=diag(1:d).^2*rand(d,'single');
noise=randn(d,N);
z1 = X\noise;
Error1=std(z1(:)),
z2=(inv(X.'*X)*X.'*noise);
Error2=std(z2(:)),
Error1 =
1.6255
Error2 =
210.7583
Daniel
il 10 Nov 2015
Oh, thanks for that answer. I wasn't aware of this. It should make the code faster and ease the problem of stability that I happened to have.
Categorie
Scopri di più su Mathematics in Centro assistenza e File Exchange
Prodotti
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!