-
Notifications
You must be signed in to change notification settings - Fork 1
/
rasl_inner_ialm.m
90 lines (68 loc) · 2.16 KB
/
rasl_inner_ialm.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
function [A_dual E_dual dt_dual iter Y] = rasl_inner_ialm(D, J, lambda, tol, maxIter)
[m n] = size(D);
if nargin < 3
error('Too few arguments') ;
end
if nargin < 4
tol = 1e-7;
elseif tol == -1
tol = 1e-7;
end
if nargin < 5
maxIter = 1000;
elseif maxIter == -1
maxIter = 1000;
end
DISPLAY_EVERY = 10 ;
% initialize
Y = D;
norm_two = norm(Y, 2);
norm_inf = norm( Y(:), inf) / lambda;
dual_norm = max(norm_two, norm_inf);
Y = Y / dual_norm;
obj_v = D(:)' * Y(:);
A_dual = zeros( m, n);
E_dual = zeros( m, n);
dt_dual = cell(1,n) ;
dt_dual_matrix = zeros(m, n) ;
mu = 1.25/norm(D) ;
rho = 1.25;
d_norm = norm(D, 'fro');
iter = 0;
converged = false;
while ~converged
iter = iter + 1;
temp_T = D + dt_dual_matrix - E_dual + (1/mu)*Y;
[U S V] = svd(temp_T, 'econ');
diagS = diag(S);
A_dual = U * diag(pos(diagS-1/mu)) * V';
temp_T = D + dt_dual_matrix - A_dual + (1/mu)*Y;
E_dual = sign(temp_T) .* pos( abs(temp_T) - lambda/mu );
temp_T = D - E_dual - A_dual + (1/mu)*Y;
for i = 1 : n
dt_dual{i} = - J{i}'*temp_T(:,i) ;
dt_dual_matrix(:, i) = J{i}*dt_dual{i} ;
end
Z = D + dt_dual_matrix - A_dual - E_dual;
Y = Y + mu*Z;
obj_v = D(:)'*Y(:);
mu = mu*rho;
stoppingCriterion = norm(Z, 'fro') / d_norm;
if mod( iter, DISPLAY_EVERY) == 0
disp(['#Iteration ' num2str(iter) ' rank(A) ' num2str(rank(A_dual)) ...
' ||E||_0 ' num2str(length(find(abs(E_dual)>0)))...
' objvalue ' num2str(obj_v) ' Stopping Criterion ' ...
num2str(stoppingCriterion)]);
end
if stoppingCriterion <= tol
disp('RASL inner loop is converged at:');
disp(['Iteration ' num2str(iter) ' rank(A) ' num2str(rank(A_dual)) ...
' ||E||_0 ' num2str(length(find(abs(E_dual)>0))) ' Stopping Criterion ' ...
num2str(stoppingCriterion)]) ;
converged = true ;
end
if ~converged && iter >= maxIter
disp('Maximum iterations reached') ;
converged = 1 ;
end
end