Release notes#
Version 0.5.0#
Functionals are real-valued: the codomain is always RealField and the
cod and real_linear arguments are gone. With checks on (cheap and
above), complex outputs, coefficients and offsets raise. Complex domains remain
supported through the real inner-product pairing. This is a breaking change.
SpaceCore 0.5.0 adds the first-order proximal surface, makes every public
operation a checked wrapper over a check-free core, and removes layers that did
not earn their keep, while keeping the Backend → Space → Mapping (LinOp /
Functional) → Element division. The full list is in CHANGELOG.md.
Migrating#
A custom space, operator or functional implements cores (
_add_core,_flatten_core,_star_core,_jordan_core,_apply_core,_grad_core, …). A public method overridden without a decorator still works: it becomes the class’s core.cg,lsqr,power_iteration,lanczos_smallestandexpm_multiplyreturn oneLinalgResult;eigenvectorandresultarex,krylov_dimisnum_iters,residual_estimateisresidual_norm.Scaling a space over the reals by a non-real number raises
SpaceValidationError.Inside
jax.jit/torch.compilechecks are off by default;set_traced_check_level("cheap")keeps shape and dtype checks.
Added#
Optional
Functional.proxrules, Hilbert-spaceconjugate_prox, and theSet/NonnegativeOrthant/IndicatorFunctionalprojection surface (Metric proximal operations).Element, a formal context-bound member of a space;Mapping, the common parent ofLinOpandFunctional;RealFieldas the codomain of functionals.A field declaration for extensions: a class lists its constructor
_fieldsonce and gets pytree flattening,convertand (for maps) equality from it (Extending SpaceCore).set_traced_check_level/get_traced_check_level: the check-level cap while a backend traces,"none"by default.Hashable spaces, operators and functionals (consistent with
==) and a notebook_repr_html_.
Changed#
LinOp,Functionaland every space capability own their checked public methods; subclasses implement the check-free cores (_apply_core,_grad_core,_riesz_core,_flatten_core,_star_core,_jordan_core, …). Composites call cores, so each checks once.Spaces over the reals reject non-real multipliers in
scale,axpyandscale_batch(breaking).A one-column or one-row
BlockMatrixLinOphas a plain endpoint rather than a one-leafTreeSpace, and the containers of its rows give the endpoint trees.Coordinate functionals that compared by identity now compare by their fields.
The pytree
auxof field-declared classes is a tuple of(field, value)pairs.
Removed#
StackedLinOpandSumToSingleLinOp(breaking): useBlockMatrixLinOp.stack(parts)andBlockMatrixLinOp.from_operators(parts).spacecore.opfamilyand theFunctional * LinOprule (breaking): it had no consumer;F * Anow raisesTypeError.The
spacecore.kernelspackage: the ADR-016 dispatch specs (mostly slower on eager NumPy, never used underjax.jit) and the core-function layer, whose cores are now methods of their classes.spacecore.optimize(breaking): the optimizer adapters live in the separatespacecore-optimizepackage.The legacy
BlockDiagonalLinOp(dom, cod, parts, ctx)form, theenable_checksshim,ShiftedFunctionaland other deprecated surfaces (breaking).Notebooks, tutorial notebooks, examples and the benchmark suite left the package repository; the rendered tutorials stay in these docs.
Version 0.4.3#
Released 2026-09-12. SpaceCore 0.4.3 moves validation policy off the context and
onto the bound object, makes pytree registration backend-neutral, and extends the
functional algebra with products, constants, and the operator-family type that
Functional * LinOp needs.
Removed#
jax_pytree_classis removed from the public API (breaking). Pytree registration is now expressed through the backend-neutralPyTreeNodemixin, so a JAX-named decorator no longer sits in a backend-agnostic surface.SpectralLpNormFunctionalis removed (breaking).spectralizelifts any coordinate functional to the spectrum of a Jordan-algebra space, which subsumes the per-formula spectral class.
Added#
Backend-neutral pytree registration.
PyTreeNodecarries the capability, andTorchOps.install_pytree_protocolmakes Torch a transform-capable backend alongside JAX.SpectralFunctional,spectralize, andeigenvalue_spacelift any coordinate functional onto a spectrum;RealifiedFunctionalandrealifyview a complex-domain functional over its real coordinates, so optimizers that assume a real vector space can consume it without hand-written Wirtinger bookkeeping.ProductFunctional/make_functional_productandConstantFunctional/make_constant_functionalcomplete the functional algebra with a pointwise product carrying the product-rule Riesz gradient, and with the embedding of a scalar as a functional.spacecore.opfamily:OperatorFamilyandFunctionalScaledOperatormodelF * A, the functional-weighted mapm(x) = F(x) A x. That map is not linear, so it is deliberately not aLinOp;m.at(x)freezes a member andm.linearize_at(x)gives the derivative for Newton-type steps.Space.scalar_field/declared_scalar_field/check_scalardeclare the field a space is closed under rather than inferring it from the dtype, andchecked_methodgainsout_scalar/out_batched_scalarso a functional’s scalar codomain is checked by the same decorator that guards everyLinOpoutput.OpsRegistryextracts the backend registry out ofContextual, andBackendOps.complex_dtypecompletes the pair withreal_dtype.
Changed#
check_levelis a property of the bound object, not ofContext(breaking).Context(ops, dtype=..., check_level=...)and the deprecatedenable_checks=argument are gone – aContextis now exactly(ops, dtype). Passcheck_level=to a space, operator, or functional, or move the ambient default withset_check_level/use_check_level. See Checking policy.spacecore._contextualis now the publicspacecore.contextual(breaking).Ambient context and check level are scoped with
contextvars, so an override is visible to the current thread and async task rather than to the whole process.Functional.__mul__/__rmul__dispatch on the operand type, and functional outputs are checked as scalars atstandardand above.available_ops()is memoized and returns a tuple.
Fixed#
ComposedFunctionalnow has a gradient:F.compose(A).grad(x)previously raised.A present-but-broken optional backend no longer aborts
import spacecore, and one broken backend warns once rather than once per discovery call.scalar_eqno longer swallows every exception; it narrows toTypeErrorso a genuinely broken__eq__propagates.
Version 0.4.2#
Released 2026-07-01. SpaceCore 0.4.2 adds the Jordan spectral primitives, a lazy functional algebra, and a compiled convergence-aware optimizer driver.
Added#
Jordan spectral primitives on every Jordan-algebra space:
trace,determinant, andunit, withTraceFunctionalover them.Functional.value_and_gradevaluates a functional and its Riesz gradient in one pass.Structure-preserving tree spectra, so a
TreeSpacespectral decomposition keeps the tree shape.minimize_optax, a compiled convergence-aware driver for the Optax optimizers.
Version 0.4.1#
Released 2026-06-28. SpaceCore 0.4.1 lands the optimized-kernel dispatch layer (off by default), explicit lazy-operator fusion, a materialized-form cache for the batched folds, and a unified benchmark submodule — all without changing any default-path result.
Added#
ADR-016 optimized-kernel dispatch (off by default).
KernelSpecgainsdispatch_key/priority/ a shape-onlyKernelCost; the registry indexes dispatch-eligible (rtol == atol == 0) specs by key, and a singlespacecore.kernels.dispatchentry point routes the first applicable, affordable spec or runs the inlinegenericfallback.dispatch_mode(off/on/verify) is settable process-globally and per-scope; the materializing fast path is gated by a memory budget fromBackendOps.free_memory_bytes(). With dispatch off, every wired call site is result-identical to its prior inline path.Eight dispatch-eligible kernels (exact,
rtol = atol = 0): composed zero-annihilation and identity-elision, and the uniform flat-dense block-diagonal / stacked / sum-to-single batched-matmulfolds across the apply / adjoint / batched directions. Each carries a correctness reference and apython -m benchprobe; all route only underdispatch_mode("on"/"verify").ADR-021 lazy-operator-algebra
LinOp.fuse(*, materialize=False): collapses each maximal dense subtree into oneDenseLinOp(composition becomes a matrix product, with scalar / sum / adjoint / block folds), mathematically equal up to rounding and adjoint-consistent on any geometry. A matrix-free operand is never densified unlessmaterialize=True.ADR-022 materialized-form cache for the uniform batched folds: the input-independent stacked block-matrix array is built once and reused, memoized per accessor on
CachedStackParts(excluded from operator identity and the pytree; matrix-free never cached; the dispatcher stays stateless).NumpyOps.free_memory_bytes()viapsutil(now a required core dependency), so the dispatcher’s memory gate can size materializing fast paths on the CPU backend.Unified
benchbenchmark submodule (python -m bench): factory probes overspace/linop/functionalmeasuring per-call overhead against a hand-optimal pure-array-library bare, a dispatch/cache regime axis, uniform- and-ragged block probes, all backends benchmarked in float64, JAX run jitted-vs-jitted (compilation excluded and reported separately), and a filter-reactive interactive HTML dashboard. Tooling only —spacecorenever importsbench.
Fixed#
Corrected stale
correctness_refnode ids on two shippedKernelSpecobjects (composed-chain-apply,block-diagonal-dense-apply) that named non-existent module-level test nodes instead of the realClass::methodids.
Version 0.4.0#
Released 2026-06-24. SpaceCore 0.4.0 stabilizes the typed linear-algebra core as
a validated algebra of structured mathematical objects: a public check-policy,
the ADR-015 Stage 1 dtype/scalar-field contract, the TreeSpace direct-product
abstraction with block-structured operators, an everyday functional and proximal
toolbox, external optimizer adapters, reusable test generators, and a backend
conformance matrix with deviation catalog.
Added#
ADR-018 external optimizer adapters in the new
spacecore.optimizesubpackage.minimize_scipyandline_search_scipydrivescipy.optimize;minimize_optaxruns the canonical optax update loop with pytree pass-through. Each adapter evaluatesF.valueand converts the metric (Riesz) gradientF.gradto the coordinate gradient external optimizers expect withX.riesz(F.grad(x))— the identity on a Euclidean space and mandatory on a weighted one. The external optimizer owns iteration, line search, and convergence.minimize_optaxrequires a JAX-backed domain and the optionaloptaxextra. See the optimizer adapter docs (now inspacecore-optimize).ADR-019 everyday functional and proximal toolbox, in the
spacecore.functional.toolssubpackage.least_squares(A, b, *, weights=None, scale=0.5)returns aLinOpQuadraticFormfor the (optionally weighted) least-squares objective. New battery functionalsSquaredL2NormFunctional,LpNormFunctional,L1NormFunctional,NegativeEntropyFunctional,KLDivergenceFunctional, andHuberFunctionalare coordinate objectives whose gradients are the metric (Riesz) gradient under the domain geometry.SpectralLpNormFunctional(with theNuclearNormFunctionalwrapper) is the spectral analogue – the Schatten-pnorm of a Jordan spectrum (e.g.HermitianSpaceeigenvalues), with the spectral function gradient reconstructed throughfrom_spectrum. The closed-formgeneralized_shrinkageproximal primitive (withprox_l1,prox_l2sq, andproject_nonneg) folds the metric into the threshold and raises on a non-diagonal metric. See Functionals API.Public
check_levelpolicy with literal values"none","cheap","standard", and"strict", plus theCHECK_LEVELSordering and the_checks_at_leastdispatch used by spaces, LinOps, functionals, and solver preconditions. See Checking policy.Space.fieldexposing aLiteral["real", "complex"]mathematical contract derived from the context dtype, distinct fromContext.dtype(representation default).TreeSpacefinite direct-product coordinate space organized by anoptreedefinition, andTreeElementoptional ordered-leaf binding.BlockDiagonalLinOpand block-matrixLinOpsupport onTreeSpacedomains and codomains, including metric-adjoint behavior.Reusable test generators for spaces, LinOps, functionals, and linalg references under
tests/generators/; see the contributor guide atdocs/dev/contributing/linop_generators.md.spacecore.kernelssubpackage with the optimized-kernel registration policy. Two demonstration kernels ship in0.4.0:composed-chain-apply(skips per-link@checked_methodon a flat LinOp chain) andblock-diagonal-dense-apply(tightops.matmulloop over dense block leaves). Each kernel has a correctness reference intests/kernels/. No dispatch or fusion is wired in0.4.0: the ADR-016 structural-dispatch mechanism is implemented but ships off by default and dormant, with no production routing. (The kernel policy page was removed with the spec layer in 0.5.0a.)
Breaking changes#
ProductSpacewas removed.TreeSpaceis now the single structured finite direct-product abstraction.Tuple-style products now use
TreeSpace.from_leaf_spaces((X1, X2, ...)). Nested tuple, list, dictionary, named-tuple, and registered optree structures useTreeSpace(template, leaf_spaces)orTreeSpace.from_template.ProductLinOpwas renamed toTreeLinOp.BlockDiagonalLinOp,StackedLinOp, andSumToSingleLinOpnow validateTreeSpacedomains and codomains directly.Product structure adapters and product-specific checks were removed. Tree structure and leaf validation are owned by
TreeSpace.Conversion (
ctx.asarrayand construction helpers) refuses silent complex-to-real narrowing. Pass an explicit dtype to convert across fields.
Deprecations#
enable_checksis deprecated in favor ofcheck_level:enable_checks=Truemaps tocheck_level="standard";enable_checks=Falsemaps tocheck_level="none";passing both keywords raises
TypeError.
See Checking policy “Migration from
enable_checks” for the full mapping and examples.enable_checkscontinues to work in0.4.0but will be removed in a future release.
Stage 1 dtype and scalar-field contract#
Context.dtypeis the array representation default;Space.fieldis the mathematical real-or-complex contract derived from it.Capability guards (Jordan-algebra eligibility, Lanczos/exponential diagnostics, Hermitian guards) now consult
Space.fieldinstead of inspecting the precision-bearing context dtype.No constructor-level
fieldoverride is available in0.4.0; ADR-015 did not authorize one. Stage 2 (operand-dtype-preservingctx.asarray, opt-in exact dtype membership, operand-dtype solver workspaces) is deferred to0.5.0.