GooFit  v2.1.3
Faddeeva.cpp
Go to the documentation of this file.
1 #include <goofit/Error.h>
2 #include <goofit/Faddeeva.h>
3 
4 #include <cmath>
5 
7 
8 namespace GooFit {
9 
10 #define M_2PI 6.28318530717958
11 
12 static fptype n1[12] = {0.25, 1.0, 2.25, 4.0, 6.25, 9.0, 12.25, 16.0, 20.25, 25.0, 30.25, 36.0};
13 static fptype e1[12] = {0.7788007830714049,
14  0.3678794411714423,
15  1.053992245618643e-1,
16  1.831563888873418e-2,
17  1.930454136227709e-3,
18  1.234098040866795e-4,
19  4.785117392129009e-6,
20  1.125351747192591e-7,
21  1.605228055185612e-9,
22  1.388794386496402e-11,
23  7.287724095819692e-14,
24  2.319522830243569e-16};
25 
26 // table 2: coefficients for h = 0.53
27 static fptype n2[12]
28  = {0.2809, 1.1236, 2.5281, 4.4944, 7.0225, 10.1124, 13.7641, 17.9776, 22.7529, 28.09, 33.9889, 40.4496};
29 static fptype e2[12] = {0.7551038420890235,
30  0.3251072991205958,
31  7.981051630007964e-2,
32  1.117138143353082e-2,
33  0.891593719995219e-3,
34  4.057331392320188e-5,
35  1.052755021528803e-6,
36  1.557498087816203e-8,
37  1.313835773243312e-10,
38  6.319285885175346e-13,
39  1.733038792213266e-15,
40  2.709954036083074e-18};
41 
42 // tables for Pade approximation
43 static fptype C[7] = {65536.0, -2885792.0, 69973904.0, -791494704.0, 8962513560.0, -32794651890.0, 175685635125.0};
44 static fptype D[7] = {192192.0, 8648640.0, 183783600.0, 2329725600.0, 18332414100.0, 84329104860.0, 175685635125.0};
45 
47  fptype *n, *e, t, u, r, s, d, f, g, h;
48  fpcomplex c, d2, v, w;
49  int i;
50 
51  s = norm(z); // Actually the square of the norm. Don't ask me, I didn't name the function.
52 
53  if(s < 1e-7) {
54  // use Pade approximation
55  fpcomplex zz = z * z;
56  v = exp(zz);
57  c = C[0];
58  d2 = D[0];
59 
60  for(i = 1; i <= 6; i++) {
61  c = c * zz + C[i];
62  d2 = d2 * zz + D[i];
63  }
64 
65  w = fptype(1.0) / v + fpcomplex(0.0, M_2_SQRTPI) * c / d2 * z * v;
66  return w;
67  }
68 
69  // use trapezoid rule
70  // select default table 1
71  n = n1;
72  e = e1;
73  r = M_1_PI * 0.5;
74 
75  // if z is too close to a pole select table 2
76  if(fabs(z.imag()) < 0.01 && fabs(z.real()) < 6.01) {
77  h = fabs(z.real()) * 2;
78  // Equivalent to modf(h, &g). Do this way because nvcc only knows about double version of modf.
79  g = floor(h);
80  h -= g;
81 
82  if(h < 0.02 || h > 0.98) {
83  n = n2;
84  e = e2;
85  r = M_1_PI * 0.53;
86  }
87  }
88 
89  d = (z.imag() - z.real()) * (z.imag() + z.real());
90  f = 4 * z.real() * z.real() * z.imag() * z.imag();
91 
92  g = h = 0.0;
93 
94  for(i = 0; i < 12; i++) {
95  t = d + n[i];
96  u = e[i] / (t * t + f);
97  g += (s + n[i]) * u;
98  h += (s - n[i]) * u;
99  }
100 
101  u = 1 / s;
102 
103  c = r * fpcomplex(z.imag() * (u + 2.0 * g), z.real() * (u + 2.0 * h));
104 
105  if(z.imag() < M_2PI) {
106  s = 2.0 / r;
107  t = s * z.real();
108  u = s * z.imag();
109  s = sin(t);
110  h = cos(t);
111  f = exp(-u) - h;
112  g = 2.0 * exp(d - u) / (s * s + f * f);
113  u = 2.0 * z.real() * z.imag();
114  h = cos(u);
115  t = sin(u);
116  c += g * fpcomplex((h * f - t * s), -(h * s + t * f));
117  }
118 
119  return c;
120 }
121 
123  // This calculation includes the normalisation - integral
124  // over the reals is equal to one.
125 
126  // return constant for zero width and sigma
127  if((0 == s) && (0 == w))
128  return 1;
129 
130  if(s <= 0 || w <= 0)
131  throw GooFit::GeneralError("s {} and w {} must be larger than 0", s, w);
132 
133  fptype coef = -0.5 / (s * s);
134  fptype arg = x - m;
135 
136  // Breit-Wigner for zero sigma
137  if(0 == s)
138  return (1 / (arg * arg + 0.25 * w * w));
139 
140  // Gauss for zero width
141  if(0 == w)
142  return exp(coef * arg * arg);
143 
144  // actual Voigtian for non-trivial width and sigma
145  fptype c = 1. / (sqrt(2) * s);
146  fptype a = 0.5 * c * w;
147  fptype u = c * arg;
148  fpcomplex z(u, a);
149  // printf("Calling Faddeeva %f %f %f %f %f %f %f\n", x, m, s, w, c, a, u);
150  fpcomplex v = Faddeeva_2(z);
151 
152  static const fptype rsqrtPi = 0.5641895835477563;
153  return c * rsqrtPi * v.real();
154 }
155 } // namespace GooFit
Thrown when a general error is encountered.
Definition: Error.h:10
double fptype
fptype cpuvoigtian(fptype x, fptype m, fptype w, fptype s)
Definition: Faddeeva.cpp:122
thrust::complex< fptype > fpcomplex
Definition: Complex.h:8
fpcomplex Faddeeva_2(const fpcomplex &z)
Definition: Faddeeva.cpp:46
#define M_2PI
Definition: Faddeeva.cpp:10