-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathMatDecomp_Sparse.m
78 lines (69 loc) · 1.35 KB
/
MatDecomp_Sparse.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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
function [U,D,V,E]=MatDecomp_Sparse(X,c1,c2,K)
% this function aims singular matrix decomposition with L1 reg.
%
% [U,D,V,E]=MatDecomp(X,K)
%
% X:n*p matrix
% K:#components
% c1,c2:upper bound of L1 norm
%
% U:n*k matrix
% D:k*k matrix whose diagnal elements are singular values
% V:p*k matrix
[n,p]=size(X);
if exist('K','var')
k=K;
else
k=min(n,p);
end
U=zeros(n,k);
D=zeros(k,k);
V=zeros(p,k);
for i=1:k
[X,d,u,v]=SparseSingleMD(X,c1,c2);
D(i,i)=d;
U(:,i)=u;
V(:,i)=v;
end
E=X;
[d,id]=sort(diag(D),'descend');
D=diag(d);
U=U(:,id);
V=V(:,id);
end
function [X,d,u,v]=SparseSingleMD(X,c1,c2)
% this function aims rank-1 singular value decomposition with L1 reg.
%
% [X,d,u,v]=SinglMD(X)
%
% X:input
% c1,c2:upper bound of L1 norm
%
% d:first singular value
% u,v:first singular vectors
tol=1e-4;
MaxIt=10000;
%initilize
[~,~,v_old]=svds(X,1);
v_old=v_old/norm(v_old,2);
u_old=X*v_old/norm(X*v_old,2);
for i=1:MaxIt
%update u
argu=X*v_old;
lmbd1=BinarySearch(argu,c1);
su=l1_softth(argu,lmbd1);
u=su/norm(su,2);
%update v
argv=X'*u;
lmbd2=BinarySearch(argv,c2);
sv=l1_softth(argv,lmbd2);
v=sv/norm(sv,2);
if norm(u_old-u,2)<tol && norm(v_old-v,2)<tol
break;
end
u_old=u;
v_old=v;
end
d=u'*X*v;
X=X-d*u*v';
end