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

148 lines
3.7 KiB
Mathematica
Raw Normal View History

2019-12-18 11:25:45 +00:00
function [x,D_struc,problem,r,res,solvertime,prob] = call_mosek_lpqpsocpsdpdual(model)
% Convert if the caller is bnb or bmibnb which might have appended bounds
% Sure, we could setup model with bounds, but...
[model.F_struc,model.K] = addStructureBounds(model.F_struc,model.K,model.ub,model.lb);
param = model.options.mosek;
prob.c = model.F_struc(1:model.K.f+model.K.l+sum(model.K.q)+3*model.K.e,1);
prob.a = -model.F_struc(1:model.K.f+model.K.l+sum(model.K.q)+3*model.K.e,2:end)';
prob.blc = -model.c;
prob.buc = -model.c;
prob.blx = -inf(size(prob.a,2),1);
prob.bux = inf(size(prob.a,2),1);
top = model.K.f+model.K.l;
prob.blx(1+model.K.f:model.K.f+model.K.l) = 0;
if model.K.q(1)>0 || model.K.e > 0
prob.cones.type = [];
prob.cones.subptr = [];
prob.cones.sub = [];
end
if model.K.q(1)>0
for i = 1:length(model.K.q)
prob.cones.type = [prob.cones.type 0];
prob.cones.subptr = [prob.cones.subptr length(prob.cones.sub)+1];
prob.cones.sub = [prob.cones.sub top+1:top+model.K.q(i)];
top = top + model.K.q(i);
end
end
if model.K.e>0
for i = 1:model.K.e
prob.cones.type = [prob.cones.type 3];
prob.cones.subptr = [prob.cones.subptr length(prob.cones.sub)+1];
prob.cones.sub = [prob.cones.sub top+3 top+2 top+1];
top = top + 3;
end
end
if model.K.s(1)>0
prob = appendMosekSDPdata(model.F_struc,model.K,prob);
end
if model.options.savedebug
ops = model.options;
save mosekdebug prob param
end
[r,res,solvertime] = doCall(prob,param,model.options);
try
x = res.sol.itr.y;
catch
x = nan(length(model.c),1);
end
if model.options.saveduals & ~isempty(x)
try
D_struc_SDP = zeros(sum(model.K.s.^2),1);
top = 1;
dtop = 1;
for i = 1:length(model.K.s)
n = model.K.s(i);
I = find(tril(ones(n)));
v = res.sol.itr.barx(top:((top+n*(n+1)/2)-1));
D_struc_SDP(dtop + I - 1) = v;
in = ceil(I/n);
jn = mod(I-1,n)+1;
D_struc_SDP(dtop + (jn-1)*n+in - 1) = v;
top = top + n*(n+1)/2;
dtop = dtop + n^2;
end
D_struc = [res.sol.itr.xx;D_struc_SDP];
catch
D_struc = [];
end
else
D_struc = [];
end
problem = MosekYALMIPError(res);
function [res,sol,solvertime] = doCall(prob,param,options)
showprogress('Calling Mosek',options.showprogress);
if options.verbose == 0
solvertime = tic;
[res,sol] = mosekopt('minimize echo(0)',prob,param);
solvertime = toc(solvertime);
else
solvertime = tic;
[res,sol] = mosekopt('minimize info',prob,param);
solvertime = toc(solvertime);
end
function problem = MosekYALMIPError(res)
if res.rcode == 2001
problem = 1;
return
elseif res.rcode == 10007
problem = 16;
return
elseif res.rcode == 1400
problem = 20;
return
elseif res.rcode == 1001
problem = -11;
return;
elseif res.rcode == 1008
problem = -12;
return;
end
try
solinfo = res.sol.itr;
catch
solinfo = res.sol.bas;
end
switch solinfo.prosta
case 'PRIMAL_AND_DUAL_FEASIBLE'
problem = 0;
case 'DUAL_INFEASIBLE'
problem = 1;
case 'PRIMAL_INFEASIBLE'
problem = 2;
case 'MSK_RES_TRM_USER_CALLBACK'
problem = 16;
case 'MSK_RES_TRM_STALL'
problem = 4;
case 'UNKNOWN'
try
if isequal(res.rcodestr,'MSK_RES_TRM_STALL')
problem = 4;
elseif isequal(res.rcodestr,'MSK_RES_OK')
problem = 0;
else
problem = 11;
end
catch
problem = 9;
end
otherwise
problem = -1;
end