NumericAL
A pure, header-only C++20 numerical computing library — a leaf of the SciLang ecosystem (a sibling of REAL), generic over its scalar type and depending on nothing but the C++ standard library.
NumericAL is agnostic of expressions and of any symbolic layer: it computes with concrete numeric structures — vectors, matrices, tensors — and the algorithms over them. SciLang consumes it as a numeric backend through its module seam; the symbolic↔numeric reconciliation stays in SciLang.
Capabilities
Small and complete, grown measured, honest about what is not yet here:
numerical::vector<T>— a dense, value-semantic vector: element-wise arithmetic, scalar multiplication, dot product, tolerance comparison, shape checks.numerical::matrix<T>— a dense, row-major, value-semantic matrix: element-wise arithmetic, scalar / matrix–vector / matrix–matrix products, transpose, tolerance comparison, shape checks.numerical::lu_decomposition<T>— an LU factorisation (partial pivoting) computed once and reused:solve(any number of right-hand sides),determinant, andinverse. Freesolve/determinant/inverseare one-shot conveniences.numerical::cholesky_decomposition<T>—A = L Lᴴfor a Hermitian positive-definite matrix (about twice as cheap as LU): the factorlower(),solve, anddeterminant; throwsnot_positive_definite_errorotherwise.numerical::qr_decomposition<T>—A = Q R(Householder reflections, soQstays orthonormal to rounding however ill-conditionedAis) for anm × nmatrix withm ≥ n: the factorsq()/r()and a least-squaressolveofA x ≈ b, which throwssingular_matrix_errorwhenAis rank-deficient.numerical::symmetric_eigen— eigenvalues (ascending) and eigenvectors of a real symmetric matrix by cyclic Jacobi rotations (A = V Λ Vᵀ).numerical::svd_decomposition<T>— the singular value decompositionA = U Σ Vᴴof a real or complexm × nmatrix, any shape: a Householder QR, then one-sided Jacobi onR, so every singular value comes to high relative accuracy, the small ones too.singular_values()(descending),u()(m × k),v()(n × k) andvh(), withk = min(m, n);UandVstay orthonormal for a rank-deficientA.numerical::lstsq(a, b)— the minimum-norm least-squares solution ofA x ≈ b, as NumPy'slstsqgives it, for any shape and rank (from the SVD);pinv(a)andmatrix_rank(a)from the same SVD, andlu_decomposition::log_determinant()— NumPy'sslogdet, which does not underflow where the determinant does.numerical::tensor<T>— a dense, row-major, N-dimensional tensor (rank-1 is a vector, rank-2 a matrix, rank-0 a scalar; built directly or from avector/matrix), witheinsum— Einstein-summation index notation for contractions and general products, as in NumPy / PyTorch.einsumis the unifying primitive of the algebra:"ij,jk->ik"is the matrix product,"i,i->"the dot product,"ij->ji"the transpose,"ii->"the trace,"i,j->ij"the outer product,"ij->i"a row reduction. It takes one or more operands and sums over every label absent from the output, in a deterministic order.
Grows in as measured: sparse storage, complex Hermitian eigen, non-symmetric eigenvalues, FFT, numeric autodiff, iterative solvers, numerical integration, arbitrary precision.
Build
make test # build and run the test suite
make coverage # line-coverage summary + HTML report
make sanitize # tests under AddressSanitizer + UndefinedBehaviorSanitizer
make lint # clang-tidy
make format # uncrustify, in place
make doc # API reference (Doxygen) with embedded coverage
Override the compiler with make test CXX=g++-14.
numerical::numerical is the CMake target — add_subdirectory, FetchContent, or an
installed config package:
# After `cmake --install <build> --prefix <prefix>`:
find_package(numerical CONFIG REQUIRED)
target_link_libraries(app PRIVATE numerical::numerical)
Releasing
make release computes the next calendar version YYYY.M.PATCH — the patch
resets each month, the first release of a month is .0 (PEP 440 drops leading
zeros, so 2026.6.1, never 2026.06.001) — bumps it in pyproject.toml and
python/numerical/__init__.py, then commits, tags and pushes from a clean main.
Pushing the tag drives release.yml, which checks the tag matches the version,
builds the abi3 wheels (Linux x86-64/aarch64, macOS universal, Windows) and the
sdist, and publishes to PyPI via Trusted Publishing (OIDC, no stored secret).
One-time PyPI setup (before the first release): create a
Trusted Publisher for the project
numeric-al — owner RECHE23, repository NumericAL, workflow release.yml,
environment pypi — and create the matching GitHub Environment named pypi.
Until that exists the build/sdist jobs still run, but the publish step fails;
the pushed tag remains a valid versioned snapshot regardless.
Python binding
pip install numeric-al # the distribution is numeric-al; the module is numerical
A CPython binding (stable ABI, one cp310 abi3 wheel serves 3.10+) exposes the
unifying object numerical.Tensor (rank-1 a vector, rank-2 a matrix, rank-0 a
scalar; float64 or complex128) and the algebra over it:
import numerical
a = numerical.Tensor([1, 2, 3, 4], shape=(2, 2))
b = numerical.Tensor([5, 6, 7, 8], shape=(2, 2))
numerical.einsum("ij,jk->ik", a, b) # matrix product
numerical.einsum("i,i->", numerical.Tensor([1, 2, 3]), numerical.Tensor([1, 2, 3])) # dot
numerical.solve(a, numerical.Tensor([1.0, 1.0])) # a @ x = b
The decomposition layer is exposed too (a numpy.linalg-style surface):
determinant(a), slogdet(a) → (sign, logabsdet), inverse(a), pinv(a),
matrix_rank(a), lstsq(a, b), cholesky(a), qr(a) → (Q, R),
eigh(a) → (values, vectors), svd(a) → (U, S, Vh) — NumPy's
svd(a, full_matrices=False), so (U * S) @ Vh is a. Every one accepts float64
and complex128 but eigh, which is float64 only (matching the C++ layer).
A Tensor is a citizen of the scientific Python stack, zero-copy:
import numpy as np, torch
np.asarray(t) # via __array_interface__ (a read-only view)
np.from_dlpack(t) # via __dlpack__
torch.from_dlpack(t) # the same DLPack capsule — JAX / CuPy consume it too
numerical.asarray(np.eye(3)) # the other direction (a copy)
asarray copies any NumPy array — bool, integer, float32/64 or complex64/128 elements, in either
byte order, at any strides (a transposed, sliced or reversed view) — as well as a nested list or
tuple of numbers and a plain number (rank 0), into float64, or complex128 for complex input.
numerical.get_include() returns the header directory, so the C++ library can be
located through its Python install. make python builds the extension in place;
make python-test runs the binding suite — including a seeded differential
fuzzer that checks hundreds of random einsum specifications and linear-algebra
problems against NumPy within tolerance (when NumPy is importable, as in CI). PETSc (petsc4py) has no such exchange protocol — bridging it
would require an explicit copy into a PETSc object.
Benchmarks
NumericAL is validated against NumPy for both result and speed — make bench-python checks every operation matches NumPy within a tolerance, then times
it; make python-test runs the correctness parity suite alone (also in CI). The
results and methodology, with an honest reading of the gap, are in
BENCHMARKS.md: NumericAL is a portable, dependency-free reference
implementation: correct within tolerance, and competitive with NumPy's own
einsum/linalg (it beats np.einsum's non-BLAS path and the decompositions
land within ~1–4×). Against hand-tuned BLAS (np.matmul) its cache-blocked,
std::thread-parallel GEMM is ~10× slower but steady (no cache cliff) — that gap
is BLAS's per-architecture SIMD micro-kernel, which a header-only library does not
chase. See BENCHMARKS.md for the honest details.
Numerical discipline
Floating-point accuracy is documented, never claimed exact where it cannot be; results are deterministic given inputs and any tolerance/seed; differential tests compare against references within a documented tolerance. Same gate bar as the rest of the ecosystem: 100% coverage, clang and g++-14, lint, format, and sanitizers green.
License
MIT — see LICENSE.
Author
René Chenard
Metadata
Release files for numeric-al 2026.10.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| numeric_al-2026.10.1.tar.gz | 21.0 kB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| numeric_al-2026.10.1-cp310-abi3-win_amd64.whl | CPython 3.10 | abi3 | Windows x86-64 | Details |
| numeric_al-2026.10.1-cp310-abi3-win32.whl | CPython 3.10 | abi3 | Windows x86-32 | Details |
| numeric_al-2026.10.1-cp310-abi3-musllinux_1_2_x86_64.whl | CPython 3.10 | abi3 | Linux musl 1.2+ x86-64 | Details |
| numeric_al-2026.10.1-cp310-abi3-musllinux_1_2_aarch64.whl | CPython 3.10 | abi3 | Linux musl 1.2+ ARM64 | Details |
| numeric_al-2026.10.1-cp310-abi3-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl | CPython 3.10 | abi3 | Linux glibc 2.24+ x86-64, Linux glibc 2.28+ x86-64 | Details |
| numeric_al-2026.10.1-cp310-abi3-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl | CPython 3.10 | abi3 | Linux glibc 2.24+ ARM64, Linux glibc 2.28+ ARM64 | Details |
| numeric_al-2026.10.1-cp310-abi3-macosx_11_0_x86_64.whl | CPython 3.10 | abi3 | macOS 11.0+ x86-64 | Details |
| numeric_al-2026.10.1-cp310-abi3-macosx_11_0_arm64.whl | CPython 3.10 | abi3 | macOS 11.0+ ARM64 | Details |
Total release size: 8.0 MB
Release files / numeric_al-2026.10.1.tar.gz
| Download URL | numeric_al-2026.10.1.tar.gz |
|---|---|
| Size | 21.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e5e2945b7009174cd1caa6a02d9750206b751c97a1d74c6d3d98285f5d6fc285
|
|
BLAKE2b-256 checksum How to use checksums |
1aaffb511a11135858ec0b78d677c0f05f2a016c2c447d13cdbf5934d1951dbb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
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 / numeric_al-2026.10.1-cp310-abi3-win_amd64.whl
| Download URL | numeric_al-2026.10.1-cp310-abi3-win_amd64.whl |
|---|---|
| Size | 319.3 kB |
| Tags | CPython 3.10 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
206275d69bec0d30def3a1e7f70ab8b628314605b4775e3e45a61f53e51c3575
|
|
BLAKE2b-256 checksum How to use checksums |
82a0f0ba1c11828bc3d524cfccad0261e07a4b7e4011cfbd9bcf87a1747728d4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
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 / numeric_al-2026.10.1-cp310-abi3-win32.whl
| Download URL | numeric_al-2026.10.1-cp310-abi3-win32.whl |
|---|---|
| Size | 312.8 kB |
| Tags | CPython 3.10 Windows x86-32 abi3 |
|
SHA-256 checksum How to use checksums |
b7d6d44f4025f333ec71fdd2bd26813265b51b91d047468db9c439eb06e90864
|
|
BLAKE2b-256 checksum How to use checksums |
0cf1a296f315d035a61ca7a9f79fcde7b9cb46c192dfa613e0da0518736d411e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
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 / numeric_al-2026.10.1-cp310-abi3-musllinux_1_2_x86_64.whl
| Download URL | numeric_al-2026.10.1-cp310-abi3-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 2.3 MB |
| Tags | CPython 3.10 Linux musl 1.2+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
9cfcee4ea57119316f786348192aa11d236cade357a62f8bdef44b46b82d1292
|
|
BLAKE2b-256 checksum How to use checksums |
99989c5d5857411a7545db62610d6f8c06c64708fc394d01ff128642b49c43c9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
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 / numeric_al-2026.10.1-cp310-abi3-musllinux_1_2_aarch64.whl
| Download URL | numeric_al-2026.10.1-cp310-abi3-musllinux_1_2_aarch64.whl |
|---|---|
| Size | 2.2 MB |
| Tags | CPython 3.10 Linux musl 1.2+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
5f9b6cd2abe3350a78a607b6b6252c42074629423dbd41669745b8c1d6443366
|
|
BLAKE2b-256 checksum How to use checksums |
af7ce6f1706366a9b118c518a6bd0a04efc782a286de6113a28f1addb1809871
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
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 / numeric_al-2026.10.1-cp310-abi3-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
| Download URL | numeric_al-2026.10.1-cp310-abi3-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 1.3 MB |
| Tags | CPython 3.10 Linux glibc 2.24+ x86-64 Linux glibc 2.28+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
cdd8254e02d33eb27267c7d4ac451ee10560d4012a55efcb9591219d02c9373b
|
|
BLAKE2b-256 checksum How to use checksums |
150245258e391ccf498769096a300d8b155dd802bc523f6adc1c873501d5ef68
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
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 / numeric_al-2026.10.1-cp310-abi3-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl
| Download URL | numeric_al-2026.10.1-cp310-abi3-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl |
|---|---|
| Size | 1.2 MB |
| Tags | CPython 3.10 Linux glibc 2.24+ ARM64 Linux glibc 2.28+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
aa3efe6b6e4f42d66053e913abbde9752a56f0e543385830a997028bb4dd11a5
|
|
BLAKE2b-256 checksum How to use checksums |
04ac6f99a064757f882603badf9d9d96a7c83c10c76311d8b5c8d5dc72a5a9eb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
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 / numeric_al-2026.10.1-cp310-abi3-macosx_11_0_x86_64.whl
| Download URL | numeric_al-2026.10.1-cp310-abi3-macosx_11_0_x86_64.whl |
|---|---|
| Size | 147.9 kB |
| Tags | CPython 3.10 abi3 macOS 11.0+ x86-64 |
|
SHA-256 checksum How to use checksums |
26994b7788927dca2a45c91bbb72d654d256491a29741732811e31b598ee4329
|
|
BLAKE2b-256 checksum How to use checksums |
659e18cf8a9e86679cb6b3c704270687491bdf5ff37822b99ddb862da92226f9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
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 / numeric_al-2026.10.1-cp310-abi3-macosx_11_0_arm64.whl
| Download URL | numeric_al-2026.10.1-cp310-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 136.1 kB |
| Tags | CPython 3.10 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
7434020e67f985d31dfaba4ee417eda37023ffa78f99c72dca0428a88a641bf7
|
|
BLAKE2b-256 checksum How to use checksums |
39287fb2fe6f8ef9e5b610e7ec195d0d442cf1a54e166c9581752ba46f866f8b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
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