finesse.cymath package
Submodules
finesse.cymath.cmatrix module
Sparse matrix objects with factorisation and solving routines performed via KLU.
- class finesse.cymath.cmatrix.CCSMatrix(name)
Bases:
object- clear_rhs(self, unsigned int rhs_index=0)
Zero all elements in the rhs vector corresponding to rhs_index.
Parameters
- rhs_indexunsigned, optional
The rhs vector to clear; defaults to 0
- construct(self, double complex diagonal_fill=complex(1, 0))
Constructing the matrix involves taking the metadata submatrix positions throughout the matrix and allocating the memory and building the various CCS matrix structures. After this the matrix can be populated and solved.
Parameters
- diagonal_fillcomplex_t, optional
Value to fill the diagonal of the matrix with; defaults to 1+0j
- declare_equations(self, SuiteSparse_long Neqs, SuiteSparse_long index, str name, is_diagonal=True, add_view=True)
This defines generally what equations exist in the matrix. It essentially defines the order of the RHS vector for which equations map to what index.
This method decalres a group of Neqs equations at once which form a “block” or submatrix within the matrix itself. This block can be referenced by the unique index provided.
When adding this block of equations a view of the diagonal of the matrix can also be added and returned if required. By default it will.
Parameters
- NeqsPy_ssize_t
Number of equations this submatrix represents
- indexlong
Subcolumn index
- nameunicode
Name used to indentify this coupling in the matrix for debugging
- is_diagonalbool, optional
If true, the view created and returned is a diagonal submatrix. If False, the view will be a dense submatrix.
- add_viewbool, optional
If True, a submatrix view will be added to the matrix so that the diagonal submatrix for these elements is available for altering the values automatically.
Returns
- viewSubCCSMatrixView
If add_view == True, a view of the diagonal submatrix for these elements will be returned.
- declare_subdiagonal_view(self, Py_ssize_t from_node, Py_ssize_t to_node, str name, bool conjugate_fill)
- declare_submatrix_view(self, Py_ssize_t from_node, Py_ssize_t to_node, str name, bool conjugate_fill)
- factor(self)
Factors the matrix.
This method is not yet implemented.
Raises
- NotImplementedError
Always, as this method is not yet implemented.
- get_matrix_elements(self)
Returns the sparse CCS format for the current state of this matrix.
Returns
- datalist[complex]
Value of each non-zero element
- rowslist[complex]
Row index of each non-zero element
- colslist[complex]
Column index of each non-zero element
- get_rhs_view(self, unsigned int index) double complex[::1]
Returns a view of the rhs vector corresponding to index.
Parameters
- indexunsigned
The rhs vector to return a view of
- indexes
- name
- nnz
- num_equations
Returns the number of equations (rows) in this matrix.
- num_rhs
- print_matrix(self)
Print a view of the non-zero elements in this matrix.
- print_rhs(self, unsigned int rhs_index=0)
Print a view of the rhs vector corresponding to rhs_index.
Parameters
- rhs_indexunsigned, optional
The rhs vector to print; defaults to 0
- print_submatrices(self)
- refactor(self)
Refactors the matrix.
This method is not yet implemented.
Raises
- NotImplementedError
Always, as this method is not yet implemented.
- rhs_to_string(self, unsigned int rhs_index=0) str
Create a string representation of the rhs vector corresponding to rhs_index.
Parameters
- rhs_indexunsigned, optional
The rhs vector to print; defaults to 0
Returns
- str
RHS vector
- rhs_view
- set_rhs(self, SuiteSparse_long index, double complex value, unsigned int rhs_index=0)
Sets the value of the entry at position index of the rhs_index`th right-hand-side vector to `value.
Parameters
- indexlong
The index in the rhs vector to set
- valuecomplex_t
The value to set
- rhs_indexunsigned, optional
Which rhs vector to change; defaults to 0
- solve(self, int transpose=False, bool conjugate=False, unsigned int rhs_index=0) const double complex[::1]
Solves the matrix equation.
This method is not yet implemented.
Parameters
- transposeint, optional
Whether to transpose the matrix before solving, by default False.
- conjugatebint, optional
Whether to conjugate the matrix before solving, by default False.
- rhs_indexunsigned, optional
The index of the right-hand side to solve for, by default 0.
Raises
- NotImplementedError
Always, as this method is not yet implemented.
Returns
- complex_t[::1]
The solution to the matrix equation.
- solve_extra_rhs(self, int transpose=False, bool conjugate=False) void
Solves the matrix equation for extra right-hand sides.
This method is not yet implemented.
Parameters
- transposeint, optional
Whether to transpose the matrix before solving, by default False.
- conjugatebint, optional
Whether to conjugate the matrix before solving, by default False.
Raises
- NotImplementedError
Always, as this method is not yet implemented.
- sub_columns
- to_scipy_coo(self)
Converts the current matrix to a scipy COO (Coordinate) sparse matrix.
This method retrieves the matrix elements using the get_matrix_elements method and then uses these elements to create a scipy COO sparse matrix.
Returns
- coo_matrix
The scipy COO sparse matrix representation of the current matrix.
- to_scipy_csc(self)
Converts the current matrix to a scipy CSC (Compressed Sparse Column) sparse matrix.
This method retrieves the matrix elements using the get_matrix_elements method and then uses these elements to create a scipy CSC sparse matrix.
Returns
- csc_matrix
The scipy CSC sparse matrix representation of the current matrix.
- to_scipy_csr(self)
Converts the current matrix to a scipy CSR (Compressed Sparse Row) sparse matrix.
This method retrieves the matrix elements using the get_matrix_elements method and then uses these elements to create a scipy CSR sparse matrix.
Returns
- csr_matrix
The scipy CSR sparse matrix representation of the current matrix.
- class finesse.cymath.cmatrix.KLUMatrix(name, klu_ordering=0, *, klu_scale=2, klu_btf=1, klu_maxwork=0, double tol=1e-3)
Bases:
CCSMatrixAn object representation of a CCS matrix with methods to factor and solve the matrix via KLU.
Parameters
- nameunicode
The name of the matrix.
- klu_orderingint, optional
The ordering method to use in KLU, by default 0.
- klu_scaleint, optional
The scaling method to use in KLU, by default 2.
- klu_btfint, optional
Whether to use BTF preordering in KLU, by default 1.
- klu_maxworkint, optional
The maximum amount of work to do in KLU, by default 0.
- tolfloat, optional
The tolerance to use in KLU for partial pivotting, by default 1e-3.
- condest(self) double
klu_condest
Computes a reasonably accurate estimate of the 1-norm condition number, using Hager’s method, as modified by Higham and Tisseur (same method as used in MATLAB’s condest)
- factor(self)
Factor the matrix using KLU.
This method first analyzes the matrix structure using klu_l_analyze, then factors the matrix using klu_zl_factor, and finally sorts the factorization using klu_zl_sort.
Raises
- Exception
If an error occurs in KLU during analysis, factoring, or sorting, an exception is raised with a message indicating the status code and its corresponding string.
- rcond(self) double
klu_rcond: compute min(abs(diag(U))) / max(abs(diag(U)))
This function returns the smallest diagonal entry of U divided by the largest, which is a very crude estimate of the reciprocal of the condition number of the matrix A. It is very cheap to compute, however. In MATLAB notation, rcond = min(abs(diag(U))) / max(abs(diag(U))). If the matrix is singular, rcond will be zero.
- refactor(self)
Refactor the matrix using KLU.
This method attempts to refactor the matrix using klu_zl_refactor. If the refactorization is not successful and the matrix appears singular (status code 1), it tries to factor the matrix again using the factor method. If the matrix is still not factorizable, an exception is raised.
Raises
- RuntimeError
If an error occurs in KLU during refactorization and the matrix does not appear singular, a runtime error is raised with a message indicating the status code and its corresponding string.
- rgrowth(self) double
klu_rgrowth : compute the reciprocal pivot growth
Pivot growth is computed after the input matrix is permuted, scaled, and off-diagonal entries pruned. This is because the LU factorization of each block takes as input the scaled diagonal blocks of the BTF form. The reciprocal pivot growth in column j of an LU factorization of a matrix C is the largest entry in C divided by the largest entry in U; then the overall reciprocal pivot growth is the smallest such value for all columns j. Note that the off-diagonal entries are not scaled, since they do not take part in the LU factorization of the diagonal blocks.
- In MATLAB notation:
rgrowth = min (max (abs ((R A(p,q)) - F)) ./ max (abs (U)))
Returns
reciprocal_pivot_growth : double
- solve(self, int transpose=False, bool conjugate=False, unsigned int rhs_index=0) const double complex[::1]
Solve the matrix with options for transposing and conjugating.
If transpose is False, solves the linear system \(Ax = b\) using the
SymbolicandNumericobjects stored by this class.Otherwise, solves the linear system \(A^T x = b\) or \(A^H x = b\). The conjugate option is zero for \(A^T x = b\) or non-zero for \(A^H x = b\).
Parameters
- transposebool
Flag determining whether to solve the transpose of the matrix.
- conjugatebool
Flag determining whether to solve \(A^T x =b\) or \(A^H x = b\) for the transposed linear system.
- rhs_indexunsigned, optional
Which rhs vector to solve for. If unset, the default rhs vector is used.
Returns
- outnp.ndarray
The (negative) solution vector.
- solve_extra_rhs(self, int transpose=False, bool conjugate=False) void
Solve the matrix for all present rhs vectors except the main one, with options for transposing and conjugating.
If transpose is False, solves the linear system \(Ax = b\) using the
SymbolicandNumericobjects stored by this class.Otherwise, solves the linear system \(A^T x = b\) or \(A^H x = b\). The conjugate option is zero for \(A^T x = b\) or non-zero for \(A^H x = b\).
As multiple rhs vectors are solved simultaneously, the result is not returned here, and must be retrieved via
get_rhs_view.Parameters
- transposebool
Flag determining whether to solve the transpose of the matrix.
- conjugatebool
Flag determining whether to solve \(A^T x =b\) or \(A^H x = b\) for the transposed linear system.
- zgemv(self, double complex[::1] out, unsigned int rhs_index=0) void
Multiply this matrix with the rhs vector corresponding to rhs_index, and store the result in out.
Performs the operation \(y = A x\).
Parameters
- outcomplex_t[::1]
The vector to store the result in.
- rhs_indexunsigned, optional
The rhs vector to multiply this matrix with; defaults to 0.
- class finesse.cymath.cmatrix.SubCCSMatrixView
Bases:
SubCCSViewThis class represents a sub-matrix view of a CCS sparse matrix. This allows code to access and set values without worrying about the underlying sparse compression being used. Although so far this is just for CCS formats.
This object will get a view of a n-by-m sub-matrix starting at index (i,j). The values of his matrix will be set initially to the coordinates.
- do_fill_prop_za_zm(self, SubCCSView V, Py_ssize_t rhs_idx, double complex a, double complex[:, ::1] M, bool increment)
- do_fill_za_zmvc(self, double complex a, double complex[:, ::1] M, double complex[::1] V)
- test_za_zm_2(self, double complex a, ndarray M)
- class finesse.cymath.cmatrix.SubCCSMatrixViewDiagonal
Bases:
SubCCSViewThis class represents a sub-matrix view of a CCS sparse matrix. This allows code to access and set values without worrying about the underlying sparse compression being used. Although so far this is just for CCS formats.
This object will get a view of a n-by-m sub-matrix starting at index (i,j). The values of his matrix will be set initially to the coordinates.
- class finesse.cymath.cmatrix.SubCCSView(CCSMatrix Matrix, Py_ssize_t _from, Py_ssize_t _to, str name, bool conjugate_fill)
Bases:
objectAn abstract class representing common features between dense and sparse diagonal structured sub-matrices.
This class serves as a base class for other classes that represent specific types of sub-matrices, such as dense or sparse diagonal structured sub-matrices. It provides a unified interface for accessing and manipulating these sub-matrices.
The class holds a weak reference to the original matrix, the starting and ending indices of the submatrix view in the original matrix, and a flag indicating whether to fill the submatrix view with the conjugate of the original matrix values.
It also provides properties to get the starting and ending indices of the submatrix view (from_idx and to_idx), the shape of the submatrix view (shape), and the strides of the submatrix view (strides).
Attributes
- nameunicode
The name of the submatrix view.
- Mweakref
A weak reference to the original matrix.
- ANoneType
Placeholder for the actual submatrix data. This should be implemented in subclasses.
- _fromPy_ssize_t
The starting index of the submatrix view in the original matrix.
- _toPy_ssize_t
The ending index of the submatrix view in the original matrix.
- conjugate_fillbint
Whether to fill the submatrix view with the conjugate of the original matrix values.
- M
- conjugate_fill
- from_idx
Returns the starting index of the submatrix view in the original matrix.
Returns
- Py_ssize_t
The starting index of the submatrix view.
- from_rhs_index
- from_rhs_view
- from_rhs_view_size
- name
- shape
Returns the shape of the submatrix view.
Returns
- tuple
The shape of the submatrix view, as a tuple of two integers.
- size1
- size2
- start_idx
- stride1
- stride2
- strides
Returns the strides of the submatrix view.
Returns
- tuple
The strides of the submatrix view, as a tuple of two integers.
- to_idx
Returns the ending index of the submatrix view in the original matrix.
Returns
- Py_ssize_t
The ending index of the submatrix view.
- view
- class finesse.cymath.cmatrix.SubCCSView1DArray
Bases:
objectThis is a class for storing sub-matrix views for coupling directly to another single SubCCSView. It offers a 1D PyObject* array which can be iterated over in C for fast access matrix data without having to do reference inc/dec in fast loops.
It can be accessed from Python for setting views, however it doesn’t support slicing or wraparounds.
Examples
Cython access to views should be cast to a SubCCSView before using it:
>>>> (<SubCCSView>arr.views[i]).fill()
This should result in no python calls when checking the Cython analysis information.
If you store this SubCCSView into a variable then a reference count will happen.
- ndim
Number of dimensions of this collection of SubCCSViews
- size
- class finesse.cymath.cmatrix.SubCCSView2DArray
Bases:
objectThis is a class for storing sub-matrix views. It offers a 2D PyObject** array which can be iterated over in C for fast access matrix data without having to do reference inc/dec in fast loops.
It can be accessed from Python for setting views, however it doesn’t support slicing or wraparounds.
Examples
Cython access to views should be cast to a SubCCSView before using it:
>>>> (<SubCCSView>arr.views[i][j]).fill()
This should result in no python calls when checking the Cython analysis information.
If you store this SubCCSView into a variable then a reference count will happen.
- cols
- ndim
Number of dimensions of this collection of SubCCSViews
- rows
- shape
finesse.cymath.complex module
Functions operating on complex numbers of type double complex.
This module provides complex number functions as well as the fundamental complex data type to be used by developers.
Note
For any developer writing a Cython extension which involves complex
mathematics, you should cimport the complex data type, which is used
consistently across the code-base, via:
from finesse.cymath cimport complex_t
or:
from finesse.cymath.complex cimport complex_t
Both statements are equivalent. This complex_t typedef corresponds
exactly to NumPy’s np.complex128_t — i.e. double complex.
Most of the standard functions of the C "complex.h" header are exposed
at a C level via this module. Refer to the Complex Number Arithmetic C reference for the names, arguments
and further details on these functions. One can cimport such functions
in the same way as cimporting any other C exposed Cython function. For example:
from finesse.cymath.complex cimport cexp
will cimport the cexp
function for use on complex_t data types in another Cython extension.
- finesse.cymath.complex.cnorm(double complex z) double
- finesse.cymath.complex.cpow_re(double complex z, double n) double complex
- finesse.cymath.complex.crotate(double complex z, double ph) double complex
- finesse.cymath.complex.crotate2(double complex z, double cph, double sph) double complex
- finesse.cymath.complex.inverse_unsafe(double complex z) double complex
finesse.cymath.gaussbeam module
Low-level calculations for Gaussian beam properties.
This module provides functions for computing properties of Gaussian beams and transforming Gaussian beam parameters via the ABCD ray-matrix framework.
Note
These are low-level functions intended for use in Cython extensions. Users
should use the functions and classes given in finesse.gaussian instead
of those defined here.
- finesse.cymath.gaussbeam.beam_size(double complex q, double nr, double lambda0) double
- finesse.cymath.gaussbeam.defocus(double complex q) double
- finesse.cymath.gaussbeam.divergence(double complex q, double nr, double lambda0) double
- finesse.cymath.gaussbeam.gouy(double complex q) double
- finesse.cymath.gaussbeam.inv_transform_q(const double[:, ::1] M, double complex q2, double nr1, double nr2) double complex
- finesse.cymath.gaussbeam.overlap(double complex qx, double complex qy) double
- finesse.cymath.gaussbeam.radius_curvature(double complex q) double
- finesse.cymath.gaussbeam.sym_abcd_multiply(object[:, ::1] m1, object[:, ::1] m2, object[:, ::1] out) void
- finesse.cymath.gaussbeam.transform_q(const double[:, ::1] M, double complex q1, double nr1, double nr2) double complex
- finesse.cymath.gaussbeam.waist_size(double complex q, double nr, double lambda0) double
finesse.cymath.homs module
Fast computations of Higher-Order Mode related properties.
This module provides functions for computing properties of HOMs, such as the spatial distribution \(u_{nm}(x,y,z;q_x,q_y)\) of Hermite-Gauss modes.
Note
These are low-level functions intended for use, by developers, in Cython
extensions. To calculate HG mode profiles, for example, users should
instead use the Python class HGMode defined in finesse.gaussian.
- class finesse.cymath.homs.HGModeWorkspace(int n, int m, double complex qx, double complex qy, double nr, double lambda0)
Bases:
objectFast computation of Hermite-Gauss spatial distributions.
This workspace class is used internally by
HGMode. Users should only ever interact with theHGModeobject rather than this class.- is_astigmatic
- lambda0
- m
m: ‘int’
- n
n: ‘int’
- nr
- qx
- qy
- set_values(self, qx=None, qy=None, nr=None, lambda0=None)
- u_m(self, y, double complex[::1] out=None)
- u_n(self, x, double complex[::1] out=None)
- u_nm(self, x, y, out=None)
- class finesse.cymath.homs.HGModes(q, modes, bool reverse_gouy=False, bool flip_odd_x_modes=False)
Bases:
objectA class that calculates a selection of Hermite-Gaussian modes.
Parameters
- q[complex | BeamParam]
Complex valued beam parameter. If one if given qx = qy. Otherwise an iterable of two must be given (qx, qy).
- modestuple((n, m))
list of mode indices
- zero_tem00_gouybool, optional
When True, the HG00 mode will have its gouy phase removed, and relatively removed from all other HG modes. ie. gouy = (n+m)*Gouy rather than (1+n+m)*Gouy
- reverse_gouybool, optional
Gouy phase is removed from coupling coefficients when True
- flip_odd_x_modesbool, optional
When True any output mode with an odd n index will have a negative sign applied. This should be used in reflection cases due to the coordinate system change.
- Unm(self, int n, int m, double x, double y)
- compute_1d_modes(self, double[::1] x, double[::1] y)
Calculates the Un and Um modes arrays for the modes that were specificied when creating this HGModes object.
Parameters
- x, yndarray
Array of x and y data points to compute the modes over
Returns
- Unndarray(shape=(N, x.size))
A 2D array of all the modes over the x array
- Umndarray(shape=(N, y.size))
A 2D array of all the modes over the y array
- compute_2d_modes(self, double[::1] x, double[::1] y)
Calculates the Unm modes that were specificied when creating this HGModes object.
Parameters
- x, yndarray
Array of x and y data points to compute the modes over
Returns
- Unmndarray(shape=(N, y.size, x.size))
A 3D array of all the modes over the x and y domain
- compute_points(self, double[::1] x, double[::1] y)
Calculates the Unm modes over a set of (x,y) points.
Parameters
- x, yndarray
Array of x and y data points to compute the modes over, size of x and y must be the same.
Returns
- Unmndarray(shape=(x.size, N), dtype=complex)
A 2D array of all the modes over the x and y domain
- flip_odd_x_modes
- reverse_gouy
- unique_m_modes
- unique_map
- unique_n_modes
- finesse.cymath.homs.field_index(int n, int m, const int[:, ::1] homs) Py_ssize_t
finesse.cymath.laguerre module
- finesse.cymath.laguerre.compute_lg_mode(int p, int l, double w0, double z, double wavelength, ndarray x, ndarray y, helical=True) np.ndarray[np.complex128]
Compute a Laguerre-Gaussian mode.
Parameters
- pint
Radial index of the Laguerre-Gaussian mode.
- lint
Azimuthal index of the Laguerre-Gaussian mode.
- w0double
Beam waist.
- zdouble
Propagation distance.
- wavelengthdouble
Wavelength of the beam.
- xnp.ndarray[double, ndim=1]
Array of x-coordinates.
- ynp.ndarray[double, ndim=1]
Array of y-coordinates.
- helicalbool
True if this is a helical LG mode, False for Sinusoidal
Returns
- np.ndarray[np.complex128]
2D array of complex values representing the Laguerre-Gaussian mode at the given coordinates.
Examples
>>> import finesse >>> from finesse.cymath import laguerre as lg >>> import numpy as np >>> import matplotlib.pyplot as plt >>> finesse.init_plotting() >>> >>> fig, axes = plt.subplots(3, 3, figsize=(8, 8)) >>> >>> w0 = 1e-3 >>> z = 0 >>> x = np.linspace(-4 * w0, +4 * w0, 50) >>> y = np.linspace(-4 * w0, +4 * w0, 51) >>> X, Y = np.meshgrid(x, y) >>> helical = False # whether to plot helical LG modes or sinusoidal LG modes >>> >>> for i, p in enumerate([0, 1, 2]): >>> for j, l in enumerate([0, 1, 2]): >>> E = lg.compute_lg_mode(p, l, w0, z, 1064e-9, x, y, helical) >>> intensity = np.abs(E) ** 2 >>> ax = axes[i, j] >>> C = ax.contourf(X, Y, intensity.T, levels=100) >>> C.set_edgecolor("face") >>> ax.set_title(f"LG Mode p={p}, l={l}") >>> ax.set_aspect("equal") >>> >>> for ax in axes.flatten(): >>> ax.set_xticks([]) >>> ax.set_yticks([]) >>> plt.tight_layout() >>> plt.show()
finesse.cymath.math module
Standard mathematical functions for non-complex calculations.
Most of the standard functions of the C "math.h" header are exposed
at a C level via this module. Refer to the Common Mathematical Functions C reference for the names, arguments
and further details on these functions. One can cimport such functions
in the same way as cimporting any other C exposed Cython function. For example:
from finesse.cymath.math cimport sin
will cimport the sin function
for use on double data types in another Cython extension.
- finesse.cymath.math.degrees(double x) double
- finesse.cymath.math.factorial(int n) double
- finesse.cymath.math.hermite(int n, double x) double
- finesse.cymath.math.msign(int n) double
- finesse.cymath.math.radians(double x) double
- finesse.cymath.math.sqrt_factorial(int n) double
finesse.cymath.sparsemath module
Sparse matrix math tools.
- class finesse.cymath.sparsemath.CSRMatrix(ndarray A)
Bases:
objectA complex value Compressed Sparse Row (CSR) matrix. This is a useful format for storing a sparse matrix for fast matrix vector products.
This class wraps the csr_matrix structure which is pure C and so can be passed to functions that do not need the GIL.
Parameters
- Anp.ndarray[complex, ndim=2]
A dense matrix to convert into a sparse format
- col_index
Column index for each non-zero element
- cols
Number of columns in matrix
- multiply(self, ndarray x)
Compute y = M @ x
- nnz
Number of non-zero elements
- row_ptr
Index in values and col_index where each row starts
- rows
Number of rows in matrix
- values
Sparse matrix non-zero values
finesse.cymath.ufuncs module
Numpy ufuncs for custom functions that support numeric and symbolic arguments.
See https://cython.readthedocs.io/en/latest/src/userguide/fusedtypes.html for more information on fused types.
finesse.cymath.zernike module
Math functions for computing Zernike polynomial information.
TODO: write tests and document these functions properly
- finesse.cymath.zernike.Gen_nm(n)
Generate n and m vectors containing n and m indices up to n, excluding zeroth mode.
- finesse.cymath.zernike.Rnm_eval(_r, _phi, n, m, a0)
Function to evaluate radial components.
- finesse.cymath.zernike.Rnm_p(n, m)
Generate radial polynomial for radial Zernikee.
- finesse.cymath.zernike.ZPhi_eval(_phi, m)
Fuction to generate azimuthal component.
- finesse.cymath.zernike.Znm_eval(_r, _phi, n, m, a0)
Module contents
Fast C functions providing common mathematical routines for the Cython level code in Finesse.
Note that the functions and classes provided by this library are generally only for developers or those extending the code via additional Cython extensions.
Unless otherwise stated, the functions here do not work on
numpy.ndarray objects. Instead, they operate on scalar
C types as they are primarily intended for use in low-level code.