-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathforbes_cp.m
105 lines (83 loc) · 2.19 KB
/
forbes_cp.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
95
96
97
98
99
100
101
102
103
104
105
function [x, y, s, info] = forbes_cp(data, K, opt)
info.name = 'FBCS matlab (ForBES wrapper)';
info.version = '0.1';
if nargin < 2
x = []; y = []; s = [];
return;
end
% some constants, flags etc.
normalize = 1;
scale = 1;
% verb_gap = 200;
% lbfgs_mem = 20;
% flag_small_stepsize = 0;
% eta = 0.00; % for nonmonotone line-search (eta = 0 makes it monotone, elsewhere we have eta = 0.85)
% max_iters_ls = 32;
% t0 = tic();
K = validate_cone(K);
n = length(data.c);
m = length(data.b);
unscaled_b = data.b;
unscaled_c = data.c;
unscaled_nm_b = norm(unscaled_b);
unscaled_nm_c = norm(unscaled_c);
data_orig = data;
work = struct();
if (normalize)
[data, work] = normalize_data(data, K, scale, work);
D = work.D;
E = work.E;
sc_b = work.sc_b;
sc_c = work.sc_c;
else
scale = 1;
D = ones(m,1);
E = ones(n,1);
sc_b = 1;
sc_c = 1;
end
% unwrap problem data
A = data.A;
b = data.b;
c = data.c;
% determine gamma
L = [sparse(n,n), A'; -A, sparse(m,m); -c', -b'];
eigsOpts.issym = 1;
eigsOpts.tol = 1e-3;
sqNormL = eigs(@(x)L*(L'*x), n+m+1, 1, 'LM', eigsOpts);
f = smoothCP(n, K, zeros(m+n,1), 1);
g = nonsmoothCP(m, n, K);
d = [-c; -b; 0];
opt.Lf = sqNormL;
t0 = tic();
out_forbes = forbes(f, g, zeros(n+m+1,1), [], {L, -1, d}, opt);
ttot = toc(t0);
% temporary
if opt.display > 0
fprintf('Solver used : %s\n', out_forbes.name);
fprintf('Iterations : %d\n', out_forbes.iterations);
fprintf('Stepsize : %.2e (1/Lip = %.2e)\n', out_forbes.gam, 1/sqNormL);
fprintf('Solve time : %.2f\n', ttot);
end
x = out_forbes.x2(1:n);
y = out_forbes.x2(n+1:end);
s = out_forbes.z(n+1:n+m);
if (normalize)
y = y ./ (D * sc_c);
x = x ./ (E * sc_b);
s = s .* (D / (sc_b * scale));
end
A_orig = data_orig.A;
b_orig = data_orig.b;
c_orig = data_orig.c;
unscaled_dres = A_orig'*y + c_orig;
unscaled_pres = b_orig - A_orig*x - s;
unscaled_cx = c_orig'*x;
unscaled_by = b_orig'*y;
unscaled_gap = -(unscaled_by + unscaled_cx);
info.resPri = norm(unscaled_pres)/(1 + unscaled_nm_b);
info.resDual = norm(unscaled_dres)/(1 + unscaled_nm_c);
info.relGap = abs(unscaled_gap)/(1 + abs(unscaled_cx) + abs(unscaled_by));
info.iter = out_forbes.iterations;
info.status = 'solved';
end