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

94 lines
3.7 KiB
Mathematica
Raw Permalink Normal View History

2019-12-18 11:25:45 +00:00
function p = addImpliedSDP(p)
if p.K.q(1)==0 && p.K.s(1) > 0
% Search for rows where there is a constant, and a diagonal term
% which thus has to be structly positive, we might leads us to a
% constraints of the type sum x_i >= 1, if only non-negative integer
% variables are involved, entering with positive coefficient (and v.s)
newF = [];
top = p.K.f + p.K.l + 1;
for i = 1:length(p.K.s)
F = p.F_struc(top:top + p.K.s(i)^2-1,:);
X0 = reshape(F(:,1),p.K.s(i),p.K.s(i));
candidates = find(any(X0-diag(diag(X0)),2) & (diag(X0)<=0));
if ~isempty(candidates);
I = speye(p.K.s(i),p.K.s(i));
pos = find(I(:));
for j = candidates(1:end)'
row = F(pos(j),2:end);
used = find(row);
if ~isempty(used)
if ~any(row(p.noninteger_variables))
if all(row <=0) && all(p.ub(used)<=0)
row(find(row)) = 1;
newF = [newF;-1 -row];
elseif all(row >=0) && all(p.lb(used)>=0)
row(find(row)) = 1;
newF = [newF;-1 row];
end
end
end
end
end
top = top + p.K.s(i)^2;
end
if size(newF,1)>0
p.F_struc = [p.F_struc(1:p.K.f + p.K.l,:);
newF;
p.F_struc(1+p.K.f+p.K.l:end,:)];
p.K.l = p.K.l + size(newF,1);
end
% Search for trivial variables entering in diagonal elements alone, and
% not entering anywhere else in model. Bad modelling?
% First, they should not appear in LP cone (can be generalized by
% checking that it acts in the correct direction)
% TODO: Check for possibility of different signs etc, currently only
% implemented for typical test cases
candidates = find(~any(p.F_struc(1:p.K.f + p.K.l,2:end),1));
fixable = nan(1,length(candidates));
top = p.K.f + p.K.l + 1;
for j = 1:length(p.K.s)
F = p.F_struc(top:top + p.K.s(j)^2-1,:);
for i = 1:length(candidates(:)')
X0 = reshape(F(:,1 + candidates(i)),p.K.s(j),p.K.s(j));
% Diagonal matrix?
d = diag(X0);
if nnz((X0-diag(d)))==0
if all(sign(d)<=0) && p.c(i)>=0 && (isnan(fixable(i)) || fixable(i)==-1)
fixable(i) = -1;
elseif all(sign(d)>=0) && p.c(i)<=0 && (isnan(fixable(i)) || fixable(i)==1)
fixable(i) = 1;
else
fixable(i) = 0;
end
else
fixable(i) = 0;
end
end
top = top + p.K.s(j)^2;
end
p.adjustable = candidates(find(fixable));
for i = candidates(find(~isnan(fixable)))
% if fixable(i) == -1
% if ~isinf(p.lb(i))
% % p.ub(i) = p.lb(i);
% % p.F_struc(:,1) = p.F_struc(:,1) + p.F_struc(:,i+1)*p.lb(i);
% % p.F_struc(:,i+1) = 0;
% % else
% % % TODO whole row/column should be removed from the LMI!
% end
% elseif fixable(i) == 1
% if ~isinf(p.ub(i))
% % p.ub(i) = p.lb(i);
% % p.F_struc(:,1) = p.F_struc(:,1) + p.F_struc(:,i+1)*p.lb(i);
% % p.F_struc(:,i+1) = 0;
% % else
% % % TODO whole row/column should be removed from the LMI!
% end
% end
end
end