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

232 lines
8.0 KiB
Mathematica
Raw Normal View History

2019-12-18 11:25:45 +00:00
%%*******************************************************************
%% HKMpred: Compute (dX,dy,dZ) for the H..K..M direction.
%%
%% SDPT3: version 3.0
%% Copyright (c) 1997 by
%% K.C. Toh, M.J. Todd, R.H. Tutuncu
%% Last modified: 2 Feb 01
%%*******************************************************************
function [dX,dy,dZ,schur,L,UU,VV,E,SMWmat,hRd] = ...
HKMpred(blk,At,par,rp,Rd,sigmu,X,Z,invZchol);
global matlabversion ispc_hp_ibm
global spdensity iter solve_ok existMA47symb existspcholsymb
global nnzmat nnzmatold matfct_options matfct_options_old use_SCM
global Lsymb cachesize
global Zinv gamz dd
%%
%% compute schur matrix
%%
m = length(rp);
schur = sparse(m,m);
UU = []; VV = []; E = []; SMWmat = []; Afree = [];
existsdpblk = 0; exist_free_vars = 0;
dX = cell(size(blk,1),1); dy = []; dZ = cell(size(blk,1),1);
Zinv = cell(size(blk,1),1);
%%
for p = 1:size(blk,1)
pblk = blk(p,:);
n = sum(pblk{2});
numblk = length(pblk{2});
if strcmp(pblk{1},'l')
Zinv{p} = 1./Z{p};
dd{p} = X{p}./Z{p};
[schur,UU,VV] = schurmat_lblkold(blk,At,schur,UU,VV,p,dd);
elseif strcmp(pblk{1},'q');
gaptmp = qops(pblk,X{p},Z{p},1);
gamz2 = qops(pblk,Z{p},Z{p},2);
gamz{p} = sqrt(gamz2);
Zinv{p} = qops(pblk,-1./gamz2,Z{p},4);
dd{p} = qops(pblk,gaptmp./gamz2,ones(n,1),4);
[schur,UU,VV] = schurmat_qblkold(blk,At,schur,UU,VV,p,dd,Zinv,X);
elseif strcmp(pblk{1},'s')
existsdpblk = 1;
if (numblk == 1)
Zinv{p} = Prod2(pblk,full(invZchol{p}),invZchol{p}',1);
else
Zinv{p} = Prod2(pblk,invZchol{p},invZchol{p}',1);
end
schur = schurmat_sblk(blk,At,par,schur,p,X,Zinv);
elseif strcmp(pblk{1},'u')
exist_free_vars = 1;
Afree = [Afree At{p}'];
end
end
diagschur = diag(schur);
if (existsdpblk);
pertdiag = 1e-16*sqrt(m)*norm(diagschur);
for k=1:m; schur(k,k) = abs(schur(k,k)) + pertdiag; end;
else
pertdiag = 1e-16*max(diagschur);
for k=1:m; schur(k,k) = abs(schur(k,k)) + pertdiag; end;
end
%%
[rhs,EinvRc,hRd] = HKMrhsfun(blk,At,par,X,Z,rp,Rd,sigmu);
%%
%% determine matrix factorization to use
%%
if (exist_free_vars)
tmp = [zeros(size(Afree,2),1); ones(size(UU,2),1)];
UU = [Afree UU]; VV = [Afree VV];
E = spdiags(tmp,0,length(tmp),length(tmp));
else
E = speye(size(UU,2));
end
rhs = [rhs; zeros(m+size(UU,2)-length(rhs),1)];
if (iter <= 2)
if (size(UU,2) < min(500,0.1*m));
use_SCM = 1;
else
use_SCM = 0;
if (norm(UU-VV,'fro') < 1e-13) & (existMA47symb) & (size(UU,2) < 0.25*m)
matfct_options = 'MA47';
else
matfct_options = 'splu';
end
end
end
%%
%% Cholesky factorization
%%
if (iter == 1); existMA47symb = 1; nnzmatold = 0; end
nnzmat = mexnnz(schur);
nnzmatdiff = (nnzmat ~= nnzmatold);
if use_SCM
if (nnzmat > spdensity*m^2);
if issparse(schur); schur = full(schur); end;
matfct_options = 'chol';
else
if ~issparse(schur), schur = sparse(schur); end;
matfct_options = 'spchol';
end
if strcmp(matfct_options,'chol')
L = [];
if (matlabversion >= 6)
if (ispc_hp_ibm), [schur,indef] = chol(schur);
else, indef = mexchol_(schur);
end
else
[schur,indef] = chol(schur);
end
if indef;
solve_ok = -2;
fprintf(' chol: Schur complement matrix not positive definite.\n');
else
[xx,solve_ok,SMWmat] = schursysolve(schur,schur,UU,VV,E,rhs,matfct_options);
end
elseif strcmp(matfct_options,'spchol')
if (nnzmatdiff | ~strcmp(matfct_options,matfct_options_old))
[Lsymb,flag] = symbcholfun(schur,cachesize);
if (flag)
solve_ok = -2;
existspcholsymb = 0;
fprintf(' spchol: symbolic factorization fails.\n');
else
existspcholsymb = 1;
end
end
if (existspcholsymb)
L = sparcholfun(Lsymb,schur);
L.d(find(L.skip)) = inf;
if ~isempty(UU) & any(L.skip);
solve_ok = -3;
fprintf(' spchol: fail to solve Schur complement equation\n');
fprintf(' via the Sherman-Morrison update.\n');
else
[xx,solve_ok,SMWmat] = schursysolve(schur,L,UU,VV,E,rhs,matfct_options);
end
end
end
end
if (solve_ok <= 0)
if ~(existsdpblk & size(UU,2)==0)
use_SCM = 0;
matfct_options = 'splu';
if (size(UU,2) > 0)
fprintf(' switch to augmented system.\n');
else
fprintf(' switch to LU factorization.\n');
end
else
return;
end
end
%%
%% LU or symmetric indefinite factorization
%%
if ~use_SCM
raugmat = [schur UU; VV' -E];
if (nnzmat > spdensity*m^2);
matfct_options = 'lu';
end
%%
if strcmp(matfct_options,'lu')
if issparse(raugmat); raugmat = full(raugmat); end
[L.l,L.u,L.p] = lu(raugmat);
xx = L.u \ (L.l \ (L.p*rhs));
end
if strcmp(matfct_options,'MA47')
if ~issparse(raugmat); raugmat = sparse(raugmat); end
if (nnzmatdiff | ~strcmp(matfct_options,matfct_options_old))
nnztmp = (nnz(raugmat) + nnz(diag(raugmat)))/2;
[keep,Jcn,flag,info] = mexMA47syb(nnztmp,raugmat);
if (flag)
existMA47symb = 0;
fprintf(' MA47: symbolic factorization fails, switch to LU.\n');
matfct_options = 'splu';
else
existMA47symb = 1;
Lsymb.keep = keep; Lsymb.Jcn = Jcn;
Lsymb.La = 2*info(1); Lsymb.Liw = 2*info(2);
end
end
if (existMA47symb)
[L.a,L.iw,flag] = mexMA47fct(raugmat, ...
Lsymb.keep,Lsymb.Jcn,Lsymb.La,Lsymb.Liw,[1e-10,0]);
xx = mexMA47slv(length(rhs),L.a,L.iw,rhs);
if (flag == 0)
solve_ok = 1;
else
existMA47symb = 0;
fprintf(' MA47: solver fails, switch to LU. \n');
matfct_options = 'splu';
end
end
end
if strcmp(matfct_options,'splu')
if ~issparse(raugmat); raugmat = sparse(raugmat); end
if (nnzmatdiff | ~strcmp(matfct_options,matfct_options_old))
Lsymb.perm = symmmd(raugmat);
end
L.perm = Lsymb.perm;
if (matlabversion >= 6.5)
[L.l,L.u,L.p,L.q] = lu(raugmat(L.perm,L.perm));
elseif (exist('umfpack2')==3)
[L.l,L.u,pp,qq] = umfpack2(raugmat(L.perm,L.perm));
len = length(pp);
L.p = spconvert([(1:len)' pp' ones(len,1)]);
L.q = spconvert([qq' (1:len)' ones(len,1)]);
else
[L.l,L.u,L.p] = lu(raugmat(L.perm,L.perm));
L.q = speye(length(raugmat));
end
xx(L.perm,1) = L.q*( L.u \ (L.l \ (L.p*rhs(L.perm))));
if any(xx == inf)
solve_ok = 0;
fprintf(' LU: fails to solve the augmented system.\n');
else
solve_ok = 1;
end
end
end
nnzmatold = nnzmat; matfct_options_old = matfct_options;
%%
%% compute (dX,dZ)
%%
if (any(isnan(xx)) | any(isinf(xx)))
error(' solution of linear system contains NaN or inf');
end
[dX,dy,dZ] = HKMdirfun(blk,At,par,Rd,EinvRc,X,xx);
%%*******************************************************************