1 #include <goofit/PDFs/basic/CrystalBallPdf.h>
2 #include <goofit/Variable.h>
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.
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;
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);
24 fptype n_over_alpha = power / alpha;
25 fptype a = exp(-0.5 * alpha * alpha);
26 fptype b = n_over_alpha - alpha;
28 d = (d != 0) ? n_over_alpha / d : 0;
29 ret = a * pow(d, power);
32 // if ((0 == THREADIDX) && (0 == BLOCKIDX)) printf("device_CB: %f %f %f %f %f %f\n", x, mean, sigma, alpha, power,
37 __device__ device_function_ptr ptr_to_CrystalBall = device_CrystalBall;
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)) {}
42 __host__ CrystalBallPdf::CrystalBallPdf(
43 std::string n, Observable _x, Variable mean, Variable sigma, Variable alpha, Variable power)
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);
54 __host__ fptype CrystalBallPdf::integrate(fptype lo, fptype hi) const {
55 static const fptype sqrtPiOver2 = 1.2533141373;
56 static const fptype sqrt2 = 1.4142135624;
61 unsigned int *indices = host_indices + parameters;
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]];
68 if(fabs(power - 1.0) < 1.0e-05)
71 fptype tmin = (lo - mean) / sigma;
72 fptype tmax = (hi - mean) / sigma;
80 fptype absAlpha = fabs(alpha);
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;
89 result += a * sigma * (log(b - tmin) - log(b - tmax));
91 result += a * sigma / (1.0 - power)
92 * (1.0 / (pow(b - tmin, power - 1.0)) - 1.0 / (pow(b - tmax, power - 1.0)));
95 fptype a = pow(power / absAlpha, power) * exp(-0.5 * absAlpha * absAlpha);
96 fptype b = power / absAlpha - absAlpha;
101 term1 = a * sigma * (log(b - tmin) - log(power / absAlpha));
103 term1 = a * sigma / (1.0 - power)
104 * (1.0 / (pow(b - tmin, power - 1.0)) - 1.0 / (pow(power / absAlpha, power - 1.0)));
107 fptype term2 = sigma * sqrtPiOver2 * (erf(tmax / sqrt2) - erf(-absAlpha / sqrt2));
108 result += term1 + term2;
114 } // namespace GooFit