Dynamic-Calibration/utils/YALMIP-master/modules/sos/create_imagemodel.m

130 lines
4.1 KiB
Mathematica
Raw Permalink Normal View History

2019-12-18 11:25:45 +00:00
function [F,obj,BlockedQ,sol] = create_imagemodel(BlockedA,Blockedb,F_parametric,parobj,options);
% *********************************
% IMAGE REPRESENTATION
% Needed for nonlinearly parameterized problems
% More efficient in some cases
% *********************************
g = [];
vecQ = [];
sol.problem = 0;
for i = 1:length(BlockedA)
q = [];
A = [];
for j = 1:length(BlockedA{i})
n = sqrt(size(BlockedA{i}{j},2));
BlockedQ{i}{j} = sdpvar(n,n);
q = [q;reshape(BlockedQ{i}{j},n^2,1)];
A = [A BlockedA{i}{j}];
end
vecQ = [vecQ;q];
g = [g;Blockedb{i}-A*q];
end
g_vars = getvariables(g);
q_vars = getvariables(vecQ);
x_vars = setdiff(g_vars,q_vars);
base = getbase(g);
if isempty(x_vars)
A = base(:,1);base = base(:,2:end);
B = (base(:,ismember(g_vars,q_vars)));
Bnull = sparsenull(B);
t = sdpvar(size(Bnull,2),1);
imQ = -B\A+Bnull*t;
else
A = base(:,1);base = base(:,2:end);
C = base(:,ismember(g_vars,x_vars));
B = (base(:,ismember(g_vars,q_vars)));
[Bnull,Q1,R1] = sparsenull(B);
[ii,jj,kk] = find(Bnull);
%Bnull(abs(Bnull) < 1e-12) = 0;
small = find(abs(kk)<1e-12);
ii(small)=[];
jj(small)=[];
kk(small)=[];
Bnull = sparse(ii,jj,kk,size(Bnull,1),size(Bnull,2));
t = sdpvar(size(Bnull,2),1);
if options.sos.model == 2
imQ = -Q1*(R1'\(A+C*recover(x_vars)))+Bnull*t;
else
H = deriveBasis(B);
imQ = -B\(A+C*recover(x_vars))+H*t;
end
end
notUsed = find(sum(abs(B),2)==0);
if ~isempty(notUsed)
ff=g(notUsed);
if isa(ff,'double')
if nnz(ff)>0
sol.yalmiptime = 0; % FIX
sol.solvertime = 0;
sol.problem = 2;
sol.info = yalmiperror(1,'YALMIP');
F = [];
obj = [];
if options.verbose > 0
disp(' ');
disp('-> During construction of data, I encountered a situation')
disp('-> situation that tells me that the problem is trivially infeasible!')
disp('-> Have you forgotten to define some parametric variables?,')
disp('-> or perhaps you have a parametric problem where the highest')
disp('-> power in some of the independent variables is odd for any choice')
disp('-> of parametric variables, such as x^8+x^7+t*y^3')
disp('-> Anyway, take a good look at your model again...');
end
return
% error('You seem to have a strange model. Have you forgotten to define some parametric variable?');
end
else
F_parametric = F_parametric + (g(notUsed)==0);
end
end
F_sos = ([]);
obj = 0;
for i = 1:length(BlockedQ)
for j = 1:size(BlockedQ{i},2)
Q_old = BlockedQ{i}{j};
Q_old_vars = getvariables(Q_old);
Q_old_base = getbase(Q_old);
in_this = [];
for k = 1:length(Q_old_vars)
in_this = [in_this;find(Q_old_vars(k)==q_vars)];
end
Q_new = Q_old_base(:,1) + Q_old_base(:,2:end)*imQ(in_this);
Q_new = reshape(Q_new,length(BlockedQ{i}{j}),length(BlockedQ{i}{j}));
obj = obj+trace(Q_new);
if ~isa(Q_new,'double')
switch options.sos.model
case {2,4}
F_sos = F_sos + [Q_new>=0];
case 5
F_sos = F_sos + [dd(Q_new)];
case 6
F_sos = F_sos + [sdd(Q_new)];
otherwise
end
elseif min(eig(Q_new))<-1e-8
sol.yalmiptime = 0; % FIX
sol.solvertime = 0;
sol.problem = 2;
sol.info = yalmiperror(1,'YALMIP');
F = [];
obj = [];
error('Problem is trivially infeasible. After block-diagonalizing, I found constant negative definite blocks!');
return
end
BlockedQ{i}{j} = Q_new;
end
end
F = F_parametric + F_sos;
if isa(obj,'double') | (options.sos.traceobj == 0)
obj = [];
end
if ~isempty(parobj)
obj = parobj;
end