Dynamic-Calibration/utils/SDPT3-4.0/Solver/Oldmfiles/detect_diagold.m

129 lines
3.5 KiB
Matlab
Executable File

%%*******************************************************************
%% detect_diag: detect diagonal blocks in the SDP data.
%%
%% [blk,At,C,b,iidxdiag] = detect_diag(blk,At,C,b);
%%
%% SDPT3: version 3.0
%% Copyright (c) 1997 by
%% K.C. Toh, M.J. Todd, R.H. Tutuncu
%% Last modified: 2 Feb 01
%%******************************************************************
function [blk,At,C,b,iidxdiag] = detect_diag(blk,At,C,b);
m = length(b); numblk = size(blk,1);
idx_keepblk = [];
%%
%% convert At{p}(:,k) to A{p,k}
%%
if size(At,2) ~=m
A = cell(size(blk,1),m);
for p = 1:size(blk,1);
pblk = blk(p,:);
if strcmp(pblk{1},'s');
for k = 1:m
A{p,k} = mexsmat(blk,At,1,p,k);
end
elseif strcmp(pblk{1},'l');
for k = 1:m
A{p,k} = At{p}(:,k);
end
end
end
conversion = 1;
else
A = At;
conversion = 0;
end
%%
%% dectect diagonal sub-block in nondiagonal blocks.
%%
blkchanged = 0;
for p = 1:size(blk,1);
blktmp = blk{p,2};
n = sum(blktmp);
if strcmp(blk{p,1},'s');
Acum = abs(C{p});
for k = 1:m
Acum = Acum + abs(A{p,k});
end;
Acum = Acum - spdiags(diag(Acum),0,n,n);
rownorm = sum(Acum.*Acum);
idxdiag = find(rownorm < 1e-13);
idxnondiag = setdiff([1:n],idxdiag);
iidxdiag{p} = idxdiag;
if ~isempty(idxdiag);
if (blkchanged == 0)
blkchanged = 1;
diagblk = numblk+1;
A(diagblk,:) = cell(1,size(A,2));
C(diagblk,1) = cell(1,1);
blk{diagblk,1} = 'l';
blk{diagblk,2} = 0;
idx_keepblk = [idx_keepblk, diagblk];
end;
blk{diagblk,2} = blk{diagblk,2} + length(idxdiag);
blk{p,2} = length(idxnondiag);
for k = 1:size(A,2);
tmp = diag(A{p,k});
A{diagblk,k} = [A{diagblk,k} ; tmp(idxdiag)];
A{p,k} = A{p,k}(idxnondiag,idxnondiag);
end;
tmp = diag(C{p,1});
C{diagblk,1} = [C{diagblk,1}; tmp(idxdiag)];
C{p,1} = C{p,1}(idxnondiag,idxnondiag);
end;
if ~isempty(idxnondiag);
idx_keepblk = [idx_keepblk, p];
end;
elseif strcmp(blk{p,1},'l');
idx_keepblk = [idx_keepblk, p];
end;
end;
if (blkchanged);
blk = blk(idx_keepblk,:);
A = A(idx_keepblk,:);
C = C(idx_keepblk,:);
end;
%%
%% concatenate diagonal blocks.
%%
diagblk = []; idx_keepblk = [];
for p = 1:size(blk,1)
if strcmp(blk{p,1},'l');
diagblk = [diagblk, p];
else;
idx_keepblk = [idx_keepblk, p];
end;
end;
if ~isempty(diagblk);
idx1 = diagblk(1);
idx_keepblk = [idx_keepblk, idx1];
end;
if (length(diagblk) >= 2);
for p = 2:length(diagblk);
idxp = diagblk(p);
for k = 1:size(A,2);
A{idx1,k} = [A{idx1,k}; A{idxp,k}];
end;
C{idx1,1} = [C{idx1,1}; C{idxp,1}];
blk{idx1,2} = blk{idx1,2} + blk{idxp,2};
end;
blk = blk(idx_keepblk,:);
A = A(idx_keepblk,:);
C = C(idx_keepblk,:);
end;
%%
%%
%%
if conversion;
At = svec(blk,A,ones(size(blk,1),1));
else
At = A;
end
%%
%%******************************************************************