QMCPACK
Bessel.h
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////////////////////
2 // This file is distributed under the University of Illinois/NCSA Open Source License.
3 // See LICENSE file in top directory for details.
4 //
5 // Copyright (c) 2019 QMCPACK developers.
6 //
7 // File developed by: Ye Luo, yeluo@anl.gov, Argonne National Laboratory
8 //
9 // File created by: Ye Luo, yeluo@anl.gov, Argonne National Laboratory
10 //
11 //////////////////////////////////////////////////////////////////////////////////////
12 
13 #ifndef QMCPLUSPLUS_NEW_BESSEL_H
14 #define QMCPLUSPLUS_NEW_BESSEL_H
15 
16 #include <cmath>
17 namespace qmcplusplus
18 {
19 /** @ingroup Numerics
20  * @brief Compute spherical bessel function from 0 to lmax
21  *
22  * Using Steed/Barnett algorithm from Comp. Phys. Comm. 21, 297 (1981)
23  */
24 template<typename T>
25 void bessel_steed_array_cpu(const int lmax, const T x, T* jl)
26 {
27  if (lmax < 0)
28  throw std::runtime_error("Negative lmax not allowed!");
29  else if (x < 0)
30  throw std::runtime_error("Negative x not allowed!");
31  else if (x == 0.0)
32  {
33  std::fill(jl, jl + lmax + 1, T(0.0));
34  jl[0] = T(1.0);
35  }
36  else if (x < 0.00024)
37  {
38  const double cone(1);
39  double inv_accumuated = cone;
40  double x_l = cone;
41  for (int l = 0; l <= lmax; l++)
42  {
43  jl[l] = x_l * inv_accumuated;
44  const double inv = cone / (2 * l + 3);
45  jl[l] *= cone - 0.5 * x * x * inv;
46  inv_accumuated *= inv;
47  x_l *= x;
48  }
49  }
50  else
51  {
52  const double cone(1);
53  const double ctwo(2);
54  double XI(cone / x);
55  double W(XI * ctwo);
56  double F(cone);
57  double FP((lmax + 1) * XI);
58  double B(FP * ctwo + XI);
59  double D(cone / B);
60  double DEL(-D);
61  FP += DEL;
62 
63  do
64  {
65  B += W;
66  D = cone / (B - D);
67  DEL *= (B * D - cone);
68  FP += DEL;
69  if (D < 0.0)
70  F = -F;
71  } while (std::fabs(DEL) >= std::fabs(FP) * 1.19209e-07);
72 
73  FP *= F;
74  jl[0] = F;
75 
76  if (lmax > 0)
77  {
78  double PL = lmax * XI;
79  jl[lmax] = F;
80  for (int L = lmax; L >= 1; L--)
81  {
82  jl[L - 1] = PL * jl[L] + FP;
83  FP = PL * jl[L - 1] - jl[L];
84  PL -= XI;
85  }
86  F = jl[0];
87  }
88 
89  // using hypot instead of sqrt to avoid overflow/underflow
90  W = XI / std::hypot(FP, F);
91  for (int L = 0; L <= lmax; L++)
92  jl[L] *= W;
93  }
94 }
95 
96 } // namespace qmcplusplus
97 
98 #endif
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
constexpr std::complex< float > cone
Definition: BLAS.hpp:50
void inv(const T *restrict in, T *restrict out, int n)
Definition: vmath.hpp:65
double B(double x, int k, int i, const std::vector< double > &t)
void bessel_steed_array_cpu(const int lmax, const T x, T *jl)
Compute spherical bessel function from 0 to lmax.
Definition: Bessel.h:25