Skip to main content

Backend-agnostic vector spaces and linear operators.

Project description

SpaceCore

CI PyPI Python License

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

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

spacecore-0.2.0.tar.gz (85.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

spacecore-0.2.0-py3-none-any.whl (115.8 kB view details)

Uploaded Python 3

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

Hashes for spacecore-0.2.0.tar.gz
Algorithm Hash digest
SHA256 6274f9ecc8e2673a7c3423e73b03d137786dab1de4fa3e2dd6e8d56a87470cc7
MD5 6823a4377e32be6f2efa16e7d58abd1d
BLAKE2b-256 55250c0ee6f25025c41410e923cfdba4a654e242acbab5ccb555119832d4a1ed

See more details on using hashes here.

Provenance

The following attestation bundles were made for spacecore-0.2.0.tar.gz:

Publisher: ci.yml on Pavlo3P/SpaceCore

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for spacecore-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9a944acacbb3af2ae5e9f5c9f1ba699199951799f2e592d8ed0ae6738032af7a
MD5 70b3db96d4637144b0f15de4bea8aa5a
BLAKE2b-256 9e5e75167610d08cc23b31322bf6459a2d9cb4317dd521227e0c85cbdd043d64

See more details on using hashes here.

Provenance

The following attestation bundles were made for spacecore-0.2.0-py3-none-any.whl:

Publisher: ci.yml on Pavlo3P/SpaceCore

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page