Skip to content

Rewrite J1's (4, 8] rational exactly to avoid cancellation - #1627

Merged
NAThompson merged 1 commit into
developfrom
bessel-j1-accuracy
Nov 3, 2026
Merged

NAThompson merged 1 commit into
developfrom
bessel-j1-accuracy

Conversation

@NAThompson

@NAThompson NAThompson commented Nov 3, 2026 •

Copy link
Copy Markdown
Collaborator

The same approximation, expanded in t = (x^2 - 40) / 24 with its root near j(1,1) divided out.
Double error on (4, 8] drops from 85 ulps to under 4.

Closes #1626

The (4, 8] branch evaluated P2(x²), whose alternating coefficients cancel by up to 62x. This rewrites the same rational function exactly (no refit): P2 is divided by (y − r₀), r₀ its root near j(1,1)², and both polynomials are re-expanded about y = 40. The remaining cancellation is at most 5.8x. Evaluated at 80 digits, the new form agrees with the old one to 9e-20 on [4, 8], so the long double approximation is unchanged.

develop this PR
double, max relative error on (0, 20], |J₁| > 0.1 58.6 eps (x = 7.695) 3.9 eps (x = 3.401, the untouched (0, 4] branch)
double, max absolute error on [4, 8] 16.3 eps 1.0 eps
64-bit mantissa (x87 long double), max relative error 55.9 eps 9.2 eps (the fit itself is 5.6)
cyl_bessel_j(1, x) on (4, 8] 7.2 ns 7.7 ns

Integer orders computed by recurrence from J₁ get the fix too: J₇(7.695) went from −58 to 0.7 eps and J₁₀(7.902) from −82 ulps to 0.7 eps.

cyl_bessel_j(1, x) on [4, 8], develop (orange) vs this PR (blue)
j1

This PR alone
j1_pr

Near the x = 4 and x = 8 branch points
j1_at_4
j1_at_8

cyl_bessel_j(7, x) on [5, 8], where its recurrence uses J₁ on (4, 8]
j7

Apple M-series, clang -O2; benchmark in reporting/performance/cyl_bessel_j_performance.cpp. Y₁'s (4, 8] branch has the same kind of cancellation; that is for a separate PR.

🤖 Generated with Claude Code

The same approximation, expanded in t = (x^2 - 40) / 24 with its root near j(1,1) divided out.
Double error on (4, 8] drops from 85 ulps to under 4.

Closes #1626

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@NAThompson
NAThompson merged commit 656d3b3 into develop Nov 3, 2026
51 checks passed
@NAThompson
NAThompson deleted the bessel-j1-accuracy branch November 3, 2026 15:28
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.

cyl_bessel_j(1, x) loses up to 85 ulps for 4 < x < 8 in double

1 participant