135 lines
3.6 KiB
Matlab
Executable File
135 lines
3.6 KiB
Matlab
Executable File
function [model,nonlinearremain] = yalmip2cplex(interfacedata)
|
|
|
|
% Author Johan Löfberg
|
|
|
|
% Retrieve needed data
|
|
options = interfacedata.options;
|
|
F_struc = interfacedata.F_struc;
|
|
c = interfacedata.c;
|
|
K = interfacedata.K;
|
|
x0 = interfacedata.x0;
|
|
integer_variables = interfacedata.integer_variables;
|
|
binary_variables = interfacedata.binary_variables;
|
|
semicont_variables = interfacedata.semicont_variables;
|
|
|
|
ub = interfacedata.ub;
|
|
lb = interfacedata.lb;
|
|
H = 2*interfacedata.Q;
|
|
if ~isempty(semicont_variables)
|
|
[F_struc,K,lb,ub,semicont_variables] = extractSemiContBounds(F_struc,K,lb,ub,semicont_variables);
|
|
end
|
|
[F_struc,K,c,H,ub,lb,x0,Qi,Li,ri] = append_normalized_socp(F_struc,K,c,H,ub,lb,x0);
|
|
|
|
nonlinearremain=0;
|
|
if any(interfacedata.variabletype)
|
|
nonlinearremain=1;
|
|
end
|
|
|
|
% Notation used
|
|
f = c;
|
|
if ~isempty(F_struc)
|
|
Aineq = -F_struc(:,2:end);
|
|
bineq = F_struc(:,1);
|
|
else
|
|
Aineq = [];
|
|
bineq = [];
|
|
end
|
|
|
|
% CPLEX assumes semi-continuous variables only can take negative values so
|
|
% we negate semi-continuous violating this
|
|
if ~isempty(semicont_variables)
|
|
[NegativeSemiVar,H,f,Aineq,lb,ub,semicont_variables] = negateNegativeSemiContVariables(H,f,Aineq,lb,ub,semicont_variables,[]);
|
|
else
|
|
NegativeSemiVar = [];
|
|
end
|
|
|
|
if K.f > 0
|
|
Aeq = Aineq(1:K.f,:);
|
|
beq = bineq(1:K.f);
|
|
% Code around performance bugs in older version of MATLAB
|
|
[ii,jj,ss] = find(Aineq);keeps = ii>K.f;
|
|
Aineq = sparse(ii(keeps)-K.f,jj(keeps),ss(keeps),size(Aineq,1)-K.f,size(Aineq,2));
|
|
[ii,jj,ss] = find(bineq);keeps = ii>K.f;
|
|
bineq = sparse(ii(keeps)-K.f,jj(keeps),ss(keeps),length(bineq)-K.f,1);
|
|
else
|
|
Aeq = [];
|
|
beq = [];
|
|
end
|
|
|
|
if all(isinf(lb))
|
|
lb = [];
|
|
end
|
|
if all(isinf(ub))
|
|
ub = [];
|
|
end
|
|
|
|
ctype = char(ones(length(f),1)*67);
|
|
if ~isempty(integer_variables)
|
|
ctype(setdiff(integer_variables,semicont_variables)) = 'I';
|
|
end
|
|
ctype(binary_variables) = 'B'; % Should not happen except from bmibnb
|
|
if ~isempty(semicont_variables)
|
|
ctype(setdiff(semicont_variables,integer_variables)) = 'S'; % Should not happen except from bmibnb
|
|
ctype(intersect(semicont_variables,integer_variables)) = 'N';
|
|
end
|
|
|
|
options.cplex.simplex.display = options.verbose;
|
|
options.cplex.mip.display = options.verbose;
|
|
options.cplex.barrier.display = options.verbose;
|
|
if str2num(interfacedata.solver.subversion)>=12.3
|
|
if options.verbose
|
|
options.cplex.diagnostics = 'on';
|
|
else
|
|
options.cplex.diagnostics = 'off';
|
|
end
|
|
end
|
|
|
|
if ~isempty(K.sos.type)
|
|
for i = 1:length(K.sos.weight)
|
|
K.sos.weight{i} = full(K.sos.weight{i}(:));
|
|
end
|
|
if length(K.sos.weight)==1
|
|
K.sos.weight = K.sos.weight{1};
|
|
K.sos.variables = K.sos.variables{1};
|
|
end
|
|
end
|
|
|
|
% Shift the objective (constant term can not be set in CPLEX?)
|
|
if isfield(options.cplex,'mip.tolerances.lowercutoff')
|
|
options.cplex.mip.tolerances.lowercutoff = options.cplex.mip.tolerances.lowercutoff-interfacedata.f;
|
|
options.cplex.mip.tolerances.uppercutoff = options.cplex.mip.tolerances.uppercutoff-interfacedata.f;
|
|
end
|
|
|
|
if nnz(H)==0
|
|
H = [];
|
|
end
|
|
|
|
% Bug in cplex 12.1
|
|
if length(K.q) == 1
|
|
if isa(Qi,'cell')
|
|
Qi = Qi{1};
|
|
end
|
|
end
|
|
|
|
model.H = H;
|
|
model.f = f;
|
|
model.Aineq = Aineq;
|
|
model.bineq = bineq;
|
|
model.Aeq = Aeq;
|
|
model.beq = beq;
|
|
model.lb = lb;
|
|
model.ub = ub;
|
|
model.x0 = x0;
|
|
model.options = options.cplex;
|
|
model.verbose = options.verbose;
|
|
model.integer_variables = integer_variables;
|
|
model.binary_variables = binary_variables;
|
|
model.semicont_variables = semicont_variables;
|
|
model.K = K;
|
|
model.ctype = ctype';
|
|
model.Qi=Qi;
|
|
model.Li=Li;
|
|
model.ri=ri;
|
|
model.NegativeSemiVar=NegativeSemiVar;
|
|
|