TPCCLIB
Loading...
Searching...
No Matches
mertwi.c File Reference

Mersenne Twister MT19937 pseudo-random number generator for TPCCLIB. More...

#include "tpcclibConfig.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#include "tpcextensions.h"
#include "tpcrand.h"

Go to the source code of this file.

Functions

void mertwiInit (MERTWI *mt)
uint32_t mertwiSeed32 (void)
 Make uint32_t seed for pseudo-random number generators.
uint64_t mertwiSeed64 (void)
 Make uint64_t seed for pseudo-random number generators.
void mertwiInitWithSeed64 (MERTWI *mt, uint64_t seed)
 Initialize the state vector mt[] inside data structure for Mersenne Twister MT19937 pseudo-random number generator using given seed.
void mertwiInitByArray64 (MERTWI *mt, uint64_t init_key[], uint64_t key_length)
 Initialize the state vector mt[] inside data structure for Mersenne Twister MT19937 pseudo-random 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 pseudo-random 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 pseudo-random 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 pseudo-random 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 pseudo-random number with normal (Gaussian) distribution with zero mean 0 and SD 1.

Detailed Description

Mersenne Twister MT19937 pseudo-random 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.

Function Documentation

◆ mertwiInit()

void mertwiInit ( MERTWI * mt)

Prepare the data structure of Mersenne Twister MT19937 for usage. Do not call any mertwi* functions before calling this function!

See also
mertwiSeed64, mertwiInitWithSeed64, mertwiInitByArray64
Parameters
mtPointer to data structure for Mersenne Twister MT19937 pseudo-random number generator.

Definition at line 28 of file mertwi.c.

31 {
32 mt->n=TPCCLIB_MERTWI_NN; // Length of mt array
33 mt->m=mt->n/2; // N/2
35 mt->um=UINT64_C(0xFFFFFFFF80000000);
36 mt->lm=UINT64_C(0x7FFFFFFF);
37 mt->mti=mt->n+1; // means that mt[] is not initialized
38}
uint64_t mti
Definition tpcrand.h:46
unsigned int m
Definition tpcrand.h:36
uint64_t lm
Definition tpcrand.h:42
uint64_t a
Definition tpcrand.h:38
uint64_t um
Definition tpcrand.h:40
unsigned int n
Definition tpcrand.h:34
#define TPCCLIB_MERTWI_NN
Definition tpcrand.h:27
#define TPCCLIB_MERTWI_A
Definition tpcrand.h:29

Referenced by nloptMPSO().

◆ mertwiInitByArray64()

void mertwiInitByArray64 ( MERTWI * mt,
uint64_t init_key[],
uint64_t key_length )

Initialize the state vector mt[] inside data structure for Mersenne Twister MT19937 pseudo-random number generator using given array.

Call either this or mertwiInitWithSeed64 before generating random numbers with MT19937 using functions.

Precondition
Initialize MERTWI data structure by calling mertwiInit() before this.
See also
mertwiSeed64, mertwiInitWithSeed64, mertwiInit
Parameters
mtPointer to data structure for Mersenne Twister MT19937 pseudo-random number generator.
init_keyThe array for initializing keys.
key_lengthLength of initialization array init_key[].

Definition at line 113 of file mertwi.c.

120 {
121 unsigned int i, j;
122 uint64_t k;
123 mertwiInitWithSeed64(mt, UINT64_C(19650218));
124 i=1; j=0; if(mt->n>key_length) k=mt->n; else k=key_length;
125 for(; k; k--) {
126 mt->mt[i] =
127 (mt->mt[i] ^ ((mt->mt[i-1] ^ (mt->mt[i-1]>>62)) * UINT64_C(3935559000370003845)))
128 + init_key[j] + j;
129 i++; j++;
130 if(i>=mt->n) {mt->mt[0]=mt->mt[mt->n-1]; i=1;}
131 if(j>=key_length) j=0;
132 }
133 for(k=mt->n-1; k; k--) {
134 mt->mt[i]=
135 (mt->mt[i] ^ ((mt->mt[i-1] ^ (mt->mt[i-1] >> 62)) * UINT64_C(2862933555777941757)))
136 - i;
137 i++;
138 if(i>=mt->n) {mt->mt[0]=mt->mt[mt->n-1]; i=1;}
139 }
140 mt->mt[0] = UINT64_C(1) << 63; /* MSB is 1; assuring non-zero initial array */
141}
void mertwiInitWithSeed64(MERTWI *mt, uint64_t seed)
Initialize the state vector mt[] inside data structure for Mersenne Twister MT19937 pseudo-random num...
Definition mertwi.c:94
uint64_t mt[TPCCLIB_MERTWI_NN]
Definition tpcrand.h:44

◆ mertwiInitWithSeed64()

void mertwiInitWithSeed64 ( MERTWI * mt,
uint64_t seed )

Initialize the state vector mt[] inside data structure for Mersenne Twister MT19937 pseudo-random number generator using given seed.

Call either this or mertwiInitByArray64 before generating random numbers with MT19937 using functions.

Precondition
Initialize MERTWI data structure by calling mertwiInit() before this.
See also
mertwiSeed64, mertwiInitByArray64, mertwiInit
Parameters
mtPointer to data structure for Mersenne Twister MT19937 pseudo-random number generator.
seedSeed, for example from mertwiSeed64().

Definition at line 94 of file mertwi.c.

99 {
100 mt->mt[0]=seed;
101 for(mt->mti=1; mt->mti<mt->n; mt->mti++)
102 mt->mt[mt->mti]=
103 (UINT64_C(6364136223846793005)*(mt->mt[mt->mti-1] ^ (mt->mt[mt->mti-1]>>62)) + mt->mti);
104}

Referenced by mertwiInitByArray64(), mertwiRandomInt64(), and nloptMPSO().

◆ 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 pseudo-random number generator. With uniform distribution, the SD=(up-low)/sqrt(12), and CV=(up-low)/(sqrt(3)*(low+up)).

Precondition
Initialize MERTWI data structure 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
mtPointer to data structure for Mersenne Twister MT19937 pseudo-random number generator.
nrNumber of values in double array d[].
dPointer to pre-allocated double array, to be filled here.
lowLower limit for random values.
upUpper limit for random values.
typeDistribution: 0=even, 1=square-root transformation.

Definition at line 270 of file mertwi.c.

283 {
284 unsigned int i;
285 double dif, v, stl, stu;
286
287 if(nr<1) return(0);
288 if(mt==NULL || d==NULL || type<0 || type>1) return(1);
289
290 dif=up-low; if(dif<0.0) return(2);
291 if(dif==0.0) {
292 for(i=0; i<nr; i++) d[i]=low;
293 return(0);
294 }
295
296 if(type==0) {
297 for(i=0; i<nr; i++) d[i] = mertwiRandomDouble1(mt)*dif + low;
298 } else if(type==1) {
299 stl=copysign(sqrt(fabs(low)),low); if(!isnormal(stl)) stl=0.0;
300 stu=copysign(sqrt(fabs(up)), up); if(!isnormal(stu)) stu=0.0;
301 dif=stu-stl;
302 for(i=0; i<nr; i++) {
303 v=mertwiRandomDouble1(mt)*dif+stl; d[i]=copysign(v*v, v);
304 }
305 }
306
307 return(0);
308}
double mertwiRandomDouble1(MERTWI *mt)
Generate a 64-bit double precision floating point pseudo-random number in the range of [0,...
Definition mertwi.c:216

◆ mertwiRandomDouble1()

double mertwiRandomDouble1 ( MERTWI * mt)

Generate a 64-bit double precision floating point pseudo-random 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 structure 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
mtPointer to data structure for Mersenne Twister MT19937 pseudo-random number generator.

Definition at line 216 of file mertwi.c.

219 {
220 return(mertwiRandomInt64(mt) >> 11) * (1.0/9007199254740991.0);
221}
uint64_t mertwiRandomInt64(MERTWI *mt)
Generate a random number on [0, 2^64-1]-interval using Mersenne Twister MT19937.
Definition mertwi.c:153

Referenced by mertwiRandomBetween(), mertwiRandomExponential(), mertwiRandomGaussian(), nloptMPSO(), and nloptRandomPoint().

◆ mertwiRandomDouble2()

double mertwiRandomDouble2 ( MERTWI * mt)

Generate a 64-bit double precision floating point pseudo-random number in the range of [0,1) with uniform distribution using Mersenne Twister MT19937.

Precondition
Initialize MERTWI data structure 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
mtPointer to data structure for Mersenne Twister MT19937 pseudo-random number generator.

Definition at line 232 of file mertwi.c.

235 {
236 return(mertwiRandomInt64(mt) >> 11) * (1.0/9007199254740992.0);
237}

◆ mertwiRandomDouble3()

double mertwiRandomDouble3 ( MERTWI * mt)

Generate a 64-bit double precision floating point pseudo-random number in the range of (0,1) with uniform distribution using Mersenne Twister MT19937.

Precondition
Initialize MERTWI data structure 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
mtPointer to data structure for Mersenne Twister MT19937 pseudo-random number generator.

Definition at line 248 of file mertwi.c.

251 {
252 return((mertwiRandomInt64(mt) >> 12) + 0.5) * (1.0/4503599627370496.0);
253}

◆ mertwiRandomExponential()

double mertwiRandomExponential ( MERTWI * mt,
double mean )

Generate pseudo-random number with exponential distribution and specified mean.

Applies Mersenne Twister MT19937 pseudo-random number generator.

Precondition
Initialize MERTWI data structure 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 non-negative double value with exponential distribution and given mean.
Parameters
mtPointer to data structure for Mersenne Twister MT19937 pseudo-random number generator.
meanMean of the exponential distribution.

Definition at line 322 of file mertwi.c.

327 {
328 double r;
329 do {r=mertwiRandomDouble1(mt);} while(r==0.0);
330 return(-mean*log(r));
331}

Referenced by nloptMPSO().

◆ mertwiRandomGaussian()

double mertwiRandomGaussian ( MERTWI * mt)

Generate a 64-bit double precision floating point pseudo-random number with normal (Gaussian) distribution with zero mean 0 and SD 1.

Applies Mersenne Twister MT19937 pseudo-random 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 structure 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
The random double value with normal distribution with zero mean and standard deviation 1.
Parameters
mtPointer to data structure for Mersenne Twister MT19937 pseudo-random number generator.

Definition at line 354 of file mertwi.c.

357 {
358 static int ready=0;
359 static double dev;
360 double fac, rsq, a, b;
361
362 /* If we don't have deviate already, then we'll have to make one */
363 if(!ready) {
364 do {
365 a = 2.*mertwiRandomDouble1(mt) - 1.0;
366 b = 2.*mertwiRandomDouble1(mt) - 1.0;
367 rsq = a*a + b*b;
368 } while (rsq>1.0 || rsq==0.0);
369
370 fac = sqrt(-2.0*log(rsq)/rsq);
371 dev=a*fac; ready=1;
372 return(b*fac);
373 } else { /* dev is ready so return it */
374 ready=0;
375 return(dev);
376 }
377}

Referenced by nloptGaussianPoint().

◆ mertwiRandomInt63()

int64_t mertwiRandomInt63 ( MERTWI * mt)

Generate a random number on [0, 2^63-1]-interval using Mersenne Twister MT19937.

Precondition
Initialize MERTWI data structure 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
mtPointer to data structure for Mersenne Twister MT19937 pseudo-random number generator.

Definition at line 197 of file mertwi.c.

200 {
201 return(int64_t)(mertwiRandomInt64(mt) >> 1);
202}

Referenced by nloptMPSO().

◆ mertwiRandomInt64()

uint64_t mertwiRandomInt64 ( MERTWI * mt)

Generate a random number on [0, 2^64-1]-interval using Mersenne Twister MT19937.

Precondition
Initialize MERTWI data structure 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
mtPointer to data structure for Mersenne Twister MT19937 pseudo-random number generator.

Definition at line 153 of file mertwi.c.

156 {
157 unsigned int i;
158 uint64_t x;
159 static uint64_t mag01[2]={UINT64_C(0), TPCCLIB_MERTWI_A};
160
161 if(mt->mti>=mt->n) { /* generate NN words at one time */
162
163 /* if init_genrand64() has not been called, a default initial seed is used */
164 if(mt->mti==mt->n+1) mertwiInitWithSeed64(mt, UINT64_C(5489));
165
166 for(i=0; i<mt->n-mt->m; i++) {
167 x=(mt->mt[i]&mt->um)|(mt->mt[i+1]&mt->lm);
168 mt->mt[i] = mt->mt[i+mt->m] ^ (x>>1) ^ mag01[(int)(x&UINT64_C(1))];
169 }
170 for(; i<mt->n-1; i++) {
171 x = (mt->mt[i]&mt->um)|(mt->mt[i+1]&mt->lm);
172 mt->mt[i] = mt->mt[i+(mt->m-mt->n)] ^ (x>>1) ^ mag01[(int)(x&UINT64_C(1))];
173 }
174 x = (mt->mt[mt->n-1]&mt->um)|(mt->mt[0]&mt->lm);
175 mt->mt[mt->n-1] = mt->mt[mt->m-1] ^ (x>>1) ^ mag01[(int)(x&UINT64_C(1))];
176 mt->mti=0;
177 }
178 x = mt->mt[mt->mti];
179
180 x ^= (x>>29) & UINT64_C(0x5555555555555555);
181 x ^= (x<<17) & UINT64_C(0x71D67FFFEDA60000);
182 x ^= (x<<37) & UINT64_C(0xFFF7EEE000000000);
183 x ^= (x>>43);
184 mt->mti++;
185
186 return(x);
187}

Referenced by mertwiRandomDouble1(), mertwiRandomDouble2(), mertwiRandomDouble3(), mertwiRandomInt63(), randomShuffle(), and randomShuffleUnsigned().

◆ mertwiSeed32()

uint32_t mertwiSeed32 ( void )

Make uint32_t seed for pseudo-random 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 48 of file mertwi.c.

49{
50 uint32_t li;
51#if defined HAVE_TIMESPEC_GET
52 struct timespec ts;
53 timespec_get(&ts, TIME_UTC);
54 li=((ts.tv_sec % 10000)*523 ^ ts.tv_nsec*10) ^ ((getpid() % 1000)*983);
55#elif defined HAVE_CLOCK_GETTIME
56 struct timespec ts;
57 clock_gettime(CLOCK_REALTIME, &ts);
58 li=((ts.tv_sec % 10000)*523 ^ ts.tv_nsec*10) ^ ((getpid() % 1000)*983);
59#elif defined HAVE_GETTIMEOFDAY
60 struct timeval tv;
61 gettimeofday(&tv, 0);
62 li=((tv.tv_sec % 10000)*523 ^ tv.tv_usec*13) ^ ((getpid() % 1000)*983);
63#else
64 li=(unsigned int)time(NULL)+(unsigned int)getpid();
65#endif
66 li+=(uint32_t)rand();
67 return(li);
68}

Referenced by mertwiSeed64().

◆ mertwiSeed64()

uint64_t mertwiSeed64 ( void )

Make uint64_t seed for pseudo-random 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 76 of file mertwi.c.

77{
78 uint32_t li;
79 uint64_t lli;
80 lli=li=mertwiSeed32();
81 lli=li; lli<<=32; lli+=li;
82 return(lli);
83}
uint32_t mertwiSeed32(void)
Make uint32_t seed for pseudo-random number generators.
Definition mertwi.c:48

Referenced by nloptMPSO().