Problem API#
Problem data (C, A, b): the container, the cost hierarchy, and the
constraint-operator hierarchy with its explicit cvxpy encoding.
Base representation of a conic problem with linear equality constraints. |
|
Return |
|
Linear constraint operator \(\mathcal{A}: \operatorname{dom} \to \operatorname{cod}\) with a cvxpy encoding. |
|
Constraint operator defined only by |
|
Adapt an arbitrary |
|
Constraint operator backed by a dense coordinate tensor. |
|
Constraint operator backed by a sparse coordinate matrix. |
|
Abstract cost \(X \mapsto \langle C, X\rangle\) on a Jordan domain. |
|
A cost stored directly as a domain element (works on any EJA, incl. |
|
Self-adjoint SDP cost represented as an operator and matrix-space element. |
|
Hermitian cost backed by a dense matrix. |
|
Hermitian cost backed by a sparse matrix. |
- class sdplab.problem.SDPProblem(C, A, b, ctx=None)[source]#
Bases:
ContextBoundBase representation of a conic problem with linear equality constraints.
An instance stores the triple \((C, \mathcal{A}, b)\) from the standard primal problem
\[\begin{split}\min_{X \in \operatorname{dom}(\mathcal{A})}\ &\langle C, X\rangle \\ \text{s.t.}\quad &\mathcal{A}X = b, \\ &X \succeq 0.\end{split}\]Here \(C \in \operatorname{dom}(\mathcal{A})\), the linear constraint operator is \(\mathcal{A} : \operatorname{dom}(\mathcal{A}) \to \operatorname{cod}(\mathcal{A})\), and \(b \in \operatorname{cod}(\mathcal{A})\). Both \(C\) and \(b\) are stored as plain elements of their spaces; primal and dual variables are likewise plain elements of
domandcod.Think of this class as the common language between modeling code and solvers. It does not decide which algorithm to use. It only stores the mathematical data and the operations that every solver needs.
- Parameters:
C (Cost | ArrayLike)
A (LinOp)
b (ArrayLike)
ctx (Context | str | None)
- __init__(C, A, b, ctx=None)[source]#
Create the problem data \((C, \mathcal{A}, b)\).
- Parameters:
C (Cost | ArrayLike) – Objective in \(\operatorname{dom}(\mathcal{A})\) — a prepared
Cost, a dense or sparse matrix on a Hermitian domain, or a plain domain element (a tree of blocks on a tree domain). Arrays are wrapped through_dispatch_cost().A (LinOp) – Linear constraint operator \(\mathcal{A} : \operatorname{dom}(\mathcal{A}) \to \operatorname{cod}(\mathcal{A})\).
b (ArrayLike) – Right-hand side in \(\operatorname{cod}(\mathcal{A})\).
ctx (Context | str | None) – Optional backend context. When supplied,
Aand array data are converted to this context.
- Raises:
TypeError or ValueError – If \(C\) is not a member of \(\operatorname{dom}(\mathcal{A})\) or \(b\) is not a member of \(\operatorname{cod}(\mathcal{A})\). This catches many modeling mistakes early: wrong matrix size, wrong dtype, or a constraint vector with the wrong length.
- property dom: EuclideanJordanAlgebraSpace#
Return \(\operatorname{dom}(\mathcal{A})\), the primal space containing \(C\) and \(X\).
- property cod: InnerProductSpace#
Return \(\operatorname{cod}(\mathcal{A})\), the space containing \(\mathcal{A}X\), \(b\), and \(y\).
- primal_objective(X)[source]#
Evaluate the primal objective \(\langle C, X\rangle\) at a
domelement.In dense symmetric or Hermitian matrix spaces this is the trace objective \(\operatorname{Re}\operatorname{Tr}[C X]\).
- Parameters:
X (Any)
- Return type:
Any
- dual_objective(y)[source]#
Evaluate the linear dual objective term \(\langle b, y\rangle\) at a
codelement.- Parameters:
y (Any)
- Return type:
Any
- dual_slack(y)[source]#
Return the dual slack \(\mathcal{A}^\dagger y - C\) in
dom.- Parameters:
y (Any)
- Return type:
Any
- feasibility_gap(X)[source]#
Return \(\mathcal{A}X - b\), the equality-constraint residual in
cod.- Parameters:
X (Any)
- Return type:
Any
- property check_level: Literal['none', 'cheap', 'standard', 'strict']#
Return this object’s runtime validation level.
- convert(new_ctx=None)#
Return this object represented in
new_ctx.- Parameters:
new_ctx (Context | BackendFamily | str | None)
- Return type:
Self
- property ctx: Context#
Return the execution context bound to this object.
- property dtype: Any#
Return the default dtype associated with this object’s context.
- property ops: BackendOps#
Return backend operations associated with this object’s context.
- sdplab.problem.as_member(space, x, ctx)[source]#
Return
xas a raw member ofspacerepresented inctx.Accepts backend arrays, array-likes, raw trees, and bound
TreeElementvalues; validates membership according to the context’s check level.- Parameters:
space (InnerProductSpace)
x (Any)
ctx (Context)
- Return type:
Any
- class sdplab.problem.ConstraintOp(dom, cod, ctx=None)[source]#
Bases:
LinOp[EuclideanJordanAlgebraSpace,InnerProductSpace]Linear constraint operator \(\mathcal{A}: \operatorname{dom} \to \operatorname{cod}\) with a cvxpy encoding.
Beyond the
LinOpaction, a constraint operator knows how to present itself to cvxpy as a list of per-constraint matrices (see the module docstring). Concrete backends:DenseConstraintOp/SparseConstraintOpwrap a stored operator tensor and derive theA_ifrom it.MatrixFreeConstraintOpis defined only byapply/rapplyand materializes theA_ithrough the adjoint; the QOT operator extends it and overridesto_cvxpy()with a cheaper Hermitian-generator form.WrappedConstraintOpadapts an arbitraryLinOpby delegation, keeping it matrix-free.
- Parameters:
dom (Domain)
cod (Codomain)
ctx (Context | str | None)
- abstractmethod to_cvxpy()[source]#
Return the per-constraint matrices
[A_0, ..., A_{m-1}].Each
A_ilives in the domain matrix space and is oriented so that thei-th equality reads \(\operatorname{Re}\operatorname{Tr}[A_i X] = b_i\).- Return type:
list[DenseArray | SparseArray]
- rhs_to_cvxpy(b)[source]#
Return the real right-hand side matching the rows of
to_cvxpy().The default flattens
bintocodcoordinates and takes the real part – correct when the codomain is a real coordinate space ofmscalar constraints. Operators with a structured codomain (e.g. QOT’s Hermitian marginals reduced to real generators) override this.- Parameters:
b (Any)
- Return type:
DenseArray
- dual_from_cvxpy(y)[source]#
Reassemble a per-constraint value vector into a
codelement.Inverse of the row layout produced by
rhs_to_cvxpy(). The default unflattensyback intocod; structured codomains override. The caller (solver) is responsible for the dual sign.- Parameters:
y (DenseArray)
- Return type:
Any
- property A: Any#
Native numerical representation of this operator.
Concrete subclasses may choose the representation that best matches their storage model: for example, dense operators return a dense array while sparse operators return their sparse matrix. Matrix-free or lazy operators generally do not have such a representation and should leave this property unimplemented. Use
to_dense()when a dense tensor materialization is explicitly required.
- property H: LinOp#
Hermitian-adjoint view of this linear operator.
- Returns:
Adjoint view satisfying \(\langle A x, y\rangle_Y = \langle x, A^* y\rangle_X\).
- Return type:
LinOp
- adjoint()#
Return the Hermitian-adjoint view of this linear operator.
- Return type:
LinOp
- adjoint_apply(y)#
Apply the adjoint of this linear operator to
y.- Parameters:
y (Any)
- Return type:
Any
- abstractmethod apply(x)#
Apply the forward map to an element of
self.domain.- Parameters:
x (Any)
- Return type:
Any
- assert_codomain(y)#
Raise if
yis not in the codomain.- Parameters:
y (Any)
- Return type:
None
- assert_domain(x)#
Raise if
xis not in the domain.- Parameters:
x (Any)
- Return type:
None
- property check_level: Literal['none', 'cheap', 'standard', 'strict']#
Return this object’s runtime validation level.
- property codomain: Codomain#
Codomain space of this linear operator.
- convert(new_ctx=None)#
Return this object represented in
new_ctx.- Parameters:
new_ctx (Context | BackendFamily | str | None)
- Return type:
Self
- property ctx: Context#
Return the execution context bound to this object.
- property domain: Domain#
Domain space of this linear operator.
- property dtype: Any#
Return the default dtype associated with this object’s context.
- fuse(*, materialize=False)#
Return an equivalent operator with fusible sub-expressions multiplied out.
Tier-2 lazy-algebra simplification ([ADR-021](021_lazy_operator_algebra_and_simplification.md)): collapse each maximal subtree of densely-fusible operators into a single materialized operator — for example, a composition of dense operators becomes one
DenseLinOpholding the matrix product \(M_A M_B\) — while leaving matrix-free and other non-materializable leaves intact.This is an explicit, opt-in materialization. The result is mathematically equal to
selfbut only within floating-point rounding: fusing reassociates the arithmetic (multiplying matrices then applying differs from applying in sequence at the ulp level), so equality holds up to tolerance, not bit-for-bit. The fused operator preserves the domain, codomain, context, and scalar-field/dtype identity. A leaf operator returns itself.- Parameters:
materialize (bool, optional) – With the default
False, a matrix-free operand ([ADR-008](008_linop_subclasses.md)) is never densified: it remains a lazy leaf and only breaks a fusible run. WithTruethe caller explicitly accepts giving up the matrix-free contract: a matrix-free operand is densified into aDenseLinOp(via itsto_densebasis probe, which may be expensive), allowing the enclosing expression to collapse to a single dense operator.- Returns:
A fused operator with the same action as
self(up to rounding).- Return type:
LinOp
- is_hermitian()#
Return whether this operator is structurally Hermitian when known.
- Returns:
TrueorFalsewhen the subclass can verify the structure cheaply, otherwiseNonefor unknown or matrix-free operators.- Return type:
bool | None
- property ops: BackendOps#
Return backend operations associated with this object’s context.
- abstractmethod rapply(y)#
Apply the adjoint map to an element of
self.codomain.- Parameters:
y (Any)
- Return type:
Any
- rvapply(ys)#
Apply the adjoint over a leading batch axis. Input must have shape
(N,) + codomain.shape; usemoveaxisfor other layouts.- Parameters:
ys (Any)
- Return type:
Any
- to_dense()#
Materialize this operator as a dense backend array.
The returned array has shape
self.codomain.shape + self.domain.shape. The default implementation is intended for small problems, debugging, and tests. It materializes the full coordinate matrix, so subclasses that already store a dense or sparse matrix should override this method for efficiency.- Return type:
Any
- to_matrix()#
Materialize this operator as a 2D dense coordinate matrix.
The returned array has shape
(prod(self.codomain.shape), prod(self.domain.shape)). The default implementation builds a batch of standard basis vectors and callsvapply()once. If a space cannot batch-flatten or batch-unflatten its representation, it falls back to a safe Python loop. This method is for small/testing use; concrete storage-backed subclasses should override it when they can expose a matrix directly.- Return type:
Any
- to_sparse()#
- vapply(xs)#
Apply over a leading batch axis. Input must have shape
(N,) + domain.shape; usemoveaxisfor other layouts.- Parameters:
xs (Any)
- Return type:
Any
- class sdplab.problem.MatrixFreeConstraintOp(dom, cod, ctx=None)[source]#
Bases:
ConstraintOpConstraint operator defined only by
apply/rapply(no stored matrix).The default
to_cvxpy()materializes each constraint matrix as \(A_i = \mathcal{A}^\dagger e_i\), the adjoint applied to thei-th codomain basis vector. For a Hermitian domain this is exactly the matrix for which \(\operatorname{Tr}[A_i X] = (\mathcal{A}X)_i\). Subclasses with a cheaper or reduced encoding (e.g.QOTConstraintOp) overrideto_cvxpy(),rhs_to_cvxpy(), anddual_from_cvxpy().The default assumes a real coordinate codomain, so that the unit vectors
e_iare valid codomain members.- Parameters:
dom (Domain)
cod (Codomain)
ctx (Context | str | None)
- to_cvxpy()[source]#
Materialize
[A_i = adjoint(e_i)]over the codomain coordinate basis.- Return type:
list[DenseArray]
- property A: Any#
Native numerical representation of this operator.
Concrete subclasses may choose the representation that best matches their storage model: for example, dense operators return a dense array while sparse operators return their sparse matrix. Matrix-free or lazy operators generally do not have such a representation and should leave this property unimplemented. Use
to_dense()when a dense tensor materialization is explicitly required.
- property H: LinOp#
Hermitian-adjoint view of this linear operator.
- Returns:
Adjoint view satisfying \(\langle A x, y\rangle_Y = \langle x, A^* y\rangle_X\).
- Return type:
LinOp
- adjoint()#
Return the Hermitian-adjoint view of this linear operator.
- Return type:
LinOp
- adjoint_apply(y)#
Apply the adjoint of this linear operator to
y.- Parameters:
y (Any)
- Return type:
Any
- abstractmethod apply(x)#
Apply the forward map to an element of
self.domain.- Parameters:
x (Any)
- Return type:
Any
- assert_codomain(y)#
Raise if
yis not in the codomain.- Parameters:
y (Any)
- Return type:
None
- assert_domain(x)#
Raise if
xis not in the domain.- Parameters:
x (Any)
- Return type:
None
- property check_level: Literal['none', 'cheap', 'standard', 'strict']#
Return this object’s runtime validation level.
- property codomain: Codomain#
Codomain space of this linear operator.
- convert(new_ctx=None)#
Return this object represented in
new_ctx.- Parameters:
new_ctx (Context | BackendFamily | str | None)
- Return type:
Self
- property ctx: Context#
Return the execution context bound to this object.
- property domain: Domain#
Domain space of this linear operator.
- property dtype: Any#
Return the default dtype associated with this object’s context.
- dual_from_cvxpy(y)#
Reassemble a per-constraint value vector into a
codelement.Inverse of the row layout produced by
rhs_to_cvxpy(). The default unflattensyback intocod; structured codomains override. The caller (solver) is responsible for the dual sign.- Parameters:
y (DenseArray)
- Return type:
Any
- classmethod from_linop(op)#
- Parameters:
op (LinOp)
- Return type:
- fuse(*, materialize=False)#
Return an equivalent operator with fusible sub-expressions multiplied out.
Tier-2 lazy-algebra simplification ([ADR-021](021_lazy_operator_algebra_and_simplification.md)): collapse each maximal subtree of densely-fusible operators into a single materialized operator — for example, a composition of dense operators becomes one
DenseLinOpholding the matrix product \(M_A M_B\) — while leaving matrix-free and other non-materializable leaves intact.This is an explicit, opt-in materialization. The result is mathematically equal to
selfbut only within floating-point rounding: fusing reassociates the arithmetic (multiplying matrices then applying differs from applying in sequence at the ulp level), so equality holds up to tolerance, not bit-for-bit. The fused operator preserves the domain, codomain, context, and scalar-field/dtype identity. A leaf operator returns itself.- Parameters:
materialize (bool, optional) – With the default
False, a matrix-free operand ([ADR-008](008_linop_subclasses.md)) is never densified: it remains a lazy leaf and only breaks a fusible run. WithTruethe caller explicitly accepts giving up the matrix-free contract: a matrix-free operand is densified into aDenseLinOp(via itsto_densebasis probe, which may be expensive), allowing the enclosing expression to collapse to a single dense operator.- Returns:
A fused operator with the same action as
self(up to rounding).- Return type:
LinOp
- is_hermitian()#
Return whether this operator is structurally Hermitian when known.
- Returns:
TrueorFalsewhen the subclass can verify the structure cheaply, otherwiseNonefor unknown or matrix-free operators.- Return type:
bool | None
- property ops: BackendOps#
Return backend operations associated with this object’s context.
- abstractmethod rapply(y)#
Apply the adjoint map to an element of
self.codomain.- Parameters:
y (Any)
- Return type:
Any
- rhs_to_cvxpy(b)#
Return the real right-hand side matching the rows of
to_cvxpy().The default flattens
bintocodcoordinates and takes the real part – correct when the codomain is a real coordinate space ofmscalar constraints. Operators with a structured codomain (e.g. QOT’s Hermitian marginals reduced to real generators) override this.- Parameters:
b (Any)
- Return type:
DenseArray
- rvapply(ys)#
Apply the adjoint over a leading batch axis. Input must have shape
(N,) + codomain.shape; usemoveaxisfor other layouts.- Parameters:
ys (Any)
- Return type:
Any
- to_dense()#
Materialize this operator as a dense backend array.
The returned array has shape
self.codomain.shape + self.domain.shape. The default implementation is intended for small problems, debugging, and tests. It materializes the full coordinate matrix, so subclasses that already store a dense or sparse matrix should override this method for efficiency.- Return type:
Any
- to_matrix()#
Materialize this operator as a 2D dense coordinate matrix.
The returned array has shape
(prod(self.codomain.shape), prod(self.domain.shape)). The default implementation builds a batch of standard basis vectors and callsvapply()once. If a space cannot batch-flatten or batch-unflatten its representation, it falls back to a safe Python loop. This method is for small/testing use; concrete storage-backed subclasses should override it when they can expose a matrix directly.- Return type:
Any
- to_sparse()#
- vapply(xs)#
Apply over a leading batch axis. Input must have shape
(N,) + domain.shape; usemoveaxisfor other layouts.- Parameters:
xs (Any)
- Return type:
Any
- class sdplab.problem.WrappedConstraintOp(op, ctx=None)[source]#
Bases:
MatrixFreeConstraintOpAdapt an arbitrary
LinOpinto a constraint operator.This is the fallback used by
sdplab.problem._base._dispatch_constraint()for a user-supplied operator that is neither aDenseLinOpnor aSparseLinOp– a hand-written matrix-free operator, an algebra expression, and so on. The wrapper only forwardsapply/rapply, so the operator stays matrix-free for the first-order solvers; the per-constraint matrices are built lazily by the inheritedMatrixFreeConstraintOp.to_cvxpy()and only if the cvxpy backend is actually called.As for every
MatrixFreeConstraintOp, the default cvxpy encoding assumes a real coordinate codomain. Wrap a structured-codomain operator in a subclass that overridesto_cvxpy(),rhs_to_cvxpy(), anddual_from_cvxpy().- Parameters:
op (LinOp)
ctx (Context | str | None)
- __init__(op, ctx=None)[source]#
Wrap
op, converting it (and its spaces) onto the resolved context.- Parameters:
op (LinOp)
ctx (Context | str | None)
- apply(x)[source]#
Apply the wrapped operator (its own membership checks still run).
- Parameters:
x (Any)
- Return type:
Any
- to_dense()[source]#
Delegate dense materialization, keeping any efficient override.
- Return type:
DenseArray
- to_matrix()[source]#
Delegate flat-matrix materialization, keeping any efficient override.
- Return type:
DenseArray
- classmethod from_linop(op)[source]#
Wrap any
LinOpwithout materializing it.- Parameters:
op (LinOp)
- Return type:
- property A: Any#
Native numerical representation of this operator.
Concrete subclasses may choose the representation that best matches their storage model: for example, dense operators return a dense array while sparse operators return their sparse matrix. Matrix-free or lazy operators generally do not have such a representation and should leave this property unimplemented. Use
to_dense()when a dense tensor materialization is explicitly required.
- property H: LinOp#
Hermitian-adjoint view of this linear operator.
- Returns:
Adjoint view satisfying \(\langle A x, y\rangle_Y = \langle x, A^* y\rangle_X\).
- Return type:
LinOp
- adjoint()#
Return the Hermitian-adjoint view of this linear operator.
- Return type:
LinOp
- adjoint_apply(y)#
Apply the adjoint of this linear operator to
y.- Parameters:
y (Any)
- Return type:
Any
- assert_codomain(y)#
Raise if
yis not in the codomain.- Parameters:
y (Any)
- Return type:
None
- assert_domain(x)#
Raise if
xis not in the domain.- Parameters:
x (Any)
- Return type:
None
- property check_level: Literal['none', 'cheap', 'standard', 'strict']#
Return this object’s runtime validation level.
- property codomain: Codomain#
Codomain space of this linear operator.
- convert(new_ctx=None)#
Return this object represented in
new_ctx.- Parameters:
new_ctx (Context | BackendFamily | str | None)
- Return type:
Self
- property ctx: Context#
Return the execution context bound to this object.
- property domain: Domain#
Domain space of this linear operator.
- property dtype: Any#
Return the default dtype associated with this object’s context.
- dual_from_cvxpy(y)#
Reassemble a per-constraint value vector into a
codelement.Inverse of the row layout produced by
rhs_to_cvxpy(). The default unflattensyback intocod; structured codomains override. The caller (solver) is responsible for the dual sign.- Parameters:
y (DenseArray)
- Return type:
Any
- fuse(*, materialize=False)#
Return an equivalent operator with fusible sub-expressions multiplied out.
Tier-2 lazy-algebra simplification ([ADR-021](021_lazy_operator_algebra_and_simplification.md)): collapse each maximal subtree of densely-fusible operators into a single materialized operator — for example, a composition of dense operators becomes one
DenseLinOpholding the matrix product \(M_A M_B\) — while leaving matrix-free and other non-materializable leaves intact.This is an explicit, opt-in materialization. The result is mathematically equal to
selfbut only within floating-point rounding: fusing reassociates the arithmetic (multiplying matrices then applying differs from applying in sequence at the ulp level), so equality holds up to tolerance, not bit-for-bit. The fused operator preserves the domain, codomain, context, and scalar-field/dtype identity. A leaf operator returns itself.- Parameters:
materialize (bool, optional) – With the default
False, a matrix-free operand ([ADR-008](008_linop_subclasses.md)) is never densified: it remains a lazy leaf and only breaks a fusible run. WithTruethe caller explicitly accepts giving up the matrix-free contract: a matrix-free operand is densified into aDenseLinOp(via itsto_densebasis probe, which may be expensive), allowing the enclosing expression to collapse to a single dense operator.- Returns:
A fused operator with the same action as
self(up to rounding).- Return type:
LinOp
- is_hermitian()#
Return whether this operator is structurally Hermitian when known.
- Returns:
TrueorFalsewhen the subclass can verify the structure cheaply, otherwiseNonefor unknown or matrix-free operators.- Return type:
bool | None
- property ops: BackendOps#
Return backend operations associated with this object’s context.
- rhs_to_cvxpy(b)#
Return the real right-hand side matching the rows of
to_cvxpy().The default flattens
bintocodcoordinates and takes the real part – correct when the codomain is a real coordinate space ofmscalar constraints. Operators with a structured codomain (e.g. QOT’s Hermitian marginals reduced to real generators) override this.- Parameters:
b (Any)
- Return type:
DenseArray
- rvapply(ys)#
Apply the adjoint over a leading batch axis. Input must have shape
(N,) + codomain.shape; usemoveaxisfor other layouts.- Parameters:
ys (Any)
- Return type:
Any
- to_cvxpy()#
Materialize
[A_i = adjoint(e_i)]over the codomain coordinate basis.- Return type:
list[DenseArray]
- to_sparse()#
- vapply(xs)#
Apply over a leading batch axis. Input must have shape
(N,) + domain.shape; usemoveaxisfor other layouts.- Parameters:
xs (Any)
- Return type:
Any
- class sdplab.problem.DenseConstraintOp(A, dom, cod=None, ctx=None)[source]#
Bases:
ConstraintOp,DenseLinOpConstraint operator backed by a dense coordinate tensor.
The stored tensor
Tof shapecod.shape + dom.shapeacts by \((\mathcal{A}X)_i = \sum_{jk} T_{i,jk} X_{jk}\) (a Frobenius pairing, no conjugation). To present thetraceconvention \(\operatorname{Tr}[A_i X] = (\mathcal{A}X)_i\), thei-th constraint matrix is the transpose of thei-th tensor slice,A_i = T_i^{T}.Note the conjugation carefully: for a genuinely complex Hermitian slice the transpose already equals the conjugate,
T_i^{T} = \overline{T_i}, and that is the correct Hermitian matrix for whichTr[A_i X]reproduces the operator. A conjugate-transposeT_i^{H}would instead returnT_iitself and break the identity. The transpose is a no-op only for the real symmetric constraint matrices of a real SDP.- Parameters:
A (DenseArray)
dom (Domain)
cod (Codomain | None)
ctx (Context | str | None)
- to_cvxpy()[source]#
Return the per-constraint matrices
[A_0, ..., A_{m-1}].Each
A_ilives in the domain matrix space and is oriented so that thei-th equality reads \(\operatorname{Re}\operatorname{Tr}[A_i X] = b_i\).- Return type:
list[DenseArray]
- classmethod from_linop(op)[source]#
Wrap an existing
DenseLinOpas a constraint operator.- Parameters:
op (DenseLinOp)
- Return type:
- property A: DenseArray#
Stored dense tensor representation of this operator.
The returned array has shape
self.codomain.shape + self.domain.shapeand is the same object supplied at construction.
- property H: LinOp#
Hermitian-adjoint view of this linear operator.
- Returns:
Adjoint view satisfying \(\langle A x, y\rangle_Y = \langle x, A^* y\rangle_X\).
- Return type:
LinOp
- adjoint()#
Return the Hermitian-adjoint view of this linear operator.
- Return type:
LinOp
- adjoint_apply(y)#
Apply the adjoint of this linear operator to
y.- Parameters:
y (Any)
- Return type:
Any
- apply(x)#
Apply the dense operator to
x.- Parameters:
x (DenseArray)
- Return type:
DenseArray
- assert_codomain(y)#
Raise if
yis not in the codomain.- Parameters:
y (Any)
- Return type:
None
- assert_domain(x)#
Raise if
xis not in the domain.- Parameters:
x (Any)
- Return type:
None
- property check_level: Literal['none', 'cheap', 'standard', 'strict']#
Return this object’s runtime validation level.
- property codomain: Codomain#
Codomain space of this linear operator.
- convert(new_ctx=None)#
Return this object represented in
new_ctx.- Parameters:
new_ctx (Context | BackendFamily | str | None)
- Return type:
Self
- property ctx: Context#
Return the execution context bound to this object.
- property domain: Domain#
Domain space of this linear operator.
- property dtype: Any#
Return the default dtype associated with this object’s context.
- dual_from_cvxpy(y)#
Reassemble a per-constraint value vector into a
codelement.Inverse of the row layout produced by
rhs_to_cvxpy(). The default unflattensyback intocod; structured codomains override. The caller (solver) is responsible for the dual sign.- Parameters:
y (DenseArray)
- Return type:
Any
- fuse(*, materialize=False)#
Return an equivalent operator with fusible sub-expressions multiplied out.
Tier-2 lazy-algebra simplification ([ADR-021](021_lazy_operator_algebra_and_simplification.md)): collapse each maximal subtree of densely-fusible operators into a single materialized operator — for example, a composition of dense operators becomes one
DenseLinOpholding the matrix product \(M_A M_B\) — while leaving matrix-free and other non-materializable leaves intact.This is an explicit, opt-in materialization. The result is mathematically equal to
selfbut only within floating-point rounding: fusing reassociates the arithmetic (multiplying matrices then applying differs from applying in sequence at the ulp level), so equality holds up to tolerance, not bit-for-bit. The fused operator preserves the domain, codomain, context, and scalar-field/dtype identity. A leaf operator returns itself.- Parameters:
materialize (bool, optional) – With the default
False, a matrix-free operand ([ADR-008](008_linop_subclasses.md)) is never densified: it remains a lazy leaf and only breaks a fusible run. WithTruethe caller explicitly accepts giving up the matrix-free contract: a matrix-free operand is densified into aDenseLinOp(via itsto_densebasis probe, which may be expensive), allowing the enclosing expression to collapse to a single dense operator.- Returns:
A fused operator with the same action as
self(up to rounding).- Return type:
LinOp
- is_hermitian()#
Return whether this dense operator is structurally self-adjoint.
- Returns:
TrueorFalsewhen the structure can be checked, otherwiseNone.- Return type:
bool or None
- property ops: BackendOps#
Return backend operations associated with this object’s context.
- rapply(y)#
Apply the adjoint dense operator to
y.Euclidean spaces use the conjugate transpose of the flattened matrix. Non-Euclidean spaces apply the codomain and domain Riesz maps around that Euclidean adjoint.
- Parameters:
y (DenseArray)
- Return type:
DenseArray
- rhs_to_cvxpy(b)#
Return the real right-hand side matching the rows of
to_cvxpy().The default flattens
bintocodcoordinates and takes the real part – correct when the codomain is a real coordinate space ofmscalar constraints. Operators with a structured codomain (e.g. QOT’s Hermitian marginals reduced to real generators) override this.- Parameters:
b (Any)
- Return type:
DenseArray
- rvapply(ys)#
Apply the adjoint over a leading batch axis. Input must have shape
(N,) + codomain.shape; usemoveaxisfor other layouts.- Parameters:
ys (DenseArray)
- Return type:
DenseArray
- to_dense()#
Return the stored dense tensor representation of this operator.
The returned array has shape
self.codomain.shape + self.domain.shape.- Return type:
DenseArray
- to_matrix()#
Return the flattened dense matrix representation.
The returned array has shape
(prod(self.codomain.shape), prod(self.domain.shape)). It is a reshape/view of the stored dense tensor when the backend permits.- Return type:
DenseArray
- to_sparse()#
- vapply(xs)#
Apply over a leading batch axis. Input must have shape
(N,) + domain.shape; usemoveaxisfor other layouts.- Parameters:
xs (DenseArray)
- Return type:
DenseArray
- class sdplab.problem.SparseConstraintOp(A, dom, cod, ctx=None)[source]#
Bases:
ConstraintOp,SparseLinOpConstraint operator backed by a sparse coordinate matrix.
Astores the flattened(m, dom.size)matrix whosei-th row, reshaped todom.shape, is the operator tensor sliceT_i.to_cvxpy()returns eachA_i = T_i^{T}as a sparse(n, n)matrix (thetraceconvention). As for the dense case the map is a plain transpose, which for a complex Hermitian slice equals its conjugate\overline{T_i}– the correct Hermitian matrix – and is a no-op only for a real symmetric SDP; it keeps large constraints sparse.to_cvxpy()usesscipy.sparserow-slice/reshape/transpose semantics – the only sparse backend in use – and feeds the cvxpy backend, which operates on numpy/scipy data.- Parameters:
A (SparseArray)
dom (CoordinateSpace)
cod (CoordinateSpace)
ctx (Context | str | None)
- to_cvxpy()[source]#
Return the per-constraint matrices
[A_0, ..., A_{m-1}].Each
A_ilives in the domain matrix space and is oriented so that thei-th equality reads \(\operatorname{Re}\operatorname{Tr}[A_i X] = b_i\).- Return type:
list[SparseArray]
- classmethod from_linop(op)[source]#
Wrap an existing
SparseLinOpas a constraint operator.- Parameters:
op (SparseLinOp)
- Return type:
- property A: SparseArray#
Stored sparse matrix representation of this operator.
The returned sparse matrix has shape
(prod(self.codomain.shape), prod(self.domain.shape))and is the same object supplied at construction.
- property H: LinOp#
Hermitian-adjoint view of this linear operator.
- Returns:
Adjoint view satisfying \(\langle A x, y\rangle_Y = \langle x, A^* y\rangle_X\).
- Return type:
LinOp
- adjoint()#
Return the Hermitian-adjoint view of this linear operator.
- Return type:
LinOp
- adjoint_apply(y)#
Apply the adjoint of this linear operator to
y.- Parameters:
y (Any)
- Return type:
Any
- apply(x)#
Forward action
y = A @ xin Euclidean coordinates.x must have shape dom.shape (dense).
- Parameters:
x (DenseArray)
- Return type:
DenseArray
- assert_codomain(y)#
Raise if
yis not in the codomain.- Parameters:
y (Any)
- Return type:
None
- assert_domain(x)#
Raise if
xis not in the domain.- Parameters:
x (Any)
- Return type:
None
- property check_level: Literal['none', 'cheap', 'standard', 'strict']#
Return this object’s runtime validation level.
- property codomain: Codomain#
Codomain space of this linear operator.
- convert(new_ctx=None)#
Return this object represented in
new_ctx.- Parameters:
new_ctx (Context | BackendFamily | str | None)
- Return type:
Self
- property ctx: Context#
Return the execution context bound to this object.
- property domain: Domain#
Domain space of this linear operator.
- property dtype: Any#
Return the default dtype associated with this object’s context.
- dual_from_cvxpy(y)#
Reassemble a per-constraint value vector into a
codelement.Inverse of the row layout produced by
rhs_to_cvxpy(). The default unflattensyback intocod; structured codomains override. The caller (solver) is responsible for the dual sign.- Parameters:
y (DenseArray)
- Return type:
Any
- fuse(*, materialize=False)#
Return an equivalent operator with fusible sub-expressions multiplied out.
Tier-2 lazy-algebra simplification ([ADR-021](021_lazy_operator_algebra_and_simplification.md)): collapse each maximal subtree of densely-fusible operators into a single materialized operator — for example, a composition of dense operators becomes one
DenseLinOpholding the matrix product \(M_A M_B\) — while leaving matrix-free and other non-materializable leaves intact.This is an explicit, opt-in materialization. The result is mathematically equal to
selfbut only within floating-point rounding: fusing reassociates the arithmetic (multiplying matrices then applying differs from applying in sequence at the ulp level), so equality holds up to tolerance, not bit-for-bit. The fused operator preserves the domain, codomain, context, and scalar-field/dtype identity. A leaf operator returns itself.- Parameters:
materialize (bool, optional) – With the default
False, a matrix-free operand ([ADR-008](008_linop_subclasses.md)) is never densified: it remains a lazy leaf and only breaks a fusible run. WithTruethe caller explicitly accepts giving up the matrix-free contract: a matrix-free operand is densified into aDenseLinOp(via itsto_densebasis probe, which may be expensive), allowing the enclosing expression to collapse to a single dense operator.- Returns:
A fused operator with the same action as
self(up to rounding).- Return type:
LinOp
- is_hermitian()#
Return whether this sparse operator is structurally self-adjoint.
- Returns:
TrueorFalsewhen the structure can be checked, otherwiseNone.- Return type:
bool or None
- property ops: BackendOps#
Return backend operations associated with this object’s context.
- rapply(y)#
Metric-aware adjoint action.
y must have shape cod.shape (dense).
- Parameters:
y (DenseArray)
- Return type:
DenseArray
- rhs_to_cvxpy(b)#
Return the real right-hand side matching the rows of
to_cvxpy().The default flattens
bintocodcoordinates and takes the real part – correct when the codomain is a real coordinate space ofmscalar constraints. Operators with a structured codomain (e.g. QOT’s Hermitian marginals reduced to real generators) override this.- Parameters:
b (Any)
- Return type:
DenseArray
- rvapply(ys)#
Apply the adjoint over a leading batch axis. Input must have shape
(N,) + codomain.shape; usemoveaxisfor other layouts.- Parameters:
ys (DenseArray)
- Return type:
DenseArray
- to_dense()#
Materialize the stored sparse matrix as a dense operator tensor.
The returned array has shape
self.codomain.shape + self.domain.shape.- Return type:
DenseArray
- to_matrix()#
Materialize the stored sparse matrix as a dense 2D coordinate matrix.
Use
to_sparse()when sparse storage should be preserved.- Return type:
DenseArray
- to_sparse()#
Return the stored sparse matrix representation without copying.
The returned object is exactly the sparse array supplied at construction.
- Return type:
SparseArray
- vapply(xs)#
Apply over a leading batch axis. Input must have shape
(N,) + domain.shape; usemoveaxisfor other layouts.- Parameters:
xs (DenseArray)
- Return type:
DenseArray
- class sdplab.problem.Cost(space, ctx=None)[source]#
Bases:
ContextBound,ABC,Generic[MSpace]Abstract cost \(X \mapsto \langle C, X\rangle\) on a Jordan domain.
The two operations every solver needs:
inner()evaluates the (real) objective pairing \(\langle C, X\rangle\).elementreturns the cost as a plain element ofspace, used to form the dual slack \(\mathcal{A}^\dagger y - C\) and first-order primal updates.
- Parameters:
space (MSpace)
ctx (Context | str | None)
- space: MSpace#
- abstractmethod inner(X)[source]#
Return the real pairing \(\langle C, X\rangle\) as a backend scalar.
The result is a backend array (not a Python float), so the pairing can be evaluated inside compiled loops and under autodiff.
- Parameters:
X (Any)
- Return type:
Any
- abstractmethod to_cvxpy()[source]#
Return the cost matrix
Cin cvxpy-ready form.The objective handed to cvxpy is \(\operatorname{Re}\operatorname{Tr}[C\, X]\), so
Cis the Hermitian cost matrix (dense or sparse). Only matrix (Hermitian) costs support this; element/tree costs do not.- Return type:
Any
- to_sparse()[source]#
Return a sparse representation; the default sparsifies
to_dense().- Return type:
SparseArray
- property check_level: Literal['none', 'cheap', 'standard', 'strict']#
Return this object’s runtime validation level.
- convert(new_ctx=None)#
Return this object represented in
new_ctx.- Parameters:
new_ctx (Context | BackendFamily | str | None)
- Return type:
Self
- property ctx: Context#
Return the execution context bound to this object.
- property dtype: Any#
Return the default dtype associated with this object’s context.
- property ops: BackendOps#
Return backend operations associated with this object’s context.
- class sdplab.problem.ElementCost(value, space, ctx=None)[source]#
Bases:
Cost[EuclideanJordanAlgebraSpace]A cost stored directly as a domain element (works on any EJA, incl. trees).
- Parameters:
value (Any)
space (MSpace)
ctx (Context | str | None)
- to_cvxpy()[source]#
Return the cost matrix
Cin cvxpy-ready form.The objective handed to cvxpy is \(\operatorname{Re}\operatorname{Tr}[C\, X]\), so
Cis the Hermitian cost matrix (dense or sparse). Only matrix (Hermitian) costs support this; element/tree costs do not.- Return type:
Any
- inner(X)[source]#
Return the real pairing \(\langle C, X\rangle\) as a backend scalar.
The result is a backend array (not a Python float), so the pairing can be evaluated inside compiled loops and under autodiff.
- Parameters:
X (Any)
- Return type:
Any
- property check_level: Literal['none', 'cheap', 'standard', 'strict']#
Return this object’s runtime validation level.
- convert(new_ctx=None)#
Return this object represented in
new_ctx.- Parameters:
new_ctx (Context | BackendFamily | str | None)
- Return type:
Self
- property ctx: Context#
Return the execution context bound to this object.
- property dtype: Any#
Return the default dtype associated with this object’s context.
- property ops: BackendOps#
Return backend operations associated with this object’s context.
- to_sparse()#
Return a sparse representation; the default sparsifies
to_dense().- Return type:
SparseArray
- space: MSpace#
- class sdplab.problem.HermitianCost(space, ctx=None)[source]#
Bases:
Cost[HermitianSpace]Self-adjoint SDP cost represented as an operator and matrix-space element.
Beyond the
Costcontract, a Hermitian cost acts on vectors of the underlying Hilbert space throughoperator(matvec), which is what matrix-free spectral algorithms consume.- Parameters:
space (MSpace)
ctx (Context | str | None)
- operator: LinOp#
- __init__(space, ctx=None)[source]#
Bind the matrix space, rejecting domains that are not Hermitian.
The
Costbase only requires a Euclidean Jordan domain, but a Hermitian cost additionally readsspace.nand acts on vectors of the underlying Hilbert space, so the domain must be aHermitianSpace(real symmetric or complex Hermitian).- Parameters:
space (HermitianSpace)
ctx (Context | str | None)
- Return type:
None
- property matrix_space: HermitianSpace#
The Hermitian matrix space this cost lives in (alias of
space).
- property vector_space: InnerProductSpace#
Vector space on which the cost acts.
- matvec_batch(xs)[source]#
Apply the cost independently over leading batch axes.
- Parameters:
xs (Any)
- Return type:
Any
- classmethod from_dense(matrix, matrix_space, ctx=None)[source]#
- Parameters:
matrix (DenseArray)
matrix_space (HermitianSpace)
ctx (Context | str | None)
- Return type:
- classmethod from_sparse(matrix, matrix_space, ctx=None)[source]#
- Parameters:
matrix (SparseArray)
matrix_space (HermitianSpace)
ctx (Context | str | None)
- Return type:
- property check_level: Literal['none', 'cheap', 'standard', 'strict']#
Return this object’s runtime validation level.
- convert(new_ctx=None)#
Return this object represented in
new_ctx.- Parameters:
new_ctx (Context | BackendFamily | str | None)
- Return type:
Self
- property ctx: Context#
Return the execution context bound to this object.
- property dtype: Any#
Return the default dtype associated with this object’s context.
- abstractmethod inner(X)#
Return the real pairing \(\langle C, X\rangle\) as a backend scalar.
The result is a backend array (not a Python float), so the pairing can be evaluated inside compiled loops and under autodiff.
- Parameters:
X (Any)
- Return type:
Any
- property ops: BackendOps#
Return backend operations associated with this object’s context.
- abstractmethod to_cvxpy()#
Return the cost matrix
Cin cvxpy-ready form.The objective handed to cvxpy is \(\operatorname{Re}\operatorname{Tr}[C\, X]\), so
Cis the Hermitian cost matrix (dense or sparse). Only matrix (Hermitian) costs support this; element/tree costs do not.- Return type:
Any
- to_sparse()#
Return a sparse representation; the default sparsifies
to_dense().- Return type:
SparseArray
- space: MSpace#
- class sdplab.problem.DenseHermitianCost(matrix, matrix_space, ctx=None)[source]#
Bases:
HermitianCostHermitian cost backed by a dense matrix.
- Parameters:
matrix (DenseArray)
matrix_space (HermitianSpace)
ctx (Context | str | None)
- property matrix: DenseArray#
Stored dense matrix.
- inner(X)[source]#
Return the real pairing \(\langle C, X\rangle\) as a backend scalar.
The result is a backend array (not a Python float), so the pairing can be evaluated inside compiled loops and under autodiff.
- Parameters:
X (Any)
- Return type:
Any
- to_sparse()[source]#
Return a sparse representation; the default sparsifies
to_dense().- Return type:
SparseArray
- property check_level: Literal['none', 'cheap', 'standard', 'strict']#
Return this object’s runtime validation level.
- convert(new_ctx=None)#
Return this object represented in
new_ctx.- Parameters:
new_ctx (Context | BackendFamily | str | None)
- Return type:
Self
- property ctx: Context#
Return the execution context bound to this object.
- property dtype: Any#
Return the default dtype associated with this object’s context.
- classmethod from_dense(matrix, matrix_space, ctx=None)#
- Parameters:
matrix (DenseArray)
matrix_space (HermitianSpace)
ctx (Context | str | None)
- Return type:
- classmethod from_sparse(matrix, matrix_space, ctx=None)#
- Parameters:
matrix (SparseArray)
matrix_space (HermitianSpace)
ctx (Context | str | None)
- Return type:
- property matrix_space: HermitianSpace#
The Hermitian matrix space this cost lives in (alias of
space).
- matvec(x)#
Apply the cost to one vector.
- Parameters:
x (Any)
- Return type:
Any
- matvec_batch(xs)#
Apply the cost independently over leading batch axes.
- Parameters:
xs (Any)
- Return type:
Any
- property ops: BackendOps#
Return backend operations associated with this object’s context.
- property vector_space: InnerProductSpace#
Vector space on which the cost acts.
- operator: LinOp#
- space: MSpace#
- class sdplab.problem.SparseHermitianCost(matrix, matrix_space, ctx=None)[source]#
Bases:
HermitianCostHermitian cost backed by a sparse matrix.
elementdensifies the stored matrix; algorithms that only need the pairing (inner()) or the vector action (matvec()) never pay that cost.- Parameters:
matrix (SparseArray)
matrix_space (HermitianSpace)
ctx (Context | str | None)
- property matrix: SparseArray#
Stored sparse matrix.
- to_cvxpy()[source]#
Return the sparse Hermitian cost matrix for
Re Tr[C X].- Return type:
SparseArray
- inner(X)[source]#
Return the real pairing \(\langle C, X\rangle\) as a backend scalar.
The result is a backend array (not a Python float), so the pairing can be evaluated inside compiled loops and under autodiff.
- Parameters:
X (Any)
- Return type:
Any
- to_sparse()[source]#
Return a sparse representation; the default sparsifies
to_dense().- Return type:
SparseArray
- property check_level: Literal['none', 'cheap', 'standard', 'strict']#
Return this object’s runtime validation level.
- convert(new_ctx=None)#
Return this object represented in
new_ctx.- Parameters:
new_ctx (Context | BackendFamily | str | None)
- Return type:
Self
- property ctx: Context#
Return the execution context bound to this object.
- property dtype: Any#
Return the default dtype associated with this object’s context.
- classmethod from_dense(matrix, matrix_space, ctx=None)#
- Parameters:
matrix (DenseArray)
matrix_space (HermitianSpace)
ctx (Context | str | None)
- Return type:
- classmethod from_sparse(matrix, matrix_space, ctx=None)#
- Parameters:
matrix (SparseArray)
matrix_space (HermitianSpace)
ctx (Context | str | None)
- Return type:
- property matrix_space: HermitianSpace#
The Hermitian matrix space this cost lives in (alias of
space).
- matvec(x)#
Apply the cost to one vector.
- Parameters:
x (Any)
- Return type:
Any
- matvec_batch(xs)#
Apply the cost independently over leading batch axes.
- Parameters:
xs (Any)
- Return type:
Any
- property ops: BackendOps#
Return backend operations associated with this object’s context.
- property vector_space: InnerProductSpace#
Vector space on which the cost acts.
- operator: LinOp#
- space: MSpace#