SDDS ToolKit Programs and Libraries for C and Python
Loading...
Searching...
No Matches
k23.c
Go to the documentation of this file.
1/**
2 * @file k23.c
3 * @brief Provides a function to compute the Modified Bessel Function of the Second Kind K_{2/3}(z).
4 *
5 * This file implements k23(), which calculates the Modified Bessel Function K_{2/3}(z)
6 * over a range of input values. It uses a series expansion for smaller arguments and an
7 * asymptotic expansion for larger arguments, referencing Abramowitz & Stegun and based on
8 * Roger Dejus's original Fortran code k23.f.
9 *
10 * @copyright
11 * - (c) 2002 The University of Chicago, as Operator of Argonne National Laboratory.
12 * - (c) 2002 The Regents of the University of California, as Operator of Los Alamos National Laboratory.
13 *
14 * @license
15 * This file is distributed under the terms of the Software License Agreement
16 * found in the file LICENSE included with this distribution.
17 *
18 * @author R. Dejus, H. Shang, R. Soliday
19 */
20#include "mdb.h"
21#include "constants.h"
22#include <math.h>
23#define A_LIM 10.1
24#define EPS1 1.0e-12
25#define EPS2 1.0e-8
26#define GAMMA_OF_NY 1.354117939426400463
27#define NY 2.0 / 3.0
28
29/**
30 * @brief Compute the Modified Bessel Function of the Second Kind K_{2/3}(z).
31 *
32 * This function calculates K_{2/3}(z) for inputs approximately in the range 0.0 < z < 60.0.
33 * For z < A_LIM, it applies a series expansion (Abramowitz & Stegun Eq. 9.6.2 and 9.6.10).
34 * For z ≥ A_LIM, it uses an asymptotic expansion (Eq. 9.7.2). The method is adapted from
35 * Roger Dejus’s code, taking into account precomputed gamma function values and
36 * ensuring numerical stability within specified tolerances (EPS1 and EPS2).
37 *
38 * @param z The input value for which K_{2/3}(z) is evaluated.
39 * @return The computed K_{2/3}(z).
40 */
41double k23(double z) {
42 double c1, c2, zs, ny_fac, neg_ny_fac, zm, zp, pm, pp, term, sum, ze, za, mu, pa, e2;
43 long k;
44
45 if (z < A_LIM) {
46 /* series expansion*/
47 c1 = PI / 2.0 / sin(PI * NY);
48 c2 = 2 * c1;
49 zs = z * z / 4.0;
50
51 ny_fac = NY * GAMMA_OF_NY; /* ! Factorial of (+ny)*/
52 neg_ny_fac = c2 / GAMMA_OF_NY; /*! Factorial of (-ny)*/
53 e2 = pow(z / 2.0, NY);
54 zm = 1 / e2 / neg_ny_fac;
55 zp = e2 / ny_fac;
56 /* first term */
57 pm = pp = 1.0;
58 sum = term = c1 * (pm * zm - pp * zp);
59 k = 0;
60 while (fabs(term) > EPS1 * sum) {
61 k = k + 1;
62 pm = pm * zs / (k * (k - NY));
63 pp = pp * zs / (k * (k + NY));
64 term = c1 * (pm * zm - pp * zp);
65 sum += term;
66 }
67 } else {
68 ze = sqrt(PI / 2.0 / z) * exp(-z);
69 za = 1.0 / (8.0 * z);
70 mu = 4.0 * NY * NY;
71 /* first term */
72 pa = 1.0;
73 sum = term = pa * ze;
74 /* Additional terms */
75 k = 0;
76 while (fabs(term) > EPS2 * sum) {
77 k = k + 1;
78 pa = pa * za * (mu - (2 * k - 1) * (2 * k - 1)) / k;
79 term = pa * ze;
80 sum += term;
81 }
82 }
83 return sum;
84}
double k23(double z)
Compute the Modified Bessel Function of the Second Kind K_{2/3}(z).
Definition k23.c:41