mixle.stats.compute.error_receipts module

Optional compensated (Kahan) accumulation with a running round-off estimate.

Precedent: mixle.inference.precision_plan already tracks a validated summed-LL error band (“~1e-6 relative”) for the reduced-precision fused kernel – a static, offline-verified bound picked once per model/data pair. This module is the dynamic, per-accumulator counterpart: an OPT-IN compensated-summation mode that carries its own running error estimate as the computation proceeds, so a partition’s numerics receipt travels with its sufficient statistics through combine() exactly like the statistics themselves.

Design: the receipt an accumulator carries is (abs_total, n) – the running sum of absolute addend magnitudes and the running term count. n is exactly additive, while abs_total and its partition merges are themselves floating-point reductions. The receipt therefore does not claim that its fields compose exactly.

For ordinary recursive summation, error_bound() uses the conservative gamma_(n-1) factor k*eps/(1-k*eps) instead of its first-order approximation. For compensated summation, the commonly used Higham expression (2*eps + n*eps**2) * sum(abs(x)) remains an asymptotic diagnostic estimate, not a certified upper bound: its omitted higher-order terms and the receipt’s own floating-point accumulation prevent certification. The compatibility names error_bound and bound are retained, but their docstrings explicitly state this distinction.

error_bound(n, abs_total, compensated)[source]

Return a round-off diagnostic for a finite float64 summation receipt.

For plain recursive summation this is the standard gamma_(n-1) bound under the usual no-overflow/no-underflow model. For Kahan summation this is a first/second-order estimate and MUST NOT be treated as a certificate. The historical function name is retained for API compatibility.

Parameters:
  • n (int) – Number of terms summed.

  • abs_total (float) – Running sum of the absolute value of each (weighted) addend.

  • compensated (bool) – Whether the sum was accumulated with Kahan compensation.

Returns:

A finite non-negative diagnostic, or inf when the classical gamma bound’s

precondition (n - 1) * eps < 1 does not hold.

Return type:

float

class CompensatedAccumulator(total=0.0, compensation=0.0, abs_total=0.0, n=0, compensated=True)[source]

Bases: object

A running (optionally Kahan-compensated) sum plus a validated numerical receipt.

total is the running sum (Kahan-corrected when compensated=True, plain float64 accumulation otherwise). abs_total and n compose under combine(), subject to float64 rounding of abs_total itself.

Parameters:
add(x, weight=1.0)[source]

Fold one (weighted) addend into the running sum.

Parameters:
Return type:

CompensatedAccumulator

combine(other)[source]

Merge another partition’s running sum + receipt into this one, in place.

Both accumulators must use the same numerical mode. The other accumulator’s compensation-corrected estimate is folded in as one addend, while receipt counts and magnitudes are merged separately.

Parameters:

other (CompensatedAccumulator)

Return type:

CompensatedAccumulator

bound()[source]

Return the historical round-off diagnostic; Kahan mode is not a certified bound.

Return type:

float

kahan_reduce(values, weights=None)[source]

Reduce a sequence (optionally weighted) to a fresh CompensatedAccumulator.

A convenience one-shot reducer, mainly used by tests and small ad hoc reductions; accumulators that need this incrementally (across update/seq_update calls) should hold their own CompensatedAccumulator instance instead of re-reducing from scratch each time.

Parameters:
Return type:

CompensatedAccumulator

class ConditioningReceipt(eigenvalues, condition_number, near_degenerate, degenerate_ratio_threshold, symmetry_error, symmetry_tolerance)[source]

Bases: object

A real, computed numerical-conditioning diagnostic for a (multivariate) fit.

Captures the covariance eigenvalue spectrum an estimate() call saw, so a caller can tell a healthy fit from one balanced on a near-degenerate direction without recomputing the eigenspectrum itself.

Parameters:
  • eigenvalues (ndarray)

  • condition_number (float)

  • near_degenerate (bool)

  • degenerate_ratio_threshold (float)

  • symmetry_error (float)

  • symmetry_tolerance (float)

eigenvalues

Eigenvalues of the (raw, pre-regularization) covariance, ascending.

Type:

np.ndarray

condition_number

max_eigenvalue / min_eigenvalue (inf if the smallest eigenvalue is <= 0, i.e. the raw covariance is singular / numerically indefinite).

Type:

float

near_degenerate

True when the smallest-to-largest eigenvalue ratio falls below degenerate_ratio_threshold (or the smallest eigenvalue is non-positive).

Type:

bool

degenerate_ratio_threshold

The ratio threshold used to set near_degenerate.

Type:

float

symmetry_error

Maximum absolute difference between opposite covariance entries before the within-tolerance numerical projection to symmetry.

Type:

float

symmetry_tolerance

Maximum accepted symmetry error for this input.

Type:

float

to_dict()[source]

JSON-friendly view of this receipt.

Return type:

dict[str, Any]

conditioning_receipt(covar, degenerate_ratio=1.0e-6)[source]

Compute a ConditioningReceipt from a (symmetric) covariance matrix.

degenerate_ratio is the smallest/largest eigenvalue ratio below which the covariance is flagged near-degenerate (i.e. it has a direction of near-zero variance relative to the dominant one) – the “near-degenerate variance flag” the roadmap calls for, generalized from a single variance to the eigenvalue spectrum for the multivariate case.

Parameters:
Return type:

ConditioningReceipt