Mersenne Twister MT19937 pseudorandom number generator for TPCCLIB.
More...
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#include "libtpcmodel.h"
Go to the source code of this file.
|
void | mertwiInit (MERTWI *mt) |
|
uint32_t | mertwiSeed32 (void) |
| Make uint32_t seed for pseudorandom number generators.
|
|
uint64_t | mertwiSeed64 (void) |
| Make uint64_t seed for pseudorandom number generators.
|
|
void | mertwiInitWithSeed64 (MERTWI *mt, uint64_t seed) |
| Initialize the state vector mt[] inside data struct for Mersenne Twister MT19937 pseudorandom number generator using given seed.
|
|
void | mertwiInitByArray64 (MERTWI *mt, uint64_t init_key[], uint64_t key_length) |
| Initialize the state vector mt[] inside data struct for Mersenne Twister MT19937 pseudorandom number generator using given array.
|
|
uint64_t | mertwiRandomInt64 (MERTWI *mt) |
| Generate a random number on [0, 2^64-1]-interval using Mersenne Twister MT19937.
|
|
int64_t | mertwiRandomInt63 (MERTWI *mt) |
| Generate a random number on [0, 2^63-1]-interval using Mersenne Twister MT19937.
|
|
double | mertwiRandomDouble1 (MERTWI *mt) |
| Generate a 64-bit double precision floating point pseudorandom number in the range of [0,1] with uniform distribution using Mersenne Twister MT19937.
|
|
double | mertwiRandomDouble2 (MERTWI *mt) |
| Generate a 64-bit double precision floating point pseudorandom number in the range of [0,1) with uniform distribution using Mersenne Twister MT19937.
|
|
double | mertwiRandomDouble3 (MERTWI *mt) |
| Generate a 64-bit double precision floating point pseudorandom number in the range of (0,1) with uniform distribution using Mersenne Twister MT19937.
|
|
int | mertwiRandomBetween (MERTWI *mt, unsigned int nr, double *d, double low, double up, int type) |
| Fill the given double array with random numbers with uniform distribution between the specified limits.
|
|
double | mertwiRandomExponential (MERTWI *mt, double mean) |
| Generate pseudo-random number with exponential distribution and specified mean.
|
|
double | mertwiRandomGaussian (MERTWI *mt) |
| Generate a 64-bit double precision floating point pseudorandom number in the range of [0,1] with normal (Gaussian) distribution. using Mersenne Twister MT19937.
|
|
Mersenne Twister MT19937 pseudorandom number generator for TPCCLIB.
For more information on the method and original source codes visit https://www.math.sci.hiroshima-u.ac.jp/m-mat/MT/emt.html
Definition in file mertwi.c.
◆ mertwiInit()
void mertwiInit |
( |
MERTWI * | mt | ) |
|
Prepare data struct Mersenne Twister MT19937 for usage. Do not call any mertwi* functions before calling this function!
Definition at line 23 of file mertwi.c.
25 {
29 mt->
um=UINT64_C(0xFFFFFFFF80000000);
30 mt->
lm=UINT64_C(0x7FFFFFFF);
32}
#define TPCCLIB_MERTWI_NN
◆ mertwiInitByArray64()
void mertwiInitByArray64 |
( |
MERTWI * | mt, |
|
|
uint64_t | init_key[], |
|
|
uint64_t | key_length ) |
Initialize the state vector mt[] inside data struct for Mersenne Twister MT19937 pseudorandom number generator using given array.
Call either this or mertwiInitWithSeed64 before generating random numbers with MT19937 using functions.
- Precondition
- Initialize MERTWI data struct by calling mertwiInit() before this.
- See also
- mertwiSeed64, mertwiInitWithSeed64, mertwiInit
- Parameters
-
mt | Data struct for Mersenne Twister MT19937 pseudorandom number generator |
init_key | The array for initializing keys |
key_length | Length of initialization array init_key[] |
Definition at line 111 of file mertwi.c.
118 {
119 unsigned int i, j;
120 uint64_t k;
122 i=1; j=0;
if(mt->
n>key_length) k=mt->
n;
else k=key_length;
123 for(; k; k--) {
125 (mt->
mt[i] ^ ((mt->
mt[i-1] ^ (mt->
mt[i-1]>>62)) * UINT64_C(3935559000370003845)))
126 + init_key[j] + j;
127 i++; j++;
128 if(i>=mt->
n) {mt->
mt[0]=mt->
mt[mt->
n-1]; i=1;}
129 if(j>=key_length) j=0;
130 }
131 for(k=mt->
n-1; k; k--) {
133 (mt->
mt[i] ^ ((mt->
mt[i-1] ^ (mt->
mt[i-1] >> 62)) * UINT64_C(2862933555777941757)))
134 - i;
135 i++;
136 if(i>=mt->
n) {mt->
mt[0]=mt->
mt[mt->
n-1]; i=1;}
137 }
138 mt->
mt[0] = UINT64_C(1) << 63;
139}
void mertwiInitWithSeed64(MERTWI *mt, uint64_t seed)
Initialize the state vector mt[] inside data struct for Mersenne Twister MT19937 pseudorandom number ...
uint64_t mt[TPCCLIB_MERTWI_NN]
◆ mertwiInitWithSeed64()
void mertwiInitWithSeed64 |
( |
MERTWI * | mt, |
|
|
uint64_t | seed ) |
Initialize the state vector mt[] inside data struct for Mersenne Twister MT19937 pseudorandom number generator using given seed.
Call either this or mertwiInitByArray64 before generating random numbers with MT19937 using functions.
- Precondition
- Initialize MERTWI data struct by calling mertwiInit() before this.
- See also
- mertwiSeed64, mertwiInitByArray64, mertwiInit
- Parameters
-
mt | Data struct for Mersenne Twister MT19937 pseudorandom number generator |
seed | Seed, for example from mertwiSeed64() |
Definition at line 91 of file mertwi.c.
96 {
100 (UINT64_C(6364136223846793005)*(mt->
mt[mt->
mti-1] ^ (mt->
mt[mt->
mti-1]>>62)) + mt->
mti);
101}
Referenced by mertwiInitByArray64(), and mertwiRandomInt64().
◆ mertwiRandomBetween()
int mertwiRandomBetween |
( |
MERTWI * | mt, |
|
|
unsigned int | nr, |
|
|
double * | d, |
|
|
double | low, |
|
|
double | up, |
|
|
int | type ) |
Fill the given double array with random numbers with uniform distribution between the specified limits.
Applies Mersenne Twister MT19937 pseudorandom number generator. With uniform distribution, the SD=(up-low)/sqrt(12), and CV=(up-low)/(sqrt(3)*(low+up)).
- Precondition
- Initialize MERTWI data struct by calling mertwiInit() before using this function. Preferably also initialize state vector by calling either mertwiInitWithSeed64() or mertwiInitByArray64; if you do not do that, mertwiInitWithSeed64() is called automatically with predetermined seed.
- See also
- mertwiInit, mertwiInitWithSeed64, mertwiInitByArray64, mertwiRandomDouble1
- Author
- Vesa Oikonen
- Returns
- 0 when successful, otherwise <> 0.
- Parameters
-
mt | Data struct for Mersenne Twister MT19937 pseudorandom number generator |
nr | Nr of values in double array |
d | Pointer to pre-allocated double array |
low | Lower limit for random values |
up | Upper limit for random values |
type | Distribution: 0=even, 1=square-root transformation |
Definition at line 275 of file mertwi.c.
288 {
289 unsigned int i;
290 double dif, v, stl, stu;
291
292 if(nr<1) return(0);
293 if(mt==NULL || d==NULL || type<0 || type>1) return(1);
294
295 dif=up-low; if(dif<0.0) return(2);
296 if(dif==0.0) {
297 for(i=0; i<nr; i++) d[i]=low;
298 return(0);
299 }
300
301 if(type==0) {
303 } else if(type==1) {
304 stl=copysign(sqrt(fabs(low)),low); if(!isnormal(stl)) stl=0.0;
305 stu=copysign(sqrt(fabs(up)), up); if(!isnormal(stu)) stu=0.0;
306 dif=stu-stl;
307 for(i=0; i<nr; i++) {
309 }
310 }
311
312 return(0);
313}
double mertwiRandomDouble1(MERTWI *mt)
Generate a 64-bit double precision floating point pseudorandom number in the range of [0,...
◆ mertwiRandomDouble1()
double mertwiRandomDouble1 |
( |
MERTWI * | mt | ) |
|
Generate a 64-bit double precision floating point pseudorandom number in the range of [0,1] with uniform distribution using Mersenne Twister MT19937.
With uniform distribution, the SD=(up-low)/sqrt(12), and CV=(up-low)/(sqrt(3)*(low+up)).
- Precondition
- Initialize MERTWI data struct by calling mertwiInit() before using this function. Preferably also initialize state vector by calling either mertwiInitWithSeed64() or mertwiInitByArray64; if you do not do that, mertwiInitWithSeed64() is called automatically with predetermined seed.
- See also
- mertwiInit, mertwiInitWithSeed64, mertwiInitByArray64
- Returns
- Returns the random double value in the range [0,1].
- Parameters
-
mt | Data struct for Mersenne Twister MT19937 pseudorandom number generator |
Definition at line 218 of file mertwi.c.
221 {
223}
uint64_t mertwiRandomInt64(MERTWI *mt)
Generate a random number on [0, 2^64-1]-interval using Mersenne Twister MT19937.
Referenced by mertwiRandomBetween(), mertwiRandomExponential(), and mertwiRandomGaussian().
◆ mertwiRandomDouble2()
double mertwiRandomDouble2 |
( |
MERTWI * | mt | ) |
|
Generate a 64-bit double precision floating point pseudorandom number in the range of [0,1) with uniform distribution using Mersenne Twister MT19937.
- Precondition
- Initialize MERTWI data struct by calling mertwiInit() before using this function. Preferably also initialize state vector by calling either mertwiInitWithSeed64() or mertwiInitByArray64; if you do not do that, mertwiInitWithSeed64() is called automatically with predetermined seed.
- See also
- mertwiInit, mertwiInitWithSeed64, mertwiInitByArray64
- Returns
- Returns the random double value in the range [0,1).
- Parameters
-
mt | Data struct for Mersenne Twister MT19937 pseudorandom number generator |
Definition at line 235 of file mertwi.c.
◆ mertwiRandomDouble3()
double mertwiRandomDouble3 |
( |
MERTWI * | mt | ) |
|
Generate a 64-bit double precision floating point pseudorandom number in the range of (0,1) with uniform distribution using Mersenne Twister MT19937.
- Precondition
- Initialize MERTWI data struct by calling mertwiInit() before using this function. Preferably also initialize state vector by calling either mertwiInitWithSeed64() or mertwiInitByArray64; if you do not do that, mertwiInitWithSeed64() is called automatically with predetermined seed.
- See also
- mertwiInit, mertwiInitWithSeed64, mertwiInitByArray64
- Returns
- Returns the random double value in the range (0,1).
- Parameters
-
mt | Data struct for Mersenne Twister MT19937 pseudorandom number generator |
Definition at line 252 of file mertwi.c.
◆ mertwiRandomExponential()
double mertwiRandomExponential |
( |
MERTWI * | mt, |
|
|
double | mean ) |
Generate pseudo-random number with exponential distribution and specified mean.
Applies Mersenne Twister MT19937 pseudorandom number generator.
- Precondition
- Initialize MERTWI data struct by calling mertwiInit() before using this function. Preferably also initialize state vector by calling either mertwiInitWithSeed64() or mertwiInitByArray64; if you do not do that, mertwiInitWithSeed64() is called automatically with predetermined seed.
- See also
- mertwiInit, mertwiInitWithSeed64, mertwiInitByArray64, mertwiRandomDouble1
- Returns
- Returns the random double value in the range [0,1] with exponential distribution.
- Parameters
-
mt | Data struct for Mersenne Twister MT19937 pseudorandom number generator |
mean | Mean of the exponential distribution |
Definition at line 329 of file mertwi.c.
334 {
335 double r;
337 return(-
mean*log(r));
338}
int mean(double *x, double *y, int nr, double *xmean, double *xsd, double *ymean, double *ysd)
◆ mertwiRandomGaussian()
double mertwiRandomGaussian |
( |
MERTWI * | mt | ) |
|
Generate a 64-bit double precision floating point pseudorandom number in the range of [0,1] with normal (Gaussian) distribution. using Mersenne Twister MT19937.
Applies Mersenne Twister MT19937 pseudorandom number generator, and the polar form of Box-Müller transform to produce numbers with Gaussian (normal) distribution which has a zero mean and standard deviation of one.
Box GEP, Muller ME. A note on the generation of random normal deviates. Annals of Mathematical Statistics, Volume 29, Issue 2, 1958, 610-611. Available from JSTOR https://www.jstor.org/
- Precondition
- Initialize MERTWI data struct by calling mertwiInit() before using this function. Preferably also initialize state vector by calling either mertwiInitWithSeed64() or mertwiInitByArray64; if you do not do that, mertwiInitWithSeed64() is called automatically with predetermined seed.
- See also
- mertwiInit, mertwiInitWithSeed64, mertwiInitByArray64, mertwiRandomDouble1, mertwiRandomBetween
- Returns
- Returns the random double value in the range [0,1] with normal distribution.
- Parameters
-
mt | Data struct for Mersenne Twister MT19937 pseudorandom number generator |
Definition at line 363 of file mertwi.c.
366 {
367 static int ready=0;
368 static double dev;
369 double fac, rsq, a, b;
370
371
372 if(!ready) {
373 do {
376 rsq = a*a + b*b;
377 } while (rsq>1.0 || rsq==0.0);
378
379 fac = sqrt(-2.0*log(rsq)/rsq);
380 dev=a*fac; ready=1;
381 return(b*fac);
382 } else {
383 ready=0;
384 return(dev);
385 }
386}
◆ mertwiRandomInt63()
int64_t mertwiRandomInt63 |
( |
MERTWI * | mt | ) |
|
Generate a random number on [0, 2^63-1]-interval using Mersenne Twister MT19937.
- Precondition
- Initialize MERTWI data struct by calling mertwiInit() before using this function. Preferably also initialize state vector by calling either mertwiInitWithSeed64() or mertwiInitByArray64; if you do not do that, mertwiInitWithSeed64() is called automatically with predetermined seed.
- See also
- mertwiInit, mertwiInitWithSeed64, mertwiInitByArray64
- Returns
- Returns the random number with range from 0 to INT64_MAX.
- Parameters
-
mt | Data struct for Mersenne Twister MT19937 pseudorandom number generator |
Definition at line 197 of file mertwi.c.
◆ mertwiRandomInt64()
uint64_t mertwiRandomInt64 |
( |
MERTWI * | mt | ) |
|
Generate a random number on [0, 2^64-1]-interval using Mersenne Twister MT19937.
- Precondition
- Initialize MERTWI data struct by calling mertwiInit() before using this function. Preferably also initialize state vector by calling either mertwiInitWithSeed64() or mertwiInitByArray64; if you do not do that, mertwiInitWithSeed64() is called automatically with predetermined seed.
- See also
- mertwiInit, mertwiInitWithSeed64, mertwiInitByArray64
- Returns
- Returns the random number with range from 0 to UINT64_MAX.
- Parameters
-
mt | Data struct for Mersenne Twister MT19937 pseudorandom number generator |
Definition at line 152 of file mertwi.c.
155 {
156 unsigned int i;
157 uint64_t x;
159
161
162
164
165 for(i=0; i<mt->
n-mt->
m; i++) {
166 x=(mt->
mt[i]&mt->
um)|(mt->
mt[i+1]&mt->
lm);
167 mt->
mt[i] = mt->
mt[i+mt->
m] ^ (x>>1) ^ mag01[(
int)(x&UINT64_C(1))];
168 }
169 for(; i<mt->
n-1; i++) {
170 x = (mt->
mt[i]&mt->
um)|(mt->
mt[i+1]&mt->
lm);
171 mt->
mt[i] = mt->
mt[i+(mt->
m-mt->
n)] ^ (x>>1) ^ mag01[(int)(x&UINT64_C(1))];
172 }
173 x = (mt->
mt[mt->
n-1]&mt->
um)|(mt->
mt[0]&mt->
lm);
174 mt->
mt[mt->
n-1] = mt->
mt[mt->
m-1] ^ (x>>1) ^ mag01[(
int)(x&UINT64_C(1))];
176 }
178
179 x ^= (x>>29) & UINT64_C(0x5555555555555555);
180 x ^= (x<<17) & UINT64_C(0x71D67FFFEDA60000);
181 x ^= (x<<37) & UINT64_C(0xFFF7EEE000000000);
182 x ^= (x>>43);
184
185 return(x);
186}
Referenced by mertwiRandomDouble1(), mertwiRandomDouble2(), mertwiRandomDouble3(), and mertwiRandomInt63().
◆ mertwiSeed32()
uint32_t mertwiSeed32 |
( |
void | | ) |
|
Make uint32_t seed for pseudorandom number generators.
Uses microseconds from the computer clock and process ID to reduce the chance of getting the same seed for simultaneously executing program threads and instances.
- Returns
- Returns the seed.
- See also
- mertwiSeed64
Definition at line 43 of file mertwi.c.
44{
45 uint32_t li;
46#if defined HAVE_TIMESPEC_GET
47 struct timespec ts;
48 timespec_get(&ts, TIME_UTC);
49 li=((ts.tv_sec % 10000)*523 ^ ts.tv_nsec*10) ^ ((getpid() % 1000)*983);
50#elif defined HAVE_CLOCK_GETTIME
51 struct timespec ts;
52 clock_gettime(CLOCK_REALTIME, &ts);
53 li=((ts.tv_sec % 10000)*523 ^ ts.tv_nsec*10) ^ ((getpid() % 1000)*983);
54#elif defined HAVE_GETTIMEOFDAY
55 struct timeval tv;
56 gettimeofday(&tv, 0);
57 li=((tv.tv_sec % 10000)*523 ^ tv.tv_usec*13) ^ ((getpid() % 1000)*983);
58#else
59 li=(unsigned int)time(NULL)+(unsigned int)getpid();
60#endif
61 li+=(uint32_t)rand();
62 return(li);
63}
Referenced by mertwiSeed64().
◆ mertwiSeed64()
uint64_t mertwiSeed64 |
( |
void | | ) |
|
Make uint64_t seed for pseudorandom number generators.
Uses microseconds from the computer clock and process ID to reduce the chance of getting the same seed for simultaneously executing program threads and instances.
- Returns
- Returns the seed.
- See also
- mertwiSeed32
Definition at line 72 of file mertwi.c.
73{
74 uint32_t li;
75 uint64_t lli;
77 lli=li; lli<<=32; lli+=li;
78 return(lli);
79}
uint32_t mertwiSeed32(void)
Make uint32_t seed for pseudorandom number generators.