Metadata-Version: 2.4
Name: spacecore
Version: 0.5.0
Summary: Backend-agnostic vector spaces and linear operators.
Author: Pavlo Pelikh
License-Expression: Apache-2.0
Keywords: linear-algebra,jax,pytorch,numpy,operators,spaces
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Mathematics
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: array-api-compat>=1.14.0
Requires-Dist: numpy>=2.0.0
Requires-Dist: optree>=0.17.0
Requires-Dist: typing-extensions>=4.12
Requires-Dist: scipy>=1.17
Provides-Extra: jax
Requires-Dist: jax>=0.9.1; extra == "jax"
Provides-Extra: torch
Requires-Dist: torch>=2.0; extra == "torch"
Provides-Extra: cupy
Requires-Dist: cupy>=13.0; extra == "cupy"
Provides-Extra: docs
Requires-Dist: sphinx>=8.0; extra == "docs"
Requires-Dist: matplotlib>=3.8; extra == "docs"
Requires-Dist: pydata-sphinx-theme>=0.16; extra == "docs"
Requires-Dist: sphinx-copybutton>=0.5; extra == "docs"
Requires-Dist: sphinx-design>=0.6; extra == "docs"
Requires-Dist: numpydoc>=1.8; extra == "docs"
Requires-Dist: ipython>=8.0; extra == "docs"
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-cov>=5; extra == "dev"
Requires-Dist: ruff>=0.6; extra == "dev"
Requires-Dist: numpydoc>=1.7; extra == "dev"
Requires-Dist: mypy>=1.19; extra == "dev"
Requires-Dist: pyright>=1.1.408; extra == "dev"
Dynamic: license-file

<h1>
  <img src="https://raw.githubusercontent.com/Pavlo3P/SpaceCore/master/docs/source/_static/spacecore-logo.svg" alt="SpaceCore logo" height="72" align="center">
  SpaceCore
</h1>

[![CI](https://github.com/Pavlo3P/SpaceCore/actions/workflows/ci.yml/badge.svg)](https://github.com/Pavlo3P/SpaceCore/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/spacecore.svg)](https://pypi.org/project/spacecore/)
[![Python](https://img.shields.io/pypi/pyversions/spacecore.svg)](https://pypi.org/project/spacecore/)
[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)

Building blocks for first-order optimization: spaces, geometry, linear operators,
functionals and proximal maps, on NumPy, JAX, Torch and CuPy.

The geometry lives in the space. Gradients, adjoints and proxes are taken in the
space's inner product, so an algorithm written once stays correct in a weighted or
operator metric, on matrices, Jordan algebras or nested trees. SpaceCore ships no
optimization loops: you write them in a few lines, or use
[spacecore-optimize](https://github.com/Pavlo3P/spacecore-optimize).

## Install

```bash
pip install spacecore            # NumPy backend
pip install "spacecore[jax]"     # or [torch], [cupy]
```

Python 3.11+.

## Example

```python
import numpy as np
import spacecore as sc

ctx = sc.Context(sc.NumpyOps(), dtype=np.float64)
X = sc.DenseCoordinateSpace((2,), ctx, geometry=sc.WeightedInnerProduct(ctx.asarray([2.0, 5.0])))
A = sc.DenseLinOp(ctx.asarray([[1.0, 2.0], [0.0, 1.0]]), X, X, ctx)
b = ctx.asarray([1.0, 2.0])

print(X.inner(b, b))   # 22.0: the weighted inner product 2*1 + 5*4
print(A.rapply(b))     # [1.  2.8]: the adjoint in this geometry, not A.T @ b = [1. 4.]

# Weighted lasso, minimize 1/2 ||A x - b||^2 + 0.1 ||x||_1, by proximal gradient.
f = sc.SquaredL2NormFunctional(X) @ A - sc.InnerProductFunctional(A.rapply(b), X, ctx)
g = 0.1 * sc.L1NormFunctional(X)
x, t = X.zeros(), 0.05
for _ in range(500):
    x = g.prox(X.axpy(-t, f.grad(x), x), t)
print(x)               # about [-2.83  1.94]
```

The loop is the algorithm; the space supplies the geometry it runs in.

## What is in it

- **Spaces:** dense vectors and matrices, Hermitian matrices and Jordan algebras,
  stacks, and trees of any of these; Euclidean, weighted and operator metrics.
- **Operators:** dense, sparse, diagonal, matrix-free and block operators, with
  lazy sums, scaling and composition; `rapply` is always the metric adjoint.
- **Functionals:** linear, quadratic and norm functionals, sums, products and
  pull-backs; gradients in the space's geometry; `prox` and `conjugate_prox`;
  sets and indicators.
- **Sub-step solvers:** CG, LSQR, Lanczos, power iteration, `expm_multiply`.
- **Backends:** NumPy, JAX, Torch, CuPy; the objects run inside `jax.jit` and
  `torch.compile`.

## Extending

A new space, operator or functional implements check-free cores (`_add_core`,
`_inner_core`, `_apply_core`, `_grad_core`, ...). The public methods (`add`,
`inner`, `apply`, `grad`, ...) are inherited wrappers that run the checks and call
the cores, and composites call cores, so each object checks once. See
[Extending](https://pavlo3p.github.io/SpaceCore/design/extending.html).

## Checks

Every object has a `check_level`: `"none"`, `"cheap"` (shape, dtype),
`"standard"` (membership, e.g. Hermiticity) or `"strict"` (+ probes). Set it per
object, or once with `sc.set_check_level` / `sc.use_check_level`. Failures raise
`sc.SpaceValidationError`. Inside `jax.jit` / `torch.compile` checks are capped by
`sc.set_traced_check_level` (default `"none"`).

## Docs

[Tutorials](https://pavlo3p.github.io/SpaceCore/tutorials/index.html) ·
[Design](https://pavlo3p.github.io/SpaceCore/design/index.html) ·
[API](https://pavlo3p.github.io/SpaceCore/api/index.html) ·
[Release notes](https://pavlo3p.github.io/SpaceCore/release_notes.html)

Experimental (0.x): the API may change before 1.0. Contributions welcome — see
[CONTRIBUTING.md](CONTRIBUTING.md). Apache 2.0.

```bibtex
@software{spacecore,
  author = {Pavlo Pelikh},
  title = {SpaceCore: Spaces, geometry and operators for first-order optimization},
  url = {https://github.com/Pavlo3P/SpaceCore},
  year = {2026},
}
```
