-
Notifications
You must be signed in to change notification settings - Fork 0
/
SPGsolver.m
70 lines (59 loc) · 1.46 KB
/
SPGsolver.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
%
% See LICENSE file distributed along with the package for the copyright and license terms.
%
% solve the following problem via SPG
% min e'*f(Ax)/n + |x-c|^2*(rho/2)
% where e is the all-ones vector, f(x) = log(1+exp(-x)),
function [x,d] = SPGsolver(A,c,rho,x,d)
% Initialization
eps = 1e-6;
gamma = 1e-4;
M = 2;
alphamin = 1e-8;
alphamax = 1;
f_1 = -inf*ones(M,1);
[f,expf] = fun(A,x);
f = f + 0.5*rho*norm(x-c)^2;
g = grad(A,c,rho,x,expf);
err = norm(g);
alphas = 1;
f_1(1) = f;
k = 1;iter_in = 1;
% Main Algorithm
while err >= eps
f_max = max(f_1);
d = -alphas*g;
delta = sum(d.*g);
[x_new,f_new,g_new] = linesearch(A,c,rho,x,d,delta,f_max,gamma);
f_1(mod(k,M)+1) = f_new;
dx = x_new - x;
dg = g_new - g;
xdotg = sum(dx.*dg);
xsqr = norm(dx)^2;
alphas = max(alphamin,min(alphamax,xsqr/xdotg));
x = x_new;
g = g_new;
err = abs(f - f_new)/max(abs(f),1);
f = f_new;
iter_in = iter_in + 1;
k = k + 1;
end
% Evaluating the gradient
function g = grad(A,c,rho,x,expz)
n = size(A,1);
tmp = 1/n./(ones(n,1)+1./expz);
g = -A'*tmp + rho*(x-c);
% Finding the stepsize
function [x_new,f_new,g_new] = linesearch(A,c,rho,x,d,delta,f_max,gamma)
alphas = 1;
while (1)
x_new = x + alphas*d;
[f_new,expf] = fun(A,x_new);
f_new = f_new + 0.5*rho*norm(x_new-c)^2;
if (f_new <= f_max + gamma*alphas*delta) || (alphas <= 1e-8)
break
else
alphas = alphas/2;
end
end
g_new = grad(A,c,rho,x_new,expf);