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.3

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.3
File Size Uploaded Provenance
precise_numpy-0.2.3.tar.gz 472.5 kB Without provenance Details

Built distributions (wheels)

Table of built distributions (wheels) for precise-numpy 0.2.3
File
precise_numpy-0.2.3-cp310-abi3-win_amd64.whl CPython 3.10 abi3 Windows x86-64 Details
precise_numpy-0.2.3-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.3-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.10 abi3 Linux glibc 2.17+ ARM64 Details
precise_numpy-0.2.3-cp310-abi3-macosx_11_0_arm64.whl CPython 3.10 abi3 macOS 11.0+ ARM64 Details
precise_numpy-0.2.3-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.3.tar.gz

Download URL precise_numpy-0.2.3.tar.gz
Size 472.5 kB
Tags Source
SHA-256 checksum
How to use checksums
7222f7aecf6fe4be5f640629e588f61119557bdb103b4eb6ee8db74552e016bd
BLAKE2b-256 checksum
How to use checksums
21aba6278620263654e91369cdc28a964f8cee2613733203fa83bac5a84c3c20
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.3-cp310-abi3-win_amd64.whl

Download URL precise_numpy-0.2.3-cp310-abi3-win_amd64.whl
Size 395.3 kB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
fe287ab643a724f66c08f1ce3517e89faca4e54dfeed2c618d6866218ad70968
BLAKE2b-256 checksum
How to use checksums
38db01792b6ede943cce59e639d12ddcb963e1668c963ef876faafb8ce4b476b
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.3-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL precise_numpy-0.2.3-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 502.6 kB
Tags CPython 3.10 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
e55c37801c6158989898c97644ea160d90faa834432ccb0a5fe43d36425fcd93
BLAKE2b-256 checksum
How to use checksums
3844482e571f2abda959df9f9c2dbc73114bc2f0cf03d37028d261a8734a7b20
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.3-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL precise_numpy-0.2.3-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 441.5 kB
Tags CPython 3.10 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
5666234121cf5bf7a98beafe2d2ba20a0baf1e0a4bdef1b68c62d56f32874793
BLAKE2b-256 checksum
How to use checksums
540b793a87d50f25ae8caa3768d7617e177871cb693f680afd69a6bf75143858
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.3-cp310-abi3-macosx_11_0_arm64.whl

Download URL precise_numpy-0.2.3-cp310-abi3-macosx_11_0_arm64.whl
Size 402.6 kB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
81426402457d54d17a0014a6bde8d3d37c29b1d4c6123a4ac8f09c22e5278d6e
BLAKE2b-256 checksum
How to use checksums
f966b11d82cdf42659ac060b4073515e2fcd6428e1d991b50c31debf5a99d38b
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.3-cp310-abi3-macosx_10_12_x86_64.whl

Download URL precise_numpy-0.2.3-cp310-abi3-macosx_10_12_x86_64.whl
Size 463.4 kB
Tags CPython 3.10 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
ae645aa7a5628d436f33792b86d5143ff5823dffd2185e2e781ab16825216b40
BLAKE2b-256 checksum
How to use checksums
7bdd946c449897505440d0155dade2af172492578fe913e0ef6f239634fe6874
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.3

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