Repository navigation
fix(statistics): compute the binomial CDF in log space so it does not underflow - #1931
Merged
jlarson4 merged 1 commit intoOct 21, 2026
Merged
Conversation
… underflow _binomial_cdf started its pmf recurrence from (1 - p) ** n, which is 0.0 once n log(1 - p) < -745, so the CDF came out 0.0 and success_rate_ci returned intervals that could exclude the observed rate (from n = 200 at high rates, n ~ 980 at 50%). The terms are now summed from their logarithms, rescaled by the largest.
Collaborator
|
@bercedev Thanks for putting this together! I will rerun any failing CI tests and give this a review once the CI run finishes. We had a lot of PRs open at once so that can often trigger rate limit errors. I will let you know when my full review is ready. |
Collaborator
|
Would you please comment on #1926 so I can assign you? |
1 task done
1 task done
Collaborator
|
This looks good @bercedev, no comments from me, merging now! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Fixes #1926
_binomial_cdfstarted its pmf recurrence from(1 - p) ** n. Oncen * log(1 - p) < -745, that term is0.0in float64, so every later term and the CDF were0.0as well. The Clopper-Pearson bisection then followed a wrong CDF, andsuccess_rate_cigave intervals that were far too wide or excluded the observed rate.As the issue suggests,
_binomial_cdfnow works in log space. Each term's logarithm islgamma(n + 1) - lgamma(i + 1) - lgamma(n - i + 1) + i log p + (n - i) log1p(-p). The terms are summed withmath.fsumasexp(log_term - peak)and scaled back byexp(peak), clamped to at most 1. The early returns and the bisection are unchanged, and the docstring now explains the underflow.I checked the new CDF against an exact
Fractionsum for n ∈ {10, 200, 2000} and p ∈ {0.01, 0.5, 0.97, 0.999}. The worst relative error was 1.5e-12._binomial_cdf(1000, 2000, 0.5)now gives 0.50892, where it used to give 0.0. One trade-off: each term costs threelgammacalls, so a 2000-trial interval takes about 0.3 s on my machine.Type of change
Checklist:
_binomial_cdfdocstring)Tests (
tests/unit/utilities/test_statistics.py):_binomial_cdfagainst an exact rational sum (math.combandFraction) at (1000, 2000, 0.5), (190, 200, 0.97), (1995, 2000, 0.999) and (5, 2000, 0.01), withrel=1e-9;success_rate_ciagainst the issue's scipy reference bounds for 199/200, 297/300, 1000/2000 and 1990/2000 (four places,abs=1e-4), and the interval contains the point estimate;0.025 ** (1 / n).On
dev(c5affed) 8 of the new cases fail. The two CDF cases that pass there don't underflow. With the change,pytest tests/unit/utilities/test_statistics.py transformer_lens/utilities/statistics.pygives 40 passed, including the module doctests and the 0/6 → [0.0, 0.459] example.black --checkandisort --check-onlyare clean on both files. I ran all of this on Python 3.12 with CPU torch, offline in a container.Note: I used Claude Code while working on this.