Functionals API#

Functionals are real 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 \(\operatorname{Re}\langle \nabla f(x), v \rangle_X = D f(x)[v]\) when implemented. Beck, First-Order Methods in Optimization, Remark 3.32; on complex domains use the real inner product as in Geometry and Riesz Maps.

Differentials#

f.derivative_at(x) returns a LinearFunctional acting on directions: df(h) evaluates \(Df(x)[h]\). f.value_and_derivative(x) returns the value and differential together, reusing an existing fused value_and_grad implementation when adapting a gradient-based functional.

import numpy as np
import spacecore as sc

ctx = sc.Context(sc.NumpyOps(), dtype=np.float64)
X = sc.DenseCoordinateSpace((2,), ctx,
    geometry=sc.WeightedInnerProduct(ctx.asarray([2., 5.])))
f = sc.SquaredL2NormFunctional(X)
value, df = f.value_and_derivative(ctx.asarray([1., 2.]))
slope = df(ctx.asarray([3., 4.]))  # 46.0
gradient = df.representer         # [1., 2.], in X's metric

Existing grad implementations remain valid. New functionals can implement derivative_at directly. The default grad then requests the derivative’s representer; a callable-only differential raises NotImplementedError instead of reconstructing a dense gradient. Implement both fused methods when a native evaluator needs to share work in both interfaces.

Sums, scalar multiples, and pullbacks of linear functionals remain LinearFunctional objects. Products of objectives use the product rule. A callable differential can be pulled back through A using only forward application: \((Df(x)\circ A)[h]=Df(x)[Ah]\). Retrieving its gradient may additionally require a representer and the metric adjoint.

Functionals are real-valued. The codomain is always RealField; complex domains remain supported. With checks on (cheap and above), a complex output dtype, coefficient or offset raises TypeError, even with a zero imaginary part; this covers batched and fused evaluations and subclass overrides. Extended-real indicator values remain valid.

Functionals pair through the domain’s real inner product real_inner(x, y) \(=\operatorname{Re}\langle x,y\rangle_X\): InnerProductFunctional evaluates real_inner(c, h) and LinOpQuadraticForm evaluates real_inner(x, Qx) / 2. Matrix-free callables return real values themselves.

At a nonsmooth point, a chosen subgradient does not become a Frechet derivative; use these interfaces where the objective is differentiable.

This API composes with existing linear operators. General nonlinear-map linearization and manifold tangent spaces are separate extensions.

Base and composition#

Optional proximal methods#

Functional.prox(x, step) computes a registered closed-form prox in the domain metric. conjugate_prox uses Hilbert-space Moreau decomposition. IndicatorFunctional connects a closed convex set’s projection to this API. See Metric proximal operations for conventions, supported rules, compiled execution, and custom representations.

spacecore.IndicatorFunctional

The extended-real indicator of a closed convex set.

spacecore.Set

A closed subset of an ambient space, with optional membership and projection.

spacecore.NonnegativeOrthant

Nonnegative real dense coordinates in Euclidean or diagonal geometry.

Scalar maps#

spacecore.functional.Functional

A real-valued map F : X -> R; subclasses implement value and optionally grad.

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, specialized where a closed form exists.

Algebra#

Lazy nodes for combining functionals. The operator overloads on Functional (a * F, F + G, F - G, -F, F * G) delegate to the make_* factories, which apply local, structural canonicalization — they read node types, never values.

spacecore.functional.ScaledFunctional

Lazy scalar multiple scalar * functional.

spacecore.functional.SumFunctional

Lazy sum of finitely many functionals on a common domain.

spacecore.functional.ZeroFunctional

The zero functional: value 0, gradient the domain's zero; the sum's identity.

spacecore.functional.ConstantFunctional

The constant functional x -> constant, with zero gradient.

spacecore.functional.ProductFunctional

Lazy pointwise product (F * G)(x) = F(x) G(x) on a shared domain.

spacecore.functional.make_scaled_functional

Return scalar * functional: 1 passes it through, nested scalars fold.

spacecore.functional.make_functional_sum

Return the lazy sum of functionals, flattened, with zero terms dropped.

spacecore.functional.make_shifted_functional

Return functional + offset as a sum with a ConstantFunctional; 0 passes it through.

spacecore.functional.make_constant_functional

Return the constant functional on dom, or ZeroFunctional for 0.

spacecore.functional.make_functional_product

Return left * right; a zero factor gives zero and a constant factor gives scaling.

  • ConstantFunctional is x -> c, the embedding of a scalar into the algebra; make_constant_functional collapses c = 0 to ZeroFunctional.

  • ProductFunctional is the pointwise product F(x) * G(x), with the product-rule Riesz gradient \(G(x)\, \nabla F(x) + F(x)\, \nabla G(x)\). Because functionals are scalar-valued, scaling is the constant-factor case of a product: make_functional_product folds a ConstantFunctional factor back into a ScaledFunctional, and a ZeroFunctional factor to zero.

The product rule follows from D(FG)[h] = G DF[h] + F DG[h] using the real pairing. All values and scaling coefficients are real.

Mapping#

spacecore.Mapping

A map from domain to codomain, with the lazy algebra of the family.

Linear functionals#

spacecore.functional.LinearFunctional

A linear scalar-valued map on dom.

spacecore.functional.InnerProductFunctional

The functional \(x \mapsto \operatorname{Re}\langle c, x\rangle_X\) of a representer c.

spacecore.functional.MatrixFreeLinearFunctional

Linear functional given by an evaluation callable; no Riesz representer is stored.

  • MatrixFreeLinearFunctional wraps a callable evaluator; a stored gradient is optional and is not inferred from the callable.

Quadratic functionals#

spacecore.functional.QuadraticForm

A scalar quadratic objective on dom.

spacecore.functional.LinOpQuadraticForm

Quadratic form 1/2 <x, Q x> + linear(x) + a for a Hermitian Q, so grad = Q x + ....

Norm functionals#

Coordinate norms (the ones the closed-form prox rules cover). Their gradients are metric (Riesz) gradients under the domain geometry.

spacecore.functional.SquaredL2NormFunctional

Half the squared space norm <x, x>_X / 2; its gradient is x.

spacecore.functional.LpNormFunctional

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

spacecore.functional.L1NormFunctional

Coordinate 1-norm: LpNormFunctional(dom, 1).

The norms live in the spacecore.functional.tools subpackage and are re-exported from spacecore.functional and the top-level spacecore namespace. Least squares, entropy, Huber, spectral lifts, the realified view (RealifiedFunctional, realify) and the shrinkage helpers are in spacecore-optimize.

Autodoc#

class spacecore.functional.Functional(*args, **kwargs)[source]#

Bases: Mapping, Generic[Domain]

A real-valued map F : X -> R; subclasses implement value and optionally grad.

grad is the Riesz gradient, an element of X. Batched evaluation falls back to vmap.

Parameters:
  • dom (Space) – Domain X.

  • ctx (Context, str, or None, optional) – Backend context; resolved from dom when omitted.

  • check_level ({"none", "cheap", "standard", "strict"}, optional) – Validation level; the ambient default when omitted.

property codomain: RealField#

The independently bound scalar field of this functional’s values.

property domain: Domain#

Domain space of this scalar-valued map.

value(x, *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:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

Any

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

Riesz gradient at an element of self.domain.

Implement _grad_core, or _derivative_core with an available Riesz representer; otherwise raises NotImplementedError. Any auxiliary *args/**kwargs mirror those accepted by value().

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

Any

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

Return (value, gradient) at x.

Implement _value_and_grad_core for a single-pass evaluator (e.g. jax.value_and_grad); it must return the same pair as the separate cores, with the gradient in the same geometry as grad().

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

tuple[Any, Any]

prox(x, step)[source]#

Minimize f(y) + ||y-x||_X^2 / (2 step) for positive step.

This optional operation uses a closed-form rule registered with register("prox", FunctionalType, GeometryType, rule). The rule takes (functional, geometry, x, step) and returns a native domain element. An unsupported functional/geometry pair raises CapabilityError; sums and linear pullbacks do not acquire a prox automatically.

Prox rules assert a proper, lower-semicontinuous convex real objective (also on complex spaces, using the real inner product). At check level "none", traced steps must be finite and positive; their values are the caller’s responsibility. Concrete invalid Python steps still raise.

Parameters:
  • x (Any)

  • step (Any)

Return type:

Any

conjugate_prox(x, step)[source]#

Return the conjugate prox by Hilbert-space Moreau decomposition.

The conjugate is f*_X(p) = sup_z Re <p,z>_X - f(z): dual variables are Riesz representers in the same space, not raw coordinate covectors. Thus prox_(step f*_X)(x) = x - step prox_(f/step)(x/step). Requires a valid convex prox and a finite, strictly positive step.

Parameters:
  • x (Any)

  • step (Any)

Return type:

Any

differential(x, *args, **kwargs)[source]#

Return the covector \(df(x)\) with \(Df(x)[h] = \langle df(x), h\rangle\).

The covector is a coordinate array paired with domain.pair and involves no metric. The default reads it off the Riesz gradient, domain.riesz(grad(x)); functionals that compute coordinate partials implement _differential_core.

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

Any

derivative_at(x, *args, **kwargs)[source]#

Return the differential at x, acting on domain directions.

The default wraps the Riesz gradient, Re <grad, h>. Implement _derivative_core for a native directional evaluator. At nonsmooth points a supplied subgradient is not a Frechet derivative.

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

LinearFunctional

value_and_derivative(x, *args, **kwargs)[source]#

Return value and differential, preserving fused gradient evaluators.

Derivative-first subclasses may implement _value_and_derivative_core to share work. No representer is reconstructed from a callable differential.

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

tuple[Any, ‘LinearFunctional’]

vgrad(xs)[source]#

Gradient over a leading batch axis; implement _vgrad_core to support it.

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.

The level is stored on the bound object (_check_level), seeded at construction. The fallback covers any construction path that assigns _ctx without going through __init__/_bind_context.

convert(new_ctx=None)#

Return this object represented in new_ctx.

The object’s check_level is a property of the object, not of the backend/dtype context, so it is preserved across conversion rather than re-seeded from the ambient default.

Parameters:

new_ctx (Context | BackendFamily | str | None)

Return type:

Self

same_math(other)#

Tier-1 equality gate: same concrete type and same math context.

Combines a runtime-type identity check with Context.same_math() (equal backend ops and dtype, ignoring check_level — a validation policy, not a mathematical or backend property). This is the mandatory first check in every __eq__: the type gate guarantees other exposes the same attributes this object’s __eq__ will read, and same_math guarantees any later ops.allclose runs only on same-backend, same-dtype arrays, making cross-backend objects compare unequal.

Callers that fail this gate should return NotImplemented so Python can try the reflected comparison and fall back to identity symmetrically.

Parameters:

other (Any)

Return type:

bool

class spacecore.functional.LinearFunctional(*args, **kwargs)[source]#

Bases: Functional[Domain]

A linear scalar-valued map on dom.

Parameters:
  • dom (Space) – Domain.

  • ctx (Context, str, or None, optional) – Backend context; resolved from dom when omitted.

  • check_level ({"none", "cheap", "standard", "strict"}, optional) – Validation level; the ambient default when omitted.

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.

The level is stored on the bound object (_check_level), seeded at construction. The fallback covers any construction path that assigns _ctx without going through __init__/_bind_context.

property codomain: RealField#

The independently bound scalar field of this functional’s values.

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

conjugate_prox(x, step)#

Return the conjugate prox by Hilbert-space Moreau decomposition.

The conjugate is f*_X(p) = sup_z Re <p,z>_X - f(z): dual variables are Riesz representers in the same space, not raw coordinate covectors. Thus prox_(step f*_X)(x) = x - step prox_(f/step)(x/step). Requires a valid convex prox and a finite, strictly positive step.

Parameters:
  • x (Any)

  • step (Any)

Return type:

Any

convert(new_ctx=None)#

Return this object represented in new_ctx.

The object’s check_level is a property of the object, not of the backend/dtype context, so it is preserved across conversion rather than re-seeded from the ambient default.

Parameters:

new_ctx (Context | BackendFamily | str | None)

Return type:

Self

derivative_at(x, *args, **kwargs)#

Return the differential at x, acting on domain directions.

The default wraps the Riesz gradient, Re <grad, h>. Implement _derivative_core for a native directional evaluator. At nonsmooth points a supplied subgradient is not a Frechet derivative.

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

LinearFunctional

differential(x, *args, **kwargs)#

Return the covector \(df(x)\) with \(Df(x)[h] = \langle df(x), h\rangle\).

The covector is a coordinate array paired with domain.pair and involves no metric. The default reads it off the Riesz gradient, domain.riesz(grad(x)); functionals that compute coordinate partials implement _differential_core.

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

Any

property domain: Domain#

Domain space of this scalar-valued map.

grad(x, *args, **kwargs)#

Riesz gradient at an element of self.domain.

Implement _grad_core, or _derivative_core with an available Riesz representer; otherwise raises NotImplementedError. Any auxiliary *args/**kwargs mirror those accepted by value().

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

Any

prox(x, step)#

Minimize f(y) + ||y-x||_X^2 / (2 step) for positive step.

This optional operation uses a closed-form rule registered with register("prox", FunctionalType, GeometryType, rule). The rule takes (functional, geometry, x, step) and returns a native domain element. An unsupported functional/geometry pair raises CapabilityError; sums and linear pullbacks do not acquire a prox automatically.

Prox rules assert a proper, lower-semicontinuous convex real objective (also on complex spaces, using the real inner product). At check level "none", traced steps must be finite and positive; their values are the caller’s responsibility. Concrete invalid Python steps still raise.

Parameters:
  • x (Any)

  • step (Any)

Return type:

Any

same_math(other)#

Tier-1 equality gate: same concrete type and same math context.

Combines a runtime-type identity check with Context.same_math() (equal backend ops and dtype, ignoring check_level — a validation policy, not a mathematical or backend property). This is the mandatory first check in every __eq__: the type gate guarantees other exposes the same attributes this object’s __eq__ will read, and same_math guarantees any later ops.allclose runs only on same-backend, same-dtype arrays, making cross-backend objects compare unequal.

Callers that fail this gate should return NotImplemented so Python can try the reflected comparison and fall back to identity symmetrically.

Parameters:

other (Any)

Return type:

bool

value(x, *args, **kwargs)#

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:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

Any

value_and_derivative(x, *args, **kwargs)#

Return value and differential, preserving fused gradient evaluators.

Derivative-first subclasses may implement _value_and_derivative_core to share work. No representer is reconstructed from a callable differential.

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

tuple[Any, ‘LinearFunctional’]

value_and_grad(x, *args, **kwargs)#

Return (value, gradient) at x.

Implement _value_and_grad_core for a single-pass evaluator (e.g. jax.value_and_grad); it must return the same pair as the separate cores, with the gradient in the same geometry as grad().

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

tuple[Any, Any]

vgrad(xs)#

Gradient over a leading batch axis; implement _vgrad_core to support it.

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.InnerProductFunctional(*args, **kwargs)[source]#

Bases: LinearFunctional[Domain]

The functional \(x \mapsto \operatorname{Re}\langle c, x\rangle_X\) of a representer c.

The real part of this pairing is always used. This represents real differentials on complex parameter spaces.

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

  • dom (Space) – Domain.

  • ctx (Context, str, or None, optional) – Backend context; resolved from dom when omitted.

  • check_level ({"none", "cheap", "standard", "strict"}, optional) – Validation level; the ambient default when omitted.

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.

The level is stored on the bound object (_check_level), seeded at construction. The fallback covers any construction path that assigns _ctx without going through __init__/_bind_context.

property codomain: RealField#

The independently bound scalar field of this functional’s values.

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

conjugate_prox(x, step)#

Return the conjugate prox by Hilbert-space Moreau decomposition.

The conjugate is f*_X(p) = sup_z Re <p,z>_X - f(z): dual variables are Riesz representers in the same space, not raw coordinate covectors. Thus prox_(step f*_X)(x) = x - step prox_(f/step)(x/step). Requires a valid convex prox and a finite, strictly positive step.

Parameters:
  • x (Any)

  • step (Any)

Return type:

Any

convert(new_ctx=None)#

Return this object represented in new_ctx.

The object’s check_level is a property of the object, not of the backend/dtype context, so it is preserved across conversion rather than re-seeded from the ambient default.

Parameters:

new_ctx (Context | BackendFamily | str | None)

Return type:

Self

derivative_at(x, *args, **kwargs)#

Return the differential at x, acting on domain directions.

The default wraps the Riesz gradient, Re <grad, h>. Implement _derivative_core for a native directional evaluator. At nonsmooth points a supplied subgradient is not a Frechet derivative.

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

LinearFunctional

differential(x, *args, **kwargs)#

Return the covector \(df(x)\) with \(Df(x)[h] = \langle df(x), h\rangle\).

The covector is a coordinate array paired with domain.pair and involves no metric. The default reads it off the Riesz gradient, domain.riesz(grad(x)); functionals that compute coordinate partials implement _differential_core.

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

Any

property domain: Domain#

Domain space of this scalar-valued map.

grad(x, *args, **kwargs)#

Riesz gradient at an element of self.domain.

Implement _grad_core, or _derivative_core with an available Riesz representer; otherwise raises NotImplementedError. Any auxiliary *args/**kwargs mirror those accepted by value().

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

Any

prox(x, step)#

Minimize f(y) + ||y-x||_X^2 / (2 step) for positive step.

This optional operation uses a closed-form rule registered with register("prox", FunctionalType, GeometryType, rule). The rule takes (functional, geometry, x, step) and returns a native domain element. An unsupported functional/geometry pair raises CapabilityError; sums and linear pullbacks do not acquire a prox automatically.

Prox rules assert a proper, lower-semicontinuous convex real objective (also on complex spaces, using the real inner product). At check level "none", traced steps must be finite and positive; their values are the caller’s responsibility. Concrete invalid Python steps still raise.

Parameters:
  • x (Any)

  • step (Any)

Return type:

Any

same_math(other)#

Tier-1 equality gate: same concrete type and same math context.

Combines a runtime-type identity check with Context.same_math() (equal backend ops and dtype, ignoring check_level — a validation policy, not a mathematical or backend property). This is the mandatory first check in every __eq__: the type gate guarantees other exposes the same attributes this object’s __eq__ will read, and same_math guarantees any later ops.allclose runs only on same-backend, same-dtype arrays, making cross-backend objects compare unequal.

Callers that fail this gate should return NotImplemented so Python can try the reflected comparison and fall back to identity symmetrically.

Parameters:

other (Any)

Return type:

bool

value(x, *args, **kwargs)#

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:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

Any

value_and_derivative(x, *args, **kwargs)#

Return value and differential, preserving fused gradient evaluators.

Derivative-first subclasses may implement _value_and_derivative_core to share work. No representer is reconstructed from a callable differential.

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

tuple[Any, ‘LinearFunctional’]

value_and_grad(x, *args, **kwargs)#

Return (value, gradient) at x.

Implement _value_and_grad_core for a single-pass evaluator (e.g. jax.value_and_grad); it must return the same pair as the separate cores, with the gradient in the same geometry as grad().

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

tuple[Any, Any]

vgrad(xs)#

Gradient over a leading batch axis; implement _vgrad_core to support it.

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.MatrixFreeLinearFunctional(*args, **kwargs)[source]#

Bases: LinearFunctional[Domain]

Linear functional given by an evaluation callable; no Riesz representer is stored.

Parameters:
  • value (callable) – value(x) returning a scalar for x in dom.

  • dom (Space) – Domain.

  • ctx (Context, str, or None, optional) – Backend context.

  • vvalue (callable or None, optional) – Batched evaluation; vmap of value by default.

  • check_level ({"none", "cheap", "standard", "strict"}, optional) – Validation level; the ambient default when omitted. The callable must return real values; no projection is applied.

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.

The level is stored on the bound object (_check_level), seeded at construction. The fallback covers any construction path that assigns _ctx without going through __init__/_bind_context.

property codomain: RealField#

The independently bound scalar field of this functional’s values.

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

conjugate_prox(x, step)#

Return the conjugate prox by Hilbert-space Moreau decomposition.

The conjugate is f*_X(p) = sup_z Re <p,z>_X - f(z): dual variables are Riesz representers in the same space, not raw coordinate covectors. Thus prox_(step f*_X)(x) = x - step prox_(f/step)(x/step). Requires a valid convex prox and a finite, strictly positive step.

Parameters:
  • x (Any)

  • step (Any)

Return type:

Any

convert(new_ctx=None)#

Return this object represented in new_ctx.

The object’s check_level is a property of the object, not of the backend/dtype context, so it is preserved across conversion rather than re-seeded from the ambient default.

Parameters:

new_ctx (Context | BackendFamily | str | None)

Return type:

Self

derivative_at(x, *args, **kwargs)#

Return the differential at x, acting on domain directions.

The default wraps the Riesz gradient, Re <grad, h>. Implement _derivative_core for a native directional evaluator. At nonsmooth points a supplied subgradient is not a Frechet derivative.

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

LinearFunctional

differential(x, *args, **kwargs)#

Return the covector \(df(x)\) with \(Df(x)[h] = \langle df(x), h\rangle\).

The covector is a coordinate array paired with domain.pair and involves no metric. The default reads it off the Riesz gradient, domain.riesz(grad(x)); functionals that compute coordinate partials implement _differential_core.

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

Any

property domain: Domain#

Domain space of this scalar-valued map.

grad(x, *args, **kwargs)#

Riesz gradient at an element of self.domain.

Implement _grad_core, or _derivative_core with an available Riesz representer; otherwise raises NotImplementedError. Any auxiliary *args/**kwargs mirror those accepted by value().

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

Any

prox(x, step)#

Minimize f(y) + ||y-x||_X^2 / (2 step) for positive step.

This optional operation uses a closed-form rule registered with register("prox", FunctionalType, GeometryType, rule). The rule takes (functional, geometry, x, step) and returns a native domain element. An unsupported functional/geometry pair raises CapabilityError; sums and linear pullbacks do not acquire a prox automatically.

Prox rules assert a proper, lower-semicontinuous convex real objective (also on complex spaces, using the real inner product). At check level "none", traced steps must be finite and positive; their values are the caller’s responsibility. Concrete invalid Python steps still raise.

Parameters:
  • x (Any)

  • step (Any)

Return type:

Any

same_math(other)#

Tier-1 equality gate: same concrete type and same math context.

Combines a runtime-type identity check with Context.same_math() (equal backend ops and dtype, ignoring check_level — a validation policy, not a mathematical or backend property). This is the mandatory first check in every __eq__: the type gate guarantees other exposes the same attributes this object’s __eq__ will read, and same_math guarantees any later ops.allclose runs only on same-backend, same-dtype arrays, making cross-backend objects compare unequal.

Callers that fail this gate should return NotImplemented so Python can try the reflected comparison and fall back to identity symmetrically.

Parameters:

other (Any)

Return type:

bool

value(x, *args, **kwargs)#

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:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

Any

value_and_derivative(x, *args, **kwargs)#

Return value and differential, preserving fused gradient evaluators.

Derivative-first subclasses may implement _value_and_derivative_core to share work. No representer is reconstructed from a callable differential.

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

tuple[Any, ‘LinearFunctional’]

value_and_grad(x, *args, **kwargs)#

Return (value, gradient) at x.

Implement _value_and_grad_core for a single-pass evaluator (e.g. jax.value_and_grad); it must return the same pair as the separate cores, with the gradient in the same geometry as grad().

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

tuple[Any, Any]

vgrad(xs)#

Gradient over a leading batch axis; implement _vgrad_core to support it.

Parameters:

xs (Any)

Return type:

Any

class spacecore.functional.QuadraticForm(*args, **kwargs)[source]#

Bases: Functional[Domain]

A scalar quadratic objective on dom.

Parameters:
  • dom (Space) – Domain.

  • ctx (Context, str, or None, optional) – Backend context; resolved from dom when omitted.

  • check_level ({"none", "cheap", "standard", "strict"}, optional) – Validation level; the ambient default when omitted.

hess_apply(x)[source]#

Apply the Hessian action at x; implement _hess_apply_core to support it.

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.

The level is stored on the bound object (_check_level), seeded at construction. The fallback covers any construction path that assigns _ctx without going through __init__/_bind_context.

property codomain: RealField#

The independently bound scalar field of this functional’s values.

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

conjugate_prox(x, step)#

Return the conjugate prox by Hilbert-space Moreau decomposition.

The conjugate is f*_X(p) = sup_z Re <p,z>_X - f(z): dual variables are Riesz representers in the same space, not raw coordinate covectors. Thus prox_(step f*_X)(x) = x - step prox_(f/step)(x/step). Requires a valid convex prox and a finite, strictly positive step.

Parameters:
  • x (Any)

  • step (Any)

Return type:

Any

convert(new_ctx=None)#

Return this object represented in new_ctx.

The object’s check_level is a property of the object, not of the backend/dtype context, so it is preserved across conversion rather than re-seeded from the ambient default.

Parameters:

new_ctx (Context | BackendFamily | str | None)

Return type:

Self

derivative_at(x, *args, **kwargs)#

Return the differential at x, acting on domain directions.

The default wraps the Riesz gradient, Re <grad, h>. Implement _derivative_core for a native directional evaluator. At nonsmooth points a supplied subgradient is not a Frechet derivative.

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

LinearFunctional

differential(x, *args, **kwargs)#

Return the covector \(df(x)\) with \(Df(x)[h] = \langle df(x), h\rangle\).

The covector is a coordinate array paired with domain.pair and involves no metric. The default reads it off the Riesz gradient, domain.riesz(grad(x)); functionals that compute coordinate partials implement _differential_core.

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

Any

property domain: Domain#

Domain space of this scalar-valued map.

grad(x, *args, **kwargs)#

Riesz gradient at an element of self.domain.

Implement _grad_core, or _derivative_core with an available Riesz representer; otherwise raises NotImplementedError. Any auxiliary *args/**kwargs mirror those accepted by value().

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

Any

prox(x, step)#

Minimize f(y) + ||y-x||_X^2 / (2 step) for positive step.

This optional operation uses a closed-form rule registered with register("prox", FunctionalType, GeometryType, rule). The rule takes (functional, geometry, x, step) and returns a native domain element. An unsupported functional/geometry pair raises CapabilityError; sums and linear pullbacks do not acquire a prox automatically.

Prox rules assert a proper, lower-semicontinuous convex real objective (also on complex spaces, using the real inner product). At check level "none", traced steps must be finite and positive; their values are the caller’s responsibility. Concrete invalid Python steps still raise.

Parameters:
  • x (Any)

  • step (Any)

Return type:

Any

same_math(other)#

Tier-1 equality gate: same concrete type and same math context.

Combines a runtime-type identity check with Context.same_math() (equal backend ops and dtype, ignoring check_level — a validation policy, not a mathematical or backend property). This is the mandatory first check in every __eq__: the type gate guarantees other exposes the same attributes this object’s __eq__ will read, and same_math guarantees any later ops.allclose runs only on same-backend, same-dtype arrays, making cross-backend objects compare unequal.

Callers that fail this gate should return NotImplemented so Python can try the reflected comparison and fall back to identity symmetrically.

Parameters:

other (Any)

Return type:

bool

value(x, *args, **kwargs)#

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:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

Any

value_and_derivative(x, *args, **kwargs)#

Return value and differential, preserving fused gradient evaluators.

Derivative-first subclasses may implement _value_and_derivative_core to share work. No representer is reconstructed from a callable differential.

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

tuple[Any, ‘LinearFunctional’]

value_and_grad(x, *args, **kwargs)#

Return (value, gradient) at x.

Implement _value_and_grad_core for a single-pass evaluator (e.g. jax.value_and_grad); it must return the same pair as the separate cores, with the gradient in the same geometry as grad().

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

tuple[Any, Any]

vgrad(xs)#

Gradient over a leading batch axis; implement _vgrad_core to support it.

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.LinOpQuadraticForm(*args, **kwargs)[source]#

Bases: QuadraticForm[Domain]

Quadratic form 1/2 <x, Q x> + linear(x) + a for a Hermitian Q, so grad = Q x + ....

Hermiticity is checked where the operator’s structure allows; matrix-free Q is trusted. For a non-Hermitian Q, pass its Hermitian part 0.5 * (Q + Q.H). Expanding the quadratic gives D(1/2 <x,Qx>)[h] = Re<Qx,h>; for a real-valued objective on a complex space the linear term must also be real. Beck, First-Order Methods in Optimization, Thm 3.29, with the real pairing.

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

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

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

  • ctx (Context, str, or None, optional) – Backend context; resolved from Q and linear when omitted.

  • check_level ({"none", "cheap", "standard", "strict"}, optional) – Validation level; the ambient default when omitted.

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.

The level is stored on the bound object (_check_level), seeded at construction. The fallback covers any construction path that assigns _ctx without going through __init__/_bind_context.

property codomain: RealField#

The independently bound scalar field of this functional’s values.

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

conjugate_prox(x, step)#

Return the conjugate prox by Hilbert-space Moreau decomposition.

The conjugate is f*_X(p) = sup_z Re <p,z>_X - f(z): dual variables are Riesz representers in the same space, not raw coordinate covectors. Thus prox_(step f*_X)(x) = x - step prox_(f/step)(x/step). Requires a valid convex prox and a finite, strictly positive step.

Parameters:
  • x (Any)

  • step (Any)

Return type:

Any

convert(new_ctx=None)#

Return this object represented in new_ctx.

The object’s check_level is a property of the object, not of the backend/dtype context, so it is preserved across conversion rather than re-seeded from the ambient default.

Parameters:

new_ctx (Context | BackendFamily | str | None)

Return type:

Self

derivative_at(x, *args, **kwargs)#

Return the differential at x, acting on domain directions.

The default wraps the Riesz gradient, Re <grad, h>. Implement _derivative_core for a native directional evaluator. At nonsmooth points a supplied subgradient is not a Frechet derivative.

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

LinearFunctional

differential(x, *args, **kwargs)#

Return the covector \(df(x)\) with \(Df(x)[h] = \langle df(x), h\rangle\).

The covector is a coordinate array paired with domain.pair and involves no metric. The default reads it off the Riesz gradient, domain.riesz(grad(x)); functionals that compute coordinate partials implement _differential_core.

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

Any

property domain: Domain#

Domain space of this scalar-valued map.

grad(x, *args, **kwargs)#

Riesz gradient at an element of self.domain.

Implement _grad_core, or _derivative_core with an available Riesz representer; otherwise raises NotImplementedError. Any auxiliary *args/**kwargs mirror those accepted by value().

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

Any

hess_apply(x)#

Apply the Hessian action at x; implement _hess_apply_core to support it.

Parameters:

x (Any)

Return type:

Any

prox(x, step)#

Minimize f(y) + ||y-x||_X^2 / (2 step) for positive step.

This optional operation uses a closed-form rule registered with register("prox", FunctionalType, GeometryType, rule). The rule takes (functional, geometry, x, step) and returns a native domain element. An unsupported functional/geometry pair raises CapabilityError; sums and linear pullbacks do not acquire a prox automatically.

Prox rules assert a proper, lower-semicontinuous convex real objective (also on complex spaces, using the real inner product). At check level "none", traced steps must be finite and positive; their values are the caller’s responsibility. Concrete invalid Python steps still raise.

Parameters:
  • x (Any)

  • step (Any)

Return type:

Any

same_math(other)#

Tier-1 equality gate: same concrete type and same math context.

Combines a runtime-type identity check with Context.same_math() (equal backend ops and dtype, ignoring check_level — a validation policy, not a mathematical or backend property). This is the mandatory first check in every __eq__: the type gate guarantees other exposes the same attributes this object’s __eq__ will read, and same_math guarantees any later ops.allclose runs only on same-backend, same-dtype arrays, making cross-backend objects compare unequal.

Callers that fail this gate should return NotImplemented so Python can try the reflected comparison and fall back to identity symmetrically.

Parameters:

other (Any)

Return type:

bool

value(x, *args, **kwargs)#

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:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

Any

value_and_derivative(x, *args, **kwargs)#

Return value and differential, preserving fused gradient evaluators.

Derivative-first subclasses may implement _value_and_derivative_core to share work. No representer is reconstructed from a callable differential.

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

tuple[Any, ‘LinearFunctional’]

value_and_grad(x, *args, **kwargs)#

Return (value, gradient) at x.

Implement _value_and_grad_core for a single-pass evaluator (e.g. jax.value_and_grad); it must return the same pair as the separate cores, with the gradient in the same geometry as grad().

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

tuple[Any, Any]

vgrad(xs)#

Gradient over a leading batch axis; implement _vgrad_core to support it.

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.ComposedFunctional(*args, **kwargs)[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.

  • check_level ({"none", "cheap", "standard", "strict"}, optional) – Validation level; the ambient default when omitted.

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.

The level is stored on the bound object (_check_level), seeded at construction. The fallback covers any construction path that assigns _ctx without going through __init__/_bind_context.

property codomain: RealField#

The independently bound scalar field of this functional’s values.

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

conjugate_prox(x, step)#

Return the conjugate prox by Hilbert-space Moreau decomposition.

The conjugate is f*_X(p) = sup_z Re <p,z>_X - f(z): dual variables are Riesz representers in the same space, not raw coordinate covectors. Thus prox_(step f*_X)(x) = x - step prox_(f/step)(x/step). Requires a valid convex prox and a finite, strictly positive step.

Parameters:
  • x (Any)

  • step (Any)

Return type:

Any

convert(new_ctx=None)#

Return this object represented in new_ctx.

The object’s check_level is a property of the object, not of the backend/dtype context, so it is preserved across conversion rather than re-seeded from the ambient default.

Parameters:

new_ctx (Context | BackendFamily | str | None)

Return type:

Self

derivative_at(x, *args, **kwargs)#

Return the differential at x, acting on domain directions.

The default wraps the Riesz gradient, Re <grad, h>. Implement _derivative_core for a native directional evaluator. At nonsmooth points a supplied subgradient is not a Frechet derivative.

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

LinearFunctional

differential(x, *args, **kwargs)#

Return the covector \(df(x)\) with \(Df(x)[h] = \langle df(x), h\rangle\).

The covector is a coordinate array paired with domain.pair and involves no metric. The default reads it off the Riesz gradient, domain.riesz(grad(x)); functionals that compute coordinate partials implement _differential_core.

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

Any

property domain: Domain#

Domain space of this scalar-valued map.

grad(x, *args, **kwargs)#

Riesz gradient at an element of self.domain.

Implement _grad_core, or _derivative_core with an available Riesz representer; otherwise raises NotImplementedError. Any auxiliary *args/**kwargs mirror those accepted by value().

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

Any

prox(x, step)#

Minimize f(y) + ||y-x||_X^2 / (2 step) for positive step.

This optional operation uses a closed-form rule registered with register("prox", FunctionalType, GeometryType, rule). The rule takes (functional, geometry, x, step) and returns a native domain element. An unsupported functional/geometry pair raises CapabilityError; sums and linear pullbacks do not acquire a prox automatically.

Prox rules assert a proper, lower-semicontinuous convex real objective (also on complex spaces, using the real inner product). At check level "none", traced steps must be finite and positive; their values are the caller’s responsibility. Concrete invalid Python steps still raise.

Parameters:
  • x (Any)

  • step (Any)

Return type:

Any

same_math(other)#

Tier-1 equality gate: same concrete type and same math context.

Combines a runtime-type identity check with Context.same_math() (equal backend ops and dtype, ignoring check_level — a validation policy, not a mathematical or backend property). This is the mandatory first check in every __eq__: the type gate guarantees other exposes the same attributes this object’s __eq__ will read, and same_math guarantees any later ops.allclose runs only on same-backend, same-dtype arrays, making cross-backend objects compare unequal.

Callers that fail this gate should return NotImplemented so Python can try the reflected comparison and fall back to identity symmetrically.

Parameters:

other (Any)

Return type:

bool

value(x, *args, **kwargs)#

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:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

Any

value_and_derivative(x, *args, **kwargs)#

Return value and differential, preserving fused gradient evaluators.

Derivative-first subclasses may implement _value_and_derivative_core to share work. No representer is reconstructed from a callable differential.

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

tuple[Any, ‘LinearFunctional’]

value_and_grad(x, *args, **kwargs)#

Return (value, gradient) at x.

Implement _value_and_grad_core for a single-pass evaluator (e.g. jax.value_and_grad); it must return the same pair as the separate cores, with the gradient in the same geometry as grad().

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

tuple[Any, Any]

vgrad(xs)#

Gradient over a leading batch axis; implement _vgrad_core to support it.

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, specialized where a closed form exists.

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

  • A (LinOp) – Operator into F.domain.

Returns:

The pull-back.

Return type:

Functional

class spacecore.functional.SquaredL2NormFunctional(*args, **kwargs)[source]#

Bases: _CoordinateFunctional[Domain]

Half the squared space norm <x, x>_X / 2; its gradient is x.

Not LpNormFunctional(X, 2), which is the unsquared coordinate norm.

Parameters:
  • dom (Space) – Domain.

  • ctx (Context, str, or None, optional) – Backend context; resolved from dom when omitted.

  • check_level ({"none", "cheap", "standard", "strict"}, optional) – Validation level; the ambient default when omitted.

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.])
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.

The level is stored on the bound object (_check_level), seeded at construction. The fallback covers any construction path that assigns _ctx without going through __init__/_bind_context.

property codomain: RealField#

The independently bound scalar field of this functional’s values.

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

conjugate_prox(x, step)#

Return the conjugate prox by Hilbert-space Moreau decomposition.

The conjugate is f*_X(p) = sup_z Re <p,z>_X - f(z): dual variables are Riesz representers in the same space, not raw coordinate covectors. Thus prox_(step f*_X)(x) = x - step prox_(f/step)(x/step). Requires a valid convex prox and a finite, strictly positive step.

Parameters:
  • x (Any)

  • step (Any)

Return type:

Any

convert(new_ctx=None)#

Return this object represented in new_ctx.

The object’s check_level is a property of the object, not of the backend/dtype context, so it is preserved across conversion rather than re-seeded from the ambient default.

Parameters:

new_ctx (Context | BackendFamily | str | None)

Return type:

Self

derivative_at(x, *args, **kwargs)#

Return the differential at x, acting on domain directions.

The default wraps the Riesz gradient, Re <grad, h>. Implement _derivative_core for a native directional evaluator. At nonsmooth points a supplied subgradient is not a Frechet derivative.

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

LinearFunctional

differential(x, *args, **kwargs)#

Return the covector \(df(x)\) with \(Df(x)[h] = \langle df(x), h\rangle\).

The covector is a coordinate array paired with domain.pair and involves no metric. The default reads it off the Riesz gradient, domain.riesz(grad(x)); functionals that compute coordinate partials implement _differential_core.

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

Any

property domain: Domain#

Domain space of this scalar-valued map.

grad(x, *args, **kwargs)#

Riesz gradient at an element of self.domain.

Implement _grad_core, or _derivative_core with an available Riesz representer; otherwise raises NotImplementedError. Any auxiliary *args/**kwargs mirror those accepted by value().

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

Any

prox(x, step)#

Minimize f(y) + ||y-x||_X^2 / (2 step) for positive step.

This optional operation uses a closed-form rule registered with register("prox", FunctionalType, GeometryType, rule). The rule takes (functional, geometry, x, step) and returns a native domain element. An unsupported functional/geometry pair raises CapabilityError; sums and linear pullbacks do not acquire a prox automatically.

Prox rules assert a proper, lower-semicontinuous convex real objective (also on complex spaces, using the real inner product). At check level "none", traced steps must be finite and positive; their values are the caller’s responsibility. Concrete invalid Python steps still raise.

Parameters:
  • x (Any)

  • step (Any)

Return type:

Any

same_math(other)#

Tier-1 equality gate: same concrete type and same math context.

Combines a runtime-type identity check with Context.same_math() (equal backend ops and dtype, ignoring check_level — a validation policy, not a mathematical or backend property). This is the mandatory first check in every __eq__: the type gate guarantees other exposes the same attributes this object’s __eq__ will read, and same_math guarantees any later ops.allclose runs only on same-backend, same-dtype arrays, making cross-backend objects compare unequal.

Callers that fail this gate should return NotImplemented so Python can try the reflected comparison and fall back to identity symmetrically.

Parameters:

other (Any)

Return type:

bool

value(x, *args, **kwargs)#

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:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

Any

value_and_derivative(x, *args, **kwargs)#

Return value and differential, preserving fused gradient evaluators.

Derivative-first subclasses may implement _value_and_derivative_core to share work. No representer is reconstructed from a callable differential.

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

tuple[Any, ‘LinearFunctional’]

value_and_grad(x, *args, **kwargs)#

Return (value, gradient) at x.

Implement _value_and_grad_core for a single-pass evaluator (e.g. jax.value_and_grad); it must return the same pair as the separate cores, with the gradient in the same geometry as grad().

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

tuple[Any, Any]

vgrad(xs)#

Gradient over a leading batch axis; implement _vgrad_core to support it.

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(*args, **kwargs)[source]#

Bases: _CoordinateFunctional[Domain]

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

The gradient is sign(x_i) |x_i|^(p-1) / ||x||_p^(p-1), Riesz-corrected; at the origin the zero subgradient is returned (Beck, First-Order Methods in Optimization, Example 3.3). For p = 1, zero coordinates also use zero subgradient components (Example 3.4); elsewhere differentiate the displayed norm.

Parameters:
  • dom (Space) – Domain.

  • p (float) – Finite order, at least 1.

  • ctx (Context, str, or None, optional) – Backend context; resolved from dom when omitted.

  • check_level ({"none", "cheap", "standard", "strict"}, optional) – Validation level; the ambient default when omitted.

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
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.

The level is stored on the bound object (_check_level), seeded at construction. The fallback covers any construction path that assigns _ctx without going through __init__/_bind_context.

property codomain: RealField#

The independently bound scalar field of this functional’s values.

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

conjugate_prox(x, step)#

Return the conjugate prox by Hilbert-space Moreau decomposition.

The conjugate is f*_X(p) = sup_z Re <p,z>_X - f(z): dual variables are Riesz representers in the same space, not raw coordinate covectors. Thus prox_(step f*_X)(x) = x - step prox_(f/step)(x/step). Requires a valid convex prox and a finite, strictly positive step.

Parameters:
  • x (Any)

  • step (Any)

Return type:

Any

convert(new_ctx=None)#

Return this object represented in new_ctx.

The object’s check_level is a property of the object, not of the backend/dtype context, so it is preserved across conversion rather than re-seeded from the ambient default.

Parameters:

new_ctx (Context | BackendFamily | str | None)

Return type:

Self

derivative_at(x, *args, **kwargs)#

Return the differential at x, acting on domain directions.

The default wraps the Riesz gradient, Re <grad, h>. Implement _derivative_core for a native directional evaluator. At nonsmooth points a supplied subgradient is not a Frechet derivative.

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

LinearFunctional

differential(x, *args, **kwargs)#

Return the covector \(df(x)\) with \(Df(x)[h] = \langle df(x), h\rangle\).

The covector is a coordinate array paired with domain.pair and involves no metric. The default reads it off the Riesz gradient, domain.riesz(grad(x)); functionals that compute coordinate partials implement _differential_core.

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

Any

property domain: Domain#

Domain space of this scalar-valued map.

grad(x, *args, **kwargs)#

Riesz gradient at an element of self.domain.

Implement _grad_core, or _derivative_core with an available Riesz representer; otherwise raises NotImplementedError. Any auxiliary *args/**kwargs mirror those accepted by value().

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

Any

prox(x, step)#

Minimize f(y) + ||y-x||_X^2 / (2 step) for positive step.

This optional operation uses a closed-form rule registered with register("prox", FunctionalType, GeometryType, rule). The rule takes (functional, geometry, x, step) and returns a native domain element. An unsupported functional/geometry pair raises CapabilityError; sums and linear pullbacks do not acquire a prox automatically.

Prox rules assert a proper, lower-semicontinuous convex real objective (also on complex spaces, using the real inner product). At check level "none", traced steps must be finite and positive; their values are the caller’s responsibility. Concrete invalid Python steps still raise.

Parameters:
  • x (Any)

  • step (Any)

Return type:

Any

same_math(other)#

Tier-1 equality gate: same concrete type and same math context.

Combines a runtime-type identity check with Context.same_math() (equal backend ops and dtype, ignoring check_level — a validation policy, not a mathematical or backend property). This is the mandatory first check in every __eq__: the type gate guarantees other exposes the same attributes this object’s __eq__ will read, and same_math guarantees any later ops.allclose runs only on same-backend, same-dtype arrays, making cross-backend objects compare unequal.

Callers that fail this gate should return NotImplemented so Python can try the reflected comparison and fall back to identity symmetrically.

Parameters:

other (Any)

Return type:

bool

value(x, *args, **kwargs)#

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:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

Any

value_and_derivative(x, *args, **kwargs)#

Return value and differential, preserving fused gradient evaluators.

Derivative-first subclasses may implement _value_and_derivative_core to share work. No representer is reconstructed from a callable differential.

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

tuple[Any, ‘LinearFunctional’]

value_and_grad(x, *args, **kwargs)#

Return (value, gradient) at x.

Implement _value_and_grad_core for a single-pass evaluator (e.g. jax.value_and_grad); it must return the same pair as the separate cores, with the gradient in the same geometry as grad().

Parameters:
  • x (Any)

  • args (Any)

  • kwargs (Any)

Return type:

tuple[Any, Any]

vgrad(xs)#

Gradient over a leading batch axis; implement _vgrad_core to support it.

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, check_level=None)[source]#

Coordinate 1-norm: LpNormFunctional(dom, 1).

Parameters:
  • dom (Space) – Domain.

  • ctx (Context, str, or None, optional) – Backend context; resolved from dom when omitted.

  • check_level ({"none", "cheap", "standard", "strict"}, optional) – Validation level; the ambient default when omitted.

Returns:

The p = 1 norm.

Return type:

LpNormFunctional