pyzernike.zernike_polynomial_up_to_order#

pyzernike.zernike_polynomial_up_to_order(rho: ndarray, theta: ndarray, order: Integral, rho_derivative: array | Sequence[Integral] | None = None, theta_derivative: array | Sequence[Integral] | None = None, default: Real = nan, precompute: bool = True) List[List[ndarray]][source]#

Computes all the Zernike polynomials \(Z_n^m\) for \(\rho \leq 1\) and \(\theta \in [0, 2\pi]\) up to a given order.

The Zernike polynomial is defined as follows:

\[Z_{n}^{m}(\rho, \theta) = R_{n}^{m}(\rho) \cos(m \theta) \quad \text{if} \quad m \geq 0\]
\[Z_{n}^{m}(\rho, \theta) = R_{n}^{-m}(\rho) \sin(-m \theta) \quad \text{if} \quad m < 0\]

If \(\rho\) is not in \(0 \leq \rho \leq 1\) or \(\rho\) is numpy.nan, the output is set to the default value (numpy.nan by default).

See also

This function allows to compute Zernike polynomials at once for different sets of derivative orders given as sequences, which can be more efficient than calling the function multiple times for each set of derivative orders.

  • The parameters rho and theta must be numpy arrays of the same shape.

  • The parameters rho_derivative and theta_derivative must be sequences of integers with the same length.

The \(\rho\) and \(\theta\) values are the same for all the polynomials. The output output[k][j] is the Zernike polynomial of order n[j] and azimuthal frequency m[j] (OSA/ANSI ordering) with same shape as rho and for the radial derivative of order rho_derivative[k] and the angular derivative of order theta_derivative[k].

Note

If the input rho or theta are not floating point numpy arrays, it is converted to one with numpy.float64 dtype. If the input rho or theta are floating point numpy arrays (ex: numpy.float32), the computation will be done in numpy.float32. If the input rho and theta are not of the same dtype, they are both converted to numpy.float64.

Parameters:
  • rho (numpy.ndarray (N-D array)) – The radial coordinate values with shape (…,) and float64 dtype.

  • theta (numpy.ndarray (N-D array)) – The angular coordinate values with shape (…,) and float64 dtype with same shape as rho.

  • order (int) – The maximum order of the Zernike polynomials to compute. It must be a positive integer.

  • rho_derivative (Optional[Union[Sequence[Integral], numpy.array]], optional) – A sequence (List, Tuple) or 1D numpy array of the order(s) of the radial derivative(s) to compute. Must be non-negative integers. If None, is it assumed that rho_derivative is 0 for all polynomials.

  • theta_derivative (Optional[Union[Sequence[Integral], numpy.array]], optional) – A sequence (List, Tuple) or 1D numpy array of the order(s) of the angular derivative(s) to compute. Must be non-negative integers. If None, is it assumed that theta_derivative is 0 for all polynomials.

  • default (Real, optional) – The default value for invalid rho values. The default is numpy.nan. If the radial coordinate values are not in the valid domain (0 <= rho <= 1) or if they are numpy.nan, the output is set to this value.

  • precompute (bool, optional) – If True, precomputes the useful terms for better performance when computing multiple polynomials with the same rho values. This can significantly speed up the computation, especially for high-order polynomials. If False, the function will compute the terms on-the-fly, which may be slower but avoid memory overhead. The default is True.

Returns:

A list of lists of numpy arrays, where each inner list corresponds to a different radial order and contains the computed Zernike polynomials for the specified orders and azimuthal frequencies. The shape of each array is the same as the input rho and theta, and the dtype is float64. output[k][j] is the Zernike polynomial of order n[j] and azimuthal frequency m[j] (OSA/ANSI ordering) with the radial derivative of order rho_derivative[k] and the angular derivative of order theta_derivative[k].

Return type:

List[List[numpy.ndarray]]

Raises:
  • TypeError – If the rho or theta values can not be converted to a numpy array of floating points values. If rho_derivative or theta_derivative (if not None) are not sequences of integers.

  • ValueError – If the rho and theta do not have the same shape. If the lengths of rho_derivative and theta_derivative (if not None) are not the same.

Examples

Compute all the Zernike polynomials up to order 3 for a grid of points:

import numpy
from pyzernike import zernike_polynomial_up_to_order, zernike_index_to_order

# Create a grid of points
rho = numpy.linspace(0, 1, 100)
theta = numpy.linspace(0, 2 * numpy.pi, 100)

# Compute the Zernike polynomials up to order 3
result = zernike_polynomial_up_to_order(rho, theta, order=3)
polynomials = result[0]  # Get the first set of polynomials (for rho_derivative=0, theta_derivative=0)

# Extract the values:
indices = list(range(len(polynomials)))
n, m = zernike_index_to_order(indices)  # Get the orders and azimuthal frequencies from the indices

for i, (n_i, m_i) in enumerate(zip(n, m)):
    print(f"Zernike polynomial Z_{n_i}^{m_i} for the given rho and theta values is: {polynomials[i]}")

To compute the polynomials and their first derivatives with respect to rho:

import numpy
from pyzernike import zernike_polynomial_up_to_order, zernike_index_to_order

# Create a grid of points
rho = numpy.linspace(0, 1, 100)
theta = numpy.linspace(0, 2 * numpy.pi, 100)

# Compute the Zernike polynomials up to order 3 with radial derivatives
result = zernike_polynomial_up_to_order(rho, theta, order=3, rho_derivative=[0, 1], theta_derivative=[0, 0])
polynomials = result[0]  # Get the first set of polynomials (for rho_derivative=0, theta_derivative=0)
derivatives = result[1]  # Get the second set of polynomials (for rho_derivative=1, theta_derivative=0)

The output will contain the Zernike polynomials and their derivatives for the specified orders and azimuthal frequencies.