28 #include "CLHEP/Random/RandPoisson.h" 
   29 #include "CLHEP/Units/PhysicalConstants.h" 
   30 #include "CLHEP/Random/DoubConv.h" 
   39 CLHEP_THREAD_LOCAL 
double RandPoisson::status_st[3] = {0., 0., 0.};
 
   40 CLHEP_THREAD_LOCAL 
double RandPoisson::oldm_st = -1.0;
 
   41 const double RandPoisson::meanMax_st = 2.0E9;
 
   43 RandPoisson::~RandPoisson() {
 
   46 double RandPoisson::operator()() {
 
   47   return double(fire( defaultMean ));
 
   50 double RandPoisson::operator()( 
double mean ) {
 
   51   return double(fire( mean ));
 
   60   static const double cof[6] = {76.18009172947146,-86.50532032941677,
 
   61                              24.01409824083091, -1.231739572450155,
 
   62                              0.1208650973866179e-2, -0.5395239384953e-5};
 
   66   tmp -= (x + 0.5) * std::log(tmp);
 
   67   double ser = 1.000000000190015;
 
   69   for ( j = 0; j <= 5; j++ ) {
 
   73   return -tmp + std::log(2.5066282746310005*ser);
 
   77 double normal (HepRandomEngine* eptr)           
 
   82     v1 = 2.0 * eptr->flat() - 1.0;
 
   83     v2 = 2.0 * eptr->flat() - 1.0;
 
   87   fac = std::sqrt(-2.0*std::log(r)/r);
 
  100   double om = getOldMean();
 
  101   HepRandomEngine* anEngine = HepRandom::getTheEngine();
 
  103   double* status = getPStatus();
 
  108   if( xm == -1 ) 
return 0;
 
  118       t *= anEngine->flat();
 
  121   else if ( xm < getMaxMean() ) {
 
  124       sq = std::sqrt(2.0*xm);
 
  126       g1 = xm*alxm - 
gammln(xm + 1.0);
 
  130         y = std::tan(
CLHEP::pi*anEngine->flat());
 
  134       t = 0.9*(1.0 + y*y)* std::exp(em*alxm - 
gammln(em + 1.0) - g1);
 
  135     } 
while( anEngine->flat() > t );
 
  138     em = xm + std::sqrt(xm) * 
normal (anEngine);        
 
  139     if ( static_cast<long>(em) < 0 ) 
 
  140       em = 
static_cast<long>(xm) >= 0 ? xm : getMaxMean();
 
  142   setPStatus(sq,alxm,g1);
 
  146 void RandPoisson::shootArray(
const int size, 
long* vect, 
double m1)
 
  148   for( 
long* v = vect; v != vect + size; ++v )
 
  161   double om = getOldMean();
 
  163   double* status = getPStatus();
 
  168   if( xm == -1 ) 
return 0;
 
  178       t *= anEngine->flat();
 
  181   else if ( xm < getMaxMean() ) {
 
  184       sq = std::sqrt(2.0*xm);
 
  186       g1 = xm*alxm - 
gammln(xm + 1.0);
 
  190         y = std::tan(
CLHEP::pi*anEngine->flat());
 
  194       t = 0.9*(1.0 + y*y)* std::exp(em*alxm - 
gammln(em + 1.0) - g1);
 
  195     } 
while( anEngine->flat() > t );
 
  198     em = xm + std::sqrt(xm) * 
normal (anEngine);        
 
  199     if ( static_cast<long>(em) < 0 ) 
 
  200       em = 
static_cast<long>(xm) >= 0 ? xm : getMaxMean();
 
  202   setPStatus(sq,alxm,g1);
 
  206 void RandPoisson::shootArray(HepRandomEngine* anEngine, 
const int size,
 
  207                              long* vect, 
double m1)
 
  209   for( 
long* v = vect; v != vect + size; ++v )
 
  210     *v = 
shoot(anEngine,m1);
 
  213 long RandPoisson::fire() {
 
  214   return long(fire( defaultMean ));
 
  217 long RandPoisson::fire(
double xm) {
 
  231   if( xm == -1 ) 
return 0;
 
  241       t *= localEngine->flat();
 
  244   else if ( xm < meanMax ) {
 
  247       sq = std::sqrt(2.0*xm);
 
  249       g1 = xm*alxm - 
gammln(xm + 1.0);
 
  253         y = std::tan(
CLHEP::pi*localEngine->flat());
 
  257       t = 0.9*(1.0 + y*y)* std::exp(em*alxm - 
gammln(em + 1.0) - g1);
 
  258     } 
while( localEngine->flat() > t );
 
  261     em = xm + std::sqrt(xm) * 
normal (localEngine.get());       
 
  262     if ( static_cast<long>(em) < 0 ) 
 
  263       em = static_cast<long>(xm) >= 0 ? xm : getMaxMean();
 
  265   status[0] = sq; status[1] = alxm; status[2] = g1;
 
  269 void RandPoisson::fireArray(
const int size, 
long* vect )
 
  271   for( 
long* v = vect; v != vect + size; ++v )
 
  272     *v = fire( defaultMean );
 
  275 void RandPoisson::fireArray(
const int size, 
long* vect, 
double m1)
 
  277   for( 
long* v = vect; v != vect + size; ++v )
 
  281 std::ostream & RandPoisson::put ( std::ostream & os )
 const {
 
  282   int pr=os.precision(20);
 
  283   std::vector<unsigned long> t(2);
 
  284   os << 
" " << 
name() << 
"\n";
 
  285   os << 
"Uvec" << 
"\n";
 
  286   t = DoubConv::dto2longs(meanMax);
 
  287   os << meanMax << 
" " << t[0] << 
" " << t[1] << 
"\n";
 
  288   t = DoubConv::dto2longs(defaultMean);
 
  289   os << defaultMean << 
" " << t[0] << 
" " << t[1] << 
"\n";
 
  290   t = DoubConv::dto2longs(status[0]);
 
  291   os << status[0] << 
" " << t[0] << 
" " << t[1] << 
"\n";
 
  292   t = DoubConv::dto2longs(status[1]);
 
  293   os << status[1] << 
" " << t[0] << 
" " << t[1] << 
"\n";
 
  294   t = DoubConv::dto2longs(status[2]);
 
  295   os << status[2] << 
" " << t[0] << 
" " << t[1] << 
"\n";
 
  296   t = DoubConv::dto2longs(oldm);
 
  297   os << oldm << 
" " << t[0] << 
" " << t[1] << 
"\n";
 
  302 std::istream & RandPoisson::get ( std::istream & is ) {
 
  305   if (inName != 
name()) {
 
  306     is.clear(std::ios::badbit | is.rdstate());
 
  307     std::cerr << 
"Mismatch when expecting to read state of a " 
  308               << 
name() << 
" distribution\n" 
  309               << 
"Name found was " << inName
 
  310               << 
"\nistream is left in the badbit state\n";
 
  313   if (possibleKeywordInput(is, 
"Uvec", meanMax)) {
 
  314     std::vector<unsigned long> t(2);
 
  315     is >> meanMax     >> t[0] >> t[1]; meanMax     = DoubConv::longs2double(t); 
 
  316     is >> defaultMean >> t[0] >> t[1]; defaultMean = DoubConv::longs2double(t); 
 
  317     is >> status[0]   >> t[0] >> t[1]; status[0]   = DoubConv::longs2double(t); 
 
  318     is >> status[1]   >> t[0] >> t[1]; status[1]   = DoubConv::longs2double(t); 
 
  319     is >> status[2]   >> t[0] >> t[1]; status[2]   = DoubConv::longs2double(t); 
 
  320     is >> oldm        >> t[0] >> t[1]; oldm        = DoubConv::longs2double(t); 
 
  324   is >> defaultMean >> status[0] >> status[1] >> status[2];
 
ThreeVector shoot(const G4int Ap, const G4int Af)
 
static int engine(pchar, pchar, double &, pchar &, const dic_type &)
 
static double normal(HepRandomEngine *eptr)
 
static const G4double fac