Skip to content

fix: avoid amplifying the rounding of x^2 for negative x in math/base/special/erfcx - #16114

Draft
Abhist17 wants to merge 1 commit into
stdlib-js:developfrom
Abhist17:fix/erfcx-negative-exp-square
Draft

Abhist17 wants to merge 1 commit into
stdlib-js:developfrom
Abhist17:fix/erfcx-negative-exp-square

Conversation

@Abhist17

Copy link
Copy Markdown
Contributor

Description

What is the purpose of this pull request?

This pull request:

  • evaluates exp(x^2) in the negative branch of math/base/special/erfcx as exp(xh^2) * exp((x-xh)*(x+xh)) (JS and C), where xh is x truncated to 16 fractional bits, so xh*xh is exact and the second factor is close to one.

For x < 0, erfcx(x) = 2 exp(x^2) - erfcx(-x). Forming x*x rounds it, and exp turns that absolute error of about x^2 ε into a relative error of the same size. That is several hundred ULPs once x^2 is in the hundreds:

var erfcx = require( '@stdlib/math/base/special/erfcx' );

erfcx( -25.150567895691 );
// develop: 1.0338731430900656e+275
// this PR: 1.033873143090124e+275 (256-bit BigFloat: 1.033873143090124e+275)

On the new fixture (2001 points in [-26.6, -1]), develop is off by up to 493 ULPs and this PR by up to 2.

  • moves medium_negative.json ([-10, -1], same grid) from the SciPy runner to a Julia runner that evaluates erfcx in 256-bit BigFloat. SciPy's erfcx uses the same Faddeeva-package construction, so its values carried the same error, up to 59 ULPs at x = -9.19284876905041 (SciPy 1.005985069797548e37, BigFloat 1.0059850697975548e37). That test is now checked at 2 ULPs instead of 1.
  • adds negative.json, down to -26.6, just above where the function overflows (-26.7).

Related Issues

Does this pull request have any related issues?

None.

Questions

Any questions for reviewers of this pull request?

No.

Other

Any other information relevant to this pull request? This may include screenshots, references, and/or implementation notes.

test.js and test.native.js pass.

Checklist

Please ensure the following tasks are completed before submitting this pull request.

AI Assistance

When authoring the changes proposed in this PR, did you use any kind of AI assistance?

  • Yes
  • No

If you answered "yes" above, how did you use AI assistance?

  • Code generation (e.g., when writing an implementation or fixing a bug)
  • Test/benchmark generation
  • Documentation (including examples)
  • Research and understanding

…/base/special/erfcx`

For negative `x`, `erfcx(x) = 2 exp(x^2) - erfcx(-x)`, and `exp( x*x )`
multiplies the rounding error of `x*x` by `x^2`: `erfcx( -25.15 )` was
off by about 380 ULPs, and the error reaches about 490 ULPs before the
function overflows. Split `x = xh + xl` so that `xh*xh` is exact and use
`exp(xh^2) * exp(xl*(x+xh))`.

The medium negative fixtures came from SciPy, whose `erfcx` has the same
construction; they are now generated in BigFloat by a Julia runner, along
with a new set down to `-26.6`.

Signed-off-by: Abhist17 <abhistkamle.170903@gmail.com>
@Abhist17
Abhist17 requested a review from a team October 13, 2026 13:31
@stdlib-bot stdlib-bot added Math Issue or pull request specific to math functionality. Needs Review A pull request which needs code review. labels Oct 13, 2026
@stdlib-bot

Copy link
Copy Markdown
Contributor

Coverage Report

Package Statements Branches Functions Lines
math/base/special/erfcx $\\color{red}1373/1448$
$\\color{green}+94.82\\%$
$\\color{green}95/95$
$\\color{green}+100.00\\%$
$\\color{red}79/104$
$\\color{green}+75.96\\%$
$\\color{red}1373/1448$
$\\color{green}+94.82\\%$

The above coverage report was generated for the changes in this PR.

@Abhist17
Abhist17 marked this pull request as draft October 14, 2026 04:17
@stdlib-bot stdlib-bot removed the Needs Review A pull request which needs code review. label Oct 14, 2026

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

Math Issue or pull request specific to math functionality.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants