sedumipy.cone¶
Port of SeDuMi’s cone-vector-algebra .m files (eigK.m, vec.m, mat.m, eyeK.m, maxeigK.m, mineigK.m, …): pure NumPy, no C bindings needed – these files are themselves plain MATLAB using the built-in eig(), not mex functions, in the original source.
Cone K is represented as a dict, in either of the two shapes these .m files themselves accept:
“external” (user-facing): keys among “f”, “l”, “q”, “r”, “s”, “z”, with “q”/”r”/”s”/”z” as sequences of block sizes.
“internal” (SeDuMi’s own, post-pretransfo.m representation): has a “rsdpN” key; “q” is stacked with all Lorentz-block x0 values first, then the vectors, matching pretransfo.m’s own reordering – ported faithfully because sedumi.m’s own iteration loop only ever uses this representation, not the external one.
All 1-indexed MATLAB slicing has been converted to 0-indexed NumPy slicing; every reshape of a PSD block uses order=”F” (column-major) to match MATLAB’s own memory layout – getting this wrong is the single most common way to silently corrupt a port like this one.
Functions
|
[y,ddotx,Dx,xTy] = PopK(d,x,K,lpq): y = P(d)*x (the full scaling operator: L for LP, minus-trace/qblkmul for Lorentz, and -- unless lpq -- psdscale twice for PSD). |
|
y = asmDxq(d,x,K,ddotx): y = D(d)*x = P(d)^{1/2} x for the Lorentz part, given the scaling point d (as built by sdinit.m/ updtransfo.m: d.q1, d.q2, d.det, d.auxdet, d.auxtr). |
|
lab = eigK(x, K): spectral values of x w.r.t. |
|
x = eyeK(K): the cone K's identity element. |
|
x = frameit(lab,frmq,frms,K): x = [lab(L-part); qframeit(...); psdframeit(...)] -- a pure concatenation, lab in the same grouped layout qframeit/qinvjmul use (see qframeit's docstring). |
|
X = mat(x, n): inverse of vec() for a square n x n matrix (n defaults to sqrt(len(x))). |
|
lab = maxeigK(x, K): largest spectral value of x w.r.t. |
|
lab = mineigK(x, K): smallest spectral value of x w.r.t. |
|
mineig = minpsdeig(x,K): smallest spectral value across all PSD blocks (divided by 2, like psdeig's own lab). |
|
[lab,q] = psdeig(x,K): spectral coefficients (and, optionally, the eigenbasis q) of the PSD part of x -- like eigK's own PSD-block handling, but PSD-only, and can also return the eigenvectors. |
|
[ux,ispos] = psdfactor(x,K): per-PSD-block lower Cholesky factor UX'*UX = X, mirrored into a full (non-triangular-looking) array via UX + tril(UX,-1)' -- callers (psdscale/psdinvscale) re-extract the triangular part they need themselves, so the mirrored upper part is dead weight kept only for byte-for-byte fidelity to psdfactor.m. Returns ispos=False (and a partial/garbage ux) the moment any block fails to be positive definite, exactly like the real chol()-based early return. |
|
y = psdinvscale(ud,x,K): y = D(d^-1) x = Ud' X / Ud per PSD block, with Ud = triu(reshape(ud[block])) (upper-triangular part only, matching psdinvscale.m). |
|
z = psdjmul(x,y,K): (XY+YX)/2 per PSD block. |
|
y = psdscale(ud,x,K,transp): y[k] = vec(Ldk' Xk Ldk) (transp=False) or vec(Udk' Xk Udk) (transp=True), with Ld=tril(reshape(ud[block])), Ud=triu(reshape(ud[block])). |
|
x = qframeit(lab,frmq,K): reconstructs the Lorentz "vector" part of x from spectral values lab and frame direction frmq. |
|
y = qinvjmul(labx,frmx,b,K): inverse Jordan multiply for Lorentz blocks. |
|
z = qjmul(x,y,K): Jordan product (x*y)/sqrt(2) for Lorentz cones. |
|
tdetx = tdet(x,K): per-Lorentz-block "trace determinant" x1^2 - x2'x2 (the internal x0-stacked-then-vectors layout, via K.mainblks/K.qblkstart). |
|
z = triumtriu(x,y,K): z = x*y for upper-triangular x,y (per PSD block), Hermitianized via the strict-upper mirror -- since the product of two upper-triangular matrices is itself upper-triangular, this just fills in the (all-zero) strict lower part. |
|
x = vec(X): column-major flatten, matching MATLAB's reshape(X, numel(X), 1) -- NOT np.ravel()'s default row-major order. |