Skip to content

fix: evaluate large arguments accurately in math/base/special/fresnel, fresnelc and fresnels - #16118

Draft
Abhist17 wants to merge 1 commit into
stdlib-js:developfrom
Abhist17:fix/fresnel-large-arguments
Draft

Abhist17 wants to merge 1 commit into
stdlib-js:developfrom
Abhist17:fix/fresnel-large-arguments

Conversation

@Abhist17

@Abhist17 Abhist17 commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Description

What is the purpose of this pull request?

This pull request:

  • fixes the large-argument branch of math/base/special/fresnel, fresnelc and fresnels (JS and C; the three packages carry the same code).

Two problems, both inherited from Cephes:

  1. For x > 36974, the functions returned exactly 0.5. The oscillating part of C(x) and S(x) is f(x) sin(πx²/2) - g(x) cos(πx²/2) with f(x) ≈ 1/(πx), which is 3.2e-6 at x = 1e5:

    var fresnelc = require( '@stdlib/math/base/special/fresnelc' );
    
    fresnelc( 100000.37 );
    // develop: 0.5
    // this PR: 0.5000006792295584 (mpmath: 0.5000006792295584)
  2. Below that, sincos( HALF_PI * x2 ) used the rounded x*x. An error of ε x² there becomes πεx²/2 radians in the argument, which at x = 1e4 is about 1.7e-8. On the medium fixtures ([100, 36968]), develop is off by up to 81920 ULPs.

The fix reduces x² modulo 4 (the period of sin/cos( πu/2 )) exactly. A Veltkamp split x = hi + lo makes hi*hi, 2*hi*lo and lo*lo exact, and each term is reduced with fmod. The asymptotic branch then runs up to x = 1e16, beyond which 1/(πx) is below half an ulp of 0.5.

  • replaces the C/Cephes fixtures, which were generated by the code being fixed and checked at 0 ULPs, with a Julia runner that evaluates both integrals in 2048-bit BigFloat: the power series below x = 10, and the asymptotic expansions of f and g (Abramowitz and Stegun 7.3.27–28) above it. I spot-checked it against mpmath. Same ranges as before, except that huge.json now runs log-spaced up to 1e15:
set develop this PR
small [1e-4, 9.99] 20 ULPs 5 ULPs
medium [100, 36968] 81920 0
large [4e4, 6e4] ~1.7e11 (returns 0.5) 0
huge [6e4, 1e15] ~1.7e11 (returns 0.5) 0

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

…l`, `fresnelc` and `fresnels`

Above `x = 36974` the functions returned exactly `0.5`, the Cephes cut-off,
although the oscillating terms are of size `1/(πx)` (`3e-6` at `x = 1e5`).
Below it, `sincos( π x^2 / 2 )` was evaluated on the rounded `x*x`, whose
error the large argument turns into whole radians (81920 ULPs on the
medium fixtures). Reduce `x^2` modulo 4 exactly, with a Veltkamp split
so that each partial product is exact, and keep the asymptotic branch up
to `x = 1e16`, where `1/(πx)` is below half an ulp of `0.5`.

The fixtures came from Cephes itself and pinned both effects at 0 ULPs.
They are replaced by a Julia runner evaluating the Fresnel integrals in
BigFloat (power series below 10, the asymptotic expansions of `f` and
`g` above); the medium, large and huge sets now pass at 0 ULPs, and the
huge set extends to `1e15`.

Signed-off-by: Abhist17 <abhistkamle.170903@gmail.com>
@Abhist17
Abhist17 requested a review from a team October 13, 2026 13:55
@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

Hello! Thank you for your contribution to stdlib.

We noticed that the contributing guidelines acknowledgment is missing from your pull request. Here's what you need to do:

  1. Please read our contributing guidelines.

  2. Update your pull request description to include this checked box:

    - [x] Read, understood, and followed the [contributing guidelines](https://github.com/stdlib-js/stdlib/blob/develop/CONTRIBUTING.md)

This acknowledgment confirms that you've read the guidelines, which include:

  • The developer's certificate of origin
  • Your agreement to license your contributions under the project's terms

We can't review or accept contributions without this acknowledgment.

Thank you for your understanding and cooperation. We look forward to reviewing your contribution!

@stdlib-bot

Copy link
Copy Markdown
Contributor

Coverage Report

Package Statements Branches Functions Lines
math/base/special/fresnel $\\color{red}604/616$
$\\color{green}+98.05\\%$
$\\color{red}28/36$
$\\color{green}+77.78\\%$
$\\color{green}7/7$
$\\color{green}+100.00\\%$
$\\color{red}604/616$
$\\color{green}+98.05\\%$
math/base/special/fresnelc $\\color{red}446/455$
$\\color{green}+98.02\\%$
$\\color{red}22/28$
$\\color{green}+78.57\\%$
$\\color{green}5/5$
$\\color{green}+100.00\\%$
$\\color{red}446/455$
$\\color{green}+98.02\\%$
math/base/special/fresnels $\\color{red}446/455$
$\\color{green}+98.02\\%$
$\\color{red}22/28$
$\\color{green}+78.57\\%$
$\\color{green}5/5$
$\\color{green}+100.00\\%$
$\\color{red}446/455$
$\\color{green}+98.02\\%$

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

@kgryte kgryte left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is where it would benefit you to attend office hours and seek alignment before opening many PRs. You should not be deleting existing fixtures, as you need to understand their intent.

In this case (and others), we need the reference fixtures in order to access how well our implementation aligns with the reference implementation. If we notice large divergences, that tells us that something may be off with our implementation. Our special function tests are not just about total accuracy, they are also about helping us assess drift from a reference implementation.

So, in general, your approach in all these PRs is off. There is room for both reference implementation fixtures and arbitrary precision fixtures. One does not preclude the existence of the other. What it means is that we may need to duplicate tests so that we have separate test files exercising the different fixtures.

But again, this is where you need to seek alignment, rather than opening now dozens of similar PRs, none of which have been merged.

@Abhist17

Copy link
Copy Markdown
Contributor Author

@kgryte thank you, that is clear, and I am sorry for the volume. I misread what the reference fixtures are for. I've moved this PR and the others like it (#16109–#16117, #16119) to draft, and I won't open more until we have agreed on the approach.

Here is how I'd rework them. Please correct me if any of it is off:

  1. Restore every reference fixture I deleted or regenerated (Cephes, Boost/C++, SciPy, Julia Float64) and the runners that produce them, unchanged.
  2. Keep the existing tests against those fixtures.
  3. Put the arbitrary-precision (Julia BigFloat) fixtures in their own directory, with a separate test file per implementation exercising them, so the two kinds of check stay apart.

One thing I'd like your view on before I touch the tests. In some packages the change deliberately departs from the reference implementation where the reference itself is inaccurate. Here, Cephes returns exactly 0.5 for x > 36974, so this PR differs from the large/huge Cephes fixtures by up to ~1e11 ULPs. Similarly, coversin near sin(x) = 1 differs from Julia's Float64 1 .- sin.(x) by up to ~2^22 ULPs. For the reference tests there, would you rather I:

  • (a) keep them over the full range with a tolerance widened to the measured divergence and a comment explaining why, or
  • (b) restrict them to the region where the implementation still follows the reference, and leave the rest to the arbitrary-precision tests?

@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.

3 participants