%%******************************************************************* %% schurmat_qblk: compute schur matrix corresponding to SOCP blocks. %% %% HKM direction: output = schur + Ax*Ae' + Ae*Ax' - Ad*Ad' %% NT direction: output = schur + Ae*Ae' - Ad*Ad' %% %% where schur = A*D*A', and Ad is the modification to ADA' %% so that the latter is positive definite. %% %% [schur,UU,EE] = schurmat_qblk(blk,At,schur,UU,EE,p,dd,ee,xx); %% %% UU: stores the dense columns of Ax, Ae, Ad, and possibly %% those of A*D^{1/2}. It has the form UU = [Ax Ae Ad]. %% EE: stores the assocaited (2,2) block matrix when the %% output matrix is expressed as an augmented matrix. %% It has the form EE = [0 -lam 0; -lam 0 0; 0 0 I]. %% %% options = 0, HKM %% = 1, NT %% %% SDPT3: version 3.1 %% Copyright (c) 1997 by %% K.C. Toh, M.J. Todd, R.H. Tutuncu %% Last Modified: 16 Sep 2004 %%******************************************************************* function [schur,UU,EE] = schurmat_qblk(blk,At,par,schur,UU,EE,p,dd,ee,xx); global idxdenAq nnzschur_qblk if (nargin == 10); options = 0; else; options = 1; end; iter = par.iter; if isempty(EE) count = 0; else count = max(max(EE(:,2)),max(EE(:,1))); end pblk = blk(p,:); n = sum(pblk{2}); numblk = length(pblk{2}); %% Ae = qprod(pblk,At{p}',ee{p}); if (options == 0) Ax = qprod(pblk,At{p}',xx{p}); end idxden = checkdense(Ae); ddsch = dd{p}; if ~isempty(idxden); % separate sparse and dense handling spcolidx = setdiff([1:numblk],idxden); s = 1 + [0, cumsum(pblk{2})]; idx = s(idxden); tmp = zeros(n,1); tmp(idx) = sqrt(2*abs(ddsch(idx))); Ad = qprod(pblk,At{p}',tmp); ddsch(idx) = abs(ddsch(idx)); if (options == 0) len = length(idxden); gamzsub = par.gamz{p}(idxden); lam = gamzsub.*gamzsub; UU = [UU, Ax(:,idxden), Ae(:,idxden)*spdiags(lam,0,len,len), Ad(:,idxden)]; tmp = count+[1:len]'; EE = [EE; [tmp, len+tmp, -lam; len+tmp, tmp, -lam; ... 2*len+tmp, 2*len+tmp, ones(len,1)] ]; count = count+3*len; Ax = Ax(:,spcolidx); Ae = Ae(:,spcolidx); tmp2 = Ax*Ae'; schur = schur + (tmp2 + tmp2'); else len = length(idxden); w2 = par.gamz{p}./par.gamx{p}; lam = w2(idxden); UU = [UU, Ae(:,idxden)*spdiags(sqrt(lam),0,len,len), Ad(:,idxden)]; tmp = count+[1:len]'; EE = [EE; [tmp, tmp, -lam; len+tmp, len+tmp, ones(len,1)] ]; count = count + 2*len; Ae = Ae(:,spcolidx); schur = schur + Ae*Ae'; end else %% either all sparse or all dense if (nnz(Ae)>0.2*numel(Ae)) Ae = full(Ae); end if (options == 0) if (nnz(Ax)>0.2*numel(Ax)) Ax = full(Ax); end tmp = Ax*Ae'; schur = schur + (tmp+tmp'); else tmp = Ae*Ae'; schur = schur + tmp; end end if (iter==1) idxdenAq{p} = checkdense(At{p}'); end if ~isempty(idxdenAq{p}); idxden = idxdenAq{p}; len = length(idxden); Ad = At{p}(idxden,:)'*spdiags(sqrt(abs(ddsch(idxden))),0,len,len); UU = [UU, Ad]; tmp = count+[1:len]'; EE = [EE; [tmp, tmp, -sign(ddsch(idxden))]]; count = count + len; ddsch(idxden) = zeros(len,1); elseif (nnz(At{p})>0.2*numel(At{p})) % heuristic from sedumi At{p}=full(At{p}); end if (issparse(At{p}) && exist('spmm','file')==3) schurtmp = spmm(At{p}',spmm(spdiags(ddsch,0,n,n),At{p})); else schurtmp = At{p}' *spdiags(ddsch,0,n,n) *At{p}; end schur = sparse(schur + schurtmp); %%*******************************************************************