mixle.engines.highprec module

Arbitrary-precision tail of the spectrum: fp128, fp256, fp512, fp1024, … fp(any bits).

The pure-numpy error-free-transform path (mixle.engines.extended) tops out near double-double (fp128) / quad-double (fp256); beyond that the renormalization cost grows and MPFR becomes the practical compute backend. This module is the correct backend for that tail, on gmpy2 (C-backed MPFR) with an mpmath fallback. Cost note: gmpy2 is per-object, so array ops are an O(N) Python loop – correct but not fast. For fp <= 256 prefer the vectorized extended path.

So: spectrum coverage is complete (fp1..fp1024+), with the fast pure-numpy backends below fp256 and the correct MPFR backend above it.

Both backends are optional extras (neither is a base dependency, per worklist P2.2): install the faster one with pip install mixle[gmpy2], or the pure-Python fallback with pip install mixle[highprec]. With neither installed, available() returns False and any call requiring fp>256 raises a clear RuntimeError naming the extended fallback – see _require().

available()[source]

True if an arbitrary-precision backend (gmpy2 or mpmath) is importable.

Return type:

bool

hp_array(x, bits)[source]

Convert values to an object array of bits-bit arbitrary-precision numbers.

Accepts float/int/str/Decimal/backend-native (MPFR) scalars, arrays, or nested sequences of them – each element is converted straight into the high-precision backend via _scalar_to_hp(), without ever routing through a float64 intermediary first. That matters: a Decimal or numeric string can carry far more significant digits than float64’s ~15-17, and an integer beyond 2**53 is not exactly representable as float64 either – casting the whole input to float64 up front (the previous bug here) would throw that precision away before it ever reached the high-precision backend, no matter how many bits were then requested.

Parameters:
Return type:

ndarray

hp_to_float(obj)[source]

Round an arbitrary-precision object array back to float64.

Parameters:

obj (Any)

Return type:

ndarray

hp_sum(x, bits)[source]

Sum values at bits mantissa precision (correct beyond what float64 / double-double give).

Accepts the same input types as hp_array() (float/int/str/Decimal/backend-native scalars, arrays, or nested sequences) – each element is converted via _scalar_to_hp(), without a float64 detour, and the accumulation itself runs in bits-bit backend arithmetic (gmpy2 context / MPFR adds, or mpmath.fsum under workprec), not float64 – so a catastrophic cancellation that would erase a value’s distinguishing digits under naive float64 summation is preserved all the way through.

O(N) per-object MPFR adds – correct but not vectorized; for large N below fp256 prefer mixle.engines.extended.dd_sum(). Returns the float64-rounded result.

Parameters:
Return type:

float

class HighPrecisionFormat(total_bits)[source]

Bases: object

An arbitrary total-width float (fp128, fp256, fp512, fp1024, …) – MPFR-backed codec.

total_bits uses the same sign+exponent+significand unit as every fpN spelling in mixle.engines.spectrum. The MPFR precision is derived from that total width; the public name therefore always remains exactly fp<total_bits>.

Parameters:

total_bits (int)

property max_rel_error: float

Return MPFR round-to-nearest unit roundoff for the derived significand precision.

quantize(x)[source]

Encode values with the configured high-precision mantissa.

Parameters:

x (Any)

Return type:

ndarray

dequantize(q)[source]

Decode high-precision values to float64.

Parameters:

q (Any)

Return type:

ndarray

round_trip(x)[source]

Quantize and decode values through the high-precision format.

Parameters:

x (Any)

Return type:

ndarray