Skip to content

ameli/special_functions

Repository files navigation

special functions

licence docs

This package provides both Python and Cython interfaces for Bessel functions and a few other special functions.

Features

  • Lightweight: This package requires no python dependency at runtime.
  • Cython interface: Both Python and Cython interfaces are available.
  • Releasing GIL: Most importantly, the functions can be used in with nogil: environment, which is essential in parallel OpenMP applications with Cython.

Tutorial

binder

Launch online interactive notebook with Binder.

Links

Install

Supported Platforms

Successful installation and tests have been performed on the following platforms and Python/PyPy versions shown in the table below.

Platform Arch Python Version PyPy Version 1 Continuous Integration
3.9 3.10 3.11 3.12 3.8 3.9 3.10
Linux X86-64 âś” âś” âś” âś” âś” âś” âś” build-linux
AARCH-64 âś” âś” âś” âś” âś” âś” âś”
macOS X86-64 âś” âś” âś” âś” âś” âś” âś” build-macos
ARM-64 âś” âś” âś” âś” âś” âś” âś”
Windows X86-64 âś” âś” âś” âś” âś” âś” âś” build-windows

Python wheels for special_functions for all supported platforms and versions in the above are available through PyPI and Anaconda Cloud. If you need special_functions on other platforms, architectures, and Python or PyPy versions, raise an issue on GitHub and we build its Python Wheel for you.

1. Wheels for PyPy are exclusively available for installation through pip and cannot be installed using conda.

Dependencies

  • At runtime: This package does not have any dependencies at runtime.

  • For tests: To run Test, scipy package is required and can be installed by

    python -m pip install -r tests/requirements.txt
    

Install Package

Either Install from PyPi, Install from Anaconda Cloud, or Build and Install from Source Code.

Install from PyPi

pypi format implementation pyversions

The recommended installation method is through the package available at PyPi using pip.

  1. Ensure pip is installed within Python and upgrade the existing pip by

    python -m ensurepip
    python -m pip install --upgrade pip
    

    If you are using PyPy instead of Python, ensure pip is installed and upgrade the existing pip by

    pypy -m ensurepip
    pypy -m pip install --upgrade pip
    
  2. Install this package in Python by

    python -m pip install special_functions
    

    or, in PyPy by

    pypy -m pip install special_functions
    

Install from Anaconda Cloud

conda-version conda-platform

Alternatively, the package can be installed through Anaconda could.

  • In Linux and Windows:

    conda install s-ameli::special_functions
    
  • In macOS:

    conda install -c s-ameli -c conda-forge special_functions
    

Build and Install from Source Code

release

Build dependencies: To build the package from the source code, numpy and cython are required. These dependencies are installed automatically during the build process and no action is needed.

  1. Install both C and Fortran compilers as follows.

    • Linux: Install gcc, for instance, by apt (or any other package manager on your Linux distro)

      sudo apt install gcc gfortran
      
    • macOS: Install gcc via Homebrew:

      sudo brew install gcc
      

      Note: If gcc is already installed, but Fortran compiler is yet not available on macOS, you may resolve this issue by reinstalling:

      sudo brew reinstall gcc
      
    • Windows: Install both Microsoft Visual C++ compiler and Intel Fortran compiler (Intel oneAPI). Open the command prompt (where you will enter the installation commands in the next step) and load the Intel compiler variables by

      C:\Program Files (x86)\Intel\oneAPI\setvars.bat
      

      Here, we assumed the Intel Fortran compiler is installed in C:\Program Files (x86)\Intel\oneAPI. You may set this directory accordingly to the directory of your Intel compiler.

  2. Clone the source code and install this package by

    git clone https://github.com/ameli/special_functions.git
    cd special_functions
    python -m pip install .
    

Warning: After the package is built and installed from the source code, the package cannot be imported properly if the current working directory is the same as the source code directory. To properly import the package, change the current working directory to a directory anywhere else outside of the source code directory. For instance:

cd ..
python
>>> import special_functions

Test

codecov-devel

To test package, install tox:

python -m pip install tox

and test the package with

tox

List of Functions

Python API

Syntax Symbol User guide
besselj(nu, z, n) image06 Bessel function of the first kind
bessely(nu, z, n) image07 Bessel function of the second kind (Weber function)
besseli(nu, z, n) image08 Modified Bessel function of the first kind
besselk(nu, z, n) image09 Modified Bessel function of the second kind
besselh(nu, k, z, n) image10 Bessel function of the third kind (Hankel function)
lngamma(x) image11 Natural logarithm of Gamma function

Typed Arguments:

Argument Type Symbol Description
nu double image01 Parameter of Bessel functions.
k int image02 Can be 1 or 2 and sets the type of Hankel function.
z double, double complex image03 Real or complex argument of the Bessel functions.
x double image04 Real argument of the functions.
n int image05 Order of derivative of function. Zero indicates no derivative.

Cython API

In Cython interface, the syntax of the real functions are similar to the Python interface. However, the syntax of complex functions start with the letter c in the beginning of each function as shown in the table below.

Symbol Real Function Complex Function
image06 besselj(nu, x, n) cbesselj(nu, z, n)
image07 bessely(nu, x, n) cbessely(nu, z, n)
image08 besseli(nu, x, n) cbesseli(nu, z, n)
image09 besselk(nu, x, n) cbesselk(nu, z, n)
image10 besselh(nu, k, x, n) cbesselh(nu, k, z, n)
image11 lngamma(x) N/A

Examples

Using in Cython Code

The codes below should be used in a .pyx file and compiled with Cython.

As shown in the codes below, the python's global lock interpreter, or gil, can be optionally released inside the scope of with nogil: statement. This is especially useful in parallel OpenMP environments.

Real Function

This example shows the real function besselk to compute the modified Bessel function of the second kind for a real argument z. The output variables d0k, d1k, and d2k represent the values of modified Bessel function and its first and second derivatives, respectively.

>>> # cimport module in a *.pyx file
>>> from special_functions cimport besselk

>>> # Declare typed variables
>>> cdef double nu = 2.5
>>> cdef double z = 2.0
>>> cdef double d0k, d1k, d2k

>>> # Releasing gil to secure maximum cythonic speedup
>>> with nogil:
...     d0k = besselk(nu, z, 0)    # no derivative
...     d1k = besselk(nu, z, 1)    # 1st derivative
...     d2k = besselk(nu, z, 2)    # 2nd derivative

Complex Function

The example below is similar to the above, except, the complex function cbesselk with complex argument z is used. The output variables d0k, d1k, and d2k are also complex.

>>> # cimport module in a *.pyx file
>>> from special_functions cimport cbesselk

>>> # Declare typed variables
>>> cdef double nu = 2.5
>>> cdef double complex z = 2.0 + 1.0j
>>> cdef double complex d0k, d1k, d2k

>>> # Releasing gil to secure maximum cythonic speedup
>>> with nogil:
...     d0k = cbesselk(nu, z, 0)    # no derivative
...     d1k = cbesselk(nu, z, 1)    # 1st derivative
...     d2k = cbesselk(nu, z, 2)    # 2nd derivative

Using in Python Code

The codes below should be used in a .py file and no compilation is required. The python's global lock interpreter, or gil, cannot be released.

Real Function

The example below uses the function besselk with the real argument z to compute the modified Bessel function of the second kind and its first and second derivatives.

>>> # import module in a *.py file
>>> from special_functions import besselk

>>> nu = 2.5
>>> z = 2.0

>>> d0k = besselk(nu, z)       # no derivative
>>> d1k = besselk(nu, z, 1)    # 1st derivative
>>> d2k = besselk(nu, z, 2)    # 2nd derivative

Complex Function

To use a complex input argument z in the Python interface, the same function besselk as the previous example can be used. This is unlike the Cython interface in which cbesselk should be used.

>>> # import module in a *.py file
>>> from special_functions import besselk

>>> nu = 2.5
>>> z = 2.0 + 1.0j

>>> d0k = besselk(nu, z)       # no derivative
>>> d1k = besselk(nu, z, 1)    # 1st derivative
>>> d2k = besselk(nu, z, 2)    # 2nd derivative

Related Packages

  • scipy.special: Many special functions were implemented in Scipy's special sub-package. This package is reimplements Bessel functions similar to scipy.special, but with simplified python and cython different interfaces.
  • G-Learn: A python package for machine learning using Gaussian process regression. This package makes use of special_functions.

Acknowledgements

  • National Science Foundation #1520825
  • American Heart Association #18EIA33900046

Citation

  • Ameli, S. (2022). ameli/special_functions: (v0.1.0). Zenodo. code-doi

Credit

This package uses the following libraries: