130 lines
4.1 KiB
Mathematica
130 lines
4.1 KiB
Mathematica
|
|
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
|