OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
ClassicRandom.cpp
Go to the documentation of this file.
1 // ------------------------------------------------------------------------
2 // $RCSfile: Random.cpp,v $
3 // ------------------------------------------------------------------------
4 // $Revision: 1.1.1.1 $
5 // ------------------------------------------------------------------------
6 // Copyright: see Copyright.readme
7 // ------------------------------------------------------------------------
8 //
9 // Class: Random:
10 // A standard random generator.
11 // ------------------------------------------------------------------------
12 // Class category: Utilities
13 // ------------------------------------------------------------------------
14 //
15 // $Date: 2000/03/27 09:32:38 $
16 // $Author: fci $
17 //
18 // ------------------------------------------------------------------------
19 
21 #include <cmath>
22 
23 
24 // using a default seed value, initialize the pseudo-random number
25 // generator and load the array irn with a set of random numbers in
26 // [0, maxran)
27 // input: a seed value in the range [0..maxran)
29  init55(123456789);
30 }
31 
32 
33 // using the given seed value, initialize the pseudo-random number
34 // generator and load the array irn with a set of random numbers in
35 // [0, maxran)
36 // input: a seed value in the range [0..maxran)
38  init55(seed);
39 }
40 
41 
42 // destructor for random generator.
44 {}
45 
46 
47 // set new seed.
48 void Random::reseed(int seed) {
49  init55(seed);
50 }
51 
52 
53 // return a real pseudo-random number in the range [0,1).
54 double Random::uniform() {
55  const double scale = 1.0 / maxran;
56 
57  if(next >= nr) irngen();
58 
59  return scale * (double) irn[next++];
60 }
61 
62 
63 // return two double Gaussioan pseudo-random numbers
64 void Random::gauss(double &gr1, double &gr2) {
65  double xi1, xi2, zzr;
66 
67  // construct two random numbers in range [-1.0,+1.0)
68  // reject, if zzr > 1
69  do {
70  xi1 = uniform() * 2.0 - 1.0;
71  xi2 = uniform() * 2.0 - 1.0;
72  zzr = xi1 * xi1 + xi2 * xi2;
73  } while(zzr > 1.0);
74 
75  // transform accepted point to Gaussian distribution
76  zzr = sqrt(-2.0 * log(zzr) / zzr);
77  gr1 = xi1 * zzr;
78  gr2 = xi2 * zzr;
79 }
80 
81 
82 // return an integer pseudo-random number in the range [0,maxran]
84  if(next > nr) irngen();
85 
86  return irn[next++];
87 }
88 
89 
90 // initializes the random generator after setting a seed.
91 void Random::init55(int seed) {
92  static const int nd = 21;
93  next = 0;
94 
95  if(seed < 0)
96  seed = - seed;
97  else if(seed == 0)
98  seed = 1234556789;
99 
100  int j = seed % maxran;
101  irn[nr-1] = j;
102  int k = 1;
103 
104  for(int i = 1; i < nr; i++) {
105  int ii = (nd * i) % nr;
106  irn[ii-1] = k;
107  k = j - k;
108 
109  if(k < 0) k += maxran;
110 
111  j = irn[ii-1];
112  }
113 
114  // call irngen a few times to "warm it up"
115  irngen();
116  irngen();
117  irngen();
118 }
119 
120 
121 // generate the next "nr" elements in the pseudo-random sequence.
123  static const int nj = 24;
124  int i, j;
125 
126  for(i = 0; i < nj; i++) {
127  j = irn[i] - irn[i+nr-nj];
128 
129  if(j < 0) j += maxran;
130 
131  irn[i] = j;
132  }
133 
134  for(i = nj; i < nr; i++) {
135  j = irn[i] - irn[i-nj];
136 
137  if(j < 0) j += maxran;
138 
139  irn[i] = j;
140  }
141 
142  next = 0;
143 }
int seed
The current random seed.
Definition: Options.cpp:41
int integer()
Uniform distribution.
const int nr
Definition: ClassicRandom.h:24
void init55(int seed)
Initialise random number generator.
void gauss(double &gr1, double &gr2)
Gaussian distribution.
Tps< T > log(const Tps< T > &x)
Natural logarithm.
Definition: TpsMath.h:182
Random()
Constructor with default seed.
double uniform()
Uniform distribution.
Tps< T > sqrt(const Tps< T > &x)
Square root.
Definition: TpsMath.h:91
void reseed(int seed=123456789)
Set a new seed.
int irn[nr]
Definition: ClassicRandom.h:75
int next
Definition: ClassicRandom.h:78
void irngen()