-
Notifications
You must be signed in to change notification settings - Fork 0
/
exact_alm_rpca.m
130 lines (110 loc) · 3.14 KB
/
exact_alm_rpca.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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
function [A_hat E_hat iter] = exact_alm_rpca(D, lambda, tol, maxIter)
% Oct 2009
% This matlab code implements the augmented Lagrange multiplier method for
% Robust PCA.
%
% D - m x n matrix of observations/data (required input)
%
% lambda - weight on sparse error term in the cost function
%
% tol - tolerance for stopping criterion.
% - DEFAULT 1e-7 if omitted or -1.
%
% maxIter - maximum number of iterations
% - DEFAULT 1000, if omitted or -1.
%
% Initialize A,E,Y,u
% while ~converged
% minimize
% L(A,E,Y,u) = |A|_* + lambda * |E|_1 + <Y,D-A-E> + mu/2 * |D-A-E|_F^2;
% Y = Y + \mu * (D - A - E);
% \mu = \rho * \mu;
% end
%
% Minming Chen, October 2009. Questions? v-minmch@microsoft.com ;
% Arvind Ganesh (abalasu2@illinois.edu)
%
% Copyright: Perception and Decision Laboratory, University of Illinois, Urbana-Champaign
% Microsoft Research Asia, Beijing
addpath PROPACK;
[m n] = size(D);
if nargin < 2
lambda = 1 / sqrt(m);
end
if nargin < 3
tol = 1e-7;
elseif tol == -1
tol = 1e-7;
end
if nargin < 4
maxIter = 1000;
elseif maxIter == -1
maxIter = 1000;
end
% initialize
Y = sign(D);
norm_two = lansvd(Y, 1, 'L');
norm_inf = norm( Y(:), inf) / lambda;
dual_norm = max(norm_two, norm_inf);
Y = Y / dual_norm;
A_hat = zeros( m, n);
E_hat = zeros( m, n);
dnorm = norm(D, 'fro');
tolProj = 1e-6 * dnorm;
total_svd = 0;
mu = .5/norm_two % this one can be tuned
rho = 6 % this one can be tuned
iter = 0;
converged = false;
stopCriterion = 1;
sv = 5;
svp = sv;
while ~converged
iter = iter + 1;
% solve the primal problem by alternative projection
primal_converged = false;
primal_iter = 0;
sv = sv + round(n * 0.1);
while primal_converged == false
temp_T = D - A_hat + (1/mu)*Y;
temp_E = max( temp_T - lambda/mu,0) + min( temp_T + lambda/mu,0);
if choosvd(n, sv) == 1
[U S V] = lansvd(D - temp_E + (1/mu)*Y, sv, 'L');
else
[U S V] = svd(D - temp_E + (1/mu)*Y, 'econ');
end
diagS = diag(S);
svp = length(find(diagS > 1/mu));
if svp < sv
sv = min(svp + 1, n);
else
sv = min(svp + round(0.05*n), n);
end
temp_A = U(:,1:svp)*diag(diagS(1:svp)-1/mu)*V(:,1:svp)';
if norm(A_hat - temp_A, 'fro') < tolProj && norm(E_hat - temp_E, 'fro') < tolProj
primal_converged = true;
end
A_hat = temp_A;
E_hat = temp_E;
primal_iter = primal_iter + 1;
total_svd = total_svd + 1;
end
Z = D - A_hat - E_hat;
Y = Y + mu*Z;
mu = rho * mu;
%% stop Criterion
stopCriterion = norm(Z, 'fro') / dnorm;
if stopCriterion < tol
converged = true;
end
disp(['Iteration' num2str(iter) ' #svd ' num2str(total_svd) ' r(A) ' num2str(svp)...
' |E|_0 ' num2str(length(find(abs(E_hat)>0)))...
' stopCriterion ' num2str(stopCriterion)]);
if ~converged && iter >= maxIter
disp('Maximum iterations reached') ;
converged = 1 ;
end
end
if nargin == 5
fclose(fid);
end