-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrandom.cpp
111 lines (90 loc) · 2.53 KB
/
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
107
108
109
110
/*
Copyright 2013, Vasudevan Venkateshwaran, Garde group @ RPI
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
random.cpp
Routines to generate random deviates
*/
#include <cstdlib>
#include <ctime>
#include <cmath>
#include "random.h"
// Uniform random variables
float ran(int iseed)
{
/* Returns a uniform random deviate between 0.0 and 1.0. ;
Based on: Park and Miller's "Minimal Standard" random number;
generator (Comm. ACM, 31, 1192, 1988);
*/
int IM=2147483647, IA=16807, IQ=127773, IR= 2836;
float AM=128.0/IM;
int K;
K = iseed/IQ;
iseed = IA*(iseed-K*IQ) - IR*K;
if (iseed < 0) iseed = iseed+IM;
return AM*(iseed/128);
}
// Gaussian random variables
double marsaglia()
{
/*
Function to return a zero mean, unit variance normally
distributed deviate using the Marsaglia polar method
*/
double x, y;
double r;
int flag;
// Generate uniform random points inside a unit circle;
do
{
x = ((double) rand() / ((double)RAND_MAX+1)) ;
y = ((double) rand() / ((double)RAND_MAX+1)) ;
x = 2.0*x - 1.0;
y = 2.0*y - 1.0;
r = x*x + y*y;
} while (r > 1.0);
x = x*sqrt(-2.0*log(r)/r);
y = y*sqrt(-2.0*log(r)/r);
return x;
}
void marsaglia_array(std::vector<double> &x, int n)
{
/*
Function to return an array of size n containing zero mean,
unit variance normally distributed deviates using the Marsaglia
polar method
*/
double r,tx,ty;
int i;
// Generate uniform random points inside a unit circle;
for(i = 1;i<=n;i+=2)
{
do
{
tx = ((double) rand() / ((double)RAND_MAX+1)) ;
ty = ((double) rand() / ((double)RAND_MAX+1)) ;
tx = 2.0*tx - 1.0;
ty = 2.0*ty - 1.0;
r = tx*tx + ty*ty;
} while ( r > 1.0 );
tx = tx*sqrt(-2.0*log(r)/r);
ty = ty*sqrt(-2.0*log(r)/r);
if (i+1 <= n)
{
x[i-1] = tx;
x[i] = ty;
}
else
{
x[i-1] = tx;
}
}
}