Backend-agnostic vector spaces and linear operators.
Project description
SpaceCore
Backend-agnostic vector spaces, linear operators, and iterative solvers for scientific computing.
Write your algorithm once. Run it on NumPy for development, JAX for GPU acceleration and autodiff, or PyTorch for ML pipelines — without changing a line.
import spacecore as sc
import numpy as np
# Define a space, a linear operator, and solve Ax = b
ctx = sc.Context(sc.NumpyOps(), dtype=np.float64)
X = sc.VectorSpace((100,), ctx)
A = sc.DenseLinOp(np.random.randn(100, 100) @ np.random.randn(100, 100).T + np.eye(100), X, X, ctx)
b = ctx.asarray(np.random.randn(100))
result = sc.cg(A, b, tol=1e-8)
print(f"Converged in {result.num_iters} iterations.")
Same code on JAX with GPU?
ctx = sc.Context(sc.JaxOps(), dtype=jnp.float64)
# ... build A and b the same way using jax arrays ...
result = sc.cg(A, b, tol=1e-8) # runs on GPU, JIT-compiled
Install
pip install spacecore # core (numpy only)
pip install "spacecore[jax]" # add JAX backend
pip install "spacecore[torch]" # add PyTorch backend
pip install "spacecore[jax,torch]" # both
Python 3.11+. Built on the Python Array API standard.
What is SpaceCore for?
SpaceCore is for people writing numerical algorithms — optimization, inverse problems, eigensolvers, quantum simulation, computational geometry — who don't want to choose between NumPy, JAX, and PyTorch.
Three things SpaceCore does well
1. Matrix-free linear operators with algebra. Write your operator once as apply and adjoint callables, then compose them:
# An FFT-based convolution operator, never materialized as a matrix
K = sc.MatrixFreeLinOp(apply=fft_convolve, rapply=fft_convolve_adjoint, dom=X, cod=X, ctx=ctx)
grad = sc.MatrixFreeLinOp(apply=finite_diff, rapply=neg_div, dom=X, cod=Y, ctx=ctx)
# Build the regularized system operator using algebra
lam = 0.01
system = K.H @ K + lam * grad.H @ grad # SumLinOp of ComposedLinOps
rhs = K.H.apply(b)
# Solve — no matrices were assembled
solution = sc.cg(system, rhs).x
2. Cross-backend iterative solvers. CG, LSQR, Lanczos, power iteration — all work uniformly across NumPy, JAX, and PyTorch. JAX backends JIT-compile:
ctx = sc.Context(sc.JaxOps(), dtype=jnp.complex128)
A = build_hermitian_operator(ctx)
# Find the smallest eigenpair via Lanczos
result = sc.lanczos_smallest(A, initial_vector, max_iter=50)
print(f"E_0 = {result.eigenvalue}, converged={result.converged}")
3. Custom Hilbert spaces with non-Euclidean geometry. Subclass VectorSpace, override inner, and every solver respects your geometry:
class WeightedL2(sc.VectorSpace):
def __init__(self, shape, weights, ctx=None):
super().__init__(shape, ctx)
self.weights = self.ctx.asarray(weights)
def inner(self, x, y):
return self.ops.vdot(x, self.weights * y)
# CG, LSQR, Lanczos all use this inner product automatically
This is the basis for RKHS spaces, truncated Fock spaces (quantum many-body), function spaces with quadrature, and anything else where the geometry isn't sum(x * y).
Quick examples
Conjugate gradient on a symmetric positive-definite system
import spacecore as sc
ctx = sc.Context(sc.NumpyOps(), dtype=np.float64)
X = sc.VectorSpace((1000,), ctx)
A = sc.DenseLinOp(make_spd_matrix(), X, X, ctx)
b = ctx.asarray(rhs)
result = sc.cg(A, b, tol=1e-10, maxiter=500)
print(f"x = {result.x}, residual = {result.residual_norm}")
Least-squares with regularization
# min ||Ax - b||^2 + λ||x||^2 via normal equations
I = sc.IdentityLinOp(X)
system = A.H @ A + lam * I
rhs = A.H.apply(b)
x_hat = sc.cg(system, rhs).x
Smallest eigenpair of a Hermitian operator
result = sc.lanczos_smallest(A, initial_vector, max_iter=100)
print(f"E_0 ≈ {result.eigenvalue}")
print(f"Krylov dimension used: {result.krylov_dim}")
print(f"Converged: {result.converged}")
Building a custom operator
class Convolution(sc.LinOp):
def __init__(self, kernel, space, ctx):
super().__init__(space, space, ctx)
self.kernel = kernel
def apply(self, x):
return self.ops.real(self.ops.fft.ifft(self.ops.fft.fft(x) * self.ops.fft.fft(self.kernel)))
def rapply(self, y):
return self.ops.real(self.ops.fft.ifft(self.ops.fft.fft(y) * self.ops.conj(self.ops.fft.fft(self.kernel))))
This operator works on NumPy, JAX, and PyTorch backends without modification.
How is SpaceCore different from...?
...scipy.sparse.linalg? SciPy's iterative solvers are great but tied to NumPy/SciPy. SpaceCore gives you the same algorithms across NumPy, JAX, and PyTorch, plus operator algebra (A @ B + lam * I actually returns a usable operator), plus first-class custom Hilbert spaces.
...PyLops? PyLops is excellent for inverse problems but assumes Euclidean vectors and is tied to NumPy/CuPy. SpaceCore handles non-Euclidean geometry (RKHS, weighted spaces, function spaces) and works on JAX/PyTorch for autodiff and ML pipelines.
...QuTiP? QuTiP is the standard for quantum optics on top of SciPy. SpaceCore lets you build the same quantum operators on JAX or PyTorch for GPU acceleration and gradient-based parameter learning. Less prebuilt, more composable.
...array_api_compat? That package gives you portable arrays. SpaceCore builds on top of it to give you portable vector spaces, linear operators, and iterative algorithms — the abstractions one level up from arrays.
Documentation
- API Reference — Full documentation
Features at a glance
Spaces. VectorSpace, HermitianSpace, ProductSpace, BatchSpace. All easy to subclass for custom geometry.
Linear operators. DenseLinOp, SparseLinOp, DiagonalLinOp, MatrixFreeLinOp, plus operator algebra (A @ B, A + B, 2 * A, A.H, IdentityLinOp, ZeroLinOp).
Functionals. LinearFunctional, QuadraticForm, with value, grad, hess_apply, and compose(linop) for pull-back.
Iterative solvers. cg, lsqr, lanczos_smallest, power_iteration.
Backends. NumPy (always), JAX (spacecore[jax]), PyTorch (spacecore[torch]), CuPy (spacecore[cupy]). Adding a backend is ~100 LOC; the registry is public.
Project status
v0.2 alpha. API may still change in minor ways. Core abstractions are stable. Suitable for research code; not yet recommended for production deployment.
The library is being developed in the open and is looking for early users and feedback. If you try it on your problem, please open an issue with what worked and what didn't — that's the single most valuable contribution right now.
Contributing
Bug reports, feature requests, and PRs welcome. See CONTRIBUTING.md.
Specific areas where help is wanted:
- Tutorials. If SpaceCore solves your problem, a notebook example helps everyone.
- Backends. CuPy and Dask integration is partial; adding a new backend is well-scoped (~100 LOC).
- Performance. Cross-backend benchmarks on real workloads.
- Documentation. Concept pages, FAQ, gotchas.
License
Apache 2.0. See LICENSE.
Citation
If SpaceCore is useful in your research, a citation is appreciated:
@software{spacecore,
author = {Pavlo, Pelikh},
title = {SpaceCore: Backend-agnostic vector spaces and linear operators},
url = {https://github.com/Pavlo3P/SpaceCore},
year = {2026},
}
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file spacecore-0.2.0.tar.gz.
File metadata
- Download URL: spacecore-0.2.0.tar.gz
- Upload date:
- Size: 85.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6274f9ecc8e2673a7c3423e73b03d137786dab1de4fa3e2dd6e8d56a87470cc7
|
|
| MD5 |
6823a4377e32be6f2efa16e7d58abd1d
|
|
| BLAKE2b-256 |
55250c0ee6f25025c41410e923cfdba4a654e242acbab5ccb555119832d4a1ed
|
Provenance
The following attestation bundles were made for spacecore-0.2.0.tar.gz:
Publisher:
ci.yml on Pavlo3P/SpaceCore
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
spacecore-0.2.0.tar.gz -
Subject digest:
6274f9ecc8e2673a7c3423e73b03d137786dab1de4fa3e2dd6e8d56a87470cc7 - Sigstore transparency entry: 1637353640
- Sigstore integration time:
-
Permalink:
Pavlo3P/SpaceCore@f7d7f4104cff973c3da50842d57d25ffde155663 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/Pavlo3P
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@f7d7f4104cff973c3da50842d57d25ffde155663 -
Trigger Event:
push
-
Statement type:
File details
Details for the file spacecore-0.2.0-py3-none-any.whl.
File metadata
- Download URL: spacecore-0.2.0-py3-none-any.whl
- Upload date:
- Size: 115.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9a944acacbb3af2ae5e9f5c9f1ba699199951799f2e592d8ed0ae6738032af7a
|
|
| MD5 |
70b3db96d4637144b0f15de4bea8aa5a
|
|
| BLAKE2b-256 |
9e5e75167610d08cc23b31322bf6459a2d9cb4317dd521227e0c85cbdd043d64
|
Provenance
The following attestation bundles were made for spacecore-0.2.0-py3-none-any.whl:
Publisher:
ci.yml on Pavlo3P/SpaceCore
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
spacecore-0.2.0-py3-none-any.whl -
Subject digest:
9a944acacbb3af2ae5e9f5c9f1ba699199951799f2e592d8ed0ae6738032af7a - Sigstore transparency entry: 1637353922
- Sigstore integration time:
-
Permalink:
Pavlo3P/SpaceCore@f7d7f4104cff973c3da50842d57d25ffde155663 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/Pavlo3P
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@f7d7f4104cff973c3da50842d57d25ffde155663 -
Trigger Event:
push
-
Statement type: