thepeg is hosted by Hepforge, IPPP Durham
ThePEG  2.2.1
RandomGenerator.h
1 // -*- C++ -*-
2 //
3 // RandomGenerator.h is a part of ThePEG - Toolkit for HEP Event Generation
4 // Copyright (C) 1999-2019 Leif Lonnblad
5 //
6 // ThePEG is licenced under version 3 of the GPL, see COPYING for details.
7 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
8 //
9 #ifndef ThePEG_RandomGenerator_H
10 #define ThePEG_RandomGenerator_H
11 // This is the declaration of the RandomGenerator class.
12 
13 #include "ThePEG/Config/ThePEG.h"
14 #include "ThePEG/Interface/Interfaced.h"
15 #include "gsl/gsl_rng.h"
16 
17 namespace ThePEG {
18 
37 class RandomGenerator: public Interfaced {
38 
39 public:
40 
42  typedef vector<double> RndVector;
43 
45  typedef RndVector::size_type size_type;
46 
47 public:
48 
55 
60 
64  virtual ~RandomGenerator();
66 
71  virtual void setSeed(long seed) = 0;
72 
79  double rnd() {
80  if ( nextNumber == theNumbers.end() ) fill();
81  return *nextNumber++;
82  }
83 
88  template <typename Unit> Unit rnd(Unit b) { return b*rnd(); }
89 
94  template <typename Unit>
95  Unit rnd(Unit a, Unit b) { return a + rnd(b - a); }
96 
101  RndVector rndvec(int n) {
102  RndVector ret(n);
103  for ( int i = 0; i < n; ++i ) ret[i] = rnd();
104  return ret;
105  }
106 
111  double operator()() { return rnd(); }
112 
119  double operator()(double N) { return double(rnd() * N); }
120 
125  long operator()(long N) { return long(rnd() * N); }
126 
130  bool rndbool(double p = 0.5) {
131  return rnd() < p;
132  }
133 
138  bool prndbool(double p = 0.5);
139 
144  bool rndbool(double p1, double p2) { return rndbool(p1/(p1 + p2)); }
145 
150  bool prndbool(double p1, double p2) { return prndbool(p1/(p1 + p2)); }
151 
156  int rndsign(double p1, double p2, double p3);
157 
162  int prndsign(double p1, double p2, double p3);
163 
168  int rnd2(double p0, double p1) {
169  return rndbool(p0, p1)? 0: 1;
170  }
171 
176  int rnd3(double p0, double p1, double p2) {
177  return 1 + rndsign(p0, p1, p2);
178  }
179 
184  int rnd4(double p0, double p1, double p2, double p3);
185 
190  int rnd5(double p0, double p1, double p2, double p3, double p4);
191 
196  double rndExp() {
197  return -log(rnd());
198  }
199 
204  template <typename Unit>
205  Unit rndExp(Unit mean) { return mean*rndExp(); }
206 
214  void rndGaussTwoNumbers(double & randomNumberOne, double & randomNumberTwo) {
215  double r = sqrt(-2.0*log(rnd()));
216  double phi = rnd()*2.0*Constants::pi;
217  randomNumberOne = r*sin(phi);
218  randomNumberTwo = r*cos(phi);
219  }
220 
227  double rndGauss() {
228  if ( gaussSaved ) {
229  gaussSaved = false;
230  return savedGauss;
231  }
232  double randomNumberOne, randomNumberTwo;
233  rndGaussTwoNumbers(randomNumberOne, randomNumberTwo);
234  savedGauss = randomNumberTwo;
235  gaussSaved = true;
236  return randomNumberOne;
237  }
238 
243  template <typename Unit>
244  Unit rndGauss(Unit sigma, Unit mean = Unit()) {
245  return mean + sigma*rndGauss();
246  }
247 
252  template <typename Unit>
253  void rndGaussTwoNumbers(Unit & randomNumberOne, Unit & randomNumberTwo, Unit sigma, Unit mean = Unit()) {
254  double r1,r2;
255  rndGaussTwoNumbers(r1,r2);
256  randomNumberOne = mean + sigma * r1;
257  randomNumberTwo = mean + sigma * r2;
258  }
259 
265  template <typename Unit>
266  Unit rndBW(Unit mean, Unit gamma) {
267  if ( gamma <= Unit() ) return mean;
268  return mean + 0.5*gamma*tan(rnd(atan(-2.0*mean/gamma), Constants::pi/2));
269  }
270 
277  template <typename Unit>
278  Unit rndBW(Unit mean, Unit gamma, Unit cut) {
279  if ( gamma <= Unit() || cut <= Unit() ) return mean;
280  return mean + 0.5*gamma*tan(rnd(atan(-2.0*min(mean,cut)/gamma),
281  atan(2.0*cut/gamma)));
282  }
283 
288  template <typename Unit>
289  Unit rndRelBW(Unit mean, Unit gamma) {
290  if ( gamma <= Unit() ) return mean;
291  return sqrt(sqr(mean) + mean*gamma*tan(rnd(atan(-mean/gamma),
292  Constants::pi/2)));
293  }
294 
301  template <typename Unit>
302  Unit rndRelBW(Unit mean, Unit gamma, Unit cut) {
303  if ( gamma <= Unit() || cut <= Unit() ) return mean;
304  double minarg = cut > mean? -mean/gamma:
305  (sqr(mean - cut) - sqr(mean))/(gamma*mean);
306  double maxarg = (sqr(mean + cut) - sqr(mean))/(mean*gamma);
307  return sqrt(sqr(mean) + mean*gamma*tan(rnd(atan(minarg), atan(maxarg))));
308  }
309 
317  long rndPoisson(double mean);
319 
336  void push_back(double r) {
337  if ( r > 0.0 && r < 1.0 && nextNumber != theNumbers.begin() )
338  *--nextNumber = r;
339  }
340 
344  void pop_back() {
345  if ( nextNumber != theNumbers.end() ) ++nextNumber;
346  }
347 
352  void flush() {
353  nextNumber = theNumbers.end();
354  gaussSaved = false;
355  }
356 
361  template <typename OutputIterator>
362  void rnd(OutputIterator o, size_type n) {
363  while ( n-- ) *o++ = rnd();
364  }
366 
367 protected:
368 
374  virtual void doinit();
375 
376 public:
377 
378 
385  void persistentOutput(PersistentOStream & os) const;
386 
392  void persistentInput(PersistentIStream & is, int version);
394 
398  static void Init();
399 
403  gsl_rng * getGslInterface() { return gsl; }
404 
405 protected:
406 
410  void setSize(size_type newSize);
411 
415  virtual void fill() = 0;
416 
420  RndVector theNumbers;
421 
425  RndVector::iterator nextNumber;
426 
430  size_type theSize;
431 
435  long theSeed;
436 
440  mutable double savedGauss;
441 
445  mutable bool gaussSaved;
446 
450  gsl_rng * gsl;
451 
452 private:
453 
459 
463  RandomGenerator & operator=(const RandomGenerator &) = delete;
464 
465 };
466 
471 template <>
474  typedef Interfaced NthBase;
475 };
476 
479 template <>
480 struct ClassTraits<RandomGenerator>:
481  public ClassTraitsBase<RandomGenerator> {
483  static string className() { return "ThePEG::RandomGenerator";
484  }
487  static TPtr create() {
488  throw std::logic_error("Tried to instantiate abstract class"
489  "'Pythis7::RandomGenerator'");
490  }
491 };
492 
495 }
496 
497 #endif /* ThePEG_RandomGenerator_H */
RndVector rndvec(int n)
Return n flat random number in the interval .
gsl_rng * gsl
A pinter to a gsl_rng interface to this generator.
PersistentIStream is used to read persistent objects from a stream where they were previously written...
Unit rnd(Unit a, Unit b)
Return a flat random number in the interval .
void flush()
Discard all random numbers in the cache.
ClassTraitsType is an empty, non-polymorphic, base class.
Definition: ClassTraits.h:30
A concreate implementation of ClassDescriptionBase describing a concrete class with persistent data...
RndVector::iterator nextNumber
Iterator pointing to the next number to be extracted.
RandomGenerator()
Default constructor.
PersistentOStream is used to write objects persistently to a stream from which they can be read in ag...
size_type theSize
The size of the cache.
void push_back(double r)
Give back a partly unused random number.
long operator()(long N)
Return a (possibly cached) flat integer random number in the interval .
constexpr double pi
Good old .
Definition: Constants.h:54
constexpr auto sqr(const T &x) -> decltype(x *x)
The square function should really have been included in the standard C++ library. ...
Definition: ThePEG.h:117
static void Init()
Standard Init function used to initialize the interface.
double operator()(double N)
Return a (possibly cached) flat integer random number in the interval .
double rndGauss()
Return a number distributed according to a Gaussian distribution with zero mean and unit variance...
virtual void setSeed(long seed)=0
Reset the underlying random engine with the given seed.
This is the main namespace within which all identifiers in ThePEG are declared.
Definition: FactoryBase.h:28
RandomGenerator is an interface to the CLHEP::RandomEngine classes.
This is the main config header file for ThePEG.
Unit rndBW(Unit mean, Unit gamma)
Return a positive number distributed according to a non-relativistic Breit-Wigner with a given width...
int rnd5(double p0, double p1, double p2, double p3, double p4)
Return an integer/ with probability p (p0+p1+p2+p3+p4).
Unit rndExp(Unit mean)
Return a number between zero and infinity, distributed according to where is the mean value...
int rnd2(double p0, double p1)
Return an integer with probability p /(p0+p1).
int rnd3(double p0, double p1, double p2)
Return an integer with probability p /(p0+p1+p2).
double rnd()
Return a (possibly cached) flat random number in the interval .
static ClassDescription< RandomGenerator > initRandomGenerator
Describe a concrete class with persistent data.
RandomGenerator & operator=(const RandomGenerator &)=delete
Private and non-existent assignment operator.
void pop_back()
Discard the next random number in the cache.
void setSize(size_type newSize)
Utility function for the interface.
virtual void fill()=0
Fill the cache with random numbers.
Unit rnd(Unit b)
Return a flat random number in the interval .
virtual void doinit()
Initializes this random generator.
RndVector theNumbers
A vector of cached numbers.
double operator()()
Return a (possibly cached) flat random number in the interval .
void persistentInput(PersistentIStream &is, int version)
Function used to read in object persistently.
Unit rndRelBW(Unit mean, Unit gamma)
Return a positive number distributed according to a relativistic Breit-Wigner with a given width...
void persistentOutput(PersistentOStream &os) const
Function used to write out object persistently.
void rndGaussTwoNumbers(Unit &randomNumberOne, Unit &randomNumberTwo, Unit sigma, Unit mean=Unit())
Return two numbers distributed according to a Gaussian distribution with a given standard deviation...
vector< double > RndVector
A vector of doubles.
int prndsign(double p1, double p2, double p3)
Return -1, 0, or 1 with relative probabilities p1, p2, p3.
int rndsign(double p1, double p2, double p3)
Return -1, 0, or 1 with relative probabilities p1, p2, p3.
bool gaussSaved
Indicate the precense of a saved Gaussian random number.
bool rndbool(double p1, double p2)
Return a true with probability p1/(p1+p2).
The Interfaced class is derived from the InterfacedBase class adding a couple of things particular to...
Definition: Interfaced.h:38
bool rndbool(double p=0.5)
Return a true with probability p.
Unit rndGauss(Unit sigma, Unit mean=Unit())
Return a number distributed according to a Gaussian distribution with a given standard deviation...
Unit rndBW(Unit mean, Unit gamma, Unit cut)
Return a positive number distributed according to a non-relativistic Breit-Wigner with a given width...
double savedGauss
A saved Gaussian random number.
void rnd(OutputIterator o, size_type n)
Generate n random numbers between 0 and 1 and put them in the output iterator.
int rnd4(double p0, double p1, double p2, double p3)
Return an integer/ with probability p (p0+p1+p2+p3).
The default concrete implementation of ClassTraitsBase.
Definition: ClassTraits.h:134
long rndPoisson(double mean)
Return a non-negative number generated according to a Poissonian distribution with a given mean...
Unit rndRelBW(Unit mean, Unit gamma, Unit cut)
Return a positive number distributed according to a relativistic Breit-Wigner with a given width...
bool prndbool(double p=0.5)
Return a true with probability p.
long theSeed
The seed to initialize the random generator with.
double rndExp()
Return a number between zero and infinity, distributed according to .
RndVector::size_type size_type
The size_type of RndVector.
BaseClassTraits describes the base classes of the templated class.
Definition: ClassTraits.h:156
void rndGaussTwoNumbers(double &randomNumberOne, double &randomNumberTwo)
Return two numbers distributed according to a Gaussian distribution with zero mean and unit variance...
gsl_rng * getGslInterface()
Return a gsl_rng interface to this random generator.
virtual ~RandomGenerator()
Destructor.
The templated ClassTraitsBase class defines a set of default information about classes used by ThePEG...
Definition: ClassTraits.h:52
bool prndbool(double p1, double p2)
Return a true with probability p1/(p1+p2).