Reputation: 2202
Here is my testing function:
function diff = svdtester()
y = rand(500,20);
[U,S,V] = svd(y);
%{
y = sprand(500,20,.1);
[U,S,V] = svds(y);
%}
diff_mat = y - U*S*V';
diff = mean(abs(diff_mat(:)));
end
There are two very similar parts: one finds the SVD of a random matrix, the other finds the SVD of a random sparse matrix. Regardless of which one you choose to comment (right now the second one is commented-out), we compute the difference between the original matrix and the product of its SVD components and return that average absolute difference.
When using rand/svd, the typical return (mean error) value is around 8.8e-16, basically zero. When using sprand/svds, the typical return values is around 0.07, which is fairly terrible considering the sparse matrix is 90% 0's to start with.
Am I misunderstanding how SVD should work for sparse matrices, or is something wrong with these functions?
Upvotes: 1
Views: 1513
Reputation: 4991
Yes, the behavior of svds
is a little bit different from svd
. According to MATLAB's documentation:
[U,S,V] = svds(A,...)
returns three output arguments, and ifA
ism
-by-n
:
U
ism
-by-k
with orthonormal columns
S
isk
-by-k
diagonal
V
isn
-by-k
with orthonormal columns
U*S*V'
is the closest rankk
approximation toA
In fact, usually k
will be somethings about 6
, so you will get rather "rude" approximation. To get more exact approximation specify k
to be min(size(y))
:
[U, S, V] = svds(y, min(size(y)))
and you will get error of the same order of magnitude as in case of svd
.
P.S. Also, MATLAB's documentations says:
Note
svds
is best used to find a few singular values of a large, sparse matrix. To find all the singular values of such a matrix,svd(full(A))
will usually perform better thansvds(A,min(size(A)))
.
Upvotes: 8