test: migrate math/base/special/ellipj to ULP-based assertions - #14788
test: migrate math/base/special/ellipj to ULP-based assertions#14788aryan7071 wants to merge 1 commit into
math/base/special/ellipj to ULP-based assertions#14788Conversation
Coverage Report
The above coverage report was generated for the changes in this PR. |
| tol = 40.0 * EPS; | ||
| t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', dn: '+dn+'. E: '+dnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); | ||
| } | ||
| t.strictEqual( isAlmostSameValue( sn, snExpected[i], 4750 ), true, 'returns expected value' ); |
There was a problem hiding this comment.
This looks off to me. How did we go from 18*EPS to 4750? I think you should double-check all these values.
There was a problem hiding this comment.
@kgryte, I ran a script to compute the actual ULP distance between the computed and fixture-expected values directly, rather than deriving it from the old EPS multiplier, for every value in every block.
All the outliers follow the same pattern: the absolute differences are in the 1e-15–1e-16 range, which is essentially a few units of double-precision floating-point noise. The relatively large ULP counts occur because these particular outputs are small in magnitude, where the representable gap between adjacent floating-point values is much finer.
Here’s the full breakdown:
| Block | ULP 1 | ULP 2 | ULP 3 |
|---|---|---|---|
| Medium positive modulus | 4750 | 9327 | 155 |
| Modulus near unity | 9944 | 12 | 12 |
| Small positive modulus | 9866 | 9792 | 1 |
| Zero modulus | 1 | 1 | (exact - untouched) |
| Unity modulus | 1 | 2 | 2 |
I also verified each of these outliers individually, and none appears to indicate an actual correctness issue.
Would you recommend that I add a short comment in the test file documenting why these higher ULP values occur, so the reasoning is clear for future reference?
Progresses #11352
Description
This pull request:
Most ULP bounds were carried over from the pre-existing tolerance blocks and verified to be the minimum integer that still passes across each fixture (medium_positive_modulus, near_unity_modulus, small_positive_modulus, zero_modulus, unity_modulus, and spot_checks in test.assign.js only).
One outlier is worth calling out explicitly. In the spot_checks fixture (test/test.assign.js), the case u=60, m=0.9999999999 requires much larger ULP bounds than any other input in that block: cn=986545, dn=986506 (versus sn=154 for the same block). Inspecting the actual computed values shows this is not a correctness issue actual and expected agree to roughly 10 significant digits (e.g. cn: 0.00044827749287320586 vs 0.00044827749281972515, an absolute difference of ~5.3e-14). At this input, m is extremely close to 1 (a known difficult region for Jacobi elliptic functions) and cn/dn evaluate to very small magnitudes (~4.5e-4), where the representable floating-point gap is extremely fine, so even a tiny absolute error translates into a large ULP count. The am comparison for the same row already used a fixture-supplied tolerance of 250, consistent with the fixture's author anticipating this row was numerically harder than the others.
Related Issues
This pull request has the following related issues:
math/base/specialpackages from relative tolerance testing to ULP difference testing (tracking issue) #11352Questions
No.
Other
No.
Checklist
AI Assistance
If you answered "yes" above, how did you use AI assistance?
Disclosure
{{TODO: add disclosure if applicable}}
@stdlib-js/reviewers