Expand description
The batch Zernike kernel: every mode through degree L at one point, in Cartesian
coordinates.
§The Cartesian substitution
The polar definition $Z_n^m = R_n^{|m|}(\rho)\cos(m\theta)$ suggests a sin_cos per
mode and a powi per mode. Both disappear under one substitution.
Write $s = x^2 + y^2 = \rho^2$. The radial polynomial factors as
R_n^{|m|}(\rho) = \rho^{|m|}\, Q_{k,|m|}(s), \qquad
Q_{k,m}(s) = P_k^{(0,m)}(2s - 1), \qquad k = \tfrac{n - |m|}{2}so the $\rho^{|m|}$ is the only place an odd power of $\rho$ appears, and
$Q$ is an honest polynomial in s. Meanwhile
(x + iy)^m = \rho^m\left(\cos m\theta + i \sin m\theta\right)so $\rho^{|m|}\cos(m\theta)$ and $\rho^{|m|}\sin(m\theta)$ are exactly the real and
imaginary parts of $(x+iy)^{|m|}$, which come off a two-line complex ladder. The
$\rho^{|m|}$ the radial part needed and the $\rho^{|m|}$ the angular part produced
are the same factor, so they never have to be formed separately:
Z_n^m = Q_{k,|m|}(s) \times \begin{cases}\operatorname{Re}(x+iy)^{m} & m \ge 0\\
\operatorname{Im}(x+iy)^{|m|} & m < 0\end{cases}The whole basis is therefore pure polynomial arithmetic in (x, y): no atan2, no
sqrt, no trigonometry, no division, $O(L^2)$ FMAs total, and no singularity at the
pupil centre (which the polar form has, in $\partial_\theta Z / \rho$).
Taking (x, y) rather than $(\rho, \theta)$ is thus not a convenience: a polar entry
point would make the caller pay an atan2 per sample to build an angle this kernel
immediately destroys. Pupil samples arrive as Cartesian coordinates anyway.
§The recurrence
$Q_{k,m}$ is the Jacobi three-term recurrence rewritten in s rather than
$t = 2s-1$, which folds the change of variable into the coefficients instead of
spending an operation on it per mode:
Q_{0,m} = 1,\qquad Q_{1,m}(s) = (m+2)s - (m+1)Q_{k,m} = (A_{k,m}\,s + B_{k,m})\,Q_{k-1,m} - C_{k,m}\,Q_{k-2,m}with, writing $c = 2k(k+m)(2k+m-2)$,
A = \frac{2(2k+m-1)(2k+m)(2k+m-2)}{c},\quad
B = \frac{-(2k+m-1)(m^2 + (2k+m)(2k+m-2))}{c},\quad
C = \frac{2(k-1)(k+m-1)(2k+m)}{c}Every coefficient is a ratio of small integers - the largest through L = 16 is 3360,
comfortably exact in f32 - and at stamped literal (k, m) they fold to .rodata
constants. Three operations per mode: one FMA for As + B, one multiply, one FMA.
Running the recurrence in k at fixed m is what makes this $O(L^2)$ rather than
the $O(L^3)$ of calling the single-mode entry point per mode, which restarts the
recurrence from k = 0 every time.
§Layout
out[j] for the ANSI Z80.28 / OSA index j = (n(n+2) + m)/2, so N must be
(L+1)(L+2)/2. ANSI is the layout rather than Noll or Fringe because it is the
scheme whose index is a closed form and whose degree truncation is contiguous;
noll_to_ansi and
fringe_to_ansi gather from it.
Nothing normalizes (x, y) onto the unit disc, exactly as the spherical-harmonic
kernels do not renormalize their direction. Outside it the polynomials are still
evaluated correctly and simply are not orthogonal.
Constants§
- MAX_
DEGREE - Highest degree the stamped ladder below covers. Beyond it the kernel takes the
rolled path, which is correct at any degree but computes its coefficients at runtime
and does not unroll. Extending the ladder is mechanical: append literals to the
mlist and, every two degrees, to theklist.
Functions§
- reduced_
radial_ impl - The reduced radial polynomial
$Q_{k,m}(s) = P_k^{(0,m)}(2s - 1)$at runtime(k, m). - zernike_
basis_ d_ impl zernike_basis_implplus the Cartesian gradient of every mode.- zernike_
basis_ impl - Every Zernike mode through degree
Lat the Cartesian point(x, y).