There is a newer version of the record available.

Published June 24, 2026 | Version v0.10.0

CNRS Scientific Toolkit

Authors/Creators

Description

v0.10.0 — Dual-Path Arithmetic, Carry-Guard Tightening, and Lagrange Inversion

v0.10.0 extends the v0.9.0 native core with three interconnected improvements: tighter, proven carry-drain bounds in the CNRS-A arithmetic layer; a dual-path architecture that automatically selects CNRS-A native or fast-path arithmetic for ScaleLaw and OdeSolution; and native Lagrange series inversion in coefficient space.

Added

cnrs/cnrs_h_mode.py — dual-path CNRS-H adapter (new module)

CnrsHMode wraps either CnrsH (fast, plain Python complex coefficients) or CnrsHNative (CNRS-A digit-string coefficients) and exposes a uniform interface. Path selection is automatic:

  • Auto (default): uses CnrsHNative when all EGF coefficients are Gaussian integers representable in CNRS-A; falls back to CnrsH silently for float coefficients or Gaussian integers too large for exact CNRS-A floating-point expansion.
  • native=True: forces CnrsHNative; raises NonGaussianCoefficientError if any coefficient is not a Gaussian integer.
  • native=False: always uses the fast CnrsH path.

The active path is readable via .native.

ScaleLaw and OdeSolution — dual-path integration

Both classes now accept an optional native parameter and expose a .native_mode property. ScaleLaw.derivative() and .integral() propagate the path. cnrs_solve_linear also accepts native.

numpy_to_cnrsh in cnrs_interop.py is fixed to return a plain CnrsH stream for backward compatibility when the fitted coefficients are Gaussian integers.

invert_native — native Lagrange series inversion

invert_native(f, order) computes the compositional inverse g of a CnrsHNative series f (i.e., f(g(s)) = s) using the Lagrange inversion recurrence derived from Faà di Bruno's formula. All arithmetic routes through CVal (add_cnrs / mul_cnrs); no Python arithmetic touches the EGF coefficients.

The recurrence:

g_1 = 1 / f_1
g_n = -(1/f_1) * Σ_{k=2}^n  f_k · B_{n,k}(g_1, …, g_{n-k+1})

where B_{n,k} are partial Bell polynomials built incrementally. Because k ≥ 2 implies the Bell argument index n−k+1 ≤ n−1, each g_n is determined solely from already-computed coefficients — the entire computation is a single forward pass.

Requirements: f(0) = 0, f′(0) ∈ {1, −1, i, −i} (Gaussian integer units; non-unit f′(0) produces non-integer inverse coefficients not storable in CVal).

verify_inversion(f, order) checks f(g(s)) = s at the digit-string level (strictest standard: strings_match=True, max_error=0.0).

InversionError

New exception raised by invert_native when f(0) ≠ 0 or f′(0) is not a Gaussian unit. Exported from cnrs top-level.

Fixed

Native integration constants in CnrsHMode.integrate()

Fixed a native-mode bug where Gaussian-integer complex integration constants such as 3+0j or 1+2j were incorrectly passed through int(), raising a TypeError. Native mode now rounds valid Gaussian-integer complex constants to complex Gaussian integers and rejects non-Gaussian constants with NonGaussianCoefficientError. Regression coverage added in tests/test_cnrs_h_mode_integrate_v010.py.

Changed

Carry-drain guards tightened

  • cnrs_add.py: drain guard 1000 → 20. Justified: the addition carry is always an element of the 14-state canonical set, so it drains in ≤ 14 steps. Guard of 20 provides a formal safety margin with explanatory comment.

  • cnrs_mul.py: drain guard 1000 → 100. The multiplication normalization carry is a general Gaussian integer (not bounded to the 14-state set); empirically drains in ≤ 12 steps for inputs up to ~10³ digits. Guard of 100 is a well-motivated reduction from 1000 with a comment explaining why the bound differs from add_cnrs. A formal proof of the carry bound remains an open item (see Research Status).

Exports added to cnrs top level

  • InversionError
  • invert_native
  • verify_inversion
  • CnrsHMode
  • native_eligible

Tests

1121 passed, 6 xfailed

New test files:

  • tests/test_stress_outside_normal.py (31 tests) — drain guard stress (TestDrainGuardStress, 6 tests: large/alternating coefficient injection, drain step bounds across 2 000 random trials, 300-digit string multiplication, 2 000 random Gaussian-integer correctness checks) and dual-path architecture (TestDualPathArchitecture, 25 tests: auto-selection, large-Gaussian fallback, forced overrides, value agreement, path propagation, ScaleLaw and OdeSolution integration).

  • tests/test_cnrs_h_mode_integrate_v010.py (6 tests) — regression coverage for native CnrsHMode.integrate() with real-complex and full Gaussian complex constants, rejection of non-Gaussian constants, fast-path preservation, and propagation through ScaleLaw / OdeSolution.

  • tests/test_lagrange_inversion.py (57 tests) — Lagrange inversion across seven test classes: identity, log-from-exp closed form (coefficients and digit strings verified against (−1)^{n−1}·(n−1)!), quadratic shift (double-factorial coefficients), Gaussian unit f′(0) = i, negation self-inverse, round-trip composition across six series including double-inversion, and all error conditions.

Notes

If you use this software, please cite the repository and the project documentation.

Files

DonGPalmer/CNRS_Scientific_Toolkit-v0.10.0.zip

Files (408.8 kB)

Name Size Download all
md5:1d7d1df20e0ce2d7189136b516e606c1
408.8 kB Preview Download

Additional details

Related works