Dynamic-Calibration/utils/YALMIP-master/solvers/callbonmin.m

187 lines
4.7 KiB
Mathematica
Raw Permalink Normal View History

2019-12-18 11:25:45 +00:00
function output = callbonmin(model)
model = yalmip2nonlinearsolver(model);
options = [];
try
options.bonmin = optiRemoveDefaults(model.options.bonmin,bonminset());
catch
options.bonmin = model.options.bonmin;
end
options.ipopt = model.options.ipopt;
options.display = model.options.verbose;
if ~model.derivative_available
disp('Derivate-free call to bonmin/ipopt not yet implemented')
error('Derivate-free call to bonmin/ipopt not yet implemented')
end
if model.options.savedebug
save bonmindebug model
end
Fupp = [ repmat(0,length(model.bnonlinineq)+length(model.K.q)*(model.K.q(1)>0),1);
repmat(0,length(model.bnonlineq),1);
repmat(0,length(model.b),1);
repmat(0,length(model.beq),1)];
Flow = [ repmat(-inf,length(model.bnonlinineq)+length(model.K.q)*(model.K.q(1)>0),1);
repmat(0,length(model.bnonlineq),1);
repmat(-inf,length(model.b),1);
repmat(0,length(model.beq),1)];
if isempty(Flow)
Flow = [];
Fupp = [];
end
% Since ipopt react strangely on lb>ub, we should bail if that is detected
% (ipopt creates an exception)
if ~isempty(model.lb)
if any(model.lb>model.ub)
problem = 1;
solverinput = [];
solveroutput = [];
output = createoutput(model.lb*0,[],[],problem,'BONMIN',solverinput,solveroutput,0);
return
end
end
% These are needed to avoid recomputation due to ipopts double call to get
% f and df, and g and dg
global latest_x_f
global latest_x_g
global latest_df
global latest_f
global latest_G
global latest_g
global latest_xevaled
global latest_x_xevaled
latest_G= [];
latest_g = [];
latest_x_f = [];
latest_x_g = [];
latest_xevaled = [];
latest_x_xevaled = [];
funcs.objective = @(x)ipopt_callback_f(x,model);
funcs.gradient = @(x)ipopt_callback_df(x,model);
if ~isempty(Fupp)
funcs.constraints = @(x)ipopt_callback_g(x,model);
funcs.jacobian = @(x)ipopt_callback_dg(x,model);
end
options.lb = model.lb(:)';
options.ub = model.ub(:)';
if ~isempty(Fupp)
options.cl = Flow;
options.cu = Fupp;
end
if ~isempty(Fupp)
m = length(model.lb);
allA=[model.Anonlinineq];
if size(model.F_struc,1) > 0
% These are SOCP cones
top = 1;
for i = 1:length(model.K.q)
rows = model.F_struc(top:top + model.K.q(i)-1,2:end)
allA = [allA;any(rows,1)];
end
end
allA = [allA;model.Anonlineq];
jacobianstructure = spalloc(size(allA,1),m,0);
depends = allA | allA;
for i = 1:size(depends,1)
vars = find(depends(i,:));
[ii,vars] = find(model.deppattern(vars,:));
vars = unique(vars);
s = size(jacobianstructure,1);
for j = 1:length(vars)
jacobianstructure(i,find(vars(j) == model.linearindicies)) = 1;
end
end
allA=[model.A; model.Aeq];
depends = allA | allA;
jacobianstructure = [jacobianstructure;depends];
Z = sparse(jacobianstructure);
funcs.jacobianstructure = @() Z;
end
if ~model.options.usex0
model.x0 = (options.lb+options.ub)/2;
model.x0(isinf(options.ub)) = options.lb(isinf(options.ub))+1;
model.x0(isinf(options.lb)) = options.ub(isinf(options.lb))-1;
model.x0(isinf(model.x0)) = 0;
end
if ~isempty(model.binary_variables) | ~isempty(model.integer_variables)
options.var_type = zeros(length(model.linearindicies),1);
options.var_type(model.binary_variables) = -1;
options.var_type(model.integer_variables) = 1;
end
showprogress('Calling BONMIN',model.options.showprogress);
solvertime = tic;
[xout,info] = bonmin(model.x0,funcs,options);
solvertime = toc(solvertime);
x = RecoverNonlinearSolverSolution(model,xout);
switch info.status
case {0,2}
problem = 0;
case 1
problem = 1;
case {-1}
problem = 3;
case {3}
problem = 15;
otherwise
problem = -1;
end
% Duals currently not supported
D_struc = [];
% Save all data sent to solver?
if model.options.savesolverinput
solverinput.x0 = model.x0;
solverinput.model = model;
solverinput.options = options;
else
solverinput = [];
end
% Save all data from the solver?
if model.options.savesolveroutput
solveroutput.x = xout;
solveroutput.info = info;
else
solveroutput = [];
end
% Standard interface
output = createoutput(x,D_struc,[],problem,'BONMIN',solverinput,solveroutput,solvertime);
% Code supplied by Jonatan Currie
function opts = removeDefaults(opts,defs)
oFn = fieldnames(opts);
for i = 1:length(oFn)
label = oFn{i};
if(isfield(defs,label))
if(ischar(opts.(label)))
if(strcmpi(defs.(label),opts.(label)))
opts = rmfield(opts,label);
end
else
if(defs.(label) == opts.(label))
opts = rmfield(opts,label);
end
end
end
end