pub fn series_j_nu<P, E, V>(nu: V, x: V, needed: V::Mask) -> Vwhere
E: FloatElement,
V: FloatVector<Element = E> + SpecializedTranscendentalMath<E> + SpecializedSpecialMath<E>,
P: Policy,Expand description
$J_\nu(x)$ by its ascending series, at arbitrary real order, for small x.
J_\nu(x) = \sum_{k\ge 0} \frac{(-1)^k}{k!\,\Gamma(\nu+k+1)}\left(\frac{x}{2}\right)^{\nu+2k}advanced by the ratio $t_{k+1}/t_k = -\frac{(x/2)^2}{(k+1)(\nu+k+1)}$, so the only
per-order quantity is the seed. No table at any order, like the rest of this module.
§Domain: roughly $x \lesssim 6$, and the limit is cancellation not convergence
The series converges everywhere, and Boost’s own comment says so (“this series will actually converge rapidly for all small x - say up to x < 20”) before adding “but the first few terms are large and divergent which leads to large errors :-(”. That is the real bound.
The terms peak near $k \approx x$ at a magnitude around $e^{x}/(\pi x)$ while the
answer is $O(x^{-1/2})$, so summing them loses about
$1.4427x - \log_2\sqrt{2\pi x}$ bits. Measured envelope-relative at $\nu = 1/3$ in
binary64: 0.00 eps at x = 8, 158 at x = 10, 6.1e3 at x = 12. So it is usable to
about 8 and comfortable to 6, and the (6, 16) hole between here and
[hankel_j_nu] is a real gap that neither arm covers
(notes/special/tools/model_fractional_arms.py).
Nothing here detects that. The caller gates on x.
§The seed sets the accuracy floor
Every term is proportional to $t_0 = (x/2)^\nu / \Gamma(\nu+1)$, so the seed’s relative
error passes straight through to the result and nothing later can recover it. That is one
powf and one tgamma, so the floor is roughly their combined error (about 2 ulp), and
no amount of extra terms improves it.
$\Gamma(\nu+1)$ has poles at negative integer $\nu$, where the seed becomes zero rather
than infinite. Negative integer orders never arrive here: they reflect through
$J_{-n} = (-1)^n J_n$ before any kernel sees them.