pyzernike.xy_zernike_polynomial_up_to_order#
- pyzernike.xy_zernike_polynomial_up_to_order(x: ndarray, y: ndarray, order: Integral, Rx: Real = 1.0, Ry: Real = 1.0, x0: Real = 0.0, y0: Real = 0.0, alpha: Real = 0.0, h: Real = 0.0, x_derivative: array | Sequence[Integral] | None = None, y_derivative: array | Sequence[Integral] | None = None, default: Real = nan, precompute: bool = True) List[ndarray][source]#
Computes all the Zernike polynomial \(Z_{n}^{m}(\rho_{eq}, \theta_{eq})\) for given cartesian coordinates \((x, y)\) on an elliptic annulus domain up to a given order.
See also
pyzernike.xy_zernike_polynomial()for computing a set of Zernike polynomials for given orders and azimuthal frequencies.pyzernike.cartesian_to_elliptic_annulus()to convert Cartesian coordinates to elliptic annulus domain polar coordinates.The page Mathematical description in the documentation for the mathematical extension of the Zernike polynomials on the elliptic domain.
See also
For the mathematical development of the method, see the paper Generalization of Zernike polynomials for regular portions of circles and ellipses by Rafael Navarro, José L. López, José Rx. Díaz, and Ester Pérez Sinusía. The associated paper is available in the resources folder of the package.
Download the PDF :
PDFLets consider the extended elliptic annulus domain defined by the following parameters:
The parameters to define the extended domain of the Zernike polynomial.#
The parameters are:
\(R_x\) and \(R_y\) are the lengths of the semi-axis of the ellipse.
\(x_0\) and \(y_0\) are the coordinates of the center of the ellipse.
\(\alpha\) is the rotation angle of the ellipse in radians.
\(h=\frac{a}{R_x}=\frac{b}{R_y}\) defining the inner boundary of the ellipse.
The Zernike polynomial \(Z_{n}^{m}(\rho_{eq}, \theta_{eq})\) is computed for the equivalent polar coordinates.
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
xandymust be numpy arrays of the same shape.The parameters
x_derivativeandy_derivativemust be sequences of integers with the same length.
The \(x\) and \(y\) values are the same for all the polynomials. The output
output[k][j]is the Zernike polynomial of ordern[j]and azimuthal frequencym[j](OSA/ANSI ordering) with same shape asxand for the radial derivative of orderx_derivative[k]and the angular derivative of ordery_derivative[k].Note
If the input
xoryare not floating point numpy arrays, it is converted to one withnumpy.float64dtype. If the inputxoryare floating point numpy arrays (ex:numpy.float32), the computation will be done innumpy.float32. If the inputxandyare not of the same dtype, they are both converted tonumpy.float64.Warning
The only available derivatives are the first and second order derivatives with respect to x or y independently (jacobian and hessian matrix). For more complex derivatives, please implement the Faa di Bruno’s formula using the standard Zernike polynomial function with polar coordinates.
Available derivatives (:math:(dx, dy)): (0, 0), (1, 0), (0, 1), (2, 0), (0, 2), (1, 1).
- Parameters:
x (numpy.ndarray) – The x coordinates in Cartesian system with shape (…,).
y (numpy.ndarray) – The y coordinates in Cartesian system with shape (…,).
order (int) – The maximum order of the Zernike polynomials to compute. It must be a positive integer.
Rx (Real, optional) – The length of the semi-axis of the ellipse along x axis. Must be strictly positive. The default is 1.0, which corresponds to the unit circle.
Ry (Real, optional) – The length of the semi-axis of the ellipse along y axis. Must be strictly positive. The default is 1.0, which corresponds to the unit circle.
x0 (Real, optional) – The x coordinate of the center of the ellipse. Can be any real number. The default is 0.0, which corresponds to an ellipse centered at the origin.
y0 (Real, optional) – The y coordinate of the center of the ellipse. Can be any real number. The default is 0.0, which corresponds to an ellipse centered at the origin.
alpha (Real, optional) – The rotation angle of the ellipse in radians. Can be any real number. The default is 0.0, such as \(x\) and \(y\) axis are aligned with the ellipse axes.
h (Real, optional) – The ratio of the inner semi-axis to the outer semi-axis. Must be in the range [0, 1). The default is 0.0, which corresponds to a filled ellipse.
x_derivative (Optional[Union[Sequence[Integral], numpy.array]], optional) – A sequence (List, Tuple) or 1D numpy array of the order(s) of the x derivative(s) to compute. Must be non-negative integers. If None, is it assumed that x_derivative is 0 for all polynomials.
y_derivative (Optional[Union[Sequence[Integral], numpy.array]], optional) – A sequence (List, Tuple) or 1D numpy array of the order(s) of the y derivative(s) to compute. Must be non-negative integers. If None, is it assumed that y_derivative is 0 for all polynomials.
default (Real, optional) – The default value to use for points outside the elliptic annulus domain. Must be a real number. The default is numpy.nan.
precompute (bool, optional) – If True, precomputes the useful terms for better performance when computing multiple polynomials with the same rho values. If False, computes the useful terms on the fly for each polynomial to avoid memory overhead. The default is True.
- Returns:
A list of numpy arrays containing the Zernike polynomial values for each order and azimuthal frequency. Each array has the same shape as
x.- Return type:
List[numpy.ndarray]
- Raises:
TypeError – If the x or y values can not be converted to a numpy array of floating points values. If x_derivative or y_derivative (if not None) are not sequences of integers.
ValueError – If the x and y do not have the same shape. If the lengths of x_derivative and y_derivative (if not None) are not the same. If Rx or Ry are not strictly positive. If h is not in the range [0, 1[. If the derivative orders are higher than 2 or mixed (ex: (1, 1)).
Examples
Compute all the Zernike polynomials up to order 3 for a cartesian grid of points in the domain defined by a circle with radius sqrt(2) centered at (0, 0):
import numpy from pyzernike import xy_zernike_polynomial_up_to_order, zernike_index_to_order # Create a grid of points x = numpy.linspace(-1, 1, 100) y = numpy.linspace(-1, 1, 100) x, y = numpy.meshgrid(x, y) # Create a 2D grid # Compute the Zernike polynomials up to order 3 result = xy_zernike_polynomial_up_to_order(x, y, order=3, Rx=numpy.sqrt(2), Ry=numpy.sqrt(2), x0=0, y0=0) polynomials = result[0] # Get the first set of polynomials (for x_derivative=0, y_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 x and y values is: {polynomials[i]}")
To compute the polynomials and their first derivatives with respect to x:
import numpy from pyzernike import xy_zernike_polynomial_up_to_order, zernike_index_to_order # Create a grid of points x = numpy.linspace(-1, 1, 100) y = numpy.linspace(-1, 1, 100) x, y = numpy.meshgrid(x, y) # Create a 2D grid # Compute the Zernike polynomials up to order 3 with x derivatives result = xy_zernike_polynomial_up_to_order(x, y, order=3, x_derivative=[0, 1], Rx=numpy.sqrt(2), Ry=numpy.sqrt(2), x0=0, y0=0) polynomials = result[0] # Get the first set of polynomials (for x_derivative=0, y_derivative=0) derivatives_x = result[1] # Get the first set of derivatives (for x_derivative=1, y_derivative=0)
The output will contain the Zernike polynomials and their derivatives for the specified orders and azimuthal frequencies.