-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsolver_apg.m
More file actions
62 lines (52 loc) · 1.59 KB
/
solver_apg.m
File metadata and controls
62 lines (52 loc) · 1.59 KB
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
function [ H, Hm, t, Gh, iter ] = solver_apg(WtV, WtW, H0, Hm, t0, varargin)
%SOLVER_APG alternating proximal gradient
% minimize (1/2)*|| V - W*H ||^2 + r(H),
% s.t. H >= 0.
%
% Author: Deqing Wang
% Email: deqing.wang@foxmail.com
% Website: http://deqing.me/
% Affiliation: Dalian University of Technology, China
% University of Jyväskylä, Finland
% Date: July 18, 2019
%
%% Set algorithm parameters from input or by using defaults
params = inputParser;
params.addParameter('maxiters',5, @(x) isscalar(x) & x > 0);
params.addParameter('beta',0, @(x) isscalar(x) & x >= 0);
params.addParameter('tol',1e-2, @isscalar);
params.addParameter('stop', 1, @(x) (isscalar(x) & ismember(x,[0,1])));
params.parse(varargin{:});
%% Copy from params object
maxiters = params.Results.maxiters;
beta = params.Results.beta;
tol = params.Results.tol;
stop = params.Results.stop;
%%
Lh = norm(WtW); % Lipschitz bound for H
beta_to_Lh = beta/Lh;
for iter = 1:maxiters
% Gradient of H
Gh = WtW*Hm - WtV; % gradient at H=Hm
if stop==0
% Projected gradient norm of H
projgrad = norm(Gh(Gh < 0 | Hm >0));
if projgrad < tol
break
end
end
% Update H
H = max(0, Hm - Gh/Lh - beta_to_Lh);% Proximal operator
Rh = H - H0;
% extrapolation
t = (1+sqrt(1+4*t0^2))/2;
w = (t0-1)/t; % extrapolation weight
Hm = H + w*Rh; % extrapolation
H0 = H; t0 = t;
if stop==1
if norm(Rh(:)) < tol*norm(H(:))
break
end
end
end
end