-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathinexact_alm_lrr_l1.m
executable file
·87 lines (74 loc) · 1.99 KB
/
inexact_alm_lrr_l1.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
function [Z,E] = inexact_alm_lrr_l21_me4(X,A,lambda,Q,gamma,display)
% This routine uses Inexact ALM algorithm to solve the following nuclear-norm optimization problem:
% min |Z|_*+lambda*|E|_2,1
% s.t., X = AZ+E
% inputs:
% X -- D*N data matrix, D is the data dimension, and N is the number
% of data vectors.
% A -- D*M matrix of a dictionary, M is the size of the dictionary
% Modified by Ying Qu
% use l1 norm to replace l21 norm, and the dictionary is learnd by the mean
% shift clustering method. The optimization sections are updated
% accordingly.
if nargin<6
display = false;
end
tol = 1e-6;
maxIter = 1e6;
[d n] = size(X);
m = size(A,2);
rho = 1.1;
max_mu = 1e10;
mu = 1e-6;
atx = A'*X;
inv_a = inv(A'*A+eye(m));
%% Initializing optimization variables
% intialize
J = zeros(m,n);
Z = zeros(m,n);
E = sparse(d,n);
Y1 = zeros(d,n);
Y2 = zeros(m,n);
%% Start main loop
iter = 0;
if display
disp(['initial,rank=' num2str(rank(Z))]);
end
beta = 1e1;
while iter<maxIter
iter = iter + 1;
%update J
temp = Z + Y2/mu;
[U,sigma,V] = svd(temp,'econ');
sigma = diag(sigma);
svp = length(find(sigma>1/mu));
if svp>=1
sigma = sigma(1:svp)-1/mu;
else
svp = 1;
sigma = 0;
end
J = U(:,1:svp)*diag(sigma)*V(:,1:svp)';
%udpate Z
Z = inv_a*(atx-A'*E+J+(A'*Y1-Y2)/mu);
%update E
xmaz = X-A*Z;
temp_T = xmaz+Y1/mu;
% E = solve_l1l2(temp_T,lambda/mu);
E = max( temp_T - lambda/mu,0) + min( temp_T + lambda/mu,0);
leq1 = xmaz-E;
leq2 = Z-J;
stopC = max(max(max(abs(leq1))),max(max(abs(leq2))))
if display && (iter==1 || mod(iter,50)==0 || stopC<tol)
disp(['iter ' num2str(iter) ',mu=' num2str(mu,'%2.1e') ...
',rank=' num2str(rank(Z,1e-3*norm(Z,2))) ',stopALM=' num2str(stopC,'%2.3e')]);
end
if stopC<tol
break;
else
Y1 = Y1 + mu*leq1;
Y2 = Y2 + mu*leq2;
mu = min(max_mu,mu*rho);
beta = beta/1e1;
end
end