SDDSlib
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;
43 static double e2;
44 long k;
45
46 if (z < A_LIM) {
47 /* series expansion*/
48 c1 = PI / 2.0 / sin(PI * NY);
49 c2 = 2 * c1;
50 zs = z * z / 4.0;
51
52 ny_fac = NY * GAMMA_OF_NY; /* ! Factorial of (+ny)*/
53 neg_ny_fac = c2 / GAMMA_OF_NY; /*! Factorial of (-ny)*/
54 e2 = pow(z / 2.0, NY);
55 zm = 1 / e2 / neg_ny_fac;
56 zp = e2 / ny_fac;
57 /* first term */
58 pm = pp = 1.0;
59 sum = term = c1 * (pm * zm - pp * zp);
60 k = 0;
61 while (fabs(term) > EPS1 * sum) {
62 k = k + 1;
63 pm = pm * zs / (k * (k - NY));
64 pp = pp * zs / (k * (k + NY));
65 term = c1 * (pm * zm - pp * zp);
66 sum += term;
67 }
68 } else {
69 ze = sqrt(PI / 2.0 / z) * exp(-z);
70 za = 1.0 / (8.0 * z);
71 mu = 4.0 * NY * NY;
72 /* first term */
73 pa = 1.0;
74 sum = term = pa * ze;
75 /* Additional terms */
76 k = 0;
77 while (fabs(term) > EPS2 * sum) {
78 k = k + 1;
79 pa = pa * za * (mu - (2 * k - 1) * (2 * k - 1)) / k;
80 term = pa * ze;
81 sum += term;
82 }
83 }
84 return sum;
85}
double k23(double z)
Compute the Modified Bessel Function of the Second Kind K_{2/3}(z).
Definition k23.c:41