Dynamic-Calibration/utils/YALMIP-master/modules/global/solvelower.m

241 lines
9.9 KiB
Mathematica
Raw Normal View History

2019-12-18 11:25:45 +00:00
function [output,cost,psave,timing] = solvelower(p,options,lowersolver,xmin,upper,timing)
psave = p;
removeThese = find(p.InequalityConstraintState==inf);
p.F_struc(p.K.f + removeThese,:) = [];
p.K.l = p.K.l - length(removeThese);
removeThese = find(p.EqualityConstraintState==inf);
p.F_struc(removeThese,:) = [];
p.K.f = p.K.f - length(removeThese);
if p.options.bmibnb.cut.bilinear
p_cut = addBilinearVariableCuts(p);
end
if p.options.bmibnb.cut.evalvariable
p_cut = addEvalVariableCuts(p_cut);
psave.evalMap = p_cut.evalMap;
end
if p.options.bmibnb.cut.monomial
p_cut = addMonomialCuts(p_cut);
end
if p.options.bmibnb.cut.multipliedequality
p_cut = addMultipliedEqualityCuts(p_cut);
end
if p.options.bmibnb.cut.convexity
p_cut = addConvexityCuts(p_cut);
end
if p.options.bmibnb.cut.complementarity
p_cut = addComplementarityCuts(p_cut);
end
% **************************************
% SOLVE NODE PROBLEM
% **************************************
if any(p_cut.ub+1e-8<p_cut.lb)
output.problem=1;
cost = inf;
else
% We are solving relaxed problem (penbmi might be local solver)
p_cut.monomtable = eye(length(p_cut.c));
if p.solver.lowersolver.objective.quadratic.convex
% Setup quadratic
[p_cut.Q,p_cut.c] = compileQuadratic(p.c,p);
if nonconvexQuadratic(p_cut.Q);
p_cut.Q = p.Q;
p_cut.c = p.c;
end
end
fixed = p_cut.lb >= p_cut.ub;
if nnz(fixed) == length(p.c)
% All variables are fixed to a bound
output.Primal = p.lb;
res = constraint_residuals(p,output.Primal);
eq_ok = all(res(1:p.K.f)>=-p.options.bmibnb.eqtol);
iq_ok = all(res(1+p.K.f:end)>=p.options.bmibnb.pdtol);
feasible = eq_ok & iq_ok;
if feasible
output.problem = 0;
else
output.problem = 1;
end
cost = output.Primal'*p.Q*output.Primal + p.c'*output.Primal + p.f;
else
if nnz(fixed)==0
if ~isempty(p_cut.bilinears) & 0
top = size(p_cut.F_struc,1);
if length(p_cut.K.s)==1 & p_cut.K.s(1)==0
p_cut.K.s = [];
end
usedterms = zeros(size(p_cut.bilinears,1),1);
for i = 1:size(p_cut.bilinears,1)
if ~usedterms(i)
windex = p_cut.bilinears(i,1);
xindex = p_cut.bilinears(i,2);
yindex = p_cut.bilinears(i,3);
if xindex ~=yindex
% OK, we have a bilinear term
xsquaredindex = find(p_cut.bilinears(:,2)==xindex & p_cut.bilinears(:,3)==xindex);
ysquaredindex = find(p_cut.bilinears(:,2)==yindex & p_cut.bilinears(:,3)==yindex);
if ~isempty(xsquaredindex) & ~isempty(ysquaredindex)
usedterms(i) = 1;
usedterms(xsquaredindex) = 1;
usedterms(ysquaredindex) = 1;
xsquaredindex = p_cut.bilinears(xsquaredindex,1);
ysquaredindex = p_cut.bilinears(ysquaredindex,1);
if 0
Z = zeros(9,size(p_cut.F_struc,2));
Z(1,xsquaredindex+1) = 1;
Z(2,windex+1) = 1;
Z(4,windex+1) = 1;
Z(5,ysquaredindex+1) = 1;
Z(3,xindex+1) = 1;
Z(7,xindex+1) = 1;
Z(6,yindex+1) = 1;
Z(8,yindex+1) = 1;
Z(9,1)=1;
else
xL = p.lb(xindex);
yL = p.lb(yindex);
Z = zeros(9,size(p_cut.F_struc,2));
Z(1,xsquaredindex+1) = 1;
Z(2,windex+1) = 1;
Z(4,windex+1) = 1;
Z(5,ysquaredindex+1) = 1;
Z(3,xindex+1) = 1;
Z(7,xindex+1) = 1;
Z(6,yindex+1) = 1;
Z(8,yindex+1) = 1;
Z(9,1)=1;
Z(3,1) = -xL;
Z(7,1) = -xL;
Z(6,1) = -yL;
Z(8,1) = -yL;
Z(1,xindex+1) = -2*xL;
Z(5,yindex+1) = -2*yL;
Z(1,1) = xL^2;
Z(5,1) = yL^2;
Z(4,xindex+1) = -yL;
Z(4,yindex+1) = -xL;
Z(4,1) = xL*yL;
Z(2,xindex+1) = -yL;
Z(2,yindex+1) = -xL;
Z(2,1) = xL*yL;
end
p_cut.F_struc = [p_cut.F_struc;Z];
p_cut.K.s = [p_cut.K.s 3];
end
end
end
end
end
p_cut.linearindicies = 1:length(p.c);
p_cut.nonlinearindicies = [];
p_cut.variabletype = zeros(1,length(p.c));
p_cut.deppattern = eye(length(p.c));
p_cut.linears = 1:length(p.c);
p_cut.bilinears = [];
p_cut.nonlinears = [];
p_cut.monomials = [];
p_cut.evaluation_scheme = [];
tstart = tic;
output = feval(lowersolver,removenonlinearity(p_cut));
psave.counter.lowersolved = psave.counter.lowersolved + 1;
timing.lowersolve = timing.lowersolve + toc(tstart);
cost = output.Primal'*p_cut.Q*output.Primal + p_cut.c'*output.Primal + p.f;
% Minor clean-up
pp=p;
output.Primal(output.Primal<p.lb) = p.lb(output.Primal<p.lb);
output.Primal(output.Primal>p.ub) = p.ub(output.Primal>p.ub);
x=output.Primal;
return
else
pp = p_cut;
removethese = fixed;
if ~isempty(p_cut.F_struc)
p_cut.F_struc(:,1)=p_cut.F_struc(:,1)+p_cut.F_struc(:,1+find(fixed))*p_cut.lb(fixed);
p_cut.F_struc(:,1+find(fixed))=[];
rf = find(~any(p_cut.F_struc,2));
rf = rf(rf<=(p_cut.K.f + p_cut.K.l));
p_cut.F_struc(rf,:) = [];
p_cut.K.l = p_cut.K.l - nnz(rf>p_cut.K.f);
p_cut.K.f = p_cut.K.f - nnz(rf<=p_cut.K.f);
end
p_cut.c(removethese)=[];
if nnz(p_cut.Q)>0
p_cut.c = p_cut.c + 2*p_cut.Q(find(~removethese),find(removethese))*p_cut.lb(removethese);
p_cut.Q(:,find(removethese))=[];
p_cut.Q(find(removethese),:)=[];
else
p_cut.Q = spalloc(length(p_cut.c),length(p_cut.c),0);
end
if ~isempty(p_cut.binary_variables)
new_bin = [];
new_var = find(~fixed);
for i = 1:length(p_cut.binary_variables)
temp = find(p_cut.binary_variables(i) == new_var);
new_bin = [new_bin temp(:)'];
end
p_cut.binary_variables = new_bin;
end
if ~isempty(p_cut.integer_variables)
new_bin = [];
new_var = find(~fixed);
for i = 1:length(p_cut.integer_variables)
temp = find(p_cut.integer_variables(i) == new_var);
new_bin = [new_bin temp(:)'];
end
p_cut.integer_variables = new_bin;
end
p_cut.lb(removethese)=[];
p_cut.ub(removethese)=[];
p_cut.x0(removethese)=[];
p_cut.monomtable(:,find(removethese))=[];
p_cut.monomtable(find(removethese),:)=[];
% The model can become absolutely trivial in some case
% For instance in ex9_2_2 everything is presolved
if nnz(p_cut.c)==0 & nnz(p_cut.Q)==0 & size(p_cut.F_struc,1)==0
% No objective and no constraints
if all(p_cut.lb <= p_cut.ub)
output.Primal = (p_cut.lb + p_cut.ub)/2;
output.Primal(isinf(p_cut.lb) & isinf(p_cut.ub))=0;
output.problem = 0;
else
output.Primal = zeros(length(p_cut.lb),1);
output.problem = 1;
end
else
try
tstart = tic;
output = feval(lowersolver,removenonlinearity(p_cut));
psave.counter.lowersolved = psave.counter.lowersolved + 1;
timing.lowersolve = timing.lowersolve + toc(tstart);
catch
1
end
end
x=full(p.c*0);
x(removethese)=p.lb(removethese);
x(~removethese)=output.Primal;
output.Primal = x;
cost = output.Primal'*pp.Q*output.Primal + pp.c'*output.Primal + p.f;
end
end
end