306 lines
9.5 KiB
Matlab
Executable File
306 lines
9.5 KiB
Matlab
Executable File
function [A,b] = generate_kernel_representation_data(N,N_unique,exponent_m2,exponent_p,p,options,p_base_parametric,ParametricIndicies,MonomIndicies,FirstRun)
|
|
|
|
persistent saveData
|
|
|
|
exponent_p_parametric = exponent_p(:,ParametricIndicies);
|
|
exponent_p_monoms = exponent_p(:,MonomIndicies);
|
|
pcoeffs = getbase(p);
|
|
if any(exponent_p_monoms(1,:))
|
|
pcoeffs=pcoeffs(:,2:end); % No constant term in p
|
|
end
|
|
b = [];
|
|
|
|
parametric = full((~isempty(ParametricIndicies) & any(any(exponent_p_parametric))));
|
|
|
|
% For problems with a lot of similar cones, this saves some time
|
|
reuse = 0;
|
|
if ~isempty(saveData) && isequal(saveData.N,N) & ~FirstRun
|
|
n = saveData.n;
|
|
ind = saveData.ind;
|
|
if isequal(saveData.N_unique,N_unique) & isequal(saveData.exponent_m2,exponent_m2)% & isequal(saveData.epm,exponent_p_monoms)
|
|
reuse = 1;
|
|
end
|
|
else
|
|
% Congruence partition sizes
|
|
for k = 1:size(N,1)
|
|
n(k) = size(N{k},1);
|
|
end
|
|
% Save old SOS definition
|
|
saveData.N = N;
|
|
saveData.n = n;
|
|
saveData.N_unique = N_unique;
|
|
saveData.exponent_m2 = exponent_m2;
|
|
saveData.N_unique = N_unique;
|
|
end
|
|
|
|
if reuse & options.sos.reuse
|
|
% Get old stuff
|
|
if size(exponent_m2{1},2)==2 % Stupid (sos(parametric)) case
|
|
ind = spalloc(1,1,0);
|
|
ind(1)=1;
|
|
allj = 1:size(exponent_p_monoms,1);
|
|
used_in_p = ones(size(exponent_p_monoms,1),1);
|
|
else
|
|
allj = [];
|
|
used_in_p = zeros(size(exponent_p_monoms,1),1);
|
|
hash = randn(size(exponent_p_monoms,2),1);
|
|
p_hash = exponent_p_monoms*hash;
|
|
exponent_p_monoms_hash = exponent_p_monoms*hash;
|
|
for i = 1:size(N_unique,1)
|
|
monom = sparse(N_unique(i,3:end));
|
|
j = find(exponent_p_monoms_hash == (monom*hash));
|
|
|
|
if isempty(j)
|
|
b = [b 0];
|
|
allj(end+1,1) = 0;
|
|
else
|
|
used_in_p(j) = 1;
|
|
allj(end+1,1:length(j)) = j(:)';
|
|
end
|
|
end
|
|
ind = saveData.ind;
|
|
end
|
|
else
|
|
allj = [];
|
|
used_in_p = zeros(size(exponent_p_monoms,1),1);
|
|
if size(exponent_m2{1},2)==2 % Stupid (sos(parametric)) case
|
|
ind = spalloc(1,1,0);
|
|
ind(1)=1;
|
|
allj = 1:size(exponent_p_monoms,1);
|
|
used_in_p = ones(size(exponent_p_monoms,1),1);
|
|
else
|
|
% To speed up some searching, we random-hash data
|
|
hash = randn(size(exponent_p_monoms,2),1);
|
|
for k = 1:length(exponent_m2)
|
|
if isempty(exponent_m2{k})
|
|
exp_hash{k}=[];
|
|
else
|
|
exp_hash{k} = sparse((exponent_m2{k}(:,3:end)))*hash; % SPARSE NEEDED DUE TO STRANGE NUMERICS IN MATLAB ON 0s (the stuff will differ on last bit in hex format)
|
|
end
|
|
end
|
|
|
|
p_hash = exponent_p_monoms*hash;
|
|
ind = spalloc(size(N_unique,1),sum(n.^2),0);
|
|
|
|
for i = 1:size(N_unique,1)
|
|
monom = N_unique(i,3:end);
|
|
monom_hash = sparse(monom)*hash;
|
|
LHS = 0;
|
|
start = 0;
|
|
for k = 1:size(N,1)
|
|
j = find(exp_hash{k} == monom_hash);
|
|
if ~isempty(j)
|
|
pos=exponent_m2{k}(j,1:2);
|
|
nss = pos(:,1);
|
|
mss = pos(:,2);
|
|
indicies = nss+(mss-1)*n(k);
|
|
ind(i,indicies+start) = ind(i,indicies+start) + 1;
|
|
end
|
|
start = start + (n(k))^2;
|
|
% start = start + (matrixSOSsize*n(k))^2;
|
|
end
|
|
|
|
j = find(p_hash == monom_hash);
|
|
|
|
if isempty(j)
|
|
allj(end+1,1) = 0;
|
|
else
|
|
used_in_p(j) = 1;
|
|
allj(end+1,1:length(j)) = j(:)';
|
|
end
|
|
end
|
|
end
|
|
end
|
|
saveData.ind = ind;
|
|
|
|
% Some parametric terms in p(x,t) do not appear in v'Qv
|
|
% So these have to be added 0*Q = b
|
|
not_dealt_with = find(used_in_p==0);
|
|
while ~isempty(not_dealt_with)
|
|
%j = findrows(exponent_p_monoms,exponent_p_monoms(not_dealt_with(1),:));
|
|
j = find(p_hash == p_hash(not_dealt_with(1)));
|
|
allj(end+1,1:length(j)) = j(:)';
|
|
used_in_p(j) = 1;
|
|
not_dealt_with = find(used_in_p==0);
|
|
ind(end+1,1)=0;
|
|
end
|
|
|
|
matrixSOSsize = length(p);
|
|
if parametric
|
|
% Inconsistent behaviour in MATLAB
|
|
if size(allj,1)==1
|
|
uu = [0;p_base_parametric];
|
|
b = sum(uu(allj+1))';
|
|
else
|
|
b = [];
|
|
for i = 1:matrixSOSsize
|
|
for j = i:matrixSOSsize
|
|
if i~=j
|
|
uu = [0;2*p_base_parametric(:,(i-1)*matrixSOSsize+j)];
|
|
else
|
|
uu = [0;p_base_parametric(:,(i-1)*matrixSOSsize+j)];
|
|
end
|
|
b = [b sum(uu(allj+1),2)'];
|
|
end
|
|
end
|
|
end
|
|
else
|
|
if matrixSOSsize == 1
|
|
uu = [zeros(size(pcoeffs,1),1) pcoeffs]';
|
|
b = sum(uu(allj+1,:),2)';
|
|
else
|
|
b = [];
|
|
for i = 1:matrixSOSsize
|
|
for j = i:matrixSOSsize
|
|
if i~=j
|
|
uu = [0;2*pcoeffs((i-1)*matrixSOSsize+j,:)'];
|
|
else
|
|
uu = [0;pcoeffs((i-1)*matrixSOSsize+j,:)'];
|
|
end
|
|
b = [b;sum(uu(allj+1,:),2)'];
|
|
end
|
|
end
|
|
end
|
|
% uu = [0;pcoeffs(:)];
|
|
% b = sum(uu(allj+1),2)';
|
|
end
|
|
|
|
b = b';
|
|
dualbase = ind;
|
|
|
|
j = 1;
|
|
A = cell(size(N,1),1);
|
|
for k = 1:size(N,1)
|
|
if matrixSOSsize==1
|
|
A{k} = dualbase(:,j:j+n(k)^2-1);
|
|
else
|
|
% Quick fix for matrix SOS case, should be optimized
|
|
A{k} = inflate(dualbase(:,j:j+n(k)^2-1),matrixSOSsize,n(k));
|
|
end
|
|
j = j + n(k)^2;
|
|
end
|
|
b = b(:);
|
|
|
|
|
|
|
|
function newAi = inflate(Ai,matrixSOSsize,n);
|
|
% Quick fix for matrix SOS case, should be optimized
|
|
newAi = [];
|
|
newAi = [];
|
|
newAj = [];
|
|
newAk = [];
|
|
top = 1;
|
|
for i = 1:matrixSOSsize
|
|
for r = i:matrixSOSsize
|
|
for m = 1:size(Ai,1)
|
|
ai = reshape(Ai(m,:),n,n);
|
|
|
|
if 1
|
|
% V = spalloc(matrixSOSsize,matrixSOSsize,2);
|
|
% V(i,r)=1;
|
|
% V(r,i)=1;
|
|
% aii = kron(V,ai);
|
|
% aii = aii(:);
|
|
% [ii,jj,kk] = find(aii);
|
|
% newAj = [newAj ii(:)'];
|
|
% newAi = [newAi repmat(top,1,length(ii))];
|
|
% newAk = [newAk kk(:)'];
|
|
[dnewAj,dnewAi,dnewAk] = inflatelocal(ai,matrixSOSsize,r,i,top);
|
|
newAj = [newAj dnewAj];
|
|
newAi = [newAi dnewAi];
|
|
newAk = [newAk dnewAk];
|
|
% newAi = [newAi;ai(:)'];
|
|
else
|
|
[dnewAjC,dnewAiC,dnewAkC] = inflatelocal(ai,matrixSOSsize,r,i,top);
|
|
[dnewAj,dnewAi,dnewAk] = inflatelocalnew(ai,matrixSOSsize,r,i,top,n);
|
|
AA=reshape(full(sparse(dnewAi*0+1,dnewAj,dnewAk,1,(matrixSOSsize*n)^2)),n*matrixSOSsize,[]);
|
|
AA2=reshape(full(sparse(dnewAiC*0+1,dnewAjC,dnewAkC,1,(matrixSOSsize*n)^2)),n*matrixSOSsize,[]);
|
|
|
|
if norm(AA-AA2)>0
|
|
1
|
|
end
|
|
|
|
|
|
newAj = [newAj dnewAj];
|
|
newAi = [newAi dnewAi];
|
|
newAk = [newAk dnewAk];
|
|
%
|
|
% [ii,jj,kk] = find(ai-diag(diag(ai)));
|
|
% iii = [(i-1)*n+ii;(r-1)*n+jj]
|
|
% jjj = [(r-1)*n+jj;(i-1)*n+ii]
|
|
% kkk = [kk;kk];
|
|
% indexi = repmat(top,1,length(iii));
|
|
% index = iii+(jjj-1)*matrixSOSsize*n
|
|
% newAj = [newAj index(:)'];
|
|
% newAi = [newAi indexi];
|
|
% newAk = [newAk kkk(:)'];
|
|
%
|
|
% [ii,jj,kk] = find(diag(diag(ai)));
|
|
% iii = [(i-1)*n+ii]
|
|
% jjj = [(r-1)*n+jj]
|
|
% kkk = [kk];
|
|
% indexi = repmat(top,1,length(iii));
|
|
% index = iii+(jjj-1)*matrixSOSsize*n
|
|
% newAj = [newAj index(:)'];
|
|
% newAi = [newAi indexi];
|
|
% newAk = [newAk kkk(:)'];
|
|
end
|
|
|
|
%sparse(indexi,index,kkk,1,(n*nA)^2)
|
|
|
|
top = top+1;
|
|
end
|
|
end
|
|
end
|
|
newAi = sparse(newAi,newAj,newAk,top-1,(matrixSOSsize*n)^2);
|
|
|
|
|
|
function [Z,Q1,R] = sparsenull(A)
|
|
|
|
[Q,R] = qr(A');
|
|
n = max(find(sum(abs(R),2)));
|
|
Q1 = Q(:,1:n);
|
|
R = R(1:n,:);
|
|
Z = Q(:,n+1:end); % New basis
|
|
|
|
|
|
function [dnewAj,dnewAi,dnewAk] = inflatelocal(ai,matrixSOSsize,r,i,top)
|
|
V = spalloc(matrixSOSsize,matrixSOSsize,2);
|
|
V(i,r)=1;
|
|
V(r,i)=1;
|
|
aii = kron(V,ai);
|
|
aii = aii(:);
|
|
[ii,jj,kk] = find(aii);
|
|
|
|
dnewAj = ii(:)';
|
|
dnewAi = repmat(top,1,length(ii));
|
|
dnewAk = kk(:)';
|
|
% newAi = [newAi;ai(:)'];
|
|
|
|
|
|
|
|
function [dnewAj,dnewAi,dnewAk] = inflatelocalnew(ai,matrixSOSsize,r,i,top,n)
|
|
|
|
if r==i
|
|
[ii,jj,kk] = find(ai-diag(diag(ai)));
|
|
else
|
|
[ii,jj,kk] = find(ai);
|
|
end
|
|
iii = [(i-1)*n+ii;(r-1)*n+jj];
|
|
jjj = [(r-1)*n+jj;(i-1)*n+ii];
|
|
kkk = [kk;kk];
|
|
indexi = repmat(top,1,length(iii));
|
|
index = iii+(jjj-1)*matrixSOSsize*n;
|
|
dnewAj = [ index(:)'];
|
|
dnewAi = [ indexi];
|
|
dnewAk = [ kkk(:)'];
|
|
|
|
[ii,jj,kk] = find(diag(diag(ai)));
|
|
iii = [(i-1)*n+ii];
|
|
jjj = [(r-1)*n+jj];
|
|
kkk = [kk];
|
|
indexi = repmat(top,1,length(iii));
|
|
index = iii+(jjj-1)*matrixSOSsize*n;
|
|
dnewAj = [dnewAj index(:)'];
|
|
dnewAi = [dnewAi indexi];
|
|
dnewAk = [dnewAk kkk(:)']; |