-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhcp_ipopt.m
72 lines (58 loc) · 1.69 KB
/
hcp_ipopt.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
%hcp_ipopt attempt to solve hcp problem with ipopt
function hcp_slv = hcp_ipopt(P,x0,name,solve_tol,solver_options)
% handle optional input
if nargin < 3 || isempty(name)
name = 'hcp_problem';
end
if nargin < 4 || isempty(solve_tol)
solve_tol = -.99;
end
if nargin < 5 || isempty(solver_options)
solver_options.print_level = 0;
%options.ipopt.derivative_test = 'second-order';
%options.ipopt.hessian_approximation = 'limited-memory';
%options.ipopt.limited_memory_max_history = 20;
end
% get number of edges
num_edges = sum(P(:));
% get constraints
[A c] = hcp_con(P);
A = A(1:end-1,:);
c = c(1:end-1);
% instrument for function eval count
fevcnt = 0;
function f = anon_hcp_func(x)
fevcnt = fevcnt + 1;
f = hcp_func(x,P);
end
% construct function struct
funcs.objective = @(x) anon_hcp_func(x);
funcs.gradient = @(x) hcp_grad(x,P);
funcs.constraints = @(x) A*x;
funcs.jacobian = @(x) A;
funcs.jacobianstructure = @() A;
funcs.hessian = @(x,sigma,lambda) sigma*hcp_hess(x,P,'L');
funcs.hessianstructure = @() hcp_hess_pat(P,'L');
% set bounds
options.lb = zeros(num_edges,1);
options.ub = ones(num_edges,1);
options.cl = c;
options.cu = c;
% set ipopt options
options.ipopt = solver_options;
options.ipopt.jac_c_constant = 'yes';
% call ipopt
[xstar, info] = ipopt(x0,funcs,options);
% prepare output structure
hcp_slv.xstar = xstar;
hcp_slv.fstar = anon_hcp_func(xstar);
hcp_slv.solver_info = info.status;
hcp_slv.itercnt = info.iter;
hcp_slv.fevcnt = fevcnt;
hcp_slv.name = name;
if hcp_slv.fstar <= solve_tol
hcp_slv.hc_found = 1;
else
hcp_slv.hc_found = 0;
end
end