218 lines
7.7 KiB
Mathematica
218 lines
7.7 KiB
Mathematica
|
|
%%*****************************************************************
|
||
|
|
%% validate: validate data
|
||
|
|
%%*****************************************************************
|
||
|
|
%% SDPT3: version 4.0
|
||
|
|
%% Copyright (c) 1997 by
|
||
|
|
%% Kim-Chuan Toh, Michael J. Todd, Reha H. Tutuncu
|
||
|
|
%% Last Modified: 16 Sep 2004
|
||
|
|
%%*****************************************************************
|
||
|
|
|
||
|
|
function [blk,At,C,b,dim,nnblk,parbarrier] = ...
|
||
|
|
validate(blk,At,C,b,par,parbarrier)
|
||
|
|
|
||
|
|
if (nargin >= 5)
|
||
|
|
spdensity = par.spdensity;
|
||
|
|
else
|
||
|
|
spdensity = 0.4;
|
||
|
|
end
|
||
|
|
%%
|
||
|
|
if ~iscell(blk);
|
||
|
|
error('validate: blk must be a cell array'); end;
|
||
|
|
if (size(blk,2) < 2)
|
||
|
|
error('validate: blk must be a cell array with at least 2 columns');
|
||
|
|
end
|
||
|
|
if ~iscell(At) | ~iscell(C);
|
||
|
|
error('validate: At, C must be cell arrays');
|
||
|
|
end
|
||
|
|
if (size(At,1) ~= size(blk,1))
|
||
|
|
if (size(At,2) == size(blk,1));
|
||
|
|
At = At';
|
||
|
|
else
|
||
|
|
error('validate: size of At is not compatible with blk');
|
||
|
|
end
|
||
|
|
end
|
||
|
|
if (size(C,1) ~= size(blk,1))
|
||
|
|
if (size(C,2) == size(blk,1))
|
||
|
|
C = C';
|
||
|
|
else
|
||
|
|
error('validate: size of C is not compatible with blk');
|
||
|
|
end
|
||
|
|
end
|
||
|
|
if (min(size(b)) > 1); error('validate: b must be a vector'); end
|
||
|
|
if (size(b,1) < size(b,2)); b = b'; end
|
||
|
|
m = length(b);
|
||
|
|
%%
|
||
|
|
%%-----------------------------------------
|
||
|
|
%% validate blk, At, C
|
||
|
|
%%-----------------------------------------
|
||
|
|
ntotal = zeros(size(blk,1),1);
|
||
|
|
for p = 1:size(blk,1)
|
||
|
|
if (size(blk{p,2},1) > size(blk{p,2},2))
|
||
|
|
blk{p,2} = blk{p,2}';
|
||
|
|
end
|
||
|
|
pblk = blk(p,:);
|
||
|
|
n = sum(pblk{2});
|
||
|
|
numblk = length(pblk{2});
|
||
|
|
if strcmp(pblk{1},'s');
|
||
|
|
m1 = size(At{p,1},2);
|
||
|
|
n2 = sum(pblk{2}.*pblk{2}); n22 = sum(pblk{2}.*(pblk{2}+1))/2;
|
||
|
|
ntotal(p) = n22;
|
||
|
|
if ~all(size(C{p}) == n)
|
||
|
|
error('validate: blk and C are not compatible');
|
||
|
|
end
|
||
|
|
if (norm(C{p}-C{p}',inf) > 1e-13*norm(C{p},inf));
|
||
|
|
error('validate: C is not symmetric');
|
||
|
|
end
|
||
|
|
if (size(At{p,1}) == [m1, n22] & m1~=n22);
|
||
|
|
At{p,1} = At{p,1}';
|
||
|
|
end
|
||
|
|
if (~isempty(At{p,1})) & (size(At{p,1},1) ~= n22)
|
||
|
|
error('validate: blk and At not compatible');
|
||
|
|
end
|
||
|
|
if (nnz(At{p,1}) < spdensity*n22*m1) || (n <= 20) %%2nd condition: 2017-May-08
|
||
|
|
if ~issparse(At{p,1}); At{p,1} = sparse(At{p,1}); end
|
||
|
|
else
|
||
|
|
if issparse(At{p,1}); At{p,1} = full(At{p,1}); end
|
||
|
|
end
|
||
|
|
if (length(pblk) > 2) %% for low rank constraints
|
||
|
|
len = sum(pblk{3});
|
||
|
|
if (size(pblk{1,3},2) < size(pblk{1,3},1))
|
||
|
|
blk{p,3} = blk{p,3}';
|
||
|
|
end
|
||
|
|
if any(size(At{p,2})- [n,len])
|
||
|
|
error(' low rank structure specified in blk and At not compatible')
|
||
|
|
end
|
||
|
|
if (length(At(p,:)) > 2) & ~isempty(At{p,3})
|
||
|
|
if all(size(At{p,3},2)-[1,4])
|
||
|
|
error(' low rank structure in At{p,3} not specified correctly')
|
||
|
|
end
|
||
|
|
if (size(At{p,3},2) == 1)
|
||
|
|
if (size(At{p,3},1) < size(At{p,3},2)); At{p,3} = At{p,3}'; end
|
||
|
|
lenn = length(At{p,3});
|
||
|
|
constrnum = mexexpand(pblk{3},[1:length(pblk{3})]');
|
||
|
|
At{p,3} = [constrnum, [1:lenn]', [1:lenn]', At{p,3}];
|
||
|
|
elseif (size(At{p,3},2) == 4)
|
||
|
|
dd = At{p,3};
|
||
|
|
[dummy,idxsort] = sort(dd(:,1));
|
||
|
|
dd = dd(idxsort,:);
|
||
|
|
lenn = size(dd,1);
|
||
|
|
idxD = [0; find(diff(dd(:,1))); lenn];
|
||
|
|
ii = zeros(lenn,1); jj = zeros(lenn,1);
|
||
|
|
ss = [0,cumsum(pblk{3})];
|
||
|
|
for k = 1:length(pblk{3})
|
||
|
|
idx = [idxD(k)+1 : idxD(k+1)];
|
||
|
|
ii(idx) = dd(idx,2)+ss(k); %% convert to cumulative indexing
|
||
|
|
jj(idx) = dd(idx,3)+ss(k);
|
||
|
|
end
|
||
|
|
At{p,3} = [dd(:,1),ii,jj,dd(:,4)];
|
||
|
|
end
|
||
|
|
else
|
||
|
|
constrnum = mexexpand(pblk{3},[1:length(pblk{3})]');
|
||
|
|
At{p,3} = [constrnum, [1:len]', [1:len]', ones(len,1)];
|
||
|
|
end
|
||
|
|
end
|
||
|
|
if (nnz(C{p}) < spdensity*n2) | (numblk > 1);
|
||
|
|
if ~issparse(C{p}); C{p} = sparse(C{p}); end;
|
||
|
|
else
|
||
|
|
if issparse(C{p}); C{p} = full(C{p}); end; %%added: 2017-May-08
|
||
|
|
end
|
||
|
|
elseif strcmp(pblk{1},'q') | strcmp(pblk{1},'l') ...
|
||
|
|
| strcmp(pblk{1},'u');
|
||
|
|
ntotal(p) = n;
|
||
|
|
if (min(size(C{p})) ~= 1 | max(size(C{p})) ~= n);
|
||
|
|
error(['validate: blk and C are not compatible']);
|
||
|
|
end;
|
||
|
|
if (size(C{p},1) < size(C{p},2)); C{p} = C{p}'; end
|
||
|
|
if (size(At{p,1}) == [m, n] & m~=n);
|
||
|
|
At{p,1} = At{p,1}';
|
||
|
|
end
|
||
|
|
if ~all(size(At{p,1}) == [n,m]);
|
||
|
|
error('validate: blk and At not compatible');
|
||
|
|
end
|
||
|
|
if ~issparse(At{p,1});
|
||
|
|
At{p,1} = sparse(At{p,1});
|
||
|
|
end
|
||
|
|
if (nnz(C{p}) < spdensity*n);
|
||
|
|
if ~issparse(C{p}); C{p} = sparse(C{p}); end;
|
||
|
|
else
|
||
|
|
if issparse(C{p}); C{p} = full(C{p}); end;
|
||
|
|
end;
|
||
|
|
else
|
||
|
|
error(' blk: some fields are not specified correctly');
|
||
|
|
end
|
||
|
|
end
|
||
|
|
if (sum(ntotal) < m)
|
||
|
|
error(' total dimension of C should be > length(b)');
|
||
|
|
end
|
||
|
|
%%
|
||
|
|
%%-----------------------------------------
|
||
|
|
%% problem dimension
|
||
|
|
%%-----------------------------------------
|
||
|
|
%%
|
||
|
|
dim = zeros(1,4); nnblk = zeros(1,2);
|
||
|
|
for p = 1:size(blk,1)
|
||
|
|
pblk = blk(p,:);
|
||
|
|
if strcmp(pblk{1},'s')
|
||
|
|
dim(1) = dim(1) + sum(pblk{2});
|
||
|
|
nnblk(1) = nnblk(1) + length(pblk{2});
|
||
|
|
nn(p) = sum(pblk{2});
|
||
|
|
elseif strcmp(pblk{1},'q')
|
||
|
|
dim(2) = dim(2) + sum(pblk{2});
|
||
|
|
nnblk(2) = nnblk(2) + length(pblk{2});
|
||
|
|
nn(p) = length(pblk{2});
|
||
|
|
elseif strcmp(pblk{1},'l')
|
||
|
|
dim(3) = dim(3) + sum(pblk{2});
|
||
|
|
nn(p) = sum(pblk{2});
|
||
|
|
elseif strcmp(pblk{1},'u')
|
||
|
|
dim(4) = dim(4) + sum(pblk{2});
|
||
|
|
nn(p) = sum(pblk{2});
|
||
|
|
end
|
||
|
|
end
|
||
|
|
%%
|
||
|
|
%%-----------------------------------------
|
||
|
|
%% validate parbarrier
|
||
|
|
%%-----------------------------------------
|
||
|
|
%%
|
||
|
|
if (nargin == 6)
|
||
|
|
if ~iscell(parbarrier);
|
||
|
|
if (length(parbarrier) == size(blk,1))
|
||
|
|
tmp = parbarrier;
|
||
|
|
clear parbarrier;
|
||
|
|
parbarrier = cell(size(blk,1),1);
|
||
|
|
for p = 1:size(blk,1)
|
||
|
|
parbarrier{p} = tmp(p);
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
if (size(parbarrier,2) > size(parbarrier,1))
|
||
|
|
parbarrier = parbarrier';
|
||
|
|
end
|
||
|
|
for p = 1:size(blk,1)
|
||
|
|
pblk = blk(p,:);
|
||
|
|
if (size(parbarrier{p},1) > size(parbarrier{p},2))
|
||
|
|
parbarrier{p} = parbarrier{p}';
|
||
|
|
end
|
||
|
|
len = length(parbarrier{p});
|
||
|
|
if strcmp(pblk{1},'s') | strcmp(pblk{1},'q')
|
||
|
|
if (len == 1)
|
||
|
|
parbarrier{p} = parbarrier{p}*ones(1,length(pblk{2}));
|
||
|
|
elseif (len == 0)
|
||
|
|
parbarrier{p} = zeros(1,length(pblk{2}));
|
||
|
|
elseif (len ~= length(pblk{2}))
|
||
|
|
error('blk and parbarrier not compatible');
|
||
|
|
end
|
||
|
|
elseif strcmp(pblk{1},'l')
|
||
|
|
if (len == 1)
|
||
|
|
parbarrier{p} = parbarrier{p}*ones(1,sum(pblk{2}));
|
||
|
|
elseif (len == 0)
|
||
|
|
parbarrier{p} = zeros(1,sum(pblk{2}));
|
||
|
|
elseif (len ~= sum(pblk{2}))
|
||
|
|
error('blk and parbarrier not compatible');
|
||
|
|
end
|
||
|
|
elseif strcmp(pblk{1},'u')
|
||
|
|
parbarrier{p}= zeros(1,sum(pblk{2}));
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
%%***********************************************************************
|