sedumipy.pcg¶
Port of loopPcg.m and wrapPcg.m: the preconditioned-conjugate-gradient solver for A*P(d)*A’ * y = rhs that sits at the heart of every interior- point iteration (sddir.m/sdfactor.m both delegate to wrapPcg), plus sparfwslv.m/sparbwslv.m (thin wrappers SeDuMi itself uses around fwblkslv/bwblkslv – i.e. this port’s own _native.fwsolve/bwsolve).
The dense-column preconditioning correction (dense.q/DAt.denq, from deninfac.py’s product-form Lden) IS implemented: loopPcg’s residual update includes the DAt.denq*DApq(dense.q) term (loopPcg.m line ~113-114) alongside the always-applied Lorentz-cone DAt.q’*DApq term. wrapPcg needs no separate dense-column term of its own – its residual updates go entirely through amul() (already dense-column-aware) and loopPcg().
Functions
|
[y,k,DAy] = loopPcg(...): solve A*P(d)*A' * y = b via PCG with L as the (block sparse Cholesky) preconditioner. |
|
y = sparbwslv(L,b): backward-solve y(L.perm) := L'b, i.e. b is already in storage order (typically straight from sparfwslv/fwdpr1/ bwdpr1) and the result is scattered back to real/original index space by L["perm"] -- matching real bwblkslv.c's mexFunction exactly. |
|
y = sparfwslv(L,b[,ysymb]): forward-solve y := Lb(L.perm) (L a blkchol.m-style dict: L["L"] the unit-lower-triangular CSC factor, L["xsuper"] the supernode boundaries, L["perm"] the elimination-order permutation -- 0-indexed in this port). |
|
[y,dx,k,r] = wrapPcg(...): solve AP(d)A'*y = rb + AD(rv) (rb may be None/empty, matching the .m file's if ~isempty(rb) guard), with one unconditional CG-preconditioned step followed by refinement passes via loopPcg() as needed. |