179 lines
4.6 KiB
Mathematica
179 lines
4.6 KiB
Mathematica
|
|
function P = horzcat(varargin)
|
||
|
|
|
||
|
|
if isempty(varargin{1}) && isa(varargin{2},'optimizer')
|
||
|
|
P = varargin{2};
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
% Are they similiar objects (same parameterization).
|
||
|
|
% FIXME: Check will be strengthened
|
||
|
|
for i = 1:nargin
|
||
|
|
if isa(varargin{i},'optimizer') && isequal(varargin{i}.diminOrig,varargin{1}.diminOrig)
|
||
|
|
else
|
||
|
|
error('The optimizer objects do not match')
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
% Do they involve the same variables?
|
||
|
|
% FIXME: Allow different sets as long as relevant to merge
|
||
|
|
for i = 1:nargin
|
||
|
|
if ~isequal(varargin{i}.model.used_variables,varargin{1}.model.used_variables)
|
||
|
|
error('The optimizer objects do not match')
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
% Set up some hash structures to enable pruning of repeated constraints
|
||
|
|
hashvar = randn(size(varargin{1}.model.F_struc,2),1);
|
||
|
|
n = size(varargin{1}.model.F_struc,1);for i = 2:nargin;n = max(n,size(varargin{i}.model.F_struc,1));end
|
||
|
|
hashcon = randn(n,1);
|
||
|
|
for i = 1:length(varargin)
|
||
|
|
varargin{i}.model = defineHash(varargin{i}.model,hashvar,hashcon);
|
||
|
|
end
|
||
|
|
|
||
|
|
% Merge all models
|
||
|
|
model = varargin{1}.model;
|
||
|
|
for i = 2:nargin
|
||
|
|
model.f = model.f + varargin{i}.model.f;
|
||
|
|
model.c = model.c + varargin{i}.model.c;
|
||
|
|
model.Q = model.Q + varargin{i}.model.Q;
|
||
|
|
model = mergeConstraints(model,varargin{i}.model);
|
||
|
|
end
|
||
|
|
|
||
|
|
% Use average objective.
|
||
|
|
model.f = model.f/nargin;
|
||
|
|
model.c = model.c/nargin;
|
||
|
|
model.Q = model.Q/nargin;
|
||
|
|
|
||
|
|
P = varargin{1};
|
||
|
|
P.model = model;
|
||
|
|
|
||
|
|
|
||
|
|
function model = mergeConstraints(model1,model2);
|
||
|
|
top1 = 1;
|
||
|
|
top2 = 1;
|
||
|
|
K = model1.K;
|
||
|
|
Data = [];
|
||
|
|
hash = model1.hash;
|
||
|
|
|
||
|
|
if model1.K.f > 0
|
||
|
|
Data = model1.F_struc(top1:top1 + model1.K.f-1,:);
|
||
|
|
end
|
||
|
|
if model2.K.f > 0
|
||
|
|
index = top2:top2 + model2.K.f-1;
|
||
|
|
index = find(~ismember(model2.hash.f,model1.hash.f));
|
||
|
|
if ~isempty(index)
|
||
|
|
Data = [Data;model2.F_struc(top2:top2 + model2.K.f-1,:)];
|
||
|
|
K.f = K.f + length(index);
|
||
|
|
hash.f = [hash.f;model2.hash.f(index)]
|
||
|
|
end
|
||
|
|
end
|
||
|
|
top1 = top1 + model1.K.f;
|
||
|
|
top2 = top2 + model2.K.f;
|
||
|
|
|
||
|
|
if model1.K.l > 0
|
||
|
|
Data = [Data;model1.F_struc(top1:top1 + model1.K.l-1,:)];
|
||
|
|
hash.l = model1.hash.l;
|
||
|
|
end
|
||
|
|
top1 = top1 + model1.K.l;
|
||
|
|
K.l = model1.K.l;
|
||
|
|
|
||
|
|
if model2.K.l > 0
|
||
|
|
index = top2:top2 + model2.K.l-1;
|
||
|
|
keep = find(~ismember(model2.hash.l,model1.hash.l));
|
||
|
|
index = index(keep);
|
||
|
|
if ~isempty(index)
|
||
|
|
Data = [Data;model2.F_struc(index,:)];
|
||
|
|
K.l = K.l + length(index);
|
||
|
|
hash.l = [hash.l;model2.hash.l(keep)];
|
||
|
|
end
|
||
|
|
end
|
||
|
|
top2 = top2 + model2.K.l;
|
||
|
|
|
||
|
|
if ~isempty(model1.K.q) && any(model1.K.q)
|
||
|
|
Data = [Data;model1.F_struc(top1:top1 + sum(model1.K.q)-1,:)];
|
||
|
|
end
|
||
|
|
top1 = top1 + sum(model1.K.q);
|
||
|
|
K.q = model1.K.q;
|
||
|
|
|
||
|
|
if ~isempty(model2.K.q) && any(model2.K.q)
|
||
|
|
keep = find(~ismember(model2.hash.q,model1.hash.q));
|
||
|
|
if any(keep)
|
||
|
|
for i = 1:length(keep)
|
||
|
|
if keep(i)
|
||
|
|
Data = [Data;model2.F_struc(top2:top2 + model2.K.q(i)-1,:)];
|
||
|
|
K.q = [K.q model2.K.q(i)];
|
||
|
|
hash.q = [hash.q model2.hash.q(i)];
|
||
|
|
top2 = top2 + model2.K.q(i);
|
||
|
|
else
|
||
|
|
top2 = top2 + model2.K.q(i);
|
||
|
|
end
|
||
|
|
end
|
||
|
|
else
|
||
|
|
top2 = top2 + sum(model2.K.q);
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
if ~isempty(model1.K.s) && any(model1.K.s)
|
||
|
|
Data = [Data;model1.F_struc(top1:top1 + sum(model1.K.s.^2)-1,:)];
|
||
|
|
end
|
||
|
|
top1 = top1 + sum(model1.K.s.^2);
|
||
|
|
K.s = model1.K.s;
|
||
|
|
|
||
|
|
if ~isempty(model2.K.s) && any(model2.K.s)
|
||
|
|
keep = find(~ismember(model2.hash.s,model1.hash.s));
|
||
|
|
if any(keep)
|
||
|
|
for i = 1:length(keep)
|
||
|
|
if keep(i)
|
||
|
|
Data = [Data;model2.F_struc(top2:top2 + model2.K.s(i)^2-1,:)];
|
||
|
|
K.s = [K.s model2.K.s(i)];
|
||
|
|
hash.s = [hash.s model2.hash.s(i)];
|
||
|
|
top2 = top2 + model2.K.s(i)^2;
|
||
|
|
else
|
||
|
|
top2 = top2 + model2.K.s(i)^2;
|
||
|
|
end
|
||
|
|
end
|
||
|
|
else
|
||
|
|
top2 = top2 + sum(model2.K.s.^2);
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
model = model1;
|
||
|
|
model.F_struc = Data;
|
||
|
|
model.K = K;
|
||
|
|
model.hash = hash;
|
||
|
|
|
||
|
|
|
||
|
|
function model = defineHash(model,hashvar,hashcon);
|
||
|
|
|
||
|
|
top = 1;
|
||
|
|
if model.K.f > 0
|
||
|
|
model.hash.f = (model.F_struc(top:top+model.K.f-1,:)*hashvar);
|
||
|
|
top = top + model.K.f;
|
||
|
|
else
|
||
|
|
model.hash.f = [];
|
||
|
|
end
|
||
|
|
|
||
|
|
if model.K.l > 0
|
||
|
|
model.hash.l = (model.F_struc(top:top+model.K.l-1,:)*hashvar);
|
||
|
|
top = top + model.K.l;
|
||
|
|
else
|
||
|
|
model.hash.l = [];
|
||
|
|
end
|
||
|
|
|
||
|
|
if ~isempty(model.K.q) && any(model.K.q)
|
||
|
|
for i = 1:length(model.K.q)
|
||
|
|
model.hash.q(i) = hashcon(1:model.K.q(i))'*(model.F_struc(top:top+model.K.q(i)-1,:)*hashvar);
|
||
|
|
top = top + model.K.q(i);
|
||
|
|
end
|
||
|
|
else
|
||
|
|
model.hash.q = [];
|
||
|
|
end
|
||
|
|
|
||
|
|
if ~isempty(model.K.s) && any(model.K.s)
|
||
|
|
for i = 1:length(model.K.s)
|
||
|
|
model.hash.s(i) = hashcon(1:model.K.s(i)^2)'*(model.F_struc(top:top+model.K.s(i)^2-1,:)*hashvar);
|
||
|
|
top = top + model.K.s(i);
|
||
|
|
end
|
||
|
|
else
|
||
|
|
model.hash.s = [];
|
||
|
|
end
|