Your free trial has ended.

Try the live demo or log in .

9c07ded6

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

Pin Symbolica with single-rounded Float products and exact ±1 factors

The Float routes (native code and interpreted expressions, which NinjaRS's
arbitrary-precision masters use) were wrong on rows where binary64 was
right, by 5e-2 to 4e6 of the value. In the D0 oracle sweeps (seeds 1-4,
25,645 rows where OneLOop is stable) that was 62 native and 44 interpreted
rows at 256 bits, and similar counts at 128, 512 and 1024 bits. Example:
3.07e4 + 19i for 8.70 + 5.83i at 256 bits. The C0 sweeps had 46 and 33.
The values were the same at 09b2c74.

Cause, in Symbolica's numerica: a Float carries its own precision, and a
square root has one bit more than its argument. Two operations broke
identities that binary64 keeps.
- A product by reference first rounded the more precise factor to the
  other's precision, so a b and b a differed, and z conj(z) kept an
  imaginary residue.
- Evaluators form a - b as a + (-1) b with a -1 at the working precision,
  so the product rounded b. x - |x| (the sign test) and x - conj(x) (the
  imaginary part) then gave one-bit residues for about half of all square
  roots.
Exact sign and zero tests branched on these residues. For example, a tie
|b + d| = |b - d| came out -2.8e-76 at 256 bits and swapped the roots of the
two-mass box above.

Fix: symbolica-dev/symbolica#97 rounds Float products and quotients once,
to the smaller precision, and keeps factors of exactly ±1 exact. The pin
moves to 9cdc2949 (ValentinHirschi/symbolica
claude/oneloopmaster-integration-float-products: e679e8c1 plus that commit)
in all three build roots.

Results:
- D0 sweeps, rows wrong at 128/256/512/1024 bits: native 82/62/56/59 ->
  12/0/0/5, interpreted 96/44/68/46 -> 12/0/4/4.
- C0 sweeps: native 62/46/33/52 -> 23/7/6/12, interpreted 62/33/33/39 ->
  20/12/8/5. A0, B0 and dB0 had none before or after.
- Binary64 is bitwise unchanged on every route over the 37,642 D0 and
  17,555 A0-C0 sweep rows. So is DoubleFloat, over those rows plus the
  7,645 NinjaRS C0/D0 calls.
- The D0 sweep failure lists (seeds 1-4, native, generated and expression)
  are byte-identical to 9a898ee and 09b2c74. The summaries equal 9a898ee's,
  except that in seed 4 twelve OneLOop-unstable rows move from
  unstable-analytic to unstable-binary64: their 256-bit values now agree
  with OneLOop's quadruple precision.
- NinjaRS: none of the 7,645 C0/D0 calls of the rank n+2 suite and final
  review lanes was affected. Their Float values move by at most 4.7e-71
  relative at 256 bits.

tests/float_exact_products.rs checks 7 D0 and 4 C0 rows in all their
relabellings:
- References: Denner and Dittmaier's two-mass box or the C0
  Feynman-parameter integral in mpmath at 40 digits, otherwise COLLIER
  1.2.9 in quadruple precision on exact decimal inputs.
- Routes: binary64 (hand-written, generated, interpreted, SymJIT),
  DoubleFloat, and native and interpreted Float at 128 to 512 bits.
- It fails with the previous pin in 605 checks on every row.
- An ignored test reproduces the interpreted Float C0 at vanishing
  invariants, which remains open.

STATUS.md records the fix, the remaining D0 and C0 Float rows and a C0
defect that every route shares. PRECISION.md and README.md describe the
new pin.

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