OPAL (Object Oriented Parallel Accelerator Library) 2022.1
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.
49 init55(seed);
50}
51
52
53// return a real pseudo-random number in the range [0,1).
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
64void 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.
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}
const int nr
Definition: ClassicRandom.h:24
Tps< T > log(const Tps< T > &x)
Natural logarithm.
Definition: TpsMath.h:182
Tps< T > sqrt(const Tps< T > &x)
Square root.
Definition: TpsMath.h:91
int seed
The current random seed.
Definition: Options.cpp:37
int integer()
Uniform distribution.
void reseed(int seed=123456789)
Set a new seed.
void irngen()
void gauss(double &gr1, double &gr2)
Gaussian distribution.
int irn[nr]
Definition: ClassicRandom.h:75
void init55(int seed)
Initialise random number generator.
double uniform()
Uniform distribution.
Random()
Constructor with default seed.
int next
Definition: ClassicRandom.h:78