CMS 3D CMS Logo

GammaFunctionGenerator.cc
Go to the documentation of this file.
1 //FAMOS headers
4 
6  xmax = 30.;
7 
8  for (unsigned i = 1; i <= 12; ++i) {
9  // For all let's put the limit at 2.*(alpha-1) (alpha-1 is the max of the dist)
10  approxLimit.push_back(2 * ((double)i));
11  myIncompleteGamma.a().setValue((double)i);
13  theGammas.push_back(GammaNumericalGenerator((double)i, 1., 0, approxLimit[i - 1] + 1.));
14  }
15  coreCoeff.push_back(0.); // alpha=1 not used
16  coreCoeff.push_back(1. / 8.24659e-01);
17  coreCoeff.push_back(1. / 7.55976e-01);
18  coreCoeff.push_back(1. / 7.12570e-01);
19  coreCoeff.push_back(1. / 6.79062e-01);
20  coreCoeff.push_back(1. / 6.65496e-01);
21  coreCoeff.push_back(1. / 6.48736e-01);
22  coreCoeff.push_back(1. / 6.25185e-01);
23  coreCoeff.push_back(1. / 6.09188e-01);
24  coreCoeff.push_back(1. / 6.06221e-01);
25  coreCoeff.push_back(1. / 6.05057e-01);
26 }
27 
29 
31  if (alpha < 0.)
32  return -1.;
33  if (badRange)
34  return xmin / beta;
35  if (alpha < 12) {
36  if (alpha == na) {
37  return gammaInt(random) / beta;
38  } else if (na == 0) {
39  return gammaFrac(random) / beta;
40  } else {
41  double gi = gammaInt(random);
42  double gf = gammaFrac(random);
43  return (gi + gf) / beta;
44  }
45  } else {
46  // an other generator has to be used in such a case
47  return -1.;
48  }
49 }
50 
52  /* This is exercise 16 from Knuth; see page 135, and the solution is
53  on page 551. */
54 
55  double p, q, x, u, v;
56  p = M_E / (frac + M_E);
57  do {
58  u = random->flatShoot();
59  v = random->flatShoot();
60 
61  if (u < p) {
62  x = exp((1 / frac) * log(v));
63  q = exp(-x);
64  } else {
65  x = 1 - log(v);
66  q = exp((frac - 1) * log(x));
67  }
68  } while (random->flatShoot() >= q);
69 
70  return x;
71 }
72 
74  // Exponential distribution : no approximation
75  if (na == 1) {
76  return xmin - log(random->flatShoot());
77  }
78 
79  unsigned gn = na - 1;
80 
81  // are we sure to be in the tail
82  if (coreProba == 0.)
83  return xmin - coreCoeff[gn] * log(random->flatShoot());
84 
85  // core-tail interval
86  if (random->flatShoot() < coreProba) {
87  return theGammas[gn].gamma_lin(random);
88  }
89  // std::cout << " Tail called " << std::endl;
90  return approxLimit[gn] - coreCoeff[gn] * log(random->flatShoot());
91 }
92 
93 void GammaFunctionGenerator::setParameters(double a, double b, double xm) {
94  // std::cout << "Setting parameters " << std::endl;
95  alpha = a;
96  beta = b;
97  xmin = xm * beta;
98  if (xm > xmax) {
99  badRange = true;
100  return;
101  }
102  badRange = false;
103  na = 0;
104 
105  if (alpha > 0. && alpha < 12)
106  na = (unsigned)floor(alpha);
107 
108  frac = alpha - na;
109  // Now calculate the probability to shoot between approxLimit and xmax
110  // The Incomplete gamma is normalized to 1
111  if (na <= 1)
112  return;
113 
114  myIncompleteGamma.a().setValue((double)na);
115 
116  unsigned gn = na - 1;
117  // std::cout << " na " << na << " xm " << xm << " beta " << beta << " xmin " << xmin << " approxLimit " << approxLimit[gn] << std::endl;
118  if (xmin > approxLimit[gn]) {
119  coreProba = 0.;
120  } else {
121  double tmp = (xmin != 0.) ? myIncompleteGamma(xmin) : 0.;
122  coreProba = (integralToApproxLimit[gn] - tmp) / (1. - tmp);
123  theGammas[gn].setSubInterval(xmin, approxLimit[gn]);
124  }
125  // std::cout << " Proba " << coreProba << std::endl;
126 }
std::vector< GammaNumericalGenerator > theGammas
double gammaFrac(RandomEngineAndDistribution const *) const
values 0<a<1.
GammaFunctionGenerator()
Constructor.
std::vector< double > approxLimit
double gammaInt(RandomEngineAndDistribution const *) const
integer values
std::vector< double > coreCoeff
Genfun::IncompleteGamma myIncompleteGamma
void setParameters(double a, double b, double xm)
The parameters must be set before shooting.
double b
Definition: hdecay.h:118
double shoot(RandomEngineAndDistribution const *) const
double a
Definition: hdecay.h:119
double gf
Definition: hdecay.h:34
double flatShoot(double xmin=0.0, double xmax=1.0) const
tmp
align.sh
Definition: createJobs.py:716
virtual ~GammaFunctionGenerator()
Destructor.
std::vector< double > integralToApproxLimit