-
Notifications
You must be signed in to change notification settings - Fork 0
/
rpca.m
77 lines (69 loc) · 1.59 KB
/
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
%MATLAB code,子函数
function [A_hat E_hat ] =rpca(res)
%res:输入图像;输出为低秩A_hat和稀疏E_hat
% Copyright (C) 2016,4, all rights reserved.
[row col] = size(res);
lambda = 1/ sqrt(max(size(res)));%
tol = 1e-7;
maxIter = 1000;
% initialize
Y = res;
[u,s,v]=svd(Y);
norm_two=s(1);
norm_inf=max(abs(Y(:)))/lambda;
dual_norm = max(norm_two, norm_inf);
Y = Y / dual_norm;
A_hat = zeros( row, col);
E_hat = zeros( row, col);
mu = 0.01/norm_two; % this one can be tuned
mu_bar = mu * 1e7;
rho = 1.9 ; % this one can be tuned
d_norm=sqrt(sum(res(:).^2));
iter = 0;
total_svd = 0;
converged = 0;%收敛
stopCriterion = 1;
sv = 10;
while ~converged
iter = iter + 1;
temp_T = res - A_hat + (1/mu)*Y;
E_hat=temp_T - lambda/mu;
n1=find(E_hat<0);
E_hat(n1)=0;
tmp=temp_T + lambda/mu;
n1=find(tmp>0);
tmp(n1)=0;
E_hat= E_hat+tmp;
[U1 S1 V1] = svd(res - E_hat + (1/mu)*Y);
% if chsvd(col, sv) == 1
U=U1(:,1:sv);
S=S1(:,1:sv);
V=V1(:,1:sv);
% end
diagS = diag(S);
svp = length(find(diagS > 1/mu));
if svp < sv
sv = min(svp + 1, col);
else
sv = min(svp + round(0.05*col), col);
end
% ? ? A_hat = U(:, 1:svp) * diag(diagS(1:svp) - 1/mu) * V(:, 1:svp)';
U2=U(:, 1:svp);
S2=diag(diagS(1:svp) - 1/mu);
V2=V(:, 1:svp)';
A_hat=U2*S2*V2;
total_svd = total_svd + 1;
Z = res - A_hat - E_hat;
Y = Y + mu*Z;
mu = min(mu*rho, mu_bar);
% stop Criterion
stopCriterion = sqrt(sum(Z(:).^2)) / d_norm;
if stopCriterion < tol
converged = 1;
end
if ~converged && iter >= maxIter
disp('Maximum iterations reached') ;
converged = 1 ;
end
end
end