-
Notifications
You must be signed in to change notification settings - Fork 0
/
libEDM_random.cpp
106 lines (82 loc) · 2.17 KB
/
libEDM_random.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#define _USE_MATH_DEFINES
#include <cmath>
#include <libEDM_library.h>
#include <libEDM_random.h>
Random globalRandom;
radians Random::angle ()
{
return PI * (2.0*sample() - 1.0);
}
bVector Random::bit_vector (const size_t length)
{
bVector output;
for (size_t i=0; i<length; i++)
output.push_back(bit());
return output;
}
complex<double> Random::complex_gaussian()
{
// generates a compex Gaussian deviate with zero mean and unity variance
// generate random point in unit circle
double rsq, v1, v2;
do
{
v1 = 2.0*sample() - 1.0;
v2 = 2.0*sample() - 1.0;
rsq = sqr(v1) + sqr(v2);
} while (rsq >= 1.0 || rsq == 0.0);
// Box-Muller transformation
double fac = sqrt(-log(rsq)/rsq);
// return as complex
return complex<double>(v1 * fac, v2 * fac);
}
double Random::gaussian()
{
// generates Gaussian deviate with zero mean and unity variance
if (!iset)
{
// compute two independent gaussian samples using complex generator
complex<double> temp = complex_gaussian();
// store one sample
iset = true;
gset = M_SQRT2 * temp.imag();
// return the other
return M_SQRT2 * temp.real();
}
else
{
// return stored deviate
iset = false;
return gset;
}
}
void Random::lognormal_params( const double mean, const double variance, double &mu, double &sigma )
{
const double sigma2 = log( 1.0 + variance / mean / mean );
mu = std::log( mean ) - 0.5 * sigma2;
sigma = std::sqrt( sigma2 );
}
size_t Random::poisson (double mean)
{
// Knuth algorithm
// Note - computation time is linear with mean. Better algorithms are available
double p = 0.0;
size_t k = 0;
do
{
k++;
p += log(sample());
}
while ( p >= -mean );
return k - 1;
}
void Random::set_seed (const uint32_t seed)
{
generator.seed(seed);
uniform01rng = uniform_01<mt19937>(generator);
iset = false;
}
int Random::uniform (int low, int high)
{
return static_cast<int>(floor(low + (high - low + 1) * sample()));
}