Dynamic-Calibration/utils/YALMIP-master/extras/@lmi/hull.m

106 lines
3.3 KiB
Matlab
Executable File

function [Fhull,t,y] = hull(varargin)
% HULL Construct a model of the convex hull
%
% H = hull(F1,F2,...)
%
% OUTPUT
% H : Constraint object describing the convex hull of the input constraints
%
% INPUT
% Fi : Constraint objects with constraints
%
% Note that the convex representation of the convex hull requires a lifting
% (introduction of auxially variables). Hence, if you have many set of
% constraints, your problem rapidly grows large.
%
% If you intend to use the hull operator in a parameterized fashion in an
% optimizer setting, you can declare the parameters in the last argument.
% These variables will then be considered as if the were constants
%
% H = hull(F1,F2,...,Parameters)
% Pull out the parameter if one is given
ParameterVariables = [];
if isa(varargin{end},'sdpvar')
Parameter = varargin{end};
ParameterVariables = getvariables(Parameter);
varargin = {varargin{1:end-1}};
end
N = length(varargin);
if N==1
Fhull = varargin{1};
t = [];
y = [];
end
% Pre-process to convert convex quadratic constraints to socp constraints.
% This makes the perspective code easier.
% We also wexpand all graph-operators etc to find out all involved
% variables and constraints
for i = 1:N
varargin{i} = convertquadratics(varargin{i});
varargin{i} = expandmodel(varargin{i},[]);
end
variables = [];
for i = 1:N
% quick fix
if isa(varargin{i},'constraint')
varargin{i} = lmi(varargin{i});
end
if ~(isa(varargin{i},'lmi') | isa(varargin{i},'socc'))
error('Hull can only be applied to linear constraints');
elseif ~(islinear(varargin{i}))
error('Hull can only be applied to linear and convex quadratic constraints');
end
variables = unique([variables depends(varargin{i})]);
variables = setdiff(variables,ParameterVariables);
end
if N == 1
Fhull = varargin{1};
return
end
% Define variables. To allow users to easily plot convex hulls, we mark the
% internally defined variables as auxilliary. YALMIP will then not plot
% w.r.t these variables
nInitial = yalmip('nvars');
y = sdpvar(repmat(length(variables),1,N),repmat(1,1,N));
t = sdpvar(N,1);
nNow = yalmip('nvars');
yalmip('addauxvariables',nInitial+1:nNow);
Fhull = lmi([]);
for i = 1:N
Fi = flatten(varargin{i});
tvariable = getvariables(t(i));
for j = 1:length(Fi.clauses)
Xi = Fi.clauses{j}.data;
if ~isempty(ParameterVariables)
Xitrue = Xi;
Xi = replace(Xi,Parameter,0);
end
local_variables = getvariables(Xi);
local_index = find(ismember(variables,local_variables));
new_variables = getvariables(y{i}(local_index));
Xipersp = brutepersp(Xi,tvariable,new_variables);
if ~isempty(ParameterVariables)
Fi.clauses{j}.data = Xipersp + t(i)*(Xitrue-Xi);
else
Fi.clauses{j}.data = Xipersp;
end
Fi.clauses{j}.handle = ['F(y_' num2str(i) ')'];
end
Fhull = Fhull + Fi;
end
Fhull = Fhull + [(sum([y{:}],2) == recover(variables)):'sum y_i == x'];
Fhull = Fhull + [(sum(t)==1):'Multipliers sum to 1'] + [(t>=0):'Positive multiplier'];
Fhull = expanded(Fhull,1);
yalmip('setdependence',[reshape([y{:}],[],1);t(:)],recover(variables));
%yalmip('setdependence',recover([10 11]),recover(variables));
yalmip('addauxvariables',getvariables([reshape([y{:}],[],1);t(:)]));
y = [y{:}];