Regularization API#

Spectral regularizers and the smoothed dual functional they induce. A Regularizer supplies a scalar convex phi applied spectrally; bind(eps) yields the single-argument functional the solvers consume.

sdplab.regularization.Regularizer

Base class for scalar spectral regularizers.

sdplab.regularization.RegularizedSDPDualFunctional

Smooth regularized dual objective of a conic problem as a Functional.

sdplab.regularization.BoundDualFunctional

A RegularizedSDPDualFunctional with ε fixed.

sdplab.regularization.EntropyReg

Entropy regularizer, \(\varphi(t) = t(\log t - 1)\).

sdplab.regularization.QuadraticReg

Quadratic spectral regularizer on nonnegative spectra.

class sdplab.regularization.Regularizer(space, ctx=None)[source]#

Bases: ContextBound

Base class for scalar spectral regularizers.

Parameters:
  • space (EuclideanJordanAlgebraSpace)

  • ctx (Context | str | None)

abstractmethod phi(x)[source]#

Scalar convex penalty \(\varphi\) applied to primal eigenvalues.

Parameters:

x (DenseArray)

Return type:

DenseArray

abstractmethod phi_star(x)[source]#

Legendre transform \(\psi\) applied to scaled slack eigenvalues.

Parameters:

x (DenseArray)

Return type:

DenseArray

abstractmethod phi_star_prime(x)[source]#

Derivative \(\psi'\) recovering primal eigenvalues.

Parameters:

x (DenseArray)

Return type:

DenseArray

abstractmethod log_phi_star_prime(x)[source]#

Log-form \(\log\psi'\) for stable normalization.

Parameters:

x (DenseArray)

Return type:

DenseArray

legendre(X, val, normalized=False)[source]#

Evaluate the smoothed dual term of the regularizer.

normalized=False is the free separable conjugate \(\varepsilon \operatorname{Tr}[\psi(X/\varepsilon)]\), whose gradient is \(\psi'(X/\varepsilon)\) with whatever trace that implies. normalized=True is the fixed-trace conjugate, the supremum taken over unit-trace primals only, whose gradient is the unit-trace recovery. The two are different functions, not two scalings of one: see _normalized_legendre().

Parameters:
  • X (Any)

  • val (float)

  • normalized (bool)

Return type:

DenseArray

legendre_and_grad(X, val, normalized=False)[source]#

Return (legendre(X, val, normalized), gradient).

A genuine value/gradient pair in both modes: the free conjugate with \(\psi'(X/\varepsilon)\), or the fixed-trace conjugate with the unit-trace recovery. Optimizers that line-search on the value therefore descend the function they are evaluating either way.

Parameters:
  • X (Any)

  • val (float)

  • normalized (bool)

Return type:

Tuple[DenseArray, Any]

phi_star_prime_matrix(X, val, normalized=True)[source]#

Return the primal matrix \((\varphi^*)'(X / \varepsilon)\).

Parameters:
  • X (ArrayLike)

  • val (float)

  • normalized (bool)

Return type:

ArrayLike

with_space(space)[source]#
Parameters:

space (EuclideanJordanAlgebraSpace)

Return type:

Regularizer

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.regularization.RegularizedSDPDualFunctional(problem, regularizer, ctx=None)[source]#

Bases: Functional

Smooth regularized dual objective of a conic problem as a Functional.

For a base problem with cost \(C \in \operatorname{dom}(\mathcal{A})\), operator \(\mathcal{A}\), and RHS \(b\), coupled to a spectral penalty with Legendre transform \(\psi\), this evaluates

\[D_\varepsilon(y) = \langle b, y\rangle - \varepsilon \operatorname{Tr}\!\left[ \psi\!\left(\tfrac{\mathcal{A}^\dagger y - C}{\varepsilon}\right) \right], \qquad y \in \operatorname{cod}(\mathcal{A}).\]

Arguments and results are plain space elements (arrays, or raw trees on a TreeSpace codomain). This always reports the maximization objective; sign handling for minimizing optimizers lives on the bound view. \(\varepsilon\) is supplied per call so a continuation schedule can vary it without rebuilding the functional; bind() fixes it and yields a standard single-argument functional.

Parameters:
slack(y)[source]#

Return the dual slack \(\mathcal{A}^\dagger y - C\) in dom.

Parameters:

y (Any)

Return type:

Any

value(y, eps_val, normalized=False, *args, **kwargs)[source]#

Return \(D_\varepsilon(y)\) for strength eps_val.

normalized selects the fixed-trace conjugate, so it changes the objective itself and not only the recovered primal – it must match the flag used for grad()/value_and_grad(), which is what bind() guarantees. The trailing *args/**kwargs keep this compatible with Functional (__call__).

Parameters:
  • y (Any)

  • eps_val (float)

  • normalized (bool)

  • args (Any)

  • kwargs (Any)

Return type:

Any

value_and_grad(y, eps_val, normalized=False, *args, **kwargs)[source]#

Return \((D_\varepsilon(y), \nabla_y D_\varepsilon(y))\).

The gradient is \(b - \mathcal{A}\,\psi'\!\big((\mathcal{A}^\dagger y - C)/\varepsilon\big)\): the Legendre gradient lives in \(\operatorname{dom}(\mathcal{A})\) and is pushed through \(\mathcal{A}\) before combining with b.

Parameters:
  • y (Any)

  • eps_val (float)

  • normalized (bool)

  • args (Any)

  • kwargs (Any)

Return type:

Tuple[Any, Any]

grad(y, eps_val, normalized=False, *args, **kwargs)[source]#

Return \(\nabla_y D_\varepsilon(y)\) alone.

Parameters:
  • y (Any)

  • eps_val (float)

  • normalized (bool)

  • args (Any)

  • kwargs (Any)

Return type:

Any

primal_from_dual(y, eps_val, normalized=True)[source]#

Recover the primal element from a dual iterate.

With \(\mathcal{A}^\dagger y - C = V \operatorname{diag}(s) V^\dagger\) the eigenvalues are \(\lambda_i = \psi'(s_i / \varepsilon)\) (or, when normalized, their unit-trace normalization), giving \(X = V \operatorname{diag}(\lambda) V^\dagger\) as a plain dom element – the first-order map used to read a primal certificate off a dual optimum.

Parameters:
  • y (Any)

  • eps_val (float)

  • normalized (bool)

Return type:

Any

bind(eps_val, *, normalized=False)[source]#

Return a single-argument functional with eps_val baked in.

The result satisfies the plain Functional contract and can be handed to spacecore.minimize_scipy() / spacecore.minimize_optax(). To hand this maximization objective to a minimizer, negate through the functional algebra: -problem.bind(eps).

Parameters:
  • eps_val (float)

  • normalized (bool)

Return type:

BoundDualFunctional

assert_domain(x)#

Raise if x is 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.

compose(A)#

Return the pull-back self o A.

Parameters:

A (LinOp) – Linear operator whose codomain matches this functional’s domain.

Returns:

Functional on A.domain evaluating self.value(A.apply(x)).

Return type:

Functional

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 scalar-valued map.

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.

vgrad(xs)#

Gradient over a leading batch axis.

Override in subclasses that support differentiation; the base raises NotImplementedError.

Parameters:

xs (Any)

Return type:

Any

vvalue(xs)#

Evaluate over a leading batch axis. Input must have shape (N,) + domain.shape; use moveaxis for other layouts.

Parameters:

xs (Any)

Return type:

Any

class sdplab.regularization.BoundDualFunctional(base, eps_val, *, normalized=False)[source]#

Bases: Functional

A RegularizedSDPDualFunctional with ε fixed.

Satisfies the single-argument Functional contract expected by the spacecore.optimize adapters, reporting the same maximization objective as its base (use -bound for a minimization view). eps_val is a pytree leaf, so continuation schedules can rebuild bound functionals per ε without retriggering jax.jit compilation.

Parameters:
value(y, *args, **kwargs)[source]#

Evaluate this functional at an element of self.domain.

Subclasses may accept extra positional/keyword arguments — auxiliary parameters such as data, temperature, or a penalty weight — that are not part of the domain. Overrides that take only x remain valid.

Parameters:
  • y (Any)

  • args (Any)

  • kwargs (Any)

Return type:

Any

grad(y, *args, **kwargs)[source]#

Gradient at an element of self.domain.

Override in subclasses that support differentiation; the base raises NotImplementedError. Any auxiliary *args/**kwargs mirror those accepted by value().

Parameters:
  • y (Any)

  • args (Any)

  • kwargs (Any)

Return type:

Any

value_and_grad(y, *args, **kwargs)[source]#

Return (value, gradient) at x.

The base default evaluates value() and grad() separately. Subclasses may override with a single-pass evaluator (e.g. jax.value_and_grad); an override must return the same pair as the default, with the gradient in the same geometry as grad().

Parameters:
  • y (Any)

  • args (Any)

  • kwargs (Any)

Return type:

Tuple[Any, Any]

primal_from_dual(y, normalized=True)[source]#

Recover the primal element from a dual iterate at the bound ε.

Parameters:
  • y (Any)

  • normalized (bool)

Return type:

Any

assert_domain(x)#

Raise if x is 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.

compose(A)#

Return the pull-back self o A.

Parameters:

A (LinOp) – Linear operator whose codomain matches this functional’s domain.

Returns:

Functional on A.domain evaluating self.value(A.apply(x)).

Return type:

Functional

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 scalar-valued map.

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.

vgrad(xs)#

Gradient over a leading batch axis.

Override in subclasses that support differentiation; the base raises NotImplementedError.

Parameters:

xs (Any)

Return type:

Any

vvalue(xs)#

Evaluate over a leading batch axis. Input must have shape (N,) + domain.shape; use moveaxis for other layouts.

Parameters:

xs (Any)

Return type:

Any

class sdplab.regularization.EntropyReg(space, ctx=None)[source]#

Bases: Regularizer

Entropy regularizer, \(\varphi(t) = t(\log t - 1)\).

Its conjugate is the exponential \(\psi(s) = e^{s}\). The free smoothed dual term (legendre(..., normalized=False)) is the separable \(\varepsilon \sum_i e^{s_i/\varepsilon}\), which is unbounded away from dual feasibility and overflows at small \(\varepsilon\). Set normalized=True (on the regularizer methods, or on BoundDualFunctional) to select the fixed-trace form: the globally bounded log-partition \(\varepsilon \log \operatorname{Tr}\exp(X/\varepsilon)\) with the unit-trace Gibbs-state gradient. Because \(\log\psi'(x) = x\) is affine here, that fixed-trace form is the exact log-partition dual — the target for the entropy dual at small \(\varepsilon\).

Parameters:
  • space (EuclideanJordanAlgebraSpace)

  • ctx (Context | str | None)

phi(x)[source]#

Return \(x(\log x - 1)\) on \(x\ge0\), else \(+\infty\).

Round-off-negative eigenvalues (down to -NEG_EIG_TOL) evaluate at the limit \(\varphi(0)=0\) rather than out of domain.

Parameters:

x (DenseArray)

Return type:

DenseArray

phi_star(x)[source]#

Return \(\psi(x) = \exp(x)\) elementwise.

Parameters:

x (DenseArray)

Return type:

DenseArray

log_phi_star_prime(x)[source]#

Return \(\log(\psi'(x))\) elementwise.

For entropy regularization, \(\psi'(x) = \exp(x)\), hence \(\log(\psi'(x)) = x\).

Parameters:

x (DenseArray)

Return type:

DenseArray

phi_star_prime(x)[source]#

Return \(\psi'(x) = \exp(x)\) elementwise.

Parameters:

x (DenseArray)

Return type:

DenseArray

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.

legendre(X, val, normalized=False)#

Evaluate the smoothed dual term of the regularizer.

normalized=False is the free separable conjugate \(\varepsilon \operatorname{Tr}[\psi(X/\varepsilon)]\), whose gradient is \(\psi'(X/\varepsilon)\) with whatever trace that implies. normalized=True is the fixed-trace conjugate, the supremum taken over unit-trace primals only, whose gradient is the unit-trace recovery. The two are different functions, not two scalings of one: see _normalized_legendre().

Parameters:
  • X (Any)

  • val (float)

  • normalized (bool)

Return type:

DenseArray

legendre_and_grad(X, val, normalized=False)#

Return (legendre(X, val, normalized), gradient).

A genuine value/gradient pair in both modes: the free conjugate with \(\psi'(X/\varepsilon)\), or the fixed-trace conjugate with the unit-trace recovery. Optimizers that line-search on the value therefore descend the function they are evaluating either way.

Parameters:
  • X (Any)

  • val (float)

  • normalized (bool)

Return type:

Tuple[DenseArray, Any]

property ops: BackendOps#

Return backend operations associated with this object’s context.

phi_star_prime_matrix(X, val, normalized=True)#

Return the primal matrix \((\varphi^*)'(X / \varepsilon)\).

Parameters:
  • X (ArrayLike)

  • val (float)

  • normalized (bool)

Return type:

ArrayLike

with_space(space)#
Parameters:

space (EuclideanJordanAlgebraSpace)

Return type:

Regularizer

class sdplab.regularization.QuadraticReg(space, ctx=None)[source]#

Bases: Regularizer

Quadratic spectral regularizer on nonnegative spectra.

The scalar convex function is

\[\varphi(t) = \frac{t^2}{2} + \iota_{[0,\infty)}(t).\]

The indicator term is zero for \(t \ge 0\) and \(+\infty\) for \(t < 0\). Since the primal constraint is \(X \succeq 0\), this defines the separable spectral penalty

\[R_\varepsilon(X) = \varepsilon \operatorname{Tr}[\varphi(X)] = \varepsilon \sum_i \frac{\lambda_i(X)^2}{2}.\]

The Legendre transform of \(\varphi\) restricted to nonnegative primal eigenvalues is

\[\psi(s) = \frac{\max\{s, 0\}^2}{2}.\]

If \(s_i\) are the eigenvalues of \(\mathcal{A}^\dagger y - C\), then primal_from_dual uses

\[\lambda_i(X) = \psi'(s_i / \varepsilon) = \max\{s_i / \varepsilon, 0\}.\]

In plain language: the quadratic regularizer clips negative scaled slack eigenvalues to zero and keeps positive scaled slack eigenvalues linearly.

Parameters:
  • space (EuclideanJordanAlgebraSpace)

  • ctx (Context | str | None)

phi(x)[source]#

Return \(x^2 / 2 + \iota_{[0,\infty)}(x)\) elementwise.

Round-off-negative eigenvalues (down to -NEG_EIG_TOL) evaluate at the limit \(\varphi(0)=0\) rather than out of domain.

Parameters:

x (DenseArray)

Return type:

DenseArray

phi_star(x)[source]#

Return \(\psi(x) = \max\{x, 0\}^2 / 2\) elementwise.

Parameters:

x (DenseArray)

Return type:

DenseArray

phi_star_prime(x)[source]#

Return \(\psi'(x) = \max\{x, 0\}\) elementwise.

Parameters:

x (DenseArray)

Return type:

DenseArray

log_phi_star_prime(x)[source]#

Return \(\log(\psi'(x))\) elementwise.

For the quadratic regularizer this is \(\log(\max\{x, 0\})\), with \(-\infty\) on nonpositive entries.

Parameters:

x (DenseArray)

Return type:

DenseArray

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.

legendre(X, val, normalized=False)#

Evaluate the smoothed dual term of the regularizer.

normalized=False is the free separable conjugate \(\varepsilon \operatorname{Tr}[\psi(X/\varepsilon)]\), whose gradient is \(\psi'(X/\varepsilon)\) with whatever trace that implies. normalized=True is the fixed-trace conjugate, the supremum taken over unit-trace primals only, whose gradient is the unit-trace recovery. The two are different functions, not two scalings of one: see _normalized_legendre().

Parameters:
  • X (Any)

  • val (float)

  • normalized (bool)

Return type:

DenseArray

legendre_and_grad(X, val, normalized=False)#

Return (legendre(X, val, normalized), gradient).

A genuine value/gradient pair in both modes: the free conjugate with \(\psi'(X/\varepsilon)\), or the fixed-trace conjugate with the unit-trace recovery. Optimizers that line-search on the value therefore descend the function they are evaluating either way.

Parameters:
  • X (Any)

  • val (float)

  • normalized (bool)

Return type:

Tuple[DenseArray, Any]

property ops: BackendOps#

Return backend operations associated with this object’s context.

phi_star_prime_matrix(X, val, normalized=True)#

Return the primal matrix \((\varphi^*)'(X / \varepsilon)\).

Parameters:
  • X (ArrayLike)

  • val (float)

  • normalized (bool)

Return type:

ArrayLike

with_space(space)#
Parameters:

space (EuclideanJordanAlgebraSpace)

Return type:

Regularizer