Available via license: CC BY 4.0
Content may be subject to copyright.
ZERNIPAX: A Fast and Accurate Zernike Polynomial
Calculator in Python
Yigit Gunsur Elmacioglua,b, Rory Conlina,1 , Daniel W. Dudtc,1, Dario
Panicia,b, Egemen Kolemena,b,∗
aPrinceton University, Princeton, 08544, New Jersey, USA
bPrinceton Plasma Physics Laboratory, Princeton, 08543, New Jersey, USA
cThea Energy, Princeton, 08542, New Jersey, USA
dUniversity of Maryland, College Park, MD, 20742, Maryland, USA
Abstract
Zernike Polynomials serve as an orthogonal basis on the unit disc, and
have been proven to be effective in optics simulations, astrophysics, and
more recently in plasma simulations. Unlike Bessel functions, they main-
tain finite values at the disc center, ensuring inherent analyticity along the
axis. We developed ZERNIPAX, an open-source Python package capable
of utilizing CPU/GPUs, leveraging Google’s JAX package and available on
https://github.com/PlasmaControl/FastZernike.git as well as PyPI. Our im-
plementation of the recursion relation between Jacobi polynomials signifi-
cantly improves computation time compared to alternative methods by use of
parallel computing while still preserving accuracy for mode numbers n > 100.
Keywords: Zernike Polynomials, Optics, Astrophysics, Spectral
Simulations, Python, JAX, CPU/GPU Computing
1. Introduction
In computational science and engineering, the use of orthogonal polyno-
mials is essential for efficient numerical simulations and data analysis. Among
these, Zernike polynomials have garnered significant attention due to their
unique properties and versatility [1]. Zernike polynomials form an orthogonal
∗ekolemen@princeton.edu, +1 609-258-9209, D302D Engineering Quadrangle, Price-
ton, New Jersey, USA
1previously at Princeton University
Preprint submitted to Applied Mathematics and Computation October 1, 2024
arXiv:2409.19156v1 [cs.PF] 27 Sep 2024
basis on the unit disc, a characteristic that has proven invaluable in various
domains, including optics simulations[2, 3, 4, 5, 6], astrophysics[7, 8, 9, 10],
and more recently, plasma simulations of toroidal magnetic confinement ma-
chines [11, 12, 13]. Unlike Bessel functions, which can exhibit singularities at
the disc center, Zernike polynomials maintain finite values, ensuring inherent
analyticity at the axis.
In optics, Zernike polynomials are widely used to describe wavefronts in
optical systems [2, 3, 4, 5, 6]. They are particularly effective in representing
aberrations in lenses and mirrors, aiding in the design and optimization of
high-precision optical instruments. The benefits of Zernike polynomials in
optics make them useful in astrophysics applications that include the analysis
and simulation of telescope optics and the characterization of optical system
performance [7, 8, 9, 10]. They are employed to model the surface irregu-
larities of telescope mirrors, enabling researchers to predict and mitigate the
impact of these irregularities on image quality. Due to their orthogonality,
numerical simulations making use of the spectral method to solve partial
differential equations (PDEs) use Zernike polynomials as the basis functions
[14]. Within the plasma simulations [11, 12, 13], Zernike polynomials are
used as a spectral basis to represent the toroidal cross-section of highly com-
plex torus geometries of stellarators and tokamaks, hence facilitate solving
the PDEs describing the plasma.
The computational study of Zernike polynomials has a rich history, char-
acterized by the development of numerous methods to enhance their eval-
uation and application. Initially, computational approaches relied on di-
rect evaluation techniques. Despite their straightforward nature, these tech-
niques were often computationally expensive and prone to numerical insta-
bility. Over time, more sophisticated methods have emerged, such as the
use of recurrence relations [15, 16, 17, 18, 19, 20, 21]. These studies suc-
cessfully addressed instability issues for higher mode numbers and provided
fast algorithms for calculating Zernike polynomials. However, the proposed
recurrence relations require additional formulas for edge cases, adding mi-
nor complexity to coding implementations, particularly on GPUs, which are
relatively slow for conditional executions.
Recent advancements in parallel computing have spurred further efforts
to utilize computational resources more efficiently. Qin et al. employed
the Jacobi recursion relation in conjunction with the relationship between
Zernike and Jacobi polynomials to decouple radial polynomials and vectorize
operations [22]. They reported faster execution times than previous recursive
2
methods such as those by Prata, Kintner, and others. However, their imple-
mentation was limited to CPUs. Janssen et al. described Zernike polynomi-
als in terms of the discrete Fourier transform (DFT) [23], and a subsequent
study implemented the DFT approach for Zernike polynomial calculation
on GPUs [24]. Despite significant progress in improving the accuracy and
speed of Zernike polynomial computations, there remains a notable lack of
open-source packages that implement these advanced methods.
The widespread application of Zernike polynomials in the aforementioned
scientific fields underscores the need for robust computational tools that can
handle complex calculations efficiently. Addressing this demand, we intro-
duce ZERNIPAX, an open-source Python package designed to exploit the
computational power of both CPUs and GPUs. By leveraging Google’s JAX
library [25], ZERNIPAX provides significantly faster computation and higher
accuracy, particularly through the implementation of the Jacobi polynomial
expression of Zernike polynomials and the recursion relation for Jacobi poly-
nomials.
This paper presents ZERNIPAX’s capabilities and demonstrates its po-
tential as a valuable tool for the scientific community. Whether in astro-
physics, optics, or any field that relies on Zernike polynomials, ZERNIPAX
offers a streamlined and powerful solution for researchers seeking to improve
their computational workflows.
2. Zernike Polynomials
Zernike Polynomials are defined for ρ∈[0,1] and θ∈[0,2π] as,
Zm
n(ρ, θ) =
Rm
n(ρ) cos(mθ) for m≥0
R|m|
n(ρ) sin(|m|θ) for m < 0
(1)
where Rm
nis the radial part of the Zernike Polynomials and it is defined as,
R|m|
n(ρ) =
(n−|m|)/2
X
s=0
(−1)s(n−s)!
s! n+|m|
2−s!! n− |m|
2−s!!
ρn−2s(2)
3
which can also be written as
R|m|
n(ρ) =
(n−|m|)/2
X
s=0
(−1)sn−s
s n−2s
n−|m|
2−sρn−2s(3)
The mode numbers nand mare defined such that n≥0, |m| ≤ n, and
the difference n− |m|must be even. Therefore, possible values for m are
m={(−n),(−n+ 2), ..., (n−2), n}. Moreover, since binomial coefficients in
Equation 3 are always integers, the coefficients of the Zernike polynomials
are also integers. The value at the center of the unit disc can be found by
setting n−2sin Equation 2 to 0 since it gives the only polynomial term that
won’t be canceled by ρ=0. So, substituting s=n/2 results in,
R|m|
n(ρ= 0) = (−1)n/2
(−m/2)!(m/2)! (4)
Since negative values for the factorial are not allowed, the only possible value
for mis 0. Notice that this removes the dependency on θfor ρ=0. Fourier
expansions of analytic functions on the polar plane must obey certain con-
ditions as outlined by [26]. The use of the Zernike polynomials inherently
satisfies these conditions, making them an excellent basis for numerical sim-
ulation codes in polar coordinates.
Zm
n(ρ= 0, θ) = R0
n(0) =
1n= 4kwhere k= 0,1,2,3...
−1n= 4k−2 where k= 0,1,2,3...
0 otherwise
(5)
The (−1)sterm in Equation 2 causes the sign of the polynomial terms to
change which leads to reduced accuracy in floating-point summation and loss
of significant digits. Consequently, direct polynomial evaluation of Equation
2 is unstable. One can obtain the recursion relation for Zernike polynomials
as follows,
Rm
n(ρ) = ρhR|m−1|
n−1(ρ) + Rm+1
n−1(ρ)i− Rm
n−2(ρ) (6)
The implementation requires special care for edge cases where m+1 > n −1.
This corresponds to n=mand those polynomials are trivial to calculate
with a single term Rn
n(ρ) = ρn, however, this would require conditionals
which will slow down the algorithm when implemented in JAX.
4
The radial part of the Zernike Polynomials can also be calculated using
Jacobi Polynomials. The reader can refer to the Appendix Appendix A for
proof of this relation.
Rm
n(ρ)=(−1)(n−m)/2ρmPm,0
(n−m)/2(1 −2ρ2) (7)
where Pα,β
n(x) is a Jacobi polynomial that is defined as,
Pα,β
n(x) =
n
X
s=0 n+α
n−sn+β
sx−1
2sx+ 1
2n−s
(8)
This allows numerical simulations to use stable recurrence relations for the
Jacobi polynomials. Here is the recursion relations for Jacobi polynomials,
2n(c−n)(c−2)Pα,β
n(ρ) = (c−1)[c(c−2)ρ+(a−b)(c−2n)]Pα,β
n−1(ρ)−2(a−1)(b−1)cP α,β
n−2(ρ)
(9)
where,
c= 2n+α+β, a =n+α, b =n+β(10)
Derivatives of Jacobi Polynomials can be calculated using the Jacobi poly-
nomials itself with the following relation,
dk
dxkP(α,β)
n(x) = Γ(α+β+n+1+k)
2kΓ(α+β+n+ 1) P(α+k,β+k)
n−k(x) (11)
Hence, the stable recursion relation can be incorporated for the derivatives
too. However, instead of using the Gamma function for the relation, since
for Zernike polynomials mode numbers nand mas well as (n−m)/2 are
always integers, the argument of the Gamma function is an integer and one
can use the factorial version to get more accurate results.
dk
dxkP(α,β)
n(x) = (α+β+n+ 1)k
2kP(α+k,β+k)
n−k(x) (12)
where the Pochhammer function is defined as,
(α+β+n+ 1)k= (α+β+n+ 1)(α+β+n+ 2) . . . (α+β+n+k) (13)
For the implementation of Zernike polynomials, we choose the Jacobi
recursion relation expressed in Equation 7 since it is better suited to be
implemented in JAX and offers higher accuracy due to being a recursive
formula.
5
3. Methodology
In this section, we present the implementation of Zernike Polynomials
using the Python JAX package and the Jacobi recursion relationship for the
polynomial evaluation. Unlike previous studies that focus on the calculation
of a single mode, we optimized our implementation to calculate a given set
of modes as fast and as accurately as possible by storing the intermediate
results of the recursion operations. In addition, we created an open-source
Python library, ZERNIPAX, that includes different versions of the function
which are optimized for different input cases such as a unique set of modes
versus an input with duplicated modes2, as well as CPU and GPU-optimized
functions. Moreover, we have written our function to be compatible with
forward and reverse-mode automatic differentiation such that users can take
full advantage of JAX in projects involving Jacobian/Hessian calculations,
etc.
It can be observed from the recursion relation that starting from known
values Pα,0
0(x) and Pα,0
1(x), one can calculate Pα,0
(n−α)/2using Equation 9,
Therefore, for a single αof Jacobi (or equivalently, mof Zernike polynomial),
calculation of highest (n−α)/2 includes the calculation of every lower value.
So, a set of Zernike modes can be calculated with 2 nested for loops, the
former for distinct mvalues, and the latter for increasing nvalues for the
given m. Since we are calculating for a set of modes instead of a single one,
our algorithm significantly minimizes the number of repeated calculations.
A naive implementation of this algorithm might be very slow due to the
lack of performance of Python built-in for-loops. However, we use JAX
that supports parallelized for-loops and just-in-time (JIT) compilation to
execute operations in XLA (Accelerated Linear Algebra) and thus are able
to compute each mode extremely fast. Moreover, the stability of the Jacobi
recursion relation helps us to compute higher-order polynomials accurately.
The abovementioned method was successfully implemented on a CPU.
However, we observed significant performance degradation when running the
2For numerical simulations in 3D, a spectral code can use Zernike polynomials for the
polar plane and another basis for the remaining dimension, such as Fourier basis in case of
periodic boundaries (i.e. f(r, θ, ϕ) = Plmn Rm
n(r)Fm(θ)Fl(ϕ) where Rm
nis the radial part
of Zernike polynomials and Fis the Fourier basis). The coupling of different bases would
result in modes with the same (n, m) but different l. We call these duplicated modes since
the output of the Zernike Polynomial function will be the same.
6
algorithm on a GPU. This degradation was caused by the interruption of
loops to store intermediate results and check if these results were required.
To address this, we employed the naive implementation and vectorized the
execution of each mode to a separate GPU kernel. Each GPU kernel pro-
cesses a mode number (n, m) and executes the Jacobi recursion relation us-
ing Equation 9, without storing intermediate values or performing checks.
Despite the inherent inefficiencies of this GPU version, we achieved faster
computation times compared to the CPU for higher orders. The paralleliza-
tion effectively compensated for the additional computation time caused by
extra calculations.
4. Results
First, we will show the accuracy of our implementation by comparing it
to the high-precision calculation of the standard form of Zernike polynomials
given in Equation 2. The high precision method used to evaluate Equa-
tion 2 includes calculating the coefficients first, and since every operation
involves integers as operands and integers as output, the coefficients can be
calculated exactly in Python which provides infinite precision for integers
and integer arithmetics. The only operation that might cause floats is the
division, however, one can easily deduce that from Equation 3, all Zernike
radial coefficients are integers. Hence, integer division can be used. Then,
we evaluate the polynomial with these coefficients. To do so, we use mpmath
[27], a Python package allowing users to set arbitrary precision, and we eval-
uate polynomials up to order n=m= 50 with the precision set to 100.
The result with mpmath 100 precision is taken to be the exact values (see
Appendix Appendix B). Due to the additional precision, this method is ac-
curate but around 300 times slower compared to the same evaluation using
64-bit numpy. It is worth noting that by default JAX operations are in 32-bit
precision but for the results shown in this paper, we set it to 64 bits. The
results in this paper are obtained using Princeton University’s Della cluster
single-core Intel Cascade CPU and 80GB memory Nvidia A100 GPU.
In Figure 1, it can be seen that Jacobi recursion is much more stable
for higher mode numbers compared to the direct polynomial evaluation of
Equation 2 using 64-bit precision. We observe that although the polynomial
coefficients can be calculated exactly, the direct polynomial evaluation in 64
bits causes floating point errors to accumulate for higher-order cases.
7
Figure 1: Accuracy of Jacobi recursion relation in ZERNIPAX (left) compared to direct
polynomial evaluation (right) of a) radial part of Zernike Polynomials b) first derivative
c) second derivative d) third derivative. For the error, we evaluate both methods at 100
linearly spaced radial points for each (n, m) mode, and take the maximum absolute value
difference with the exact calculation (with mpmath 100 significant digit precision), ˜
Znm,
for the error of that mode.
Compared to most of the previous studies on Zernike Polynomials, in
this paper, we are sharing our code as an open-source library, instead of
explaining the methodology. Therefore, we will also compare the performance
of our code with the limited number of other open-source Zernike Polynomial
codes, such as ZERN [28], ZERNIKE [29] and ZERNPY [30], instead of
comparing it to our versions of different algorithms since the implementation
could significantly affect the performance of the algorithm. In Figure 2, it can
be seen that the codes using Jacobi recursion relation, namely ZERNIPAX
and ZERN, perform substantially better for high mode numbers, whereas
libraries ZERNIKE (which uses direct polynomial evaluation), and ZERNPY
(which uses direct polynomial evaluation until n= 10 and then switches
to the recursion relation of Zernike Polynomials in Equation 6) suffer from
numerical instabilities at higher mode numbers.
To compare computation time, we calculate the radial part of Zernike
Polynomials at 100 and 1000 linearly spaced points of ρfor a full set of
Zernike Polynomial modes for resolutions ranging from 10 to 100. Since
ZERNPY is documented to be slow for mode numbers greater than 50, it
is not included in the time comparison. In Figure 3, the time comparison
8
Figure 2: Comparison of the accuracies with 3 open-source codes, namely ZERN, ZERNPY
and ZERNIKE, respectively. For the error, maxx∈(0,1) |Znm(x)−˜
Znm(x)|, we evaluate
every code at 100 linearly spaced radial points for each (n, m) mode, and take the maximum
absolute value difference with the exact calculation (with mpmath 100 significant digit
precision), ˜
Znm, for the error of that mode.
of 3 different packages for both radial resolutions is shown with CPU and
GPU versions of ZERNIPAX. ZERNIPAX execution is more than an order
of magnitude faster. In the GPU case, we see even faster computations with
ZERNIPAX for higher modes. However, the other 2 packages perform the
same, since they are not able to run on GPU. Moreover, it can be seen that
for low resolutions, the CPU version of ZERNIPAX is faster for 100 linearly
spaced radial points, this is due to the creation of kernels on GPU being
overhead and the inefficiency of the GPU version mentioned in Section 3. As
we increase the number of radial points, hence the parallelization, the GPU
version becomes faster than the CPU version even for low resolutions.
An important point to note about the implementation with JAX is that
there are 400 milliseconds of overhead due to the just-in-time compilation
which is a single-time cost paid at the first execution of the function. Al-
though for low-resolution cases, the overhead is significant, we see that for
mode numbers higher than 80, the execution times of the other 2 codes are
longer even if we include the compilation time. If the function is called with
the same input dimensions3more than 10 times, it can be said that our
algorithm gives significantly faster results with resolutions above n=∼30.
3The just-in-time compilation in JAX compiles and stores the compiled function in
runtime for future use. The compiled version of the function is used if the input arguments
have the same dimensions as one of the previously compiled functions. However, if the
function is called with an unprecedented input shape, JAX will recompile the function.
Notice that the values can be different, the important point is the shapes of the arrays.
9
Figure 3: Execution time of the full set of radial Zernike Polynomials for both 100 and
1000 linearly spaced points along radial direction a) for resolutions n∈[10,100] in log
scale b) for resolutions n∈[10,30] on a linear scale. Packages ZERN and ZERNIKE can
only use CPU resources.
5. Conclusion
In this study, we developed an implementation of Zernike polynomials in
Python using JAX and the Jacobi recursion relation. Our approach demon-
strates a high level of computational accuracy, even for very high mode num-
bers (n≥100). Notably, the CPU version of our code exhibits performance
that is approximately ten times faster than other comparable open-source
implementations, while maintaining similar accuracy levels.
Furthermore, we extended our implementation to optimize performance
on GPU architectures. This optimization resulted in even faster computation
times for higher-order polynomials, showcasing the significant advantages of
leveraging parallel processing capabilities.
The integration of JAX in our Python implementation offers a dual ben-
efit: it provides a high-performance computational framework and facilitates
ease of use. This is particularly valuable in optimization routines, where
the convenience of automatic differentiation for Jacobian calculations is a
critical factor. The ability to perform efficient and accurate computations
while maintaining user-friendly code enhances the overall applicability of our
implementation in various scientific and engineering contexts.
Overall, our work represents a significant advancement in the computa-
tional evaluation of Zernike polynomials. By combining the robustness of
the Jacobi recursion relation with the computational efficiency of JAX, we
10
have created a powerful tool that can be readily incorporated into a wide
range of applications, from optical systems analysis to image processing and
beyond. Future work may explore further optimizations and extensions, po-
tentially incorporating other advanced computational techniques to enhance
performance and broaden the scope of applications.
6. Funding
This work is funded through the SciDAC program by the US Department
of Energy, Office of Fusion Energy Science and Office of Advanced Scientific
Computing Research under contract No. DE-AC02-09CH11466, as well as
DE-SC0022005 and Field Work Proposal No. 1019. The United States Gov-
ernment retains a non-exclusive, paid-up, irrevocable, world-wide license to
publish or reproduce the published form of this manuscript, or allow others
to do so, for United States Government purposes.
7. Data availability statement
The source code to generate the results and plots in this study are openly
available on GitHub at https://github.com/PlasmaControl/Zernike-Paper.
git. The latest version of ZERNIPAX can be accessed through https:
//github.com/PlasmaControl/FastZernike.git or can be used in Python
using pip package.
8. Declaration of generative AI and AI-assisted technologies in the
writing process
During the preparation of this work the author(s) used Yigit Gunsur
Elmacioglu in order to increase the readability of the text. After using this
tool/service, the author(s) reviewed and edited the content as needed and
take(s) full responsibility for the content of the publication.
References
[1] K. Niu, C. Tian, Zernike polynomials and their applications, Journal
of Optics 24 (12) (2022) 123001, publisher: IOP Publishing. doi:10.
1088/2040-8986/ac9e08.
URL https://dx.doi.org/10.1088/2040-8986/ac9e08
11
[2] J. Schwiegerling, J. E. Greivenkamp, J. M. Miller, Representation
of videokeratoscopic height data with Zernike polynomials, JOSA
A 12 (10) (1995) 2105–2113, publisher: Optica Publishing Group.
doi:10.1364/JOSAA.12.002105.
URL https://opg.optica.org/josaa/abstract.cfm?uri=
josaa-12-10-2105
[3] J. Schwiegerling, J. E. Greivenkamp, Using corneal height maps
and polynomial decomposition to determine corneal aberrations, Op-
tometry and Vision Science: Official Publication of the American
Academy of Optometry 74 (11) (1997) 906–916. doi:10.1097/
00006324-199711000-00024.
[4] D. Iskander, M. Collins, B. Davis, Optimal modeling of corneal surfaces
with Zernike polynomials, IEEE Transactions on Biomedical Engineer-
ing 48 (1) (2001) 87–95. doi:10.1109/10.900255.
URL http://ieeexplore.ieee.org/document/900255/
[5] M. M. Rodrigues, A. Rosa, N. Vieira, J. N. Murta, Modeling ophthalmic
surfaces using Zernike, Bessel and Chebyshev type functions, Journal of
Physics: Conference Series 1194 (1) (2019). doi:10.1088/1742-6596/
1194/1/012093.
[6] S. D. Klyce, M. D. Karon, M. K. Smolek, Advantages and disadvantages
of the Zernike expansion for representing wave aberration of the normal
and aberrated eye, Journal of Refractive Surgery (Thorofare, N.J.: 1995)
20 (5) (2004) S537–541. doi:10.3928/1081-597X-20040901-25.
[7] GRAVITY Collaboration, R. Abuter, A. Amorim, M. Baub¨ock, J. P.
Berger, H. Bonnet, W. Brandner, Y. Cl´enet, R. Davies, P. T.
De Zeeuw, J. Dexter, Y. Dallilar, A. Drescher, A. Eckart, F. Eisenhauer,
N. M. F¨orster Schreiber, P. Garcia, F. Gao, E. Gendron, R. Genzel,
S. Gillessen, M. Habibi, X. Haubois, G. Heißel, T. Henning, S. Hip-
pler, M. Horrobin, A. Jim´enez-Rosales, L. Jochum, L. Jocou, A. Kaufer,
P. Kervella, S. Lacour, V. Lapeyr`ere, J.-B. Le Bouquin, P. L´ena, D. Lutz,
M. Nowak, T. Ott, T. Paumard, K. Perraut, G. Perrin, O. Pfuhl,
S. Rabien, G. Rodr´ıguez-Coira, J. Shangguan, T. Shimizu, S. Schei-
thauer, J. Stadler, O. Straub, C. Straubmeier, E. Sturm, L. J. Tacconi,
F. Vincent, S. Von Fellenberg, I. Waisberg, F. Widmann, E. Wieprecht,
12
E. Wiezorrek, J. Woillez, S. Yazici, A. Young, G. Zins, Improved GRAV-
ITY astrometric accuracy from modeling optical aberrations, Astronomy
& Astrophysics 647 (2021) A59. doi:10.1051/0004-6361/202040208.
URL https://www.aanda.org/10.1051/0004-6361/202040208
[8] V. Capalbo, M. De Petris, F. De Luca, W. Cui, G. Yepes, A. Knebe,
E. Rasia, The Three Hundred project: quest of clusters of galaxies mor-
phology and dynamical state through Zernike polynomials, Monthly
Notices of the Royal Astronomical Society 503 (4) (2021) 6155–6169.
doi:10.1093/mnras/staa3900.
URL https://doi.org/10.1093/mnras/staa3900
[9] S. Bar´a, M. Nievas, A. S. d. Miguel, J. Zamorano, Zernike analysis of
all-sky night brightness maps, Applied Optics 53 (12) (2014) 2677–2686,
publisher: Optica Publishing Group. doi:10.1364/AO.53.002677.
URL https://opg.optica.org/ao/abstract.cfm?uri=
ao-53-12-2677
[10] S. Bar´a, V. Tilve, M. Nievas, A. S. d. Miguel, J. Zamorano, Zernike
power spectra of clear and cloudy light-polluted urban night skies,
Applied Optics 54 (13) (2015) 4120–4129, publisher: Optica Publishing
Group. doi:10.1364/AO.54.004120.
URL https://opg.optica.org/ao/abstract.cfm?uri=
ao-54-13-4120
[11] D. W. Dudt, E. Kolemen, DESC: A stellarator equilibrium
solver, Physics of Plasmas 27 (10) (2020) 102513. arXiv:https:
//pubs.aip.org/aip/pop/article-pdf/doi/10.1063/5.0020743/
15926767/102513\_1\_online.pdf,doi:10.1063/5.0020743.
URL https://doi.org/10.1063/5.0020743
[12] S. R. Hudson, R. L. Dewar, M. J. Hole, M. McGann, Non-
axisymmetric, multi-region relaxed magnetohydrodynamic equilibrium
solutions, Plasma Physics and Controlled Fusion 54 (1) (2011) 014005.
doi:10.1088/0741-3335/54/1/014005.
URL https://dx.doi.org/10.1088/0741-3335/54/1/014005
[13] Z. S. Qu, D. Pfefferl´e, S. R. Hudson, A. Baillod, A. Kumar, R. L. Dewar,
M. J. Hole, Coordinate parameterisation and spectral method optimi-
sation for Beltrami field solver in stellarator geometry, Plasma Physics
13
and Controlled Fusion 62 (12) (2020) 124004, publisher: IOP Publish-
ing. doi:10.1088/1361-6587/abc08e.
URL https://dx.doi.org/10.1088/1361-6587/abc08e
[14] J. P. Boyd, F. Yu, Comparing seven spectral methods for interpola-
tion and for solving the Poisson equation in a disk: Zernike polyno-
mials, Logan-Shepp ridge polynomials, Chebyshev-Fourier Series, cylin-
drical Robert functions, Bessel-Fourier expansions, square-to-disk con-
for, Journal of Computational Physics 230 (4) (2011) 1408–1438. doi:
10.1016/j.jcp.2010.11.011.
[15] C.-W. Chong, P. Raveendran, R. Mukundan, A comparative analysis
of algorithms for fast computation of Zernike moments, Pattern Recog-
nition 36 (3) (2003) 731–742. doi:10.1016/S0031-3203(02)00091-2.
URL https://linkinghub.elsevier.com/retrieve/pii/
S0031320302000912
[16] P. Nov´ak, J. Nov´ak, Efficient and stable numerical method for evalu-
ation of Zernike polynomials and their Cartesian derivatives, Munich,
Germany, 2013, p. 878913. doi:10.1117/12.2020389.
URL http://proceedings.spiedigitallibrary.org/proceeding.
aspx?doi=10.1117/12.2020389
[17] C. Singh, E. Walia, Fast and numerically stable methods for the
computation of Zernike moments, Pattern Recognition 43 (7) (2010)
2497–2506. doi:10.1016/j.patcog.2010.02.005.
URL https://linkinghub.elsevier.com/retrieve/pii/
S003132031000083X
[18] A.-W. Deng, C.-H. Wei, C.-Y. Gwo, Stable, fast computation of high-
order Zernike moments using a recursive method, Pattern Recognition
56 (2016) 16–25. doi:10.1016/j.patcog.2016.02.014.
URL https://linkinghub.elsevier.com/retrieve/pii/
S0031320316000856
[19] G. Papakostas, Y. Boutalis, C. Papaodysseus, D. Fragoulis, Numer-
ical stability of fast computation algorithms of Zernike moments,
Applied Mathematics and Computation 195 (1) (2008) 326–345.
doi:10.1016/j.amc.2007.04.110.
14
URL https://linkinghub.elsevier.com/retrieve/pii/
S0096300307005565
[20] E. C. Kintner, A Recurrence Relation for Calculating the Zernike Poly-
nomials, Optica Acta: International Journal of OpticsPublisher: Taylor
& Francis Group (Jun. 1976). doi:10.1080/713819279.
URL https://www.tandfonline.com/doi/abs/10.1080/713819279
[21] A. Prata, W. V. T. Rusch, Algorithm for computation of Zernike poly-
nomials expansion coefficients, Applied Optics 28 (4) (1989) 749–754,
publisher: Optica Publishing Group. doi:10.1364/AO.28.000749.
URL https://opg.optica.org/ao/abstract.cfm?uri=ao-28-4-749
[22] H. Qin, L. Qin, L. Xue, C. Yu, A parallel recurrence method for the
fast computation of Zernike moments, Applied Mathematics and Com-
putation 219 (4) (2012) 1549–1561. doi:10.1016/j.amc.2012.07.055.
URL https://www.sciencedirect.com/science/article/pii/
S0096300312007850
[23] A. Janssen, Computing Zernike polynomials of arbitrary degree using
the discrete Fourier transform, Journal of The European Optical Society-
rapid Publications - J EUR OPT SOC-RAPID PUBL 2 (Apr. 2007).
doi:10.2971/jeos.2007.07012.
[24] M. Al-Rawi, Ultra-Fast Zernike Moments using FFT and GPU (Apr.
2023).
[25] J. Bradbury, R. Frostig, P. Hawkins, M. J. Johnson, C. Leary,
D. Maclaurin, G. Necula, A. Paszke, J. VanderPlas, S. Wanderman-
Milne, Q. Zhang, JAX: composable transformations of Python+NumPy
programs (2018).
URL http://github.com/google/jax
[26] H. R. Lewis, P. M. Bellan, Physical constraints on the coefficients of
Fourier expansions in cylindrical coordinates, Journal of Mathemati-
cal Physics 31 (11) (1990) 2592–2596, publisher: American Institute of
Physics. doi:10.1063/1.529009.
URL https://aip.scitation.org/doi/10.1063/1.529009
15
[27] T. mpmath development team, mpmath: a Python library for arbitrary-
precision floating-point arithmetic (version 1.3.0), http://mpmath.org/
(2023).
[28] A. Menduina, Zern, https://github.com/AlvaroMenduina/ZERN.git.
URL https://github.com/AlvaroMenduina/ZERN.git
[29] J. Antonello, Zernike, https://github.com/jacopoantonello/zernike.git.
URL https://github.com/jacopoantonello/zernike.git
[30] S. Klykov, Zernpy, https://github.com/sklykov/zernpy.git.
URL https://github.com/sklykov/zernpy.git
Appendix A. Relation between Zernike Polynomials and Jacobi
Polynomials
For the special case of β= 0, x= 1 −2ρ2and α=m, Jacobi Polynomials
can be written using Equation 8,
Pm,0
n(1 −2ρ2) =
n
X
s=0
(−1)sn+m
n−sn
sρ2s(1 −ρ2)n−s(A.1)
Now use the binomial theorem to expand (1 −ρ2)n−s,
(1 −ρ2)n−s=
n−s
X
k=0
(−1)kn−s
kρ2k(A.2)
Substitute this in eq A.1,
Pm,0
n(1 −2ρ2) =
n
X
s=0
(−1)sn
sn+m
n−sρ2s
n−s
X
k=0
(−1)kn−s
kρ2k(A.3)
Now, rearrange the terms,
Pm,0
n(1 −2ρ2) =
n
X
s=0
n−s
X
k=0
(−1)(s+k)n+m
n−sn
sn−s
kρ2(s+k)(A.4)
16
Substitute j=s+k, hence k=j−s,
Pm,0
n(1 −2ρ2) =
n
X
s=0
j−s=n−s
X
j−s=0
(−1)jn+m
n−sn
sn−s
j−sρ2j(A.5)
Pm,0
n(1 −2ρ2) =
n
X
s=0
n
X
j=s
(−1)jn+m
n−sn
sn−s
j−sρ2j(A.6)
Here, we can change the order of summation, it is better to use table to find
new limits,
0 1 2 · · · n−1n
s= 0 × × × · · · × ×
s= 1 × × · · · × ×
s= 2 × · · · × ×
.
.
.....
.
..
.
.
s=n−1× ×
s=n×
Each ×represents a valid pair (s, j). This can be re-written in terms of
summation over jfirst, then s,
0 1 2 · · · n−1n
j= 0 ×
j= 1 × ×
j= 2 × × ×
.
.
....
j=n−1× × × · · · ×
j=n× × × · · · × ×
Since the (s, j) pairs are the same, the nested summation can be written as,
Pm,0
n(1 −2ρ2) =
n
X
j=0
ρ2j
j
X
s=0
(−1)j(n+m)!
(n−s)!(m+s)!
n!
s!(n−s)!
(n−s)!
(j−s)!(n−j)!
(A.7)
Pm,0
n(1 −2ρ2) =
n
X
j=0
ρ2j
j
X
s=0
(−1)j(n+m)!
(n−s)!(m+s)!
j!
s!(j−s)!
n!
j!(n−j)! (A.8)
Pm,0
n(1 −2ρ2) =
n
X
j=0
(−1)jn
jρ2j
j
X
s=0 n+m
n−sj
s(A.9)
17
Now, we need to use a property of the binomial coefficients. Consider,
(1 + x)n=
n
X
k=0 n
kxk(A.10)
(1 + x)n+m(1 + x)j= n+m
X
k=0 n+m
kxk! j
X
k=0 j
kxk!
= n
X
s=−mn+m
n−sxn−s! j
X
k=0 j
kxk!(A.11)
(1 + x)n+m+j=
n+m+j
X
k=0 n+m+j
kxk(A.12)
For xγcoefficient, we have
n+m+j
γxγ=
γ
X
k=0 j
kn+m
γ−kxγ(A.13)
In previous step, I used n−s+k=γand s=n+k−γ, hence n−s=γ−k.
Now, let’s substitute γ=n,
n+m+j
n=
j
X
k=0 n+m
n−kj
k(A.14)
We can finally use this relation to simplify eq A.9,
Pm,0
n(1 −2ρ2) =
n
X
j=0
(−1)jρ2jn
jn+m+j
n(A.15)
Lets’s multiply last equation by ρmand (−1)n,
(−1)nρmPm,0
n(1 −2ρ2) =
n
X
j=0
(−1)j+nρ2j+mn
jn+m+j
n(A.16)
Substitute j=n−s,
(−1)nρmPm,0
n(1 −2ρ2) =
n−s=n
X
n−s=0
(−1)2n−sρ2n+m−sn
n−s2n+m−s
n
(A.17)
18
(−1)l−m
2ρmPm,0
l−m
2
(1 −2ρ2) =
(l−m)/2
X
s=0
(−1)sρl−2sl−m
2
sl−s
l−m
2(A.18)
(−1)l−m
2ρmPm,0
l−m
2
(1 −2ρ2) =
(l−m)/2
X
s=0
(−1)s
l−m
2!
s!(l−m
2−s)!
(l−s)!
l−m
2!(l+m
2−s)!ρl−2s
(A.19)
Rm
l(ρ)=(−1)l−m
2ρmPm,0
l−m
2
(1 −2ρ2)
=
(l−m)/2
X
s=0
(−1)s(l−s)!
s! l+m
2−s!! l−m
2−s!!
ρl−2s(A.20)
which is exactly equivalent to the radial part of the Zernike Polynomials.
Appendix B. Validity of chosen precision in mpmath
The accuracy of different algorithms is tested using the mpmath package
which allows arbitrary precision in Python. A user can set different decimal
point precisions with the option mpmath.mp.dps that will change the number
of significant digits used in mpmath functions such as fsub() for subtraction
and fadd() for addition. The corresponding bit precision can be found using
mpmath.mp.prec and the relation is shown in Figure B.4.
We performed the direct polynomial evaluation of Zernike polynomials
up to n, m=100 with different decimal point precisions and compared the
difference with an excessively high value of 200 significant digits. Since the
machine precision of 64 bits is aimed for the final result, we use the native
Python subtraction operation for error calculation.
After mpmath.mp.dps=54, the difference calculated with Python subtrac-
tion is 0. This corresponds to 153-bit precision. To be able to show the results
on a log scale in Figure B.5, we have set the 0 values to 64-bit machine preci-
sion that is 2−53. Although the required precision is 54 dps, we have chosen
100 dps for the results of this paper just to be on the safe side and to be
able to use the same functions for higher mode numbers which require higher
precision.
19
Figure B.4: The corresponding bit precision of different mpmath decimal point precisions
shown for range [8,100]. 64-bit precision can be achieved by setting dps to 18. The
minimum value chosen for this figure dps=8 has 30-bit and the maximum value dps=100
has 336-bit precision.
Figure B.5: The maximum difference between Zernike polynomials up to n, m=100 calcu-
lated with lower dps and 200 dps,˜
Znm(x). For the log scale, 0’s are set to 2−53 .
20