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

162 lines
4.1 KiB
Matlab
Executable File

function output = callsedumi(model)
% Retrieve needed data
options = model.options;
F_struc = model.F_struc;
c = model.c;
K = model.K;
ub = model.ub;
lb = model.lb;
% Create the parameter structure
pars = options.sedumi;
pars.fid = double(options.verbose);
% *********************************************
% Bounded variables converted to constraints
% N.B. Only happens when caller is BNB
% *********************************************
if ~isempty(ub)
[F_struc,K] = addStructureBounds(F_struc,K,ub,lb);
end
% Avoid bug (by design?) in SeDuMi on 1D second order cones
if any(K.q == 2)
[F_struc,K] = fix1Dqcone(F_struc,K);
end
if options.savedebug
save sedumidebug F_struc c K pars
end
% *********************************************
% Call SeDuMi
% *********************************************
if options.showprogress;showprogress(['Calling ' model.solver.tag],options.showprogress);end
problem = 0;
warnState = warning;
solvertime = tic;
try
[x_s,y_s,info] = sedumi(-F_struc(:,2:end),-c,F_struc(:,1),K,pars);
catch
if findstr(lasterr,'Out of memory')
error(lasterr)
end
try
if options.verbose > 0
disp(' ');
disp('SeDuMi had unexplained problems, maybe due to linear dependence?')
disp('YALMIP tweaks the problem (adds 1e6 magnitude bounds on all variables) and restarts...')
disp(' ');
end
% Boring issue in sedumi for trivial problem min x+y, s.t x+y>0
n = length(c);
[F_struc,K] = addStructureBounds(F_struc,K,ones(n,1)*1e6,-ones(n,1)*1e6);
[x_s,y_s,info] = sedumi(-F_struc(:,2:end),-c,F_struc(:,1),K,pars);
x_s((1:2*n)+K.f)=[];
K.l=K.l-2*n;
catch
disp('Nope, unexplained crash in SeDuMi! (could be memory issues or wrong binary)')
disp('Make sure you have a recent and compiled version')
disp(' ')
disp(' ')
disp('For better diagnostics, use sdpsettings(''debug'',1)')
disp(' ')
disp(' ')
end
end
warning(warnState);
solvertime = toc(solvertime);
% Internal format
Primal = y_s;
Dual = x_s;
temp = info.pinf;
pinf = info.dinf;
dinf = temp;
% Check for reported errors
if (pinf==0) & (dinf==0)
problem = 0; % No problems
end
% We can only report one error, use priorities
if (problem==0) & (pinf==1)
problem = 1; % Primal infeasability
end
if (problem==0) & (dinf==1)
problem = 2; % Dual infeasability
end
if (problem==0) & (info.numerr==1) | (info.numerr==2)
problem = 4; %Numerical problems
end
if (problem==0) & (info.iter >= options.sedumi.maxiter)
% Did we need exactly maxiter iterations to find optimum
if (pinf==0) & (dinf==0) & (info.numerr==0)
problem = 0; % Yes
else
problem = 3; % No, we are not optimal yet
end
end
if (problem==0) & (info.feasratio<0.98)
problem = 4;
end
% Fix for cases not really explained in documentation of sedumi?
if (abs(info.feasratio+1)<0.1) & (pinf==0) & (dinf==0)
problem = 1;
end
if (abs(info.feasratio+1)<0.1) & (pinf==0) & (dinf==0) & (c'*y_s<-1e10)
problem = 2;
end
infostr = yalmiperror(problem,model.solver.tag);
% Save ALL data sent to solver
if options.savesolverinput
solverinput.A = -F_struc(:,2:end);
solverinput.c = F_struc(:,1);
solverinput.b = -c;
solverinput.K = K;
solverinput.pars = pars;
else
solverinput = [];
end
% Save ALL data from the solution?
if options.savesolveroutput
solveroutput.x = x_s;
solveroutput.y = y_s;
solveroutput.info = info;
else
solveroutput = [];
end
% Standard interface
output = createOutputStructure(Primal,Dual,[],problem,infostr,solverinput,solveroutput,solvertime);
function [new_F_struc,K] = fix1Dqcone(F_struc,K);
new_F_struc = F_struc(1:(K.l+K.f),:);
top = K.f + K.l + 1;
for i = 1:length(K.q)
if K.q(i) == 2
new_F_struc = [new_F_struc;F_struc(top,:);F_struc(top+1,:);F_struc(top,:)*0];
K.q(i) = 3;
top = top + 2;
else
new_F_struc = [new_F_struc;F_struc(top:top+K.q(i)-1,:)];
top = top + K.q(i);
end
end
new_F_struc = [new_F_struc;F_struc(top:end,:)];