sedumipy.getdatm

Port of getDAtm.m: computes DAt.q[k,j] = d[k]’*Aj[k] for each Lorentz block k and constraint column j – the per-iteration “scaled A” quantity loopPcg.m/PopK.m/sddir.m need for the Lorentz part – plus the dense-Lorentz-block correction DAt.denq (via _native.adendotd), which folds the dense.q blocks’ contribution into a separate Woodbury-update term and zeroes their rows out of DAt.q proper.

Implemented directly with NumPy/SciPy sparse arithmetic rather than by wrapping extractA()/ddot()’s C kernels for the DAt.q part: ddot()’s existing binding (_native.py, cluster 1) only wraps ddotxj() (the dense-X path); getDAtm.m’s own ddot(d.q2, A, K.qblkstart, Ablkjc) call uses the sparse-X path (spddotxj(), not bound) precisely because A is the full sparse constraint matrix here – reimplementing the same reduction via sparse matrix algebra avoids needing that binding at all. The DAt.denq part instead wraps the real adendotd() C kernel directly (_native.adendotd), since that computation is intricate enough (the Sherman-Morrison-Woodbury dense-column bookkeeping) that reimplementing it in NumPy would risk silently drifting from the reference algorithm.

Ablkjc is _native.partitA(A, K[“mainblks”])’s output – unused by this port’s DAt.q computation (which builds it via sparse slicing instead), kept only for signature fidelity with getDAtm.m. DAtdenq is the previous DAt.denq (or getdense()’s own Adotdden the very first time) – only its sparsity pattern (shape m x len(dense.q)) is used, as a template adendotd() fills in-place; see _native.adendotd’s docstring.

is_dense (new, not in getDAtm.m – sedumi.py’s own hint, computed once from getsymbada()’s structural ADA pattern density and threaded through every call this port makes here) picks DAt.q’s in-memory form: sparse (csr, the default) keeps getada()’s ADA = DAt.q’ * DAt.q a sparse @ sparse product, needed to avoid OOM on large-lorN/large-m problems like DIMACS’s nql180/qssp180 (m ~ 1.3e5) where ADA stays about as sparse as A itself; dense (plain ndarray) instead avoids sparse-format bookkeeping overhead entirely, which dominates on problems where ADA already comes out dense/near-dense (e.g. nb.mat, m=123) – there sparse @ sparse is pure overhead over what a dense BLAS matmul does directly. Bug-for-bug identical either way: the two branches below only pick data representation, not values.

Functions

getDAtm(A, Ablkjc, dense, DAtdenq, d, K[, ...])

DAt = getDAtm(A,Ablkjc,dense,DAtdenq,d,K): A is the internal-format At (N x m, SeDuMi's own storage convention: rows are the N cone variables, columns are the m constraints).