The ‘finesse.cymath’ extension

Using fast mathematical routines

The sub-module finesse.cymath is a Cython extension containing external declarations from the C headers "math.h" and "complex.h" as well as C implemented functions defining common mathematical routines required for the various parts of Finesse. Where applicable, these methods are declared as cpdef such that they can be used from other Cython extensions (as a fast C function call) and Python modules (as a slower Python function call). Note that it is only the function call overhead that is different for any cpdef function - the code inside is implemented in pure C for all finesse.cymath functions and this is the same for both the generated C function and Python function.

The complex data type

One of the key elements exposed by finesse.cymath to other Cython extensions is the C type definition complex_t - defined as np.complex128_t which is just equivalent to the double complex C type.

Whenever your Cython extension requires complex numbers, always use this type definition rather than defining your own or redefining from elsewhere. To do this, simply add the following to your .pyx file(s):

from finesse.cymath cimport complex_t

Importing standard "math.h" functions

Here is the general process for using a standard C math function on non-complex types:

  • By inspecting the cdef extern from "math.h" block at the start of finesse/cymath/math.pxd, check that the C function you need already exists within this.

  • If it is already present, then you can simply cimport the function. For example, if you need the sin function acting on double type values then simply cimport as:

    from finesse.cymath.math cimport sin
    
  • Otherwise, refer to the necessary function signature in the Common Mathematical Functions C reference and add this to the cdef extern block. For example, if you need the base-2 logarithm routine then simply add it as follows:

    # In this block (already present)
    cdef extern from "math.h" nogil:
        # all the existing functions...
    
        double log2(double x)
    

Importing standard "complex.h" functions

Similarly to above:

  • By inspecting the cdef extern from "complex.h" block at the start of finesse/cymath/complex.pxd, check that the C function you need already exists within this.

  • If it is already present, then you can simply cimport the function. For example, if you need the csqrt function then simply cimport as:

    from finesse.cymath.complex cimport csqrt
    
  • Otherwise, refer to the necessary function signature in the Complex Number Arithmetic C reference and add this to the cdef extern block. For example, if you need the projection routine then simply add it as follows:

    # In this block (already present)
    cdef extern from "complex.h" nogil:
        # all the existing functions...
    
        double complex cproj(double complex z)
    

Importing custom fast arithmetic functions from finesse.cymath

In addition to the standard C functions, this module also provides various fast mathematical routines which are not defined in the C numerics libraries. These are typically declared in the relevant *.pxd file and then defined in the corresponding .pyx file; however some may be defined immediately in the *.pxd if they are declared as inline.

An example of such a function is the crotate routine which sits in finesse.cymath.complex and performs the rotation of a complex number (of type complex_t) by a given phase in radians. Importing such functions, at a C level, is as simple as the standard routines. For this example, one can just do:

from finesse.cymath.complex cimport crotate

to get access to this function.

If you need to implement any custom fast (C level) mathematics to use in some other finesse cython extension, then declare and define such functions in an identical way to those that exist within the sub-modules of finesse.cymath.