OPALX (Object Oriented Parallel Accelerator Library for Exascal) master (dc2a29eed580)
OPALX
Loading...
Searching...
No Matches
ExpressionRandom.cpp
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2// $RCSfile: ExpressionRandom.cpp,v $
3// ------------------------------------------------------------------------
4// $Revision: 1.1.1.1 $
5// ------------------------------------------------------------------------
6// Copyright: see Copyright.readme
7// ------------------------------------------------------------------------
8//
9// Class: Random:
10// The OPALX expression 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// using a default seed value, initialize the pseudo-random number
24// generator and load the array irn with a set of random numbers in
25// [0, maxran)
26// input: a seed value in the range [0..maxran)
27Random::Random() { init55(123456789); }
28
29// using the given seed value, initialize the pseudo-random number
30// generator and load the array irn with a set of random numbers in
31// [0, maxran)
32// input: a seed value in the range [0..maxran)
33Random::Random(int seed) { init55(seed); }
34
35// destructor for random generator.
37
38// set new seed.
39void Random::reseed(int seed) { init55(seed); }
40
41// return a real pseudo-random number in the range [0,1).
43 const double scale = 1.0 / maxran;
44
45 if (next >= nr) irngen();
46
47 return scale * (double)irn[next++];
48}
49
50// return two double Gaussioan pseudo-random numbers
51void Random::gauss(double& gr1, double& gr2) {
52 double xi1, xi2, zzr;
53
54 // construct two random numbers in range [-1.0,+1.0)
55 // reject, if zzr > 1
56 do {
57 xi1 = uniform() * 2.0 - 1.0;
58 xi2 = uniform() * 2.0 - 1.0;
59 zzr = xi1 * xi1 + xi2 * xi2;
60 } while (zzr > 1.0);
61
62 // transform accepted point to Gaussian distribution
63 zzr = sqrt(-2.0 * log(zzr) / zzr);
64 gr1 = xi1 * zzr;
65 gr2 = xi2 * zzr;
66}
67
68// return an integer pseudo-random number in the range [0,maxran]
70 if (next > nr) irngen();
71
72 return irn[next++];
73}
74
75// initializes the random generator after setting a seed.
76void Random::init55(int seed) {
77 static const int nd = 21;
78 next = 0;
79
80 if (seed < 0)
81 seed = -seed;
82 else if (seed == 0)
83 seed = 1234556789;
84
85 int j = seed % maxran;
86 irn[nr - 1] = j;
87 int k = 1;
88
89 for (int i = 1; i < nr; i++) {
90 int ii = (nd * i) % nr;
91 irn[ii - 1] = k;
92 k = j - k;
93
94 if (k < 0) k += maxran;
95
96 j = irn[ii - 1];
97 }
98
99 // call irngen a few times to "warm it up"
100 irngen();
101 irngen();
102 irngen();
103}
104
105// generate the next "nr" elements in the pseudo-random sequence.
107 static const int nj = 24;
108 int i, j;
109
110 for (i = 0; i < nj; i++) {
111 j = irn[i] - irn[i + nr - nj];
112
113 if (j < 0) j += maxran;
114
115 irn[i] = j;
116 }
117
118 for (i = nj; i < nr; i++) {
119 j = irn[i] - irn[i - nj];
120
121 if (j < 0) j += maxran;
122
123 irn[i] = j;
124 }
125
126 next = 0;
127}
const int nr
int integer()
Uniform distribution.
void reseed(int seed=123456789)
Set a new seed.
void gauss(double &gr1, double &gr2)
Gaussian distribution.
int irn[nr]
void init55(int seed)
Initialise random number generator.
double uniform()
Uniform distribution.
Random()
Constructor with default seed.