Skip to main content

legendre_series

Function legendre_series 

Source
pub fn legendre_series<E, V, const N: usize>(x: V, coeffs: &[E; N]) -> V
where 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 / 2

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

Last built: 2026-09-08 21:35:55 UTC