Skip to content

Fix non-terminating Newton iterations in erfinv/erfcinv for BigFloat - #559

Open
devmotion wants to merge 1 commit into
masterfrom
dmw/erfinv-bigfloat-termination
Open

devmotion wants to merge 1 commit into
masterfrom
dmw/erfinv-bigfloat-termination

Conversation

@devmotion

Copy link
Copy Markdown
Member

Fixes #557.

The iteration has two representation floors, but only one was tested: the correction falling below the resolution of x. The residual erfc(x) - y cannot go below the resolution of erfc(x), and that noise is amplified into the step by 1 / erfc'(x) = sqrtπhalf * exp(x^2). Whenever sqrtπhalf * exp(x^2) * eps(y) > 2eps(x) the tested condition is unattainable and the iterates end up in a two-cycle. So the residual is now checked as well.

This affects roughly 1–3% of random arguments at every precision. erfinv is affected in the same way for y close to ±1 (erfinv(big"0.96") hangs on master), so it is fixed too.

2eps(y) rather than eps(y): when erfc(x) sits one binade above y, the smallest attainable nonzero residual is already 2eps(y).

Verified with 25000 inversions over precisions 64/128/256/512/1024 in four regimes (mid-range, y → ±1, y → 0, y → 2): no hangs, round-trips within 8eps(BigFloat), and accuracy unchanged against a precision + 128 reference.

🤖 Generated with Claude Code

The iteration has two representation floors but only tested one: the
correction falling below the resolution of `x`. The residual `erfc(x) - y`
cannot go below the resolution of `erfc(x)`, and that noise is amplified
into the step by `1 / erfc'(x) = sqrtπhalf * exp(x^2)`. Whenever
`sqrtπhalf * exp(x^2) * eps(y) > 2eps(x)` the tested condition is
unattainable and the iterates end up in a two-cycle.

Check the residual as well. `erfinv` is affected in the same way for `y`
close to ±1.

Fixes #557

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@codecov

codecov Bot commented Sep 22, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.67%. Comparing base (b2a7190) to head (c1d35f9).

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #559   +/-   ##
=======================================
  Coverage   94.67%   94.67%           
=======================================
  Files          14       14           
  Lines        3023     3025    +2     
=======================================
+ Hits         2862     2864    +2     
  Misses        161      161           
Flag Coverage Δ
unittests 94.67% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

This branch has not been deployed

No deployments
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.

Bug: both erfcinv(2big"0.8") and erfcinv(2big(0.41)) do not terminate.

1 participant