svd(X,"econ") does not work as expected if X is square nxn matrix with rank<n
2 views (last 30 days)
If X=[1 1;1 1] then with [U,S,V]=svd(X,"econ") I had expected that U=V=[1;1]/sqrt(2) and S=.
But "econ" does not work, S=[2 0;0 0] and U=V=[1 1;1 -1]/sqrt(2) (actually matlab gives opposite signs in U, but that does not matter).
What is the trick to make "econ" work in this case, so U is 2x1 and not 2x2 and S is 1x1 and not 2x2?
Steven Lord on 25 Aug 2022
If you want a number of singular values fewer than the maximum number, consider using svds. Though for a tiny problem like this if you're expecting it to be faster than just calling svd the difference is likely to be negligible.
X=[1 1;1 1];
[U, S, V] = svds(X, 1) % Ask for the 1 largest singular value
More Answers (2)
Chunru on 25 Aug 2022
X=[1 1;1 1]
%I had expected that U=V=[1;1]/sqrt(2) and S=.
%But "econ" does not work, S=[2 0;0 0] and U=V=[1 1;1 -1]/sqrt(2), except for signs.
You can see svd with "econ" actually works. You expect U=V=[1;1]/sqrt(2) but another solution U=V=-[1;1]/sqrt(2) is actually the same solution (with opposite sign). It is obvious that X=U*S*V'=(-U)*S*(-V)'.
Bruno Luong on 25 Aug 2022
Edited: Bruno Luong on 25 Aug 2022
You should read the doc again:
"[___] = svd(A,"econ") produces an economy-size decomposition of A using either of the previous output argument combinations. If A is an m-by-n matrix, then:
- m > n — Only the first n columns of U are computed, and S is n-by-n.
- m = n — svd(A,"econ") is equivalent to svd(A).
- m < n — Only the first m columns of V are computed, and S is m-by-m.
The "econ" option truncates the output when the matrix is not square based on matrix size. It does not do any truncation based on rank.
If you want to truncate on rank you can do it as post ptocessing step
r = rank(X); % r = find(diag(S)>=S(1,1)*eps,1,'last')
U = U(:,r);
S = S(1:r,1:r);
V = V(:,1:r);