Numerical backends
GaussianProcess accepts a numerical backend through solver.
linalg.DenseBackend() is the stateless default backend. Its prepare method
returns a CholeskySystem containing the factorization and activity state for
exact dense inference and fitting.
Backend contract
SolverConfiguration.prepare(system, ...) prepares an immutable LinearSystem.
The input SymmetricLinearOperator supplies capacity, matmul, diagonal,
and tiled materialize.
Prepared systems provide solves, quadratic forms, log determinants, covariance
and variance reductions, reusable projections, and append operations. These
interfaces use numerical arrays and activity information rather than GP
measurement types.
For a prepared system, size is the active scalar count as a dynamic JAX
integer, and capacity is the reserved scalar dimension as a static Python
integer. Solves and projections accept full-capacity inputs. Activation increases
size while preserving capacity. Input operators also expose capacity, and
updates expose previous_capacity for the reserved dimension before activation.
Custom backends inherit from eqx.Module and SolverConfiguration. Their
prepared systems inherit from eqx.Module and LinearSystem. Both interfaces
are abstract base classes, so subclasses must implement all abstract methods
before they can be instantiated. Numerical inputs and update descriptions
explicitly inherit the SymmetricLinearOperator and LinearSystemUpdate
abstract base classes. Updates store their numerical system and newly active
indices as fields.
The small input interface keeps backends independent of kernels and observation types. Dense preparation requests materialization. The operator also supports products without storing the full matrix, ready for future iterative backends.
CovarianceProjection is an abstract interface for reusable covariance
reductions. The dense CholeskyProjection stores a whitened cross-covariance
whose Gram matrix is the reduction. Diagonal and cross reductions let consumers
reuse that state without accessing a backend's factorization.
Likelihood objectives use the configured backend's quadratic_form and
logdet. The dense quadratic form needs one triangular solve. Invalid
factorizations propagate non-finite statistics so fitting can reject invalid
trials. Backend configuration, prepared state, and returned results must support
JAX transformations, with numerical arrays stored as dynamic PyTree leaves.
Use configuration.prepare(system) to construct prepared state. For an already
materialized matrix, use CholeskySystem.from_matrix(matrix, jitter=...).
Factorization uses the symmetric part of the matrix with diagonal jitter.
cholops owns this input symmetrization and the symmetry-preserving reverse rule.
Dense systems store a cholops PaddedCholesky in factor. cholops owns
factorization, numerical consumers, reserved-slot activation, and coefficient
reuse. factor.order maps physical factor rows to canonical slots, and
factor.inverse_order maps canonical slots back to physical rows. factor.factor
exposes the lower-triangular array in physical order. solve and
project accept canonical-order inputs. Preparing a system with active=mask
reserves the inactive identity slots for append. Solves, quadratic forms, and
projections ignore inactive input entries, including non-finite values. Solves
return zero inactive coefficients. Generic systems without a mask are fully
active. CholeskySystem(factor, tile_size) wraps an existing PaddedCholesky.
gpex.linalg.DenseBackend
Bases: Module, SolverConfiguration
Stateless backend preparing dense Cholesky systems.
Jitter is owned by the input system. Preparation returns a reusable
:class:CholeskySystem containing the factorization and activity state.
prepare
prepare(
system: SymmetricLinearOperator,
*,
materialization_tile_size: int | None = None,
active: Activity | None = None,
) -> CholeskySystem
Prepare a factorization from a backend-neutral operator.
If supplied, active identifies used rows. Inactive rows must be an
independent identity system. They become reusable factor storage.
Numerical consumers ignore inactive input entries. If no activity
mask is supplied, every row is active.
Source code in src/gpex/linalg/dense.py
gpex.linalg.CholeskySystem
Bases: Module, LinearSystem
A dense system backed by a cholops fixed-capacity factor.
cholops owns storage, ordering, inactive-slot masking, and numerical updates. Failed factorizations retain NaNs. Numerical operations support JIT, vmap, and first-order differentiation.
from_matrix
classmethod
from_matrix(
matrix: SquareMatrix, jitter: float
) -> CholeskySystem
Factorize the symmetric part of a square matrix with diagonal jitter.
Source code in src/gpex/linalg/dense.py
solve
Solve on active rows for vector or array RHS, including empty batches.
Inactive input entries are ignored and inactive solution entries are zero.
Source code in src/gpex/linalg/dense.py
quadratic_form
Return the active inverse quadratic form with one triangular solve.
The vector has shape (capacity,) in canonical order. Supports JIT,
vectorization, and differentiation through the factor and vector.
Inactive entries are ignored. Failed factorizations propagate non-finite
values on the active system.
Source code in src/gpex/linalg/dense.py
logdet
covariance_reduction
variance_reduction
append
append(update: LinearSystemUpdate) -> CholeskySystem
Activate reserved slots with a Schur-complement factor update.
Source code in src/gpex/linalg/dense.py
append_solve
append_solve(
update: LinearSystemUpdate,
solution: Vector,
right_hand_side: Vector,
) -> tuple[CholeskySystem, Vector]
Activate reserved slots and reuse the existing coefficients.
Inputs and outputs use canonical ordering. Old active RHS entries must be unchanged. Inactive inputs are ignored, and returned inactive coefficients are zero.
Source code in src/gpex/linalg/dense.py
project
project(cross: Matrix) -> CholeskyProjection
gpex.linalg.SolverConfiguration
Bases: ABC
Abstract backend preparing a numerical system with optional tiling.
prepare
abstractmethod
prepare(
system: SymmetricLinearOperator,
*,
materialization_tile_size: int | None = None,
active: Activity | None = None,
) -> LinearSystem
gpex.linalg.LinearSystem
Bases: ABC
Abstract prepared system shared by inference and exact fitting.
Inputs and outputs use canonical observation order. Numerical state must remain differentiable and cross JIT boundaries as dynamic PyTree leaves. Invalid fitting trials retain non-finite quadratic forms and log determinants so optimizers can reject them without changing the system.
capacity
abstractmethod
property
Static scalar dimension of input and output arrays, including padding.
solve
abstractmethod
quadratic_form
abstractmethod
logdet
abstractmethod
covariance_reduction
abstractmethod
variance_reduction
abstractmethod
project
abstractmethod
project(cross: Matrix) -> CovarianceProjection
append
abstractmethod
append(update: LinearSystemUpdate) -> LinearSystem
append_solve
abstractmethod
append_solve(
update: LinearSystemUpdate,
solution: Vector,
right_hand_side: Vector,
) -> tuple[LinearSystem, Vector]
gpex.linalg.SymmetricLinearOperator
Bases: ABC
Symmetric numerical input supporting matrix-free and dense operations.
Backends consume this interface without knowing about GP measurements. They choose when to materialize the matrix and how to prepare its state.
capacity
abstractmethod
property
Materialized matrix dimension, including any reserved slots.
matmul
abstractmethod
Apply the system to canonical rows without materializing the matrix.
The input has shape (capacity, *columns). Reserved inactive slots
are independent identity rows, so their input values pass through.
tile_size bounds pairwise work, subject to indivisible operator
outputs. Numerical inputs support JIT, vmap, and differentiation.
Source code in src/gpex/linalg/base.py
diagonal
abstractmethod
materialize
abstractmethod
gpex.linalg.LinearSystemUpdate
Bases: ABC
Activate unused slots without changing the system capacity.
indices are distinct canonical slots that were inactive. Cross rows use
canonical ordering and are zero at previously inactive slots. Existing
active entries of the system and right-hand side must remain unchanged.
previous_capacity
abstractmethod
property
Materialized dimension before the update, including reserved slots.
gpex.linalg.CovarianceProjection
Bases: ABC
Reusable reductions for targets of one prepared system.
Implementations own their numerical representation and expose it as dynamic PyTree leaves. Cross reductions require projections from the same system.
gram
abstractmethod
diagonal
abstractmethod
cross_gram
abstractmethod
gpex.linalg.CholeskyProjection
Bases: Module, CovarianceProjection
Factors for a symmetric bilinear covariance reduction.
Dense systems store factor = L⁻¹ C. Cross reductions require
projections from the same system.
All factors are dynamic leaves, including across an outer JIT boundary.
gram
diagonal
Return the reduction diagonal without a query-sized matrix.
cross_gram
Return the cross reduction for two targets of the same system.
Moment assembly
gpex.moments assembles prior means and covariances of linear functionals in
canonical block order. These functions accept public blocks or reusable
PreparedFunctionals from gpex.moments.measurements. Preparation groups
compatible operators and retains activity and ordering information.
assemble_covariance supports tiled evaluation while still returning the full
dense matrix. assemble_covariance_diagonal evaluates only the diagonal.
Inactive reserved entries are zero. These functions evaluate arrays and can be
wrapped in an outer JIT with their consumers.
gpex.moments
Gaussian mean and covariance assembly for linear functionals.
apply_covariance
apply_covariance(
blocks: Functionals,
kernel: ScalarKernel,
right_hand_side: FunctionalColumns,
*,
tile_size: int = 128,
) -> FunctionalColumns
Apply latent covariance to canonical rows without constructing its matrix.
Accept vectors or arrays with leading dimension equal to the scalar
functional size. Inactive inputs are ignored and inactive outputs are zero.
One operator output is indivisible and can exceed tile_size. Pairwise
tiles are recomputed in reverse mode, bounding working storage in both
directions. Supports JIT, vmap, and differentiation of numerical inputs.
General kernels still require quadratic pairwise work per application.
Source code in src/gpex/moments/assembly.py
assemble_mean
Apply each functional to the mean and return canonical scalar ordering.
Accept public blocks or prepared groups. Inactive reserved entries are zero. Supports JIT, vmap, and differentiation of numerical inputs.
Source code in src/gpex/moments/assembly.py
assemble_covariance
assemble_covariance(
left_blocks: Functionals,
right_blocks: Functionals,
kernel: ScalarKernel,
*,
tile_size: int | None = None,
) -> FlatCovariance
Materialize covariance, optionally bounding pairwise working tiles.
Tiles traverse numerical operator groups rather than public blocks. One
operator output is never split. The final dense matrix is still allocated.
With None, each complete group pair is vectorized.
Source code in src/gpex/moments/assembly.py
assemble_covariance_diagonal
Assemble the prior diagonal without allocating a full covariance.
Source code in src/gpex/moments/assembly.py
Covariance operator
CovarianceSystem describes an observation covariance including block noise,
jitter, and reserved inactive slots. Backends can consume it through the
SymmetricLinearOperator interface:
product = system.matmul(rhs, tile_size=128)
diagonal = system.diagonal()
matrix = system.materialize(tile_size=128)
rhs has shape (capacity, *columns) in canonical order. Multiplication
accumulates tiles directly and passes inactive inputs through as identity rows.
The diagonal contains ones in inactive slots. This differs from prepared
solve, which ignores inactive inputs. Tile widths count scalar outputs, but
one operator output is indivisible. Tile size is static under JIT.
Products support JIT, vmap, and numerical differentiation. Pairwise intermediates are recomputed in reverse mode so differentiation also avoids full covariance storage. General kernels still require quadratic pairwise work. Dense Cholesky remains the only backend, and likelihood evaluation remains exact.
gpex.covariance_systems.CovarianceSystem
Bases: Module, SymmetricLinearOperator
A stabilized GP covariance exposed as generic linear-algebra operations.
variance contains measurement-error variances in canonical scalar-output order.
diagonal_shift
matmul
Apply covariance, noise, and jitter using bounded pairwise tiles.
Inputs have shape (capacity, *columns) in canonical order. Inactive
slots act as independent identity rows, unlike a prepared solve which
ignores inactive inputs. Supports JIT, vmap, and differentiation.
Source code in src/gpex/covariance_systems.py
diagonal
Return the stabilized diagonal, including unit inactive entries.