📄 compileinterfacedata.m
字号:
% Identifiers of the SDP constraints
lmiid = getlmiid(F);
for i = 1:length(lowrankdetails)
lowrankdetails{i}.id = find(ismember(lmiid,lowrankdetails{i}.id));
if ~isempty(lowrankdetails{i}.variables)
index = ismember(used_variables,lowrankdetails{i}.variables);
lowrankdetails{i}.variables = find(index);
end
end
end
% *************************************************************************
% SPECIAL VARIABLES
% Relax = 1 : relax both integers and nonlinear stuff
% Relax = 2 : relax integers
% Relax = 3 : relax nonlinear stuff
% *************************************************************************
if (options.relax==1) | (options.relax==3)
nonlins = [];
end
if (options.relax) | (options.relax==2)
integer_variables = [];
binary_variables = [];
old_binary_variables = find(ismember(used_variables,old_binary_variables));
else
integer_variables = find(ismember(used_variables,integer_variables));
binary_variables = find(ismember(used_variables,binary_variables));
old_binary_variables = find(ismember(used_variables,old_binary_variables));
end
parametric_variables = find(ismember(used_variables,parametric_variables));
extended_variables = find(ismember(used_variables,yalmip('extvariables')));
% *************************************************************************
% Equality constraints not supported or supposed to be removed
% *************************************************************************
% We may save some data in order to reconstruct
% dual variables related to equality constraints that
% have been removed.
oldF_struc = [];
oldQ = [];
oldc = [];
oldK = K;
Fremoved = [];
if (K.f>0)
% reduce if user explicitely says remove, or user says nothing but
% solverdefinitions does, and there are no nonlinear variables
if ((options.removeequalities==1 | options.removeequalities==2) & isempty(intersect(used_variables,nonlinearvariables))) | ((options.removeequalities==0) & (solver.constraint.equalities.linear==-1))
showprogress('Solving equalities',options.showprogress);
[x_equ,H,A_equ,b_equ,factors] = solveequalities(F_struc,K,options.removeequalities==1);
% Exit if no consistent solution exist
if (norm(A_equ*x_equ-b_equ,'inf')>1e-5)%sqrt(eps)*size(A_equ,2))
diagnostic.solvertime = 0;
diagnostic.info = yalmiperror(1,'YALMIP');
diagnostic.problem = 1;
solution = diagnostic;
solution.variables = used_variables(:);
solution.optvar = x_equ;
% And we are done! Save the result
% sdpvar('setSolution',solution);
return
end
% We dont need the rows for equalities anymore
oldF_struc = F_struc;
oldc = c;
oldQ = Q;
oldK = K;
F_struc = F_struc(K.f+1:end,:);
K.f = 0;
Fold = F;
[nlmi neq]=size(F);
F = lmi;
Fremoved = set([]);
for i = 1:nlmi+neq
if ~is(Fold(i),'equality')
F = F + Fold(i);
else
Fremoved = Fremoved + Fold(i);
end
end
% No variables left. Problem solved!
if size(H,2)==0
diagnostic.solvertime = 0;
diagnostic.info = yalmiperror(0,'YALMIP');
diagnostic.problem = 0;
solution = diagnostic;
solution.variables = used_variables(:);
solution.optvar = x_equ;
% And we are done! Save the result
% Note, no dual is saved
sdpvar('setSolution',solution);
p = checkset(F);
if any(p<1e-5)
diagnostic.info = yalmiperror(1,'YALMIP');
diagnostic.problem = 1;
end
return
end
showprogress('Converting problem to new basis',options.showprogress)
% objective in new basis
f = f + x_equ'*Q*x_equ;
c = H'*c + 2*H'*Q*x_equ;
Q = H'*Q*H;Q=((Q+Q')/2);
% LMI in new basis
F_struc = [F_struc*[1;x_equ] F_struc(:,2:end)*H];
else
% Solver does not support equality constraints and user specifies
% double-sided inequalitis to remove them
if (solver.constraint.equalities.linear==0 | options.removeequalities==-1)
% Add equalities
F_struc = [-F_struc(1:1:K.f,:);F_struc];
K.l = K.l+K.f*2;
% Keep this in mind...
K.fold = K.f;
K.f = 0;
end
% For simpliciy we introduce a dummy coordinate change
x_equ = 0;
H = 1;
factors = [];
end
else
x_equ = 0;
H = 1;
factors = [];
end
% *************************************************************************
% Setup the initial solution
% *************************************************************************
x0 = [];
if options.usex0
if options.relax
x0_used = relaxdouble(recover(used_variables));
else
%FIX : Do directly using yalmip('solution')
x0_used = double(recover(used_variables));
end
x0 = zeros(sdpvar('nvars'),1);
x0(used_variables) = x0_used(:);
x0(isnan(x0))=0;
end
if ~isempty(x0)
% Get a coordinate in the reduced space
x0 = H\(x0(used_variables)-x_equ);
end
% Monomial table for nonlinear variables
% FIX : Why here!!! mt handled above also
[mt,variabletype] = yalmip('monomtable');
if size(mt,1)>size(mt,2)
mt(size(mt,1),size(mt,1)) = 0;
end
% In local variables
mt = mt(used_variables,used_variables);
variabletype = variabletype(used_variables);
if (options.relax)|(options.relax==3)
mt = eye(length(used_variables));
end
% FIX : Make sure these things work...
lub = yalmip('getbounds',used_variables);
lb = lub(:,1)-inf;
ub = lub(:,2)+inf;
lb(old_binary_variables) = max(lb(old_binary_variables),0);
ub(old_binary_variables) = min(ub(old_binary_variables),1);
% This does not work if we have used removeequalities, so we clear them for
% safety. note that bounds are not guaranteed to be used according to the
% manual, so this is allowed, although it might be a bit inconsistent to
% some users.
if ~isempty(oldc)
lb = [];
ub = [];
end
% *************************************************************************
% GENERAL DATA EXCHANGE WITH SOLVER
% *************************************************************************
interfacedata.F_struc = F_struc;
interfacedata.c = c;
interfacedata.Q = Q;
interfacedata.f = f;
interfacedata.K = K;
interfacedata.lb = lb;
interfacedata.ub = ub;
interfacedata.x0 = x0;
interfacedata.options = options;
interfacedata.solver = solver;
interfacedata.monomtable = mt;
interfacedata.variabletype = variabletype;
interfacedata.integer_variables = integer_variables;
interfacedata.binary_variables = binary_variables;
interfacedata.uncertain_variables = [];
interfacedata.parametric_variables= parametric_variables;
interfacedata.extended_variables = extended_variables;
interfacedata.used_variables = used_variables;
interfacedata.lowrankdetails = lowrankdetails;
interfacedata.problemclass = ProblemClass;
interfacedata.KCut = KCut;
interfacedata.getsolvertime = 1;
% Data to be able to recover duals when model is reduced
interfacedata.oldF_struc = oldF_struc;
interfacedata.oldc = oldc;
interfacedata.oldK = oldK;
interfacedata.factors = factors;
interfacedata.Fremoved = Fremoved;
interfacedata.evalMap = evalMap;
interfacedata.evalVariables = evalVariables;
% *************************************************************************
% GENERAL DATA EXCANGE TO RECOVER SOLUTION AND UPDATE YALMIP VARIABLES
% *************************************************************************
recoverdata.H = H;
recoverdata.x_equ = x_equ;
recoverdata.used_variables = used_variables;
function yesno = warningon
s = warning;
if isa(s,'char')
yesno = isequal(s,'on');
else
yesno = isequal(s(1).state,'on');
end
function [evalMap,evalVariables,used_variables,nonlinearvariables,linearvariables] = detectHiddenNonlinear(used_variables,options,nonlinearvariables,linearvariables)
evalVariables = yalmip('evalVariables');
old_used_variables = used_variables;
goon = 1;
if ~isempty(evalVariables)
while goon
% Which used_variables are representing general functions
evalVariables = yalmip('evalVariables');
usedEvalVariables = find(ismember(used_variables,evalVariables));
evalMap = yalmip('extstruct',used_variables(usedEvalVariables));
if ~isa(evalMap,'cell')
evalMap = {evalMap};
end
% Find all variables used in the arguments of these functions
hidden = [];
for i = 1:length(evalMap)
if isequal(getbase(evalMap{i}.arg{1}),[0 1])% & is(evalMap{i}.arg{1},'linear')
for j = 1:length(evalMap{i}.arg)-1
% The last argument is the help variable z in the
% transformation from f(ax+b) to f(z),z==ax+b. We should not
% use this transformation if the argument already is unitary
hidden = [hidden getvariables(evalMap{i}.arg{j})];
end
else
for j = 1:length(evalMap{i}.arg)
% The last argument is the help variable z in the
% transformation from f(ax+b) to f(z),z==ax+b. We should not
% use this transformation if the argument already is unitary
hidden = [hidden getvariables(evalMap{i}.arg{j})];
end
end
end
used_variables = union(used_variables,hidden);
% The problem is that linear terms might be missing in problems with only
% nonlinear expressions
[monomtable,variabletype] = yalmip('monomtable');
if (options.relax==1)|(options.relax==3)
monomtable = [];
nonlinearvariables = [];
linearvariables = used_variables;
else
nonlinearvariables = find(variabletype);
linearvariables = used_variables(find(variabletype(used_variables)==0));
end
needednonlinear = nonlinearvariables(ismembc(nonlinearvariables,used_variables));
linearinnonlinear = find(sum(abs(monomtable(needednonlinear,:)),1));
missinglinear = setdiff(linearinnonlinear(:),linearvariables);
used_variables = uniquestripped([used_variables(:);missinglinear(:)]);
usedEvalVariables = find(ismember(used_variables,evalVariables));
evalMap = yalmip('extstruct',used_variables(usedEvalVariables));
if ~isa(evalMap,'cell')
evalMap = {evalMap};
end
evalVariables = usedEvalVariables;
for i = 1:length(evalMap)
if isequal(getbase(evalMap{i}.arg{1}),[0 1])
index = ismember(used_variables,getvariables(evalMap{i}.arg{1}));
evalMap{i}.variableIndex = find(index);
else
index = ismember(used_variables,getvariables(evalMap{i}.arg{end}));
evalMap{i}.variableIndex = find(index);
end
end
goon = ~isequal(used_variables,old_used_variables);
old_used_variables = used_variables;
end
else
evalMap = [];
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -