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

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.5
File Size Uploaded Provenance
precise_numpy-0.2.5.tar.gz 478.3 kB Without provenance Details

Built distributions (wheels)

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

Download URL precise_numpy-0.2.5.tar.gz
Size 478.3 kB
Tags Source
SHA-256 checksum
How to use checksums
10ce78db11239c1dab78e2856b0f653335b405f061f80e54fadb4351781aca84
BLAKE2b-256 checksum
How to use checksums
de5ed8d2b19eb53cd95c83e843811509bf621b4765b533d1a81dc05e0fd5c016
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.5-cp310-abi3-win_amd64.whl

Download URL precise_numpy-0.2.5-cp310-abi3-win_amd64.whl
Size 405.9 kB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
c581a6dd89fb6292bc587609ac48cf9fb11fd4afde55379c1a007c17541bfc3b
BLAKE2b-256 checksum
How to use checksums
6d0615d3cee6e929de0cb0914d1ac47bf9e8549b150564a8c17935bb4164447f
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.5-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL precise_numpy-0.2.5-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 512.9 kB
Tags CPython 3.10 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
9c163ae81002fee22d64ca092f9dd88524a2650a4eabe4760ac5003fff71c07f
BLAKE2b-256 checksum
How to use checksums
3cca8437f39b5ced5fd14594b90d0aa4fedb5f32e2993d37f9da09ef3d5a1952
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.5-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL precise_numpy-0.2.5-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
112b1f189567458c146144385b1329e81e963738fae02502c255e574e67bb2a0
BLAKE2b-256 checksum
How to use checksums
eb76099dff489421acbf2f4fc75a63532c79a2f80c5686295fca70e3bd1b1f0d
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.5-cp310-abi3-macosx_11_0_arm64.whl

Download URL precise_numpy-0.2.5-cp310-abi3-macosx_11_0_arm64.whl
Size 411.4 kB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
9e4cef20ce7f3d3b92de46b38e6bb33a7808518b9544cbb50fcbd780d5969961
BLAKE2b-256 checksum
How to use checksums
e32a835e5e1fc2c6052cba7ca9b6b8c578344742fa27ac15da61faf203c77cec
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.5-cp310-abi3-macosx_10_12_x86_64.whl

Download URL precise_numpy-0.2.5-cp310-abi3-macosx_10_12_x86_64.whl
Size 473.2 kB
Tags CPython 3.10 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
1869d71b27127309a3b13b1096d0719c39729f89b8c8684480efe550f225b044
BLAKE2b-256 checksum
How to use checksums
ce7aba60ee5ff3190278c7829356135ef14a1de410428f19fe923098eaf05ad7
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.5

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