Your free trial has ended.

Try the live demo or log in .

3cbe08d9

By: ValentinHirschi <valentin.hirschi@gmail.com>

Condition coincident dilogarithm differences and tiny box invariants

Two accuracy defects found through NinjaRS:

C0 with nearly coincident roots (tests/c0_coincident_roots.rs). The
two-mass triangle p² = (-237088.34352377, -236743.32762192388, 0),
m² = (29929 - 259.5i, 0, 6464.16 - 168.84i), mu² = 10^4 has
sqrt(lambda)/|p²| = 1.5e-3. The dilogarithm divided differences
(Li2(1-x1) - Li2(1-x2))/(x1-x2) of its roots cancelled by that much, and
those of the reflected labelling, whose second root is zero, cancelled
against Li2(1). Binary64 was off by 2.4e-13 (native), 2.3e-14 (native,
reflected) and 3.8e-13 (SymJIT); OneLOop 3.6 by 3.3e-15.
`sheet_exact::difference_body` now detects a cancellation by more than 16
and then uses `near_difference`, the term-wise Bernoulli expansion of
OneLOop's dilog2_c (reflected, unreflected and inverted forms, a
zero-partner form, `s` from log(1+w) without cancellation), with the
series degree chosen by a probe that is exact at the working precision.
log(x)/(1-x) next to one uses log(1+w) through `log_one_plus_body`. Every
binary64 route is now within 2e-15 to 9e-15 (native 2.2e-15, reflected
6.9e-15; SymJIT 6.5e-15 / 8.4e-15; expressions 3.0e-15 / 9.1e-15), and
256 bits agree with a 400-bit reference.

D0 with a tiny invariant (tests/d0_tiny_invariant.rs). For
p = [eps, 40000, 0, -100000/3, eps, 0], m² = 29929 x4, mu² = 10^4,
eps = 2^-114, the contour box's zero-external chart formed coefficients
such as m2 - m3 - p2 = -eps and a + b + c = eps by cancellation. Float
tracks such a difference with the bits left after the cancellation and
computed everything downstream at that precision: from 132 to 184 bits
the result kept 7 to 55 bits and was wrong beyond them (6e-2 at 136
bits). Mass differences are now subtracted first (`in_order`), and a
coefficient sum that cancels by more than 2^16 uses the invariant it
equals (`coefficient_sum`). The value is now correct at every precision
from 128 to 1024 bits; binary64 is unchanged.

Both fixes are transcribed to the hand-written binary64 kernels
(`sheet::dd`, `log_over_one_minus`, the contour box's `t1`/`tfun`), the
native code is regenerated and the C0 and D0 SymJIT assets rebuilt.

The Rust emitter now reads helper parameters that are the same constant
at every call from the context instead of threading them through every
helper's arguments (Symbolica's export passes a shared body's constants as
arguments). Generated outputs are unchanged (A0/B0/dB0 bitwise on 7048
sweep rows); this pays for the new series constants.

Cost on the NinjaRS call streams (retired instructions per call, all 34
recorded cases, against 264a6ce): boxes +0.6% (max +1.7%), hand-written
triangles +1.2% (max +4% where the new path is taken), generated
two-mass triangles -3%. Oracle sweeps: 48 C0 rows (45 for the
expressions) and 16 D0 rows fixed, none regressed, on the native,
generated and expression routes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>