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

248 lines
6.5 KiB
Matlab
Executable File

function output = callscipnl(model)
% This sets up everything and more. Can be simplified significantly since
% baron handles its own computational tree etc
model = yalmip2nonlinearsolver(model);
% [Anonlinear*f(x) <= b;Anonlinear*f(x) == b]
cu = full([model.bnonlinineq;model.bnonlineq]);
cl = full([repmat(-inf,length(model.bnonlinineq),1);model.bnonlineq]);
Anonlinear = [ model.Anonlinineq; model.Anonlineq];
% Create string representing objective
obj = createmodelstring(model.c,model);
obj = strrep(obj,'sqrtm_internal','sqrt');
if nnz(model.Q)>0
obj = [obj '+' createQstring(model.Q,model)];
end
if model.f > 0
obj = [obj '+' num2str(model.f)];
end
if isempty(obj)
obj = [];
else
if obj(1)=='+'
obj = obj(2:end);
end
% Append quadratic term
obj = ['@(x) ' obj];
obj = eval(obj);
end
% Create string representing nonlinear constraints
if length(cu)>0
con = '[';
remove = [];
for i = 1:length(cu)
if isinf(cl(i)) & isinf(cu(i))
remove = [remove;i];
else
con = [con createmodelstring(Anonlinear(i,:),model) ';'];
end
end
cl(remove) = [];
cu(remove) = [];
con = [con ']'];
con = strrep(con,'sqrtm_internal','sqrt');
con = strrep(con,'slog(x','log(1+x');
con = ['@(x) ' con];
con = eval(con);
else
cu = [];
cl = [];
con = [];
end
% Linear constraints
ru = full([model.b;model.beq]);
rl = full([repmat(-inf,length(model.b),1);model.beq]);
A = [model.A; model.Aeq];
if length(ru)>0
remove = find(isinf(rl) & isinf(ru));
A(remove,:)=[];
rl(remove) = [];
ru(remove) = [];
end
lb = model.lb;
ub = model.ub;
xtype = [];
xtype = repmat('C',length(lb),1);
xtype(model.binary_variables) = 'B';
xtype(model.integer_variables) = 'I';
x0 = model.x0;
opts = model.options.scip;
switch model.options.verbose
case 0
opts.display = 'off';
otherwise
opts.display = 'iter';
end
if model.options.savedebug
save scipnldebug obj con A ru rl cl cu xtype lb ub x0 opts
end
solvertime = tic;
[x,fval,exitflag,info] = opti_scipnl(obj,A,rl,ru,lb,ub,con,cl,cu,xtype,[],opts);%,x0,opts);
solvertime = toc(solvertime);
% Check, currently not exhaustive...
switch exitflag
case 0
if ~isempty(strfind(info.Status,'Exceed')) || ~isempty(strfind(info.Status,'Node Limit Reached'))
problem = 3;
else
problem = 9;
end
case 1
problem = 0;
case {2,-1}
problem = 1;
case 3
problem = 2;
case {4,5}
problem = 11;
otherwise
problem = 9;
end
% Save all data sent to solver?
if model.options.savesolverinput
solverinput.obj = obj;
solverinput.A = A;
solverinput.rl = rl;
solverinput.ru = ru;
solverinput.lb = lb;
solverinput.ub = ub;
solverinput.con = con;
solverinput.cl = cl;
solverinput.cu = cu;
solverinput.xtype = xtype;
solverinput.opts = opts;
else
solverinput = [];
end
% Save all data from the solver?
if model.options.savesolveroutput
solveroutput.x = x;
solveroutput.fval = fval;
solveroutput.exitflag = exitflag;
solveroutput.info=info;
else
solveroutput = [];
end
if ~isempty(x)
x = RecoverNonlinearSolverSolution(model,x);
end
% Standard interface
output = createoutput(x,[],[],problem,'SCIP-NL',solverinput,solveroutput,solvertime);
function z = createOneterm(i,model)
[evalPos,pos] = ismember(i,model.evalVariables);
if pos
% This is a nonlinear operator
map = model.evalMap{pos};
% We might hqave vectorized things to compute several expressions at the same time
if length(map.computes) == 1 && length(map.variableIndex) > 1
if isequal(map.fcn,'plog')
j1 = find(model.linearindicies == map.variableIndex(1));
j2 = find(model.linearindicies == map.variableIndex(2));
if isempty(j1)
z1 = createmonomstring(model.monomtable(map.variableIndex(1),:),model);
else
z1 = ['x(' num2str(j1) ')'];
end
if isempty(j2)
z1 = createmonomstring(model.monomtable(map.variableIndex(2),:),model);
else
z2 = ['x(' num2str(j2) ')'];
end
z = [z1 '*log(' z2 '/' z1 ')'];
else
z = [map.fcn '('];
for j = map.variableIndex
jl = find(model.linearindicies == j);
if isempty(jl)
z = [z createmonomstring(model.monomtable(j,:),model)];
else
z = [z 'x(' num2str(jl) ')'];
end
if j == length(map.variableIndex)
z = [z ')'];
else
z = [z ','];
end
end
end
else
j = find(map.computes == i);
j = map.variableIndex(j);
% we have f(x(j)), but have to map back to linear indicies
jl = find(model.linearindicies == j);
if isempty(jl)
z = [map.fcn '(' createmonomstring(model.monomtable(j,:),model) ')'];
else
z = [map.fcn '(x(' num2str(jl) '))'];
end
end
else
i = find(model.linearindicies == i);
z = ['x(' num2str(i) ')'];
end
function monomstring = createmonomstring(v,model)
monomstring = '';
for i = find(v)
z = createOneterm(i,model);
if v(i)==1
monomstring = [monomstring z '*'];
else
monomstring = [monomstring z '^' num2str(v(i),12) '*'];
end
end
monomstring = monomstring(1:end-1);
function string = createmodelstring(row,model)
string = '';
index = find(row);
for i = index(:)'
monomstring = createmonomstring(model.monomtable(i,:),model);
string = [string num2str(row(i),12) '*' monomstring '+'];
end
string = string(1:end-1);
string = strrep(string,'+-','-');
string = strrep(string,')-1*',')-');
string = strrep(string,')+1*',')+');
function string = createQstring(Q,model)
% Special code for the quadratic term
string = '';
[ii,jj,c]= find(triu(Q));
for i = 1:length(ii)
if ii(i)==jj(i)
% Quadratic term
monomstring = createmonomstring(sparse(1,ii(i),1,1,size(Q,1)),model);
string = [string num2str(c(i),12) '*' monomstring '^2' '+'];
else
% Bilinear term
monomstring1 = createmonomstring(sparse(1,ii(i),1,1,size(Q,1)),model);
monomstring2 = createmonomstring(sparse(1,jj(i),1,1,size(Q,1)),model);
string = [string num2str(c(i),12) '*2*' monomstring1 '*' monomstring2 '+'];
end
end
string = string(1:end-1);
string = strrep(string,'+-','-');
string = strrep(string,'-1*','-');
string = strrep(string,'+1*','+');