-
Notifications
You must be signed in to change notification settings - Fork 1
/
svdsecon.m
40 lines (38 loc) · 970 Bytes
/
svdsecon.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
function [U,S,V] = svdsecon(X,k)
% Input:
% X : m x n matrix
% k : extracts the first k singular values
%
% Output:
% X = U*S*V' approximately (up to k)
%
% Description:
% Does equivalent to svds(X,k) but faster
% Requires that k < min(m,n) where [m,n] = size(X)
% This function is useful if k is much smaller than m and n
% or if X is sparse (see doc eigs)
%
% Vipin Vijayan (2014)
%X = bsxfun(@minus,X,mean(X,2));
[m,n] = size(X);
assert(k <= m && k <= n, 'k needs to be smaller than size(X,1) and size(X,2)');
if m <= n
C = double(X*X');
[U,D] = eigs(C,k);
clear C;
if nargout > 2
V = X'*U;
s = sqrt(abs(diag(D)));
V = bsxfun(@(x,c)x./c, V, s');
S = diag(s);
end
else
C = double(X'*X);
[V,D] = eigs(C,k);
clear C;
U = X*V; % convert evecs from X'*X to X*X'. the evals are the same.
%s = sqrt(sum(U.^2,1))';
s = sqrt(abs(diag(D)));
U = bsxfun(@(x,c)x./c, U, s');
S = diag(s);
end