CMS 3D CMS Logo

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