pyzernike.cartesian_to_elliptic_annulus#
- pyzernike.cartesian_to_elliptic_annulus(x: ndarray, y: ndarray, 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) Tuple[List[ndarray], List[ndarray]][source]#
Transform Cartesian coordinates \((x, y)\) to elliptic annulus domain polar coordinates \((\rho_{eq}, \theta_{eq})\).
See also
pyzernike.elliptic_domain_to_cartesian()to convert elliptic annulus domain polar coordinates to Cartesian coordinates.pyzernike.xy_zernike_polynomial()to compute Zernike polynomials on the elliptic annulus domain.pyzernike.core.core_cartesian_to_elliptic_annulus()to inspect the core implementation of the computation.The page Mathematical description in the documentation for the mathematical extension of the Zernike polynomials on the elliptic domain.
Lets 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 methods allow to compute the polar coordinates \((\rho_{eq}, \theta_{eq})\) and their derivatives with respect to the Cartesian coordinates \((x, y)\).
xandyare expected to be numpy arrays of the same shape.x_derivativeandy_derivativemust be sequences of non-negative integers of the same length.
The output is a tuple of two lists with lengths equal to the length of
x_derivativeandy_derivative:The first list contains the equivalent polar radius \(\rho_{eq}\) and its derivatives with respect to the given orders.
The second list contains the equivalent polar angle \(\theta_{eq}\) and its derivatives with respect to the given orders.
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.The derivatives for orders higher than 2 are computed using symbolic differentiation with sympy library (high computational cost). For orders 0, 1 and 2, the derivatives are computed using the analytical expressions derived from the chain rule.
- Parameters:
x (numpy.ndarray) – The x coordinates in Cartesian system with shape (…,).
y (numpy.ndarray) – The y coordinates in Cartesian system with shape (…,).
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.
- Returns:
The polar coordinates (\(\rho_{eq}, \theta_{eq}\)) and their derivatives with respect to the Cartesian coordinates \((x, y)\) as two lists of numpy arrays with shape (…,) and dtype matching the input arrays.
output[0][i]is the derivative with respect to x of orderx_derivative[i]and with respect to y of ordery_derivative[i]of \(\rho_{eq}\).output[1][i]is the derivative with respect to x of orderx_derivative[i]and with respect to y of ordery_derivative[i]of \(\theta_{eq}\).- Return type:
Tuple[List[numpy.ndarray], List[numpy.ndarray]]
Examples
Lets compute Zernike polynomial \(Z_2^0\) on an extended circle of radius 2 centered at (1,1).
First, we convert a grid of Cartesian coordinates to elliptic annulus polar coordinates using
pyzernike.cartesian_to_elliptic_annulus():import numpy from pyzernike import cartesian_to_elliptic_annulus # Define the elliptic annulus domain parameters Rx = 2.0 # Semi-axis along x Ry = 2.0 # Semi-axis along y x0 = 1.0 # Center x y0 = 1.0 # Center y # Create a grid of Cartesian coordinates x = np.linspace(-1, 3, 100) y = np.linspace(-1, 3, 100) X, Y = np.meshgrid(x, y) # Convert to elliptic annulus polar coordinates list_rho_eq, list_theta_eq = cartesian_to_elliptic_annulus(X, Y, Rx, Ry, x0, y0) # Extract the polar coordinates (0th order derivatives) rho_eq = list_rho_eq[0] theta_eq = list_theta_eq[0]
Then the variables
rho_eqandtheta_eqcan be directly used to compute Zernike polynomials on the elliptic annulus domain usingpyzernike.zernike_polynomial(). Note that the complete process can be done in one step usingpyzernike.xy_zernike_polynomial().from pyzernike import zernike_polynomial # Compute the Zernike polynomial Z_2^0 on the elliptic annulus domain Z20 = zernike_polynomial(rho_eq, theta_eq, n=2, m=0)[0]
If you also want to extract
rho_eqandtheta_eqand their first derivatives with respect to x and y, you can specify the derivative orders:# Define the derivative orders x_derivative = [0, 1, 0] # 0th and 1st derivative with respect to x y_derivative = [0, 0, 1] # 0th and 1st derivative with respect to y # Convert to elliptic annulus polar coordinates and compute derivatives list_rho_eq, list_theta_eq = cartesian_to_elliptic_annulus(X, Y, Rx, Ry, x0, y0, x_derivative=x_derivative, y_derivative=y_derivative) # Extract the polar coordinates and their derivatives rho_eq = list_rho_eq[0] # 0th order derivative of rho_eq drho_eq_dx = list_rho_eq[1] # 1st order derivative of rho_eq with respect to x drho_eq_dy = list_rho_eq[2] # 1st order derivative of rho_eq with respect to y theta_eq = list_theta_eq[0] # 0th order derivative of theta_eq dtheta_eq_dx = list_theta_eq[1] # 1st order derivative of theta_eq with respect to x dtheta_eq_dy = list_theta_eq[2] # 1st order derivative of theta_eq with respect to y
These derivatives can be useful for computing gradients or Jacobians of Zernike polynomials on the elliptic annulus domain, see
pyzernike.xy_zernike_polynomial()for more details.