CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
List of all members | Public Member Functions
DoubleCrystalBallGenerator Class Reference

#include <DoubleCrystalBallGenerator.h>

Public Member Functions

 DoubleCrystalBallGenerator ()
 
double shoot (double mu, double sigma, double aL, double nL, double aR, double nR, RandomEngineAndDistribution const *random)
 
virtual ~DoubleCrystalBallGenerator ()
 

Detailed Description

Definition at line 12 of file DoubleCrystalBallGenerator.h.

Constructor & Destructor Documentation

DoubleCrystalBallGenerator::DoubleCrystalBallGenerator ( )
inline

Definition at line 15 of file DoubleCrystalBallGenerator.h.

15 {}
virtual DoubleCrystalBallGenerator::~DoubleCrystalBallGenerator ( )
inlinevirtual

Definition at line 17 of file DoubleCrystalBallGenerator.h.

17 {}

Member Function Documentation

double DoubleCrystalBallGenerator::shoot ( double  mu,
double  sigma,
double  aL,
double  nL,
double  aR,
double  nR,
RandomEngineAndDistribution const *  random 
)

Definition at line 11 of file DoubleCrystalBallGenerator.cc.

References RandomEngineAndDistribution::flatShoot(), N, Pi, x, and y.

12  {
13  if (nL <= 1 || nR <= 1)
14  return 0; //n>1 required
15 
16  double dL = nL / aL;
17  double dR = nR / aR;
18  double N = 1 / (sigma * (nL / aL * 1 / (nL - 1) * Exp(-aL * aL / 2) +
19  Sqrt(Pi() / 2) * (Erf(aL / Sqrt(2)) + Erf(aR / Sqrt(2))) +
20  nR / aR * 1 / (nR - 1) * Exp(-aR * aR / 2)));
21 
22  //start x as NaN
23  double x = 0. / 0.;
24  while (!Finite(x)) {
25  //shoot a flat random number
26  double y = random->flatShoot();
27 
28  //check range
29  //crystal ball CDF changes at (x-mu)/sigma = -aL && (x-mu)/sigma = aR
30  //compute this in pieces because it is awful
31  double AL = dL / (nL - 1) * Exp(-aL * aL / 2);
32  double CL = Sqrt(Pi() / 2) * Erf(aL / Sqrt(2));
33  double CR = Sqrt(Pi() / 2) * Erf(aR / Sqrt(2));
34  if (y < sigma * N * AL) { //below lower boundary, use inverted power law CDF (left side)
35  double BL = dL / (nL - 1) * Exp(-aL * aL / 2);
36  x = mu + sigma * (-dL * Power(y / (sigma * N * BL), 1 / (-nL + 1)) - aL + dL);
37  } else if (y > sigma * N * (AL + CL + CR)) { //above lower boundary, use inverted power law CDF (right side)
38  double AR = dR / (nR - 1) * Exp(-aR * aR / 2);
39  double BR = dR / (1 - nR) * Exp(-aR * aR / 2);
40  double D = (y / (sigma * N) - AL - CL - CR - AR) / BR;
41  x = mu + sigma * (dR * Power(D, 1 / (-nR + 1)) + aR - dR);
42  } else { //between boundaries, use gaussian CDF with proper normalization (in terms of erfc)
43  double D = 1 - Sqrt(2 / Pi()) * (y / (sigma * N) - AL - CL);
44  x = mu + sigma * Sqrt(2) * ErfcInverse(D);
45  }
46  }
47  return x;
48 }
const double Pi
const int mu
Definition: Constants.h:22
#define N
Definition: blowfish.cc:9
DecomposeProduct< arg, typename Div::arg > D
Definition: Factorize.h:141