splineax
Sparse linear operators and direct solvers for Lineax.
splineax lets you keep a linear system in its native sparse storage
(jax.experimental.sparse.BCOO / BCSR) and solve it with a sparse direct solver that
plugs straight into lineax.linear_solve. It also interfaces with asdex for calculating sparse Jacobians and using them as operators.
- Operators:
BCOOLinearOperatorandBCSRLinearOperatorto hold sparse matrices, and tags forlineax.JacobianLinearOperatorandlineax.FunctionLinearOperatorthat allow solvers to materialize them as sparse matrices via asdex. - Stateful solver protocols:
StatefulSolverandSparseLinearSolverfor writing solver-agnostic code that reuses factorizations over many solves and operators. - Solver library bindings:
Spsolve(any backend),KLU(CPU-only, SuiteSparse KLU),Pardiso(CPU-only, Intel oneMKL Pardiso, installed as extra), andCuDSS(CUDA GPU-only, NVIDIA cuDSS, installed as extra).KLU,Pardiso, andCuDSSreuse their factorization across solves. - Higher-level solvers:
AutoSparseLinearSolver, which picks an appropriate solver based on platform and settings, andHybridDirectIterative, which combines a direct solver with an iterative solver that uses the factorization as its preconditioner. For example,IterativeRefinementapplies a Richardson iteration to the direct solver result in order to recover a high-precision solution using a limited-precision solver. - Lineax code interop:
stateful_solve_transformrewrites a function that callslineax.linear_solveso its solves thread a solver state and reuse a factorization.
Installation
pip install splineax
Example
Solve a 10000 x 10000 system. As a dense matrix it would need 10^8 entries, but kept sparse it has only ~3 x 10^4 nonzeros, and the solver never materialises the dense form.
import jax.numpy as jnp
import lineax as lx
import numpy as np
from jax.experimental.sparse import BCOO
import splineax as splx
n = 10000
np.random.seed(0)
# A large, randomly sparse matrix with a heavy diagonal (so it is invertible).
diagonal_indices = np.stack([np.arange(n), np.arange(n)], axis=1)
off_diagonal_indices = np.unique(np.random.randint(0, n, size=(2 * n, 2)), axis=0)
indices = jnp.concatenate([diagonal_indices, off_diagonal_indices])
values = jnp.concatenate(
[
np.full(n, float(n)),
np.random.uniform(low=-1, high=1, size=off_diagonal_indices.shape[0]),
]
)
matrix = BCOO((values, indices), shape=(n, n)).sum_duplicates()
operator = splx.BCOOLinearOperator(matrix)
vectors = [jnp.ones(n), jnp.arange(n) % 2]
solver = splx.AutoSparseLinearSolver()
# Solve once, then thread the returned state back in to reuse the factorization.
solution, state = splx.linear_solve(operator, vectors[0], solver)
assert jnp.allclose(matrix @ solution.value, vectors[0], atol=1e-4)
solution, state = splx.linear_solve(operator, vectors[1], solver, state=state)
assert jnp.allclose(matrix @ solution.value, vectors[1], atol=1e-4)
# Free the factorization when you are done with it.
state.release()
Testing on a GPU
CuDSS wraps NVIDIA's cuDSS library, which is CUDA-only, so its tests skip on ordinary
(CPU) CI. The easiest way to run them for real is
notebooks/colab_gpu_tests.ipynb:
Open it, pick a GPU runtime, and choose Run all. It clones a branch, installs the
locked environment with the cudss extra, and runs the test suite. On any other machine
with a CUDA 13 GPU, the same run is uv run --python 3.12 --extra cudss pytest tests. On
a GPU, the tests marked cpu_only skip, since they solve through KLU or Pardiso.
Documentation
Build the docs locally with uv run mkdocs serve, or view the user guide and API reference here.
Metadata
Release files for splineax 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| splineax-0.4.0.tar.gz | 81.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| splineax-0.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 174.4 kB
Release files / splineax-0.4.0.tar.gz
| Download URL | splineax-0.4.0.tar.gz |
|---|---|
| Size | 81.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8fa8a022655c4912604925f16a3712ce7c5974f29388c0f4eead6e27ddf521c5
|
|
BLAKE2b-256 checksum How to use checksums |
442a4f3cf73a81777d558404bc1b5bd8e36e0d1019b945b7fdc300d91ee512cf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.
Transparency logRelease files / splineax-0.4.0-py3-none-any.whl
| Download URL | splineax-0.4.0-py3-none-any.whl |
|---|---|
| Size | 93.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
cad2bf75a9106e8aadcbdb75f572ffc98a77b79e6520c22b159791307bfe7481
|
|
BLAKE2b-256 checksum How to use checksums |
adca74b5267f9be200e9c395e7a95830e33f1fde9360bd91a147b3e4491f4e4d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.
Transparency log