-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMCAGA.m
94 lines (85 loc) · 2.18 KB
/
MCAGA.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
function [L,S,iter,cost] = MCAGA(X,tol,maxIter,muScale)
% Group Algebra Matrix Completion
% solve min_L |L|_* s.t. L+S=X, Pi(S)=0
% using the inexact augmented Lagrangian method (IALM)
% ----------------------------------
% Chia-An Yu
% June, 2017
% Copyright: Music and Audio Computing Lab, Academia Sinica, Taiwan
%
% Parameters
if nargin<2
tol = 1e-7;
end
if nargin<3
maxIter = 1000;
end
if nargin<4
muScale = 0.0001;
end
rho0 = 1.2172;
rho1 = 1.8588;
% Initialization
absAGA = @(x) norm(x(:),2);
ST = @(x,c) max(1-c/norm(x(:)),0)*x;
D2 = length(size(X));
[N,M,G] = size(X);
P = min(N,M);
U = zeros(N,P,G);
Sigma = zeros(P,P,G);
V = zeros(M,P,G);
sv = zeros(P,1,G);
L = zeros(size(X));
S = zeros(size(X));
lambda = zeros(size(X));
omega = logical(X);
rho = rho0+rho1*nnz(omega)/numel(omega); % from Lin et al. (2009)
for k = 3:D2, X = fft(X,[],k); end % move to the frequency domain
for i = 1:G
sv(1,1,i) = svds(X(:,:,i),1,'L');
end
X_fro = norm(X(:));
mu = muScale/absAGA(sv(1,1,:));
for iter = 1:maxIter
% Update L, singular value thresholding
Z = X-S+lambda/mu;
for i = 1:G
[U(:,:,i),Sigma(:,:,i),V(:,:,i)] = svd(Z(:,:,i),'econ');
sv(:,1,i) = diag(Sigma(:,:,i));
end
for i = 1:P
sv(i,1,:) = ST(sv(i,1,:),1/mu);
end
for i = 1:G
L(:,:,i) = U(:,:,i)*spdiags(sv(:,1,i),0,P,P)*V(:,:,i)';
end
% Update S, masking in data domain
S = X-L+lambda/mu;
for k = 3:D2, S = ifft(S,[],k); end
err = sum(abs(S(omega)));
S(omega) = 0;
for k = 3:D2, S = fft(S,[],k); end
R = X-L-S;
lambda = lambda+mu*R;
mu = rho*mu;
% Check for convergence
cost = 0;
for i = 1:P
cost = cost+absAGA(sv(i,1,:));
end
fprintf('#Iter.%2d: Res.=%f, |L|_*=%f, |Pi(S)|_1=%f\n',...
iter,norm(R(:))/X_fro,cost,err);
if norm(R(:))/X_fro<tol
break;
elseif iter==maxIter
warning('Maximum iterations exceeded.');
end
end
for k = 3:D2 % back to the data domain
S = ifft(S,[],k);
L = ifft(L,[],k);
end
S = real(S);
L = real(L);
end