GooFit  v2.1.3
CrystalBallPdf.cu
Go to the documentation of this file.
1 #include <goofit/PDFs/basic/CrystalBallPdf.h>
2 #include <goofit/Variable.h>
3 
4 namespace GooFit {
5 
6 __device__ fptype device_CrystalBall(fptype *evt, fptype *p, unsigned int *indices) {
7  // Left-hand tail if alpha is less than 0,
8  // right-hand tail if greater, pure Gaussian if 0.
9  // return 1;
10 
11  fptype x = evt[indices[2 + indices[0]]];
12  fptype mean = p[indices[1]];
13  fptype sigma = p[indices[2]];
14  fptype alpha = p[indices[3]];
15  fptype power = p[indices[4]];
16  fptype rx = (sigma != 0) ? (x - mean) / sigma : 0;
17  fptype ret = 0;
18 
19  if((alpha > 0 && rx <= alpha) || // Right-hand tail, in Gaussian region
20  (alpha < 0 && rx >= alpha) || // Left-hand tail, in Gaussian region
21  (alpha == 0)) { // Pure Gaussian
22  ret = exp(-0.5 * rx * rx);
23  } else { // Tail part
24  fptype n_over_alpha = power / alpha;
25  fptype a = exp(-0.5 * alpha * alpha);
26  fptype b = n_over_alpha - alpha;
27  fptype d = b + rx;
28  d = (d != 0) ? n_over_alpha / d : 0;
29  ret = a * pow(d, power);
30  }
31 
32  // if ((0 == THREADIDX) && (0 == BLOCKIDX)) printf("device_CB: %f %f %f %f %f %f\n", x, mean, sigma, alpha, power,
33  // ret);
34  return ret;
35 }
36 
37 __device__ device_function_ptr ptr_to_CrystalBall = device_CrystalBall;
38 
39 __host__ CrystalBallPdf::CrystalBallPdf(std::string n, Observable _x, Variable mean, Variable sigma, Variable alpha)
40  : CrystalBallPdf(n, _x, mean, sigma, alpha, Variable(n + "_n", 2)) {}
41 
42 __host__ CrystalBallPdf::CrystalBallPdf(
43  std::string n, Observable _x, Variable mean, Variable sigma, Variable alpha, Variable power)
44  : GooPdf(n, _x) {
45  std::vector<unsigned int> pindices;
46  pindices.push_back(registerParameter(mean));
47  pindices.push_back(registerParameter(sigma));
48  pindices.push_back(registerParameter(alpha));
49  pindices.push_back(registerParameter(power));
50  GET_FUNCTION_ADDR(ptr_to_CrystalBall);
51  initialize(pindices);
52 }
53 
54 __host__ fptype CrystalBallPdf::integrate(fptype lo, fptype hi) const {
55  static const fptype sqrtPiOver2 = 1.2533141373;
56  static const fptype sqrt2 = 1.4142135624;
57 
58  fptype result = 0.0;
59  bool useLog = false;
60 
61  unsigned int *indices = host_indices + parameters;
62 
63  fptype mean = host_params[indices[1]];
64  fptype sigma = host_params[indices[2]];
65  fptype alpha = host_params[indices[3]];
66  fptype power = host_params[indices[4]];
67 
68  if(fabs(power - 1.0) < 1.0e-05)
69  useLog = true;
70 
71  fptype tmin = (lo - mean) / sigma;
72  fptype tmax = (hi - mean) / sigma;
73 
74  if(alpha < 0) {
75  fptype tmp = tmin;
76  tmin = -tmax;
77  tmax = -tmp;
78  }
79 
80  fptype absAlpha = fabs(alpha);
81 
82  if(tmin >= -absAlpha) {
83  result += sigma * sqrtPiOver2 * (erf(tmax / sqrt2) - erf(tmin / sqrt2));
84  } else if(tmax <= -absAlpha) {
85  fptype a = pow(power / absAlpha, power) * exp(-0.5 * absAlpha * absAlpha);
86  fptype b = power / absAlpha - absAlpha;
87 
88  if(useLog) {
89  result += a * sigma * (log(b - tmin) - log(b - tmax));
90  } else {
91  result += a * sigma / (1.0 - power)
92  * (1.0 / (pow(b - tmin, power - 1.0)) - 1.0 / (pow(b - tmax, power - 1.0)));
93  }
94  } else {
95  fptype a = pow(power / absAlpha, power) * exp(-0.5 * absAlpha * absAlpha);
96  fptype b = power / absAlpha - absAlpha;
97 
98  fptype term1 = 0.0;
99 
100  if(useLog) {
101  term1 = a * sigma * (log(b - tmin) - log(power / absAlpha));
102  } else {
103  term1 = a * sigma / (1.0 - power)
104  * (1.0 / (pow(b - tmin, power - 1.0)) - 1.0 / (pow(power / absAlpha, power - 1.0)));
105  }
106 
107  fptype term2 = sigma * sqrtPiOver2 * (erf(tmax / sqrt2) - erf(-absAlpha / sqrt2));
108  result += term1 + term2;
109  }
110 
111  return result;
112 }
113 
114 } // namespace GooFit