Skip to content

Floor the noise estimate at the rounding error of the function values - #87

Merged
dweindl merged 1 commit into
mainfrom
noise-floor-rounding
Oct 26, 2026
Merged

dweindl merged 1 commit into
mainfrom
noise-floor-rounding

Conversation

@dweindl

@dweindl dweindl commented Oct 21, 2026 •

Copy link
Copy Markdown
Member

The difference-table noise estimate scatters by tens of percent, and near the rounding level it also depends on the platform's floating-point behaviour. The noise floor is now at least eps * median|f| over the probe points (about two ulps of the function values), per output component; non-finite probe values are ignored and exactly-zero outputs get no floor. A user-supplied noise_floor is not affected. This conservative floor covers rounding errors accumulated in typical computations and the sampling error of the estimate, which would otherwise make the noise floor, and every step size and tolerance derived from it, platform-dependent at the rounding level.

Found via the AMICI SBML semantic test suite, case 00206 (plain mass action, no events): on Ubuntu 26.04 CI, both adjoint directions came out discontinuity_suspected. The log-likelihood there is ~-303 (eps * |f| = 6.7e-14), but the estimated noise floor was 2.7e-14 (0.40 eps * |f|), versus 7.3e-14 (1.09 eps * |f|) on Ubuntu 24.04, where the case passes. With the low estimate, the kink check's noise budget (5.3e-9) fell just below the residual between ladder rungs (8.0e-9).

Also reports the function value at the point as diagnostics["f0"], so the noise floor can be related to the function's magnitude when analyzing results.

Validated on AMICI CI (SBML semantic suite and benchmark collection, Ubuntu 24.04 and 26.04, on top of #86); compared to #86 alone:

  • 00206 adjoint on 26.04: sigma 2.7e-14 -> 6.7e-14, both directions converged and passing. All SBML and benchmark tests pass on both runners; no direction fails its check.
  • The floor raises sigma for ~1.1M of ~1.9M SBML forward outputs, mostly without changing the status.
  • Discontinuity flags from the adjacent-rung check alone (i.e. without a cross-regime disagreement), SBML forward: 1088 -> 740 (26.04), 793 -> 479 (24.04); ~330 directions per runner go from discontinuity_suspected to converged.
  • Status differences between 24.04 and 26.04, SBML: 10325 -> 9785. (The benchmark jobs are not bitwise reproducible between CI runs, so their platform comparison is not informative.)
  • One side effect: 16 new discontinuity_suspected directions in SBML 01010 on 24.04 (previously converged and passing). In estimate_jacobian, the ladder is shared across outputs and sized by the largest output noise floor; the floor raised it slightly (1.6e-15 -> 2.2e-15), and outputs with a much smaller own noise floor (7.8e-17) have a correspondingly tight discontinuity budget at those step sizes. The residual was already ~1.4x the budget before this change, so this is a pre-existing sensitivity of the per-output budget with a shared ladder, to be looked at separately.

An earlier version of this change used max|f| instead of median|f|; the numbers above are for the final version, which differs from the max|f| one only in 62 SBML forward directions (outputs with an exactly-zero derivative whose shared Jacobian ladder shifted by ~2%; converged -> noise_dominated, none failing).

🤖 Generated with Claude Code

@dweindl
dweindl force-pushed the noise-floor-rounding branch from 4968729 to bd3908d Compare October 21, 2026 13:44
The difference-table noise estimate scatters by tens of percent, and
near the rounding level it also depends on the platform's floating-point
behaviour. For an AMICI log-likelihood of ~-303 (`eps * |f| = 6.7e-14`),
the estimate was 2.7e-14 on one platform and 7.3e-14 on another; the
low estimate made the kink check flag both directions of a smooth model
as `discontinuity_suspected`.

The noise floor is now at least `eps * median|f|` over the probe points
(about two ulps), per output component, ignoring non-finite probe
values. A user-supplied `noise_floor` is not affected.

Also report the function value at the point as `diagnostics["f0"]`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dweindl
dweindl merged commit d3f1a60 into main Oct 26, 2026
5 checks passed
@dweindl
dweindl deleted the noise-floor-rounding branch October 26, 2026 19:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants