-
Notifications
You must be signed in to change notification settings - Fork 0
/
MT_random.h
240 lines (218 loc) · 9.78 KB
/
MT_random.h
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
#ifndef MT_RANDOM_H
#define MT_RANDOM_H
////////////////////////////////////////////////////////////////////////////////
// Description:
// Contains routines to use a non global mersenne twister for int,
// uniformly, and gaussian distributed pseudo random number generation.
// The random number states are independen of each other, which allows for
// arbritrarily many independend streams.
// Usage:
// Import this header:
// #include "MT_random.h"
// Define a variable to hold the RNG state for uniform random numbers:
// rng_uniform_type rng_stateu
// For gaussian random numbers:
// rng_gaussian_type rng_stateg
// For int and long int random numbers over the complete int/long int range
// rng_integer_type :: rng_statei
// Initialize the uniform random nuber state:
// rng_stateu = init_rng(seed, lowerbound, upperbound)
// Initialize the gaussian random nuber state:
// rng_stateg = init_rng_gaussian(seed, meanvalue, stddev)
// Initialize the int/long int random number state:
// rng_statei = init_rng_int(seed)
// Get the next random number:
// Uniform:
// random_number = next_random_uniform(&rng_rng_stateu) ;
// Gaussian:
// random_number = next_random_gaussian(&rng_rng_stateg) ;
// Int:
// random_number = next_random_int(&rng_rng_statei) ;
// Long int:
// random_number = next_random_lint(&rng_rng_statei) ;
// Store the state in a string for writeout:
// Uniform:
// state_string = get_random_state_uniform(rng_stateu)
// Gaussian:
// state_string = get_random_state_gaussian(rng_stateg)
// Int / Lint:
// state_string = get_random_state_int(rng_statei)
// Restore a previously extracted state:
// Uniform:
// rng_stateu = get_random_state_uniform(state_string)
// Gaussian:
// rng_stateg = get_random_state_gaussian(state_string)
// Int / Lint:
// rng_statei = get_random_state_int(state_string)
// There is no need for freeing anything except the state string pointer
////////////////////////////////////////////////////////////////////////////////
#include <stdbool.h>
#define MTSTATESIZE 312
/////////////////////////////////////////////////////////////////////////////
// Description:
// Type to hold the state of an int random number generator
// Variables:
// seed: The seed
// mtstate: State of the mersenne twister
// mtidx: index of the current random number of current state
/////////////////////////////////////////////////////////////////////////////
typedef struct rng_int_s {
int seed ;
int mtidx ;
long int mtstate[MTSTATESIZE] ;
} rng_int_type ;
/////////////////////////////////////////////////////////////////////////////
// Description:
// Type to hold the state of uniform random number generator
// Variables:
// seed: The seed
// lower: lower bound of random numbers
// upper: upper bound of random numbers
// mtstate: State of the mersenne twister
// mtidx: index of the current random number of current state
/////////////////////////////////////////////////////////////////////////////
typedef struct rng_uniform_s {
double lower ;
double upper ;
rng_int_type rng_int;
} rng_uniform_type ;
/////////////////////////////////////////////////////////////////////////////
// Description:
// Type to hold the state of gaussian random number generator
// Variables:
// mean: mean value of the gaussian
// stddev: standard deviation of the gaussian
// z1: first random number of Box-Muller algorithm
// z2: second random number of Box-Muller algorithm
// generated: Boolean if Box-Muller needs to be reexecuted
// rng_uniform: uniform random number state
/////////////////////////////////////////////////////////////////////////////
typedef struct rng_gaussian_s {
double mean ;
double stddev ;
double z1, z2 ;
bool generated ;
rng_uniform_type rng_uniform ;
} rng_gaussian_type;
/////////////////////////////////////////////////////////////////////////////
// Description:
// Initializes a int random number generator
// Variables:
// seed: The seed
// Return value:
// rng_int: int random number state
/////////////////////////////////////////////////////////////////////////////
rng_int_type init_rng_int(int seed);
/////////////////////////////////////////////////////////////////////////////
// Description:
// Initializes a uniform random number generator
// Variables:
// seed: The seed
// lower: lower bound of random numbers
// upper: upper bound of random numbers
// Return value:
// rng_uniform: uniform random number state
/////////////////////////////////////////////////////////////////////////////
rng_uniform_type init_rng_uniform(int seed, double lower, double upper);
/////////////////////////////////////////////////////////////////////////////
// Description:
// Initializes a gaussian random number generator
// Variables:
// seed: The seed
// mean: Mean value of the gaussian
// stddev: standard deviation of the gaussian
// Return value:
// rng_gaussian: gaussian random number state
/////////////////////////////////////////////////////////////////////////////
rng_gaussian_type init_rng_gaussian(int seed, double mean, double stddev);
/////////////////////////////////////////////////////////////////////////////
// Description:
// Generates the next int random number
// Variables:
// rng_int: Random number generator state
// Return value:
// randnum: next random number
/////////////////////////////////////////////////////////////////////////////
int next_random_int(rng_int_type* rng_int);
/////////////////////////////////////////////////////////////////////////////
// Description:
// Generates the next int random number
// Variables:
// rng_int: Random number generator state
// Return value:
// randnum: next random number
/////////////////////////////////////////////////////////////////////////////
long next_random_lint(rng_int_type* rng_int);
/////////////////////////////////////////////////////////////////////////////
// Description:
// Generates the next int random number
// Variables:
// rng_uniform: Random number generator state
// Return value:
// randnum: next random number
/////////////////////////////////////////////////////////////////////////////
double next_random_uniform(rng_uniform_type* rng_uniform);
/////////////////////////////////////////////////////////////////////////////
// Description:
// Generates the next int random number
// Variables:
// rng_gaussian: Random number generator state
// Return value:
// randnum: next random number
/////////////////////////////////////////////////////////////////////////////
double next_random_gaussian(rng_gaussian_type* rng_gaussian);
/////////////////////////////////////////////////////////////////////////////
// Description:
// Save rng state to a string
// Variables:
// rng_int: Random number generator state
// Return value:
// intstate: that contains all the state information
/////////////////////////////////////////////////////////////////////////////
char* get_random_state_int(rng_int_type* rng_int);
/////////////////////////////////////////////////////////////////////////////
// Description:
// Save rng state to a string
// Variables:
// rng_uniform: Random number generator state
// Return value:
// uniformstate: that contains all the state information
/////////////////////////////////////////////////////////////////////////////
char* get_random_state_uniform(rng_uniform_type* rng_uniform);
/////////////////////////////////////////////////////////////////////////////
// Description:
// Save rng state to a string
// Variables:
// rng_gaussian: Random number generator state
// Return value:
// gaussianstate: that contains all the state information
/////////////////////////////////////////////////////////////////////////////
char* get_random_state_gaussian(rng_gaussian_type* rng_gaussian);
/////////////////////////////////////////////////////////////////////////////
// Description:
// Restore rng state from a string
// Variables:
// intstate: that contains all the state information
// Return value:
// rng_int: Random number generator state
/////////////////////////////////////////////////////////////////////////////
rng_int_type restore_rng_state_int(char* rng_state);
/////////////////////////////////////////////////////////////////////////////
// Description:
// Restore rng state from a string
// Variables:
// uniformstate: that contains all the state information
// Return value:
// rng_uniform: Random number generator state
/////////////////////////////////////////////////////////////////////////////
rng_uniform_type restore_rng_state_uniform(char* rng_state);
/////////////////////////////////////////////////////////////////////////////
// Description:
// Restore rng state from a string
// Variables:
// gaussianstate: that contains all the state information
// Return value:
// rng_gaussian: Random number generator state
/////////////////////////////////////////////////////////////////////////////
rng_gaussian_type restore_rng_state_gaussian(char* rng_state);
#endif