Skip to main content
precise-numpy logo

precise-numpy

Interval arithmetic with guaranteed error bounds for Python, powered by Rust.

PyPI Version Python Versions License: MIT Rust


Overview

precise-numpy is a Python library for numerical computing with provable error bounds. Every element is an interval stored as (midpoint, radius); every operation propagates both values with hardware-directed rounding (MXCSR on x86_64), so results carry a rigorous enclosure of the true mathematical value.

This is not a drop-in replacement for NumPy — arrays track two f64 values per element and intervals behave differently from plain floats (see Semantics). It is a fast, NumPy-flavored API for interval arithmetic.

Key capabilities:

  • Hardware-directed rounding (MXCSR on x86_64) for guaranteed mathematical enclosures.
  • Parallel GEMM microkernels (assembly dgemm via matrixmultiply) + Rayon for the midpoint pass; the radius pass is a branch-free RTN accumulation partitioned across the same thread pool.
  • NumPy-like API: creation, indexing, broadcasting, reductions, stacking, linalg (rigorous eig/svd/pinv plus interval LU solve), random, I/O.
  • GIL release during long computations.

Installation

pip install precise-numpy

Build from source:

git clone https://github.com/your-org/precise-numpy.git
cd precise-numpy
maturin develop --release

Requires Python >= 3.10 and a Rust toolchain. Wheels are built for CPython (abi3).


Quick Start

import precise_numpy as pnp

# Create interval arrays with error bounds
a = pnp.array([0.1, 0.2, 0.3], error=1e-4)
b = pnp.array([0.4, 0.5, 0.6], error=1e-4)

# Arithmetic propagates both midpoints and radii
c = a + b
print(c.radii())            # [2e-4, 2e-4, 2e-4]
print(c.max_radius())       # 2e-4

# Reductions return (midpoint, radius) tuples
mid, err = c.sum()
print(f"sum = {mid} +/- {err}")

# Inspect error growth
print("max relative error:", c.max_relative_error())

Semantics

  • Values: get(i), a[0], sum(), etc. return a (midpoint, radius) tuple. To get raw float arrays use a.values() / a.radii().
  • == / != mean interval overlap; <, <=, >, >= use strict endpoint ordering (a.hi < b.lo, etc.).
  • Division by zero raises a RuntimeWarning and produces the entire real line (radius inf) for the affected element.
  • len(a) is a.shape[0], matching NumPy.
  • Reductions (sum, mean, ...) support an optional axis argument; scalar results come back as (midpoint, radius) tuples, axis results as IntervalArrays.
  • dtype is "interval64", itemsize is 16 (two f64s per element).
  • Rounding (round) uses round-half-to-even, like Python and NumPy.
  • reshape(-1, ...) infers the missing dimension; transpose/.t support 1D/2D.

API Reference

Array creation

array(values, error=0.0), asarray, zeros(shape), ones, empty, full(shape, value, error=0.0), eye(n, m=None, k=0), identity(n), diag(v), arange(start, stop, step=1.0), linspace(start, stop, num=50, endpoint=True), from_raw_parts(midpoints, radii, shape). empty(shape) deliberately zeros memory: uninitialised radii would break the rigorous enclosure guarantee (zeros + zero radius = exact zeros, a sound result for any operation). to_numpy(a, dtype=None) and from_numpy(a, error=scalar_or_array) convert between IntervalArrays and NumPy ndarrays.

Properties & conversions

shape, ndim, size, dtype ("interval64"), itemsize (16), nbytes, strides, t, values(), radii(), tolist(), get(i), item(i), midpoint(i), radius(i), copy(), flatten(), ravel(), reshape(*shape), transpose(), sort(), argsort(). __array__(dtype=None) (NEP18) — returns a plain float64 ndarray of midpoints so np.asarray(pnp_array) and np + pnp_array work naturally. Use to_numpy() explicitly; convert back with from_numpy(np_array, error=...).

Indexing

Integer (with negatives), slices (a[1:4], a[::-1]), fancy integer lists (a[[0, 2]]), boolean masks (a[a > 2.0], a[BoolArray]), and 2D tuples (m[1, :], m[:, 0]). Assignment works for integers, slices, and lists.

Arithmetic & math

+ - * / ** @, in-place variants, scalar operands on either side, NumPy broadcasting. sin, cos, tan, exp, ln, log2, log10, sqrt, abs, floor, ceil, trunc, round, clip(a_min, a_max), sign, nan_to_num, power(x, y), maximum(x, y), minimum(x, y).

Comparisons

==, != (overlap), <, <=, >, >= (strict ordering) return BoolArray values with & | ^ ~, any(), all(), sum(), count_nonzero(), tolist().

Reductions

sum, mean, prod, var, std, min, max, argmin, argmax, all, any — each with an optional axis; plus min_val(), max_val(), cumsum(axis=None), norm(ord=None, axis=None) with numpy-compatible ord in {None/2/'fro', 1, -1, inf, -inf, 'nuc'} and int axis.

Stacking & selection

concatenate(arrays, axis=0), stack, vstack, hstack, split(a, sections_or_indices, axis=0), where(condition, x, y), nonzero(a) (tuple of index lists per axis).

Linear algebra (precise_numpy.linalg)

det, inv, solve(A, b), lstsq(A, b), pinv, eig, svd, norm.

Notes: eig/eig_general returns real numbers. eig_symmetric (Jacobi) returns rigorous eigenvalue and eigenvector enclosures. eig_general (Hessenberg QR) returns rigorous eigenvalue radii; eigenvector radii are returned as inf because the true eigenspace width is unbounded without symmetry (sound but conservative). svd returns rigorous singular value and singular vector enclosures (Davis–Kahan). pinv is rigorous via interval reciprocals of singular values. solve uses rigorous LU+forward/back substitution.

Random (precise_numpy.random)

seed, rand(*size), random_sample(*size), random(*size), randn(*size), randint(low, high, *size), uniform(low, high, *size), normal(loc=0.0, scale=1.0, *size). Deterministic xoshiro256** generator; no size argument returns a Python float.

File I/O

save(path, arr) / load(path) (binary) and savetxt(path, arr, fmt="%.17g") / loadtxt(path) (text with a shape header). Both round-trip midpoints and radii.


Error-Bound Example: AI Quantization Audit

import precise_numpy as pnp

# Wrap input data with interval error bounds
X = pnp.array(floats, error=1e-4).reshape([128, 64])
W = pnp.array(weights).reshape([64, 64])

# Propagate error through a linear layer
Q = X.matmul(W)

print("Max Radius Error:", Q.max_radius())
print("Max Relative Error:", Q.max_relative_error())

See examples/quantization_safety_audit.py and examples/precision_audit_test.py.


Performance Notes

Element-wise ops with zero input radii (error=0.0) are ~1.1–2× the cost of equivalent NumPy element-wise work because each arithmetic step rounds up the enclosure radius. matmul (1000×1000) runs in ~0.14s in release mode with four lightweight dgemm-based radius passes; plain NumPy/OpenBLAS is ~0.02s on the same machine but carries no error bound. Operation counts for the radius pass are strictly larger than the midpoint pass, which is why rigorous bounds cost more than plain FP multiplication.

When inputs have non-zero radii (error=1e-4, etc.) the relative price of the radius pass does not grow; it is purely a function of M×N×K.


Technical Architecture

  1. Structure-of-Arrays (SoA) buffer: midpoints and radii stored in 64-byte aligned contiguous memory for efficient cache-line loads.
  2. Two-pass matmul: the midpoint pass is a single dgemm call (assembly GEMM microkernels via matrixmultiply); the radius pass is a branch-free round-to-nearest accumulation split into three additional dgemm calls plus a scalar inflation factor (O(1) per element), executed on the same thread pool.
  3. Shared buffers: IntervalArray clones, slices, and reshapes are O(1) reference-counted.
  4. GIL release: long-running kernels run under py.allow_threads() with Rayon parallelism.
  5. No external dependencies at runtime; pure Rust + pyo3. (NumPy is an optional test dependency only.)

Testing

cargo test          # Rust unit tests (arithmetic, linalg, reduction, extra, random)
python -m unittest tests/python/test_api.py   # Python integration tests

License

MIT License. See LICENSE for details.

Metadata

Release files for precise-numpy 0.2.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for precise-numpy 0.2.4
File Size Uploaded Provenance
precise_numpy-0.2.4.tar.gz 478.2 kB Without provenance Details

Built distributions (wheels)

Table of built distributions (wheels) for precise-numpy 0.2.4
File
precise_numpy-0.2.4-cp310-abi3-win_amd64.whl CPython 3.10 abi3 Windows x86-64 Details
precise_numpy-0.2.4-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.10 abi3 Linux glibc 2.17+ x86-64 Details
precise_numpy-0.2.4-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.10 abi3 Linux glibc 2.17+ ARM64 Details
precise_numpy-0.2.4-cp310-abi3-macosx_11_0_arm64.whl CPython 3.10 abi3 macOS 11.0+ ARM64 Details
precise_numpy-0.2.4-cp310-abi3-macosx_10_12_x86_64.whl CPython 3.10 abi3 macOS 10.12+ x86-64 Details

Total release size: 2.7 MB

Release files / precise_numpy-0.2.4.tar.gz

Download URL precise_numpy-0.2.4.tar.gz
Size 478.2 kB
Tags Source
SHA-256 checksum
How to use checksums
cf9e45d55b5bac757c235d0c26a952517229198e64cb25c12aa217ba19e9a34b
BLAKE2b-256 checksum
How to use checksums
cb87bf8b8f38cae33bf61e92d29221ae4618a8aa6aa1d4b693bf71ae13bb61d8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / precise_numpy-0.2.4-cp310-abi3-win_amd64.whl

Download URL precise_numpy-0.2.4-cp310-abi3-win_amd64.whl
Size 405.8 kB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
8a3ca65e74b096ddfb95f001f8a8395ca5bafdb22e1727be46e54014dd1d686f
BLAKE2b-256 checksum
How to use checksums
5aff10b860645c3dca91e8b235e46a68c1bca6c0e813c03baaab20a802b62250
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / precise_numpy-0.2.4-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL precise_numpy-0.2.4-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 512.8 kB
Tags CPython 3.10 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
de68d49e9fe69544360c1745087f804c1335ff8a45173daa3fff1e8cbf781606
BLAKE2b-256 checksum
How to use checksums
b84d36bb63e61d6ab7fbb87eff4abbe6a1c869824d0cd8d9a22b3ceb3e94b459
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / precise_numpy-0.2.4-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL precise_numpy-0.2.4-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 451.1 kB
Tags CPython 3.10 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
f1b13dbe78a7d2b4d119e9826e208dd53c71bc534709c6331eb80f1c6e791386
BLAKE2b-256 checksum
How to use checksums
97bddffdfaba5bf6f3d9292ef81ed0c49e059d84ca59b85f3c21693347f23380
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / precise_numpy-0.2.4-cp310-abi3-macosx_11_0_arm64.whl

Download URL precise_numpy-0.2.4-cp310-abi3-macosx_11_0_arm64.whl
Size 411.3 kB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
cdd835cdd30579c46a7d552559ba74be748369525ca6f26b76be53c3662d6e2d
BLAKE2b-256 checksum
How to use checksums
dbf2f67a3b7bfdef1c74e1bbbad152918d680d8fd59a335a80d2100f9a89a99d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / precise_numpy-0.2.4-cp310-abi3-macosx_10_12_x86_64.whl

Download URL precise_numpy-0.2.4-cp310-abi3-macosx_10_12_x86_64.whl
Size 473.1 kB
Tags CPython 3.10 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
89f4388e7826f608fc8b892c9566e15ccc3295a8c9dbcc9cf805f15bc1c9c213
BLAKE2b-256 checksum
How to use checksums
ae7e279541472d61981504737b93ccd846e96c62b0da61d6a5a736e9b1898e8d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Security for precise-numpy 0.2.4

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page