Skip to content

Validation

Rust tests are the main numerical check and run without Python. They use proptest to sample bounded physical domains and check algebraic and adjoint identities. Hypothesis tests exercise the installed Python package: array shapes and memory layouts, input validation, reusable derivative contexts, and complete user workflows.

Kinds of evidence

  • Physical invariants: zero-contrast scattering, lossless energy balance (unitarity, which implies the optical theorem), reciprocity, mirror and duality symmetries, passivity, invariance under global translation, covariance under rotation, and invariance under splitting a homogeneous layer.
  • Analytic identities: Bessel Wronskians, differential equations and reflection formulas, Legendre recurrences, Wigner selection rules and orthogonality, independent algorithms for one function (Wigner d by recurrence and by the generator exponential), the group laws of translations, split, Bloch and primitive-basis independence of Ewald sums, and matrix residual equations.
  • Differentiation: arbitrary cotangents (gradients with respect to an output) and parameter directions, complex real-pairing adjoint identities, directional finite-difference convergence and reusable derivative contexts. Symmetries give exact identities of complete pullbacks without finite differences: Euler scaling of lengths against wavenumbers, and similarity or unitary orbits of spectra. Framework adapters reproduce the native pullback exactly (tests/autodiff/test_adjoint_identities.py, tests/autodiff/test_adapter_bridges.py).
  • Independent references: fixed versions of treams, SciPy and mpmath. Agreement adds evidence but does not define correctness.

Property tests sample finite domains that match each property's assumptions, reduce failing inputs to simpler examples and save them for future tests. Polar-axis, origin and small-argument points are added explicitly. No numerical tolerance is loosened to make an implementation pass. Benchmarks run only on optimized builds, separately from correctness checks.

Rust properties and proofs

Hosted CI checks Rust on the minimum and stable toolchains and Python on CPython 3.12–3.15. The complete reference suite runs on 3.12 and 3.13; later versions omit tests whose reference dependencies are unavailable (development). Native proptest properties, mostly in crates/treams-core/src/properties/, check:

  • the group laws of translations;
  • Bessel, Legendre and Wigner identities, including the Wigner small-d recurrence against the generator exponential up to degree 128;
  • split, Bloch, primitive-basis and point-group invariances of every Ewald family, in value and every derivative;
  • Lorentz reciprocity of particles and of dense, heterogeneous, matrix-free (iterative::tests) and cylindrical clusters;
  • the lossless energy balance of sphere and cylinder T-matrices and of sphere clusters;
  • EBCM against Mie;
  • implicit-adjoint closed forms of the solves against an independent LU;
  • composition, reciprocity, unitarity and layer-split invariance of planar stacks.

Finite differences are used only as test references, never to compute pullbacks.

Lean proofs establish, over exact arithmetic, that:

  • diffraction-order enumeration is complete and duplicate-free;
  • lattice shells partition the integer lattice;
  • the translation degree loop matches the Wigner 3j selection rules;
  • equilibrated LU solves are exact solves;
  • the dense requested-illumination pullback is the exact derivative.

The proofs do not cover rounding. In the rounding case that the diffraction-order proof exposed, a cutoff equal to the magnitude of an order, the enumeration keeps that order (diffraction_cutoff_on_an_order_keeps_it). The proofs cover hand-written models, not the Rust source; Rust tests compare cube, degrees and harmonics with outputs generated from those models.

Accuracy evidence

Errors are relative unless stated otherwise. The workflow comparisons and the 2,032 finite-output reference cases come from one recorded Linux run (Ryzen 9 9950X, Python 3.13.1); the performance page lists its build.

Development tests compare against treams 0.4.7. Archived workflow and gallery measurements retain their recorded treams 0.4.5 identity. The results below belong to those measurements, not automatically to a later release build.

Evidence Scope Outcome Source
Rust property tests Physical, analytic and adjoint identities above, on bounded random domains with saved regressions Pass in CI crates/treams-core/src/properties/
Python Hypothesis and reference tests Broadcasting, strides, validation, derivative contexts and workflows through the installed extension, against SciPy, treams and mpmath Pass in CI on Python 3.12 and 3.13 tests/special/, tests/lattice/, tests/waves/, tests/tmatrix/, tests/smatrix/, tests/plane/, tests/autodiff/
High precision: incomplete gamma 1494 40-digit mpmath values; 60-digit sweeps over |n| <= 128 Within 1e-13 relative; sweeps within 1.5e-13 incgamma.txt, limits
High precision: Kambe integrals 181 quadrature values; 1249 70-digit values at the lattice-sum arguments 1e-13 relative; even orders within 1e-11 kambe.txt, kambe_lattice.txt
High precision: lattice sums Ewald sums and derivatives against mpmath, near and off the plane or axis Values within 5e-14 to 2e-13 near the plane or axis; 1D spherical sums off the axis within 1.4e-13 lattice_sums.txt, lattice_chain.txt, generate_references.py
High precision: fractional Legendre, archived pre-release implementation 530 finite value and derivative cases and two expected overflows against 70-digit hypergeometric values Largest relative error 2.17e-13 in that record qualify_legendre.py, record
High precision: reference collector 2,032 finite-output reference cases, including a metallic sphere of size parameter 80; 18 inputs beyond the float64 range are excluded All pass qualify_references.py, linux-core-qualification.json
treams workflow comparisons 527 complete workflows against treams 0.4.5, plus 51 complete-gradient cases All pass qualify_upstream.py, linux-core-qualification.json
Published applications Electron-beam spectra, treams paper spectra and thermal radiation Within the stated tolerances of the author data, for example all 300 thermal absorption values within 0.577% Published applications, benchmarks/papers/
Lean proofs The five statements above, over exact arithmetic Proved; Rust tests compare cube, degrees and harmonics with model outputs formal proofs
Floating-point environment Every scalar binding and ufunc loop, records with their pullbacks, solves and a slab on a thread that flushes subnormals to zero Equal to the results of an IEEE thread, bit for bit test_float_environment.py, float_environment.py, floating-point environment
Thread count Values and gradients of every parallel reduction, dense solves and decompositions, a cluster solve and ufuncs at one, two and three threads; the Python suite on one thread and on every CPU Equal at every thread count, bit for bit test_thread_pool.py, parallelism

Testing explains how to add a test.