46 #include "RandPoisson.h"
48 RandPoisson::~RandPoisson() {
49 if ( deleteEngine )
delete localEngine;
52 HepDouble RandPoisson::operator()() {
53 return HepDouble(fire());
56 HepDouble gammln(HepDouble xx) {
62 static HepDouble cof[6] = {76.18009172947146,-86.50532032941677,
63 24.01409824083091, -1.231739572450155,
64 0.1208650973866179e-2, -0.5395239384953e-5};
66 HepDouble x = xx - 1.0;
67 HepDouble tmp = x + 5.5;
68 tmp -= (x + 0.5) * ::log(tmp);
69 HepDouble ser = 1.000000000190015;
71 for ( j = 0; j <= 5; j++ ) {
75 return -tmp + ::log(2.5066282746310005*ser);
78 long RandPoisson::shoot(HepDouble xm) {
87 HepDouble sq, alxm, g;
88 HepDouble om = getOldMean();
90 HepDouble* status = getPStatus();
95 if( xm == -1 )
return 0;
105 t *= HepRandom::getTheGenerator()->flat();
108 else if ( xm < getMaxMean() ) {
113 g = xm*alxm - gammln(xm + 1.0);
117 y = tan(M_PI*HepRandom::getTheGenerator()->flat());
121 t = 0.9*(1.0 + y*y)* exp(em*alxm - gammln(em + 1.0) - g);
122 }
while( HepRandom::getTheGenerator()->flat() > t );
129 g = xm*alxm - gammln(xm + 1.0);
133 setPStatus(sq,alxm,g);
137 void RandPoisson::shootArray(
const HepInt size,
long* vect, HepDouble m)
139 for (
int i=0; i<size; ++i)
144 #ifndef ST_NO_TEMPLATE_DEF_ARGS
145 RandPoisson::shootArray(vector<long>& vec, HepDouble m)
147 RandPoisson::shootArray(vector<
long,allocator<long> >& vec, HepDouble m)
150 for (
unsigned int i=0; i<vec.size(); ++i)
163 HepDouble sq, alxm, g;
164 HepDouble om = getOldMean();
166 HepDouble* status = getPStatus();
171 if( xm == -1 )
return 0;
181 t *= anEngine->flat();
184 else if ( xm < getMaxMean() ) {
189 g = xm*alxm - gammln(xm + 1.0);
193 y = tan(M_PI*anEngine->flat());
197 t = 0.9*(1.0 + y*y)* exp(em*alxm - gammln(em + 1.0) - g);
198 }
while( anEngine->flat() > t );
205 g = xm*alxm - gammln(xm + 1.0);
209 setPStatus(sq,alxm,g);
213 void RandPoisson::shootArray(
HepRandomEngine* anEngine,
const HepInt size,
214 long* vect, HepDouble m)
218 for (i=0; i<size; ++i)
219 vect[i] = shoot(anEngine,m);
222 #ifndef ST_NO_TEMPLATE_DEF_ARGS
224 vector<long>& vec, HepDouble m)
227 vector<
long,allocator<long> >& vec, HepDouble m)
230 for (
unsigned int i=0; i<vec.size(); ++i)
231 vec[i] = shoot(anEngine,m);
233 long RandPoisson::fire(HepDouble xm) {
242 HepDouble sq, alxm, g;
248 if( xm == -1 )
return 0;
258 t *= localEngine->flat();
261 else if ( xm < meanMax ) {
266 g = xm*alxm - gammln(xm + 1.0);
270 y = tan(M_PI*localEngine->flat());
274 t = 0.9*(1.0 + y*y)* exp(em*alxm - gammln(em + 1.0) - g);
275 }
while( localEngine->flat() > t );
282 g = xm*alxm - gammln(xm + 1.0);
286 status[0] = sq; status[1] = alxm; status[2] = g;
290 void RandPoisson::fireArray(
const HepInt size,
long* vect, HepDouble m)
294 for (i=0; i<size; ++i)
299 #ifndef ST_NO_TEMPLATE_DEF_ARGS
300 RandPoisson::fireArray(vector<long>& vec, HepDouble m)
302 RandPoisson::fireArray(vector<
long,allocator<long> >& vec, HepDouble m)
305 for (
unsigned int i=0; i<vec.size(); ++i)