Functionals API#

Functionals are scalar-valued maps on a domain space \(f : X \to R\). Gradients are represented as elements of X using the domain geometry: for a differentiable functional, grad(x) satisfies \(\langle \nabla f(x), v \rangle_X = D f(x)[v]\) when implemented.

Base and composition#

spacecore.functional.Functional

Scalar-valued map on a space.

spacecore.functional.ComposedFunctional

Generic pull-back of a functional through a linear operator.

spacecore.functional.make_functional_composed

Return the pull-back F o A with local specializations.

  • Functional is the base scalar-valued map contract.

  • ComposedFunctional represents pullback f o A for a linear operator A.

  • make_functional_composed constructs the same pullback with simplifications.

Linear functionals#

spacecore.functional.LinearFunctional

Represent a linear scalar-valued map.

spacecore.functional.InnerProductFunctional

Linear functional represented by a domain element.

spacecore.functional.MatrixFreeLinearFunctional

Linear functional defined by user-supplied evaluation callables.

  • LinearFunctional is the base class for linear maps to scalars.

  • InnerProductFunctional stores a Riesz representer c and evaluates <c, x>.

  • MatrixFreeLinearFunctional wraps callable value and gradient logic.

Quadratic functionals#

spacecore.functional.QuadraticForm

Represent a scalar quadratic objective on a space.

spacecore.functional.LinOpQuadraticForm

Represent a quadratic form backed by a linear operator.

  • QuadraticForm models objectives with value, gradient, and Hessian-vector action.

  • LinOpQuadraticForm represents 0.5 <x, Qx> + ell(x) + a.

Battery functionals#

Named constructors over the existing machinery (ADR-019). Their gradients are metric (Riesz) gradients under the domain geometry.

spacecore.functional.least_squares

Build the least-squares objective scale * ||A x - b||^2 as a quadratic form.

spacecore.functional.SquaredL2NormFunctional

Half the squared space norm F(x) = 1/2 ||x||_X^2 = 1/2 <x, x>_X.

spacecore.functional.LpNormFunctional

Coordinate p-norm F(x) = (sum_i |x_i|^p)^{1/p} for p >= 1.

spacecore.functional.L1NormFunctional

Coordinate 1-norm ||x||_1 -- a thin wrapper for LpNormFunctional(X, 1).

spacecore.functional.SpectralLpNormFunctional

Schatten p-norm F(X) = (sum_i |lambda_i(X)|^p)^{1/p} for p >= 1.

spacecore.functional.NuclearNormFunctional

Nuclear (trace) norm, a thin wrapper for SpectralLpNormFunctional(X, 1).

spacecore.functional.NegativeEntropyFunctional

Negative (Shannon) entropy F(x) = sum_i x_i log x_i.

spacecore.functional.KLDivergenceFunctional

Kullback--Leibler divergence to a fixed positive target.

spacecore.functional.HuberFunctional

Separable Huber loss F(x) = sum_i h_delta(x_i).

  • least_squares builds the scale ||A x - b||^2 objective as a LinOpQuadraticForm.

  • SquaredL2NormFunctional is 1/2 ||x||_X^2 (gradient x, clean shrinkage prox).

  • LpNormFunctional / L1NormFunctional are coordinate p-norms.

  • SpectralLpNormFunctional / NuclearNormFunctional are the Schatten p-norm and nuclear norm of a Jordan spectrum (e.g. Hermitian eigenvalues).

  • NegativeEntropyFunctional and KLDivergenceFunctional are the entropy objectives.

  • HuberFunctional is the separable Huber loss.

These constructors live in the spacecore.functional.tools subpackage and are re-exported from spacecore.functional and the top-level spacecore namespace.

Proximal and projection#

A closed-form, metric-aware proximal primitive and its named wrappers (ADR-019). Valid on Euclidean and diagonal metrics; a non-diagonal metric raises.

spacecore.functional.generalized_shrinkage

Solve the separable forward--backward subproblem in the space metric.

spacecore.functional.prox_l1

Proximal operator of t * ||.||_1 in the space metric (soft-threshold).

spacecore.functional.prox_l2sq

Proximal operator of t * (1/2) ||.||_X^2 (linear shrinkage v / (1 + t)).

spacecore.functional.project_nonneg

Metric projection onto the nonnegative orthant: coordinatewise max(v, 0).

  • generalized_shrinkage solves <c, x>_X + eps ||x - x0||^2_X + lam ||x||_1 (optionally x >= 0).

  • prox_l1 is the metric soft-threshold; prox_l2sq is the shrinkage v / (1 + t).

  • project_nonneg is the metric projection onto the nonnegative orthant.

Autodoc#

class spacecore.functional.Functional(dom, ctx=None)[source]#

Bases: ContextBound, Generic[Domain]

Scalar-valued map on a space.

Functional represents a map F : X -> K without assuming any storage model. It mirrors the minimal LinOp contract: the domain is converted into the resolved context, value checks follow ctx.check_level, and batched evaluation is implemented by a backend vmap fallback.

Parameters:
  • dom (Space) – Domain space X.

  • ctx (Context, str, or None, optional) – Backend context specification. Default is resolved from dom.

dom#

Domain space converted to ctx.

Type:

Space

ctx#

Resolved backend context.

Type:

Context

property domain: Domain#

Domain space of this scalar-valued map.

abstractmethod value(x)[source]#

Evaluate this functional at an element of self.domain.

Parameters:

x (Any)

Return type:

Any

grad(x)[source]#

Gradient at an element of self.domain.

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

Parameters:

x (Any)

Return type:

Any

vgrad(xs)[source]#

Gradient over a leading batch axis.

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

Parameters:

xs (Any)

Return type:

Any

compose(A)[source]#

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

vvalue(xs)[source]#

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

Parameters:

xs (Any)

Return type:

Any

assert_domain(x)[source]#

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.

convert(new_ctx=None)#

Return this object represented in new_ctx.

Parameters:

new_ctx (Context | BackendFamily | str | None)

Return type:

Self

class spacecore.functional.LinearFunctional(dom, ctx=None)[source]#

Bases: Functional[Domain]

Represent a linear scalar-valued map.

Parameters:
  • dom (Space) – Domain space.

  • ctx (Context, str, or None, optional) – Backend context specification. Default is resolved from dom.

grad(x)[source]#

Return the constant Riesz gradient of this linear functional.

For ell(x) = <c, x>_X, the gradient is the space element c. Matrix-free functionals without a stored representer inherit the NotImplementedError raised by representer.

Parameters:

x (Any)

Return type:

Any

vgrad(xs)[source]#

Return the constant Riesz gradient over a leading batch axis.

Parameters:

xs (Any)

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 domain: Domain#

Domain space of this scalar-valued map.

abstractmethod value(x)#

Evaluate this functional at an element of self.domain.

Parameters:

x (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 spacecore.functional.InnerProductFunctional(c, dom, ctx=None)[source]#

Bases: LinearFunctional[Domain]

Linear functional represented by a domain element.

InnerProductFunctional(c, X) evaluates \(\ell_c(x) = \langle c, x\rangle_X\).

Parameters:
  • c (array-like) – Riesz representer in dom.

  • dom (Space) – Domain space.

  • ctx (Context, str, or None, optional) – Backend context specification. Default is resolved from dom.

representer#

Stored domain element c.

Type:

array-like

value(x)[source]#

Return domain.inner(representer, x).

Parameters:

x (Any)

Return type:

Any

vvalue(xs)[source]#

Evaluate domain.inner(representer, xs[i]) without a Python loop.

Parameters:

xs (Any)

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 domain: Domain#

Domain space of this scalar-valued map.

grad(x)#

Return the constant Riesz gradient of this linear functional.

For ell(x) = <c, x>_X, the gradient is the space element c. Matrix-free functionals without a stored representer inherit the NotImplementedError raised by representer.

Parameters:

x (Any)

Return type:

Any

vgrad(xs)#

Return the constant Riesz gradient over a leading batch axis.

Parameters:

xs (Any)

Return type:

Any

class spacecore.functional.MatrixFreeLinearFunctional(value, dom, ctx=None, vvalue=None)[source]#

Bases: LinearFunctional[Domain]

Linear functional defined by user-supplied evaluation callables.

MatrixFreeLinearFunctional(value, X) represents a linear scalar-valued map on X without storing or materializing a Riesz representer.

Parameters:
  • value (callable) – Callable with signature value(x: Any) -> Any accepting an element of dom and returning a scalar-like backend value.

  • dom (Space) – Domain space of the functional.

  • ctx (Context, str, or None, optional) – Optional context specification. An explicit context wins over inferred and default contexts.

  • vvalue (callable or None, optional) – Optional callable with signature vvalue(xs: Any) -> Any for batched evaluation. If omitted, backend vmap fallback is used.

Returns:

Functional using the supplied callable for scalar evaluation and, optionally, batched scalar evaluation.

Return type:

MatrixFreeLinearFunctional

__init__(value, dom, ctx=None, vvalue=None)[source]#

Initialize a matrix-free linear functional.

Parameters:
  • value (Callable[[Any], Any]) – Callable value(x) accepting an element of dom and returning a scalar-like value.

  • dom (Domain) – Domain space of the functional.

  • ctx (Context | str | None) – Optional context specification for the functional and converted domain.

  • vvalue (Callable[[Any], Any] | None) – Optional callable vvalue(xs) accepting a batch of domain elements and returning a batch of scalar-like values.

Returns:

The initializer stores the callables and converted domain on self.

Return type:

None

value(x)[source]#

Evaluate the scalar functional.

Parameters:

x (Any) – Element of self.domain passed to value_fn.

Returns:

Scalar-like backend value returned by value_fn.

Return type:

Any

vvalue(xs)[source]#

Evaluate the scalar functional over a batch of domain elements.

Parameters:

xs (Any) – Batched element of self.domain.

Returns:

Backend array of scalar-like values with shape matching the leading batch shape.

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 domain: Domain#

Domain space of this scalar-valued map.

grad(x)#

Return the constant Riesz gradient of this linear functional.

For ell(x) = <c, x>_X, the gradient is the space element c. Matrix-free functionals without a stored representer inherit the NotImplementedError raised by representer.

Parameters:

x (Any)

Return type:

Any

vgrad(xs)#

Return the constant Riesz gradient over a leading batch axis.

Parameters:

xs (Any)

Return type:

Any

class spacecore.functional.QuadraticForm(dom, ctx=None)[source]#

Bases: Functional[Domain]

Represent a scalar quadratic objective on a space.

Parameters:
  • dom (Space) – Domain space.

  • ctx (Context, str, or None, optional) – Backend context specification. Default is resolved from dom.

hess_apply(x)[source]#

Apply the Hessian action at x when available.

Parameters:

x (Any)

Return type:

Any

grad(x)[source]#

Return the gradient with respect to domain.inner when available.

Parameters:

x (Any)

Return type:

Any

vgrad(xs)[source]#

Evaluate grad independently over leading batch axes.

Parameters:

xs (Any)

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 domain: Domain#

Domain space of this scalar-valued map.

abstractmethod value(x)#

Evaluate this functional at an element of self.domain.

Parameters:

x (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 spacecore.functional.LinOpQuadraticForm(Q, linear=None, a=0, ctx=None)[source]#

Bases: QuadraticForm[Domain]

Represent a quadratic form backed by a linear operator.

Assumption:

Q is Hermitian/self-adjoint. Under this assumption, grad f(x) = Q x.

Non-Hermitian operators are not supported here. If users need the Hermitian part, they must construct 0.5 * (Q + Q.H) explicitly.

The full objective is q(x) = 1/2 * <x, Qx> + linear(x) + a with Q : X -> X. Structurally available dense and diagonal operators are checked at construction. Matrix-free operators are not validated; correctness is the caller’s responsibility.

Parameters:
  • Q (LinOp) – Hermitian operator from a space to itself.

  • linear (LinearFunctional or None, optional) – Optional linear term on Q.domain.

  • a (scalar-like, optional) – Constant scalar offset. Default is 0.

  • ctx (Context, str, or None, optional) – Backend context specification. Default is resolved from Q and linear.

Q#

Stored Hermitian operator.

Type:

LinOp

linear#

Stored linear term.

Type:

LinearFunctional or None

a#

Stored scalar offset.

Type:

scalar-like

value(x)[source]#

Return 1/2 * <x, Qx> + linear(x) + a.

Parameters:

x (Any)

Return type:

Any

grad(x)[source]#

Return the gradient with respect to domain.inner.

This is the Riesz gradient: for Euclidean geometry it is the ordinary coordinate gradient, while for non-Euclidean geometry it is corrected by the domain inner product.

LinOpQuadraticForm assumes Q is Hermitian/self-adjoint, so the quadratic contribution is exactly Q.apply(x).

Parameters:

x (Any)

Return type:

Any

hess_apply(x)[source]#

Return the Hessian action Q x under the Hermitian assumption.

Parameters:

x (Any)

Return type:

Any

vvalue(xs)[source]#

Evaluate the quadratic objective over a leading batch axis.

Parameters:

xs (Any)

Return type:

Any

vgrad(xs)[source]#

Evaluate the Riesz gradient over a leading batch axis.

Parameters:

xs (Any)

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 domain: Domain#

Domain space of this scalar-valued map.

class spacecore.functional.ComposedFunctional(F, A)[source]#

Bases: Functional

Generic pull-back of a functional through a linear operator.

ComposedFunctional(F, A) represents x -> F(A x) on A.domain.

Parameters:
  • F (Functional) – Functional defined on A.codomain.

  • A (LinOp) – Linear operator whose codomain is F.domain.

value(x)[source]#

Evaluate F(A x).

Parameters:

x (Any) – Element of A.domain.

Returns:

Scalar-like value returned by the composed functional.

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 domain: Domain#

Domain space of this scalar-valued map.

grad(x)#

Gradient at an element of self.domain.

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

Parameters:

x (Any)

Return type:

Any

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

spacecore.functional.make_functional_composed(F, A)[source]#

Return the pull-back F o A with local specializations.

Parameters:
  • F (Functional) – Functional defined on A.codomain.

  • A (LinOp) – Linear operator whose codomain is F.domain.

Returns:

Specialized pull-back when available, otherwise ComposedFunctional.

Return type:

Functional

spacecore.functional.least_squares(A, b, *, weights=None, scale=0.5)[source]#

Build the least-squares objective scale * ||A x - b||^2 as a quadratic form.

The objective is expanded into the canonical LinOpQuadraticForm q(x) = 1/2 <x, Q x>_X + <c, x>_X + a with

  • Q = 2 scale * (A.H @ A) (the normal operator, Hermitian by construction),

  • c = -2 scale * A.H(b) (a Riesz/metric gradient, the linear term), and

  • a = scale * <b, b>_Y (the constant residual energy),

so that q(x) equals scale * ||A x - b||_Y^2 exactly on real spaces. With scale = 0.5 (the default) this is the textbook 1/2 ||A x - b||^2 and Q is exactly A.H @ A.

Adjoints and inner products are taken in the operator’s declared geometry (ADR-009), so the result is metric-correct on non-Euclidean domains and codomains without any extra work by the caller.

Parameters:
  • A (LinOp) – Forward operator A : X -> Y.

  • b (array-like) – Observation in the codomain Y = A.codomain.

  • weights (array-like or None, optional) – Diagonal residual weights w with the codomain shape and strictly positive, finite entries. When given, the objective is the weighted least squares scale * <A x - b, W (A x - b)>_Y with W = diag(w). Default None is the unweighted objective.

  • scale (float, optional) – Positive scalar multiplying the squared residual. Default 0.5.

Returns:

Quadratic form whose value is the (weighted) least-squares objective and whose grad is the metric gradient 2 scale * A.H(W (A x - b)).

Return type:

LinOpQuadraticForm

Examples

>>> import numpy as np
>>> import spacecore as sc
>>> ctx = sc.Context(sc.NumpyOps(), dtype=np.float64)
>>> X = sc.DenseCoordinateSpace((2,), ctx)
>>> Y = sc.DenseCoordinateSpace((2,), ctx)
>>> A = sc.DenseLinOp(ctx.asarray([[1.0, 0.0], [0.0, 2.0]]), X, Y, ctx)
>>> f = sc.least_squares(A, ctx.asarray([1.0, 4.0]))
>>> float(f.value(ctx.asarray([1.0, 2.0])))
0.0
class spacecore.functional.SquaredL2NormFunctional(dom, ctx=None)[source]#

Bases: _CoordinateFunctional[Domain]

Half the squared space norm F(x) = 1/2 ||x||_X^2 = 1/2 <x, x>_X.

This is the smooth quadratic energy whose Riesz gradient is x and whose proximal operator is the clean shrinkage v / (1 + t) (see prox_l2sq()). It is intentionally distinct from LpNormFunctional(X, 2), which is the un-squared coordinate 2-norm (sum_i |x_i|^2)^{1/2}.

Parameters:
  • dom (Space) – Domain space X.

  • ctx (Context, str, or None, optional) – Backend context specification. Default is resolved from dom.

Examples

>>> import numpy as np
>>> import spacecore as sc
>>> ctx = sc.Context(sc.NumpyOps(), dtype=np.float64)
>>> X = sc.DenseCoordinateSpace((2,), ctx)
>>> f = sc.SquaredL2NormFunctional(X)
>>> float(f.value(ctx.asarray([3.0, 4.0])))
12.5
>>> np.asarray(f.grad(ctx.asarray([3.0, 4.0])))
array([3., 4.])
value(x)[source]#

Return 1/2 <x, x>_X as a real scalar.

Parameters:

x (Any)

Return type:

Any

grad(x)[source]#

Return the Riesz gradient x.

Parameters:

x (Any)

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 domain: Domain#

Domain space of this scalar-valued map.

vgrad(xs)#

Evaluate grad() independently over a leading batch axis.

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 spacecore.functional.LpNormFunctional(dom, p, ctx=None)[source]#

Bases: _CoordinateFunctional[Domain]

Coordinate p-norm F(x) = (sum_i |x_i|^p)^{1/p} for p >= 1.

Parameters:
  • dom (Space) – Domain space X.

  • p (float) – Norm order; must be finite and >= 1.

  • ctx (Context, str, or None, optional) – Backend context specification. Default is resolved from dom.

Notes

The gradient at x != 0 is d/dx_i ||x||_p = sign(x_i) |x_i|^{p-1} / ||x||_p^{p-1} (Riesz-corrected). At the origin the function is not differentiable; this returns the zero subgradient there. For p = 1 the gradient is sign(x).

Examples

>>> import numpy as np
>>> import spacecore as sc
>>> ctx = sc.Context(sc.NumpyOps(), dtype=np.float64)
>>> X = sc.DenseCoordinateSpace((3,), ctx)
>>> f = sc.LpNormFunctional(X, 1)
>>> float(f.value(ctx.asarray([1.0, -2.0, 3.0])))
6.0
value(x)[source]#

Return (sum_i |x_i|^p)^{1/p}.

Parameters:

x (Any)

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 domain: Domain#

Domain space of this scalar-valued map.

grad(x)#

Return the Riesz gradient under the domain geometry.

Parameters:

x (Any)

Return type:

Any

vgrad(xs)#

Evaluate grad() independently over a leading batch axis.

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

spacecore.functional.L1NormFunctional(dom, ctx=None)[source]#

Coordinate 1-norm ||x||_1 – a thin wrapper for LpNormFunctional(X, 1).

Parameters:
  • dom (Space) – Domain space X.

  • ctx (Context, str, or None, optional) – Backend context specification. Default is resolved from dom.

Returns:

The p = 1 instance of LpNormFunctional.

Return type:

LpNormFunctional

class spacecore.functional.SpectralLpNormFunctional(dom, p, ctx=None)[source]#

Bases: _CoordinateFunctional[Domain]

Schatten p-norm F(X) = (sum_i |lambda_i(X)|^p)^{1/p} for p >= 1.

lambda(X) is the Jordan-algebraic spectrum of X (eigenvalues for a Hermitian matrix). The gradient is the spectral function gradient: with X = U diag(lambda) U^*, it is U diag(g) U^* where g is the coordinate p-norm gradient of lambda, reconstructed through the space’s from_spectrum. p = 1 is the nuclear / trace norm (see NuclearNormFunctional()); p = 2 is the Frobenius norm.

Parameters:
  • dom (JordanAlgebraSpace) – Domain space with a spectral decomposition (e.g. HermitianSpace). A space without a Jordan spectrum raises TypeError.

  • p (float) – Norm order; must be finite and >= 1.

  • ctx (Context, str, or None, optional) – Backend context specification. Default is resolved from dom.

Examples

>>> import numpy as np
>>> import spacecore as sc
>>> ctx = sc.Context(sc.NumpyOps(), dtype=np.float64)
>>> X = sc.HermitianSpace(2, ctx=ctx)
>>> A = ctx.asarray([[2.0, 0.0], [0.0, -3.0]])
>>> f = sc.SpectralLpNormFunctional(X, 1)  # nuclear norm |2| + |-3|
>>> float(f.value(A))
5.0
value(x)[source]#

Return the Schatten-p norm (sum_i |lambda_i|^p)^{1/p}.

Parameters:

x (Any)

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 domain: Domain#

Domain space of this scalar-valued map.

grad(x)#

Return the Riesz gradient under the domain geometry.

Parameters:

x (Any)

Return type:

Any

vgrad(xs)#

Evaluate grad() independently over a leading batch axis.

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

spacecore.functional.NuclearNormFunctional(dom, ctx=None)[source]#

Nuclear (trace) norm, a thin wrapper for SpectralLpNormFunctional(X, 1).

Computes sum_i |lambda_i(X)|, the Schatten-1 norm of the Jordan spectrum.

Parameters:
  • dom (JordanAlgebraSpace) – Domain space with a spectral decomposition.

  • ctx (Context, str, or None, optional) – Backend context specification. Default is resolved from dom.

Returns:

The p = 1 instance of SpectralLpNormFunctional.

Return type:

SpectralLpNormFunctional

class spacecore.functional.NegativeEntropyFunctional(dom, ctx=None)[source]#

Bases: _CoordinateFunctional[Domain]

Negative (Shannon) entropy F(x) = sum_i x_i log x_i.

The natural domain is the positive orthant x_i > 0; the value uses the convention 0 log 0 = 0 so the origin and zero coordinates evaluate cleanly, but the gradient log x_i + 1 is only defined for x_i > 0.

Parameters:
  • dom (Space) – Domain space X.

  • ctx (Context, str, or None, optional) – Backend context specification. Default is resolved from dom.

Examples

>>> import numpy as np
>>> import spacecore as sc
>>> ctx = sc.Context(sc.NumpyOps(), dtype=np.float64)
>>> X = sc.DenseCoordinateSpace((2,), ctx)
>>> f = sc.NegativeEntropyFunctional(X)
>>> float(f.value(ctx.asarray([1.0, 1.0])))
0.0
>>> np.asarray(f.grad(ctx.asarray([1.0, 1.0])))  # log(x) + 1
array([1., 1.])
value(x)[source]#

Return sum_i x_i log x_i with 0 log 0 = 0.

Parameters:

x (Any)

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 domain: Domain#

Domain space of this scalar-valued map.

grad(x)#

Return the Riesz gradient under the domain geometry.

Parameters:

x (Any)

Return type:

Any

vgrad(xs)#

Evaluate grad() independently over a leading batch axis.

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 spacecore.functional.KLDivergenceFunctional(target, dom, ctx=None)[source]#

Bases: _CoordinateFunctional[Domain]

Kullback–Leibler divergence to a fixed positive target.

F(x) = sum_i x_i log(x_i / t_i) against a strictly positive target t. The natural domain is x_i >= 0 (with 0 log 0 = 0) and t_i > 0. With target equal to the all-ones element this reduces exactly to NegativeEntropyFunctional, and the gradient log(x_i / t_i) + 1 reduces accordingly.

Parameters:
  • target (array-like) – Reference element t in dom with strictly positive coordinates.

  • dom (Space) – Domain space X. ADR-019 writes KLDivergenceFunctional(target); the explicit space follows the (data, dom, ctx) constructor shape used by InnerProductFunctional, because a bare element does not carry its space.

  • ctx (Context, str, or None, optional) – Backend context specification. Default is resolved from dom.

Examples

>>> import numpy as np
>>> import spacecore as sc
>>> ctx = sc.Context(sc.NumpyOps(), dtype=np.float64)
>>> X = sc.DenseCoordinateSpace((2,), ctx)
>>> f = sc.KLDivergenceFunctional(ctx.asarray([1.0, 1.0]), X)
>>> float(f.value(ctx.asarray([1.0, 1.0])))  # zero divergence at x == target
0.0
>>> np.asarray(f.grad(ctx.asarray([1.0, 1.0])))  # log(x / t) + 1
array([1., 1.])
property target: Any#

Stored reference element t.

value(x)[source]#

Return sum_i x_i log(x_i / t_i) with 0 log 0 = 0.

Parameters:

x (Any)

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 domain: Domain#

Domain space of this scalar-valued map.

grad(x)#

Return the Riesz gradient under the domain geometry.

Parameters:

x (Any)

Return type:

Any

vgrad(xs)#

Evaluate grad() independently over a leading batch axis.

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 spacecore.functional.HuberFunctional(dom, delta, ctx=None)[source]#

Bases: _CoordinateFunctional[Domain]

Separable Huber loss F(x) = sum_i h_delta(x_i).

The per-coordinate loss is quadratic near the origin and linear in the tails: h_delta(r) = 1/2 r^2 for |r| <= delta and delta (|r| - delta/2) otherwise. It is everywhere differentiable, with gradient r in the quadratic region and delta sign(r) in the tails.

Parameters:
  • dom (Space) – Domain space X.

  • delta (float) – Transition threshold; must be finite and > 0.

  • ctx (Context, str, or None, optional) – Backend context specification. Default is resolved from dom.

Examples

>>> import numpy as np
>>> import spacecore as sc
>>> ctx = sc.Context(sc.NumpyOps(), dtype=np.float64)
>>> X = sc.DenseCoordinateSpace((2,), ctx)
>>> f = sc.HuberFunctional(X, 1.0)
>>> float(f.value(ctx.asarray([0.5, 3.0])))  # 0.125 + (3 - 0.5)
2.625
value(x)[source]#

Return sum_i h_delta(x_i).

Parameters:

x (Any)

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 domain: Domain#

Domain space of this scalar-valued map.

grad(x)#

Return the Riesz gradient under the domain geometry.

Parameters:

x (Any)

Return type:

Any

vgrad(xs)#

Evaluate grad() independently over a leading batch axis.

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

spacecore.functional.generalized_shrinkage(X, *, c, x0, eps, lam=0.0, nonneg=False)[source]#

Solve the separable forward–backward subproblem in the space metric.

Returns the coordinatewise minimizer of

<c, x>_X + eps * ||x - x0||^2_X + lam * ||x||_1   (optionally x >= 0)

The smooth part has unconstrained minimizer v = x0 - c / (2 eps) (the metric weight cancels, because c is a metric gradient). The l1 term then applies a soft-threshold with the metric-aware width tau_i = lam / (2 eps w_i) for a diagonal weight w (w_i = 1 on a Euclidean space); with nonneg=True the nonnegative-orthant constraint turns the step into max(v - tau, 0).

Parameters:
  • X (Space) – Ambient inner-product space. Must be Euclidean or have a diagonal (weighted) metric; a non-diagonal metric raises.

  • c (array-like) – Metric gradient (linear-term coefficient) in X.

  • x0 (array-like) – Proximal center in X.

  • eps (float) – Strictly positive, finite quadratic weight.

  • lam (float, optional) – Nonnegative, finite l1 weight. Default 0.0 (no thresholding).

  • nonneg (bool, optional) – Constrain the solution to x >= 0 (real spaces only). Default False.

Returns:

The minimizer, an element of X.

Return type:

Element

spacecore.functional.prox_l1(v, t, X)[source]#

Proximal operator of t * ||.||_1 in the space metric (soft-threshold).

Returns argmin_x  1/2 ||x - v||^2_X + t ||x||_1, i.e. the metric-aware soft-threshold with per-coordinate width t / w_i on a diagonal metric.

Parameters:
  • v (array-like) – Point in X to be thresholded.

  • t (float) – Nonnegative threshold / step size.

  • X (Space) – Ambient inner-product space (Euclidean or diagonal metric).

Returns:

The soft-thresholded element.

Return type:

Element

spacecore.functional.prox_l2sq(v, t, X)[source]#

Proximal operator of t * (1/2) ||.||_X^2 (linear shrinkage v / (1 + t)).

Returns argmin_x  1/2 ||x - v||^2_X + t (1/2) ||x||^2_X = v / (1 + t).

Completing the square casts this into the primitive’s form: it is the minimizer of <-v, x>_X + ((1 + t)/2) ||x||^2_X, i.e. generalized_shrinkage with c = -v, x0 = 0 and eps = (1 + t)/2.

Parameters:
  • v (array-like) – Point in X to be shrunk.

  • t (float) – Nonnegative step size.

  • X (Space) – Ambient inner-product space (Euclidean or diagonal metric).

Returns:

The shrunk element v / (1 + t).

Return type:

Element

spacecore.functional.project_nonneg(v, X)[source]#

Metric projection onto the nonnegative orthant: coordinatewise max(v, 0).

This is the proximal operator of the indicator of {x : x >= 0}. On a diagonal metric the projection is still coordinatewise (the orthant is separable), and a non-diagonal metric raises via the shared primitive.

Parameters:
  • v (array-like) – Point in X to project.

  • X (Space) – Ambient inner-product space (Euclidean or diagonal metric).

Returns:

The projected element max(v, 0).

Return type:

Element