Modified Bessel Function of the Second Kind
This module computes the modified Bessel function of the second kind or its \(n\)th derivative
where
\(n \in \mathbb{N}\) is the order of the derivative (\(n = 0\) indicates no derivative).
\(\nu \in \mathbb{R}\) is the order of the modified Bessel function.
\(z \in \mathbb{C}\) is the input argument.
Syntax
This function has the following syntaxes depending on whether it is used in Python or Cython, or the input argument z
is complex or real.
Interface |
Input Type |
Function Signature |
---|---|---|
Python |
Real or Complex |
|
Cython |
Real |
|
Complex |
|
Input Arguments:
- nu: double
The parameter \(\nu\) of modified Bessel function.
- z: double or double complex
The input argument \(z\) of modified Bessel function.
In Python, the function
besselk
acceptsdouble
anddouble complex
types.In Cython, the function
besselk
acceptsdouble
type.In Cython, the function
cbesselk
acceptsdouble complex
type.
- n: int = 0
The order \(n\) of the derivative of modified Bessel function. Zero indicates no derivative.
For the Python interface, the default value is
0
and this argument may not be provided.For the Cython interfaces, no default value is defined and this argument should be provided.
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
Tests
The test script of this module is located at tests/test_besselk.py
. The test compares the results of this module with scipy.special
package (functions k0
, k1
, kn
, kv
, and kvp
) for several combinations of input parameters with multiple values. Run the test by
git clone https://github.com/ameli/special_functions.git
cd special_functions/tests
python test_besselk.py
Algorithm
Depending on the values of the input parameters \((\nu, z, n)\), one of the following three algorithms is employed.
If \(z \in \mathbb{R}\) (that is,
z
is of typedouble
) and \(\nu = 0\) or \(\nu = 1\), the computation is carried out by Cephes C library (see [Cephes-1989]), respectively usingk0
,k1
, orkn
functions in that library.If \(\nu + \frac{1}{2} \in \mathbb{Z}\), the modified Bessel function is computed using half-integer formulas in terms of elementary functions.
For other cases, the computation is carried out by Amos Fortran library (see [Amos-1986]) using
zbesk
subroutine in that library.
Special Cases
In the special cases below, the computation is performed by taking advantage of some of the known formulas and properties of the modified Bessel functions.
Branch-Cut
In the real domain where \(z \in\mathbb{R}\), if \(z < 0\), the value of
NAN
is returned.However, in the complex domain \(z \in\mathbb{C}\) and on the branch-cut of the function, \(\Re(z) < 0\) and \(\Im(z) = 0\), its principal value corresponding to the branch
\[\mathrm{arg}(z) \in (-\pi, \pi]\]is returned. This value may be finite, infinity or undefined depending on \(\nu\) and \(z\).
Negative \(\nu\)
When \(\nu < 0\) the modified Bessel function is computed is related to the modified Bessel function of the positive parameter \(-\nu\) by (see [DLMF] Eq. 10.27.3):
Derivatives
If \(n > 0\), the following relation for the derivative is applied (see [DLMF] Eq. 10.29.5):
Half-Integer \(\nu\)
When \(\nu\) is half-integer, the modified Bessel function is computed in terms of elementary functions as follows.
If \(z = 0\):
If \(z \in \mathbb{R}\), then \(K_{\nu}(0) = +\infty\).
If \(z \in \mathbb{C}\), then
NAN
is returned.
If \(\nu = \pm \frac{1}{2}\) (see [DLMF] Eq. 10.39.2)
\[K_{\pm\frac{1}{2}}(z) = \sqrt{\frac{\pi}{2 z}} \exp(-z).\]Depending on \(z\), the above relations are computed using the real or complex implementation of the elementary functions.
Higher-order half-integer parameter \(\nu\) is related to the above relation for \(\nu = \pm \frac{1}{2}\) using recursive formulas (see [DLMF] Eq. 10.6.1):
References
Moshier, S. L. (1989). C language library with special functions for mathematical physics. Available at http://www.netlib.org/cephes.
Amos, D. E. (1986). Algorithm 644: A portable package for Bessel functions of a complex argument and nonnegative order. ACM Trans. Math. Softw. 12, 3 (Sept. 1986), 265-273. DOI: https://doi.org/10.1145/7921.214331. Available at http://netlib.org/amos/.
Olver, F. W. J., Olde Daalhuis, A. B., Lozier, D. W., Schneider, B. I., Boisvert, R. F., Clark, C. W., Miller, B. R., Saunders, B. V., Cohl, H. S., and McClain, M. A., eds. NIST Digital Library of Mathematical Functions. http://dlmf.nist.gov/, Release 1.1.0 of 2020-12-15.