pub fn legendre_series<E, V, const N: usize>(x: V, coeffs: &[E; N]) -> Vwhere
E: FloatElement,
V: FloatVector<Element = E>,Expand description
Clenshaw summation of a Legendre series, $\sum_{k=0}^{N-1} c_k P_k(x)$.
The Legendre recurrence (k+1) P_{k+1} = (2k+1) x P_k - k P_{k-1} is
P_{k+1} = a_k x P_k + b_k P_{k-1} with a_k = (2k+1)/(k+1) and b_k = -k/(k+1), so
Clenshaw’s adjoint recurrence is
y_k = c_k + a_k x y_{k+1} + b_{k+1} y_{k+2} k = N-1 down to 1, y_N = y_{N+1} = 0
S = c_0 + x y_1 + b_1 y_2 = c_0 + x y_1 - y_2 / 2Both ratios depend only on k, which is a compile-time constant at every step of the
unrolled loop, so they fold to literals. The per-step critical path is the one FMA
that carries y_{k+1}, exactly as in the Chebyshev kernel. Unlike that kernel there is
no endpoint-cancellation variant here: P_n(1) = 1 for every n makes the same
degeneracy exist at $x = \pm 1$, but its Reinsch-style rewrite has not been derived
or measured, so this is plain Clenshaw at every policy, which is why, unlike its
siblings, this kernel takes no policy parameter.