TPCCLIB
Loading...
Searching...
No Matches
mertwi.c
Go to the documentation of this file.
1
8/*****************************************************************************/
9#include "tpcclibConfig.h"
10/*****************************************************************************/
11#include <stdio.h>
12#include <stdlib.h>
13#include <math.h>
14#include <unistd.h>
15#include <time.h>
16#include <sys/time.h>
17/*****************************************************************************/
18#include "tpcextensions.h"
19/*****************************************************************************/
20#include "tpcrand.h"
21/*****************************************************************************/
22
23/*****************************************************************************/
30 MERTWI *mt
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}
39/*****************************************************************************/
40
41/*****************************************************************************/
48uint32_t mertwiSeed32(void)
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}
69/*****************************************************************************/
76uint64_t mertwiSeed64(void)
77{
78 uint32_t li;
79 uint64_t lli;
80 lli=li=mertwiSeed32();
81 lli=li; lli<<=32; lli+=li;
82 return(lli);
83}
84/*****************************************************************************/
85
86/*****************************************************************************/
96 MERTWI *mt,
98 uint64_t seed
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}
105/*****************************************************************************/
115 MERTWI *mt,
117 uint64_t init_key[],
119 uint64_t key_length
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}
142/*****************************************************************************/
143
144/*****************************************************************************/
155 MERTWI *mt
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}
188/*****************************************************************************/
199 MERTWI *mt
200) {
201 return(int64_t)(mertwiRandomInt64(mt) >> 1);
202}
203/*****************************************************************************/
218 MERTWI *mt
219) {
220 return(mertwiRandomInt64(mt) >> 11) * (1.0/9007199254740991.0);
221}
222/*****************************************************************************/
234 MERTWI *mt
235) {
236 return(mertwiRandomInt64(mt) >> 11) * (1.0/9007199254740992.0);
237}
238/*****************************************************************************/
250 MERTWI *mt
251) {
252 return((mertwiRandomInt64(mt) >> 12) + 0.5) * (1.0/4503599627370496.0);
253}
254/*****************************************************************************/
255
256/*****************************************************************************/
272 MERTWI *mt,
274 unsigned int nr,
276 double *d,
278 double low,
280 double up,
282 int type
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}
309/*****************************************************************************/
310
311/*****************************************************************************/
324 MERTWI *mt,
326 double mean
327) {
328 double r;
329 do {r=mertwiRandomDouble1(mt);} while(r==0.0);
330 return(-mean*log(r));
331}
332/*****************************************************************************/
333
334/*****************************************************************************/
356 MERTWI *mt
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}
378/*****************************************************************************/
379
380/*****************************************************************************/
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 limit...
Definition mertwi.c:270
uint64_t mertwiRandomInt64(MERTWI *mt)
Generate a random number on [0, 2^64-1]-interval using Mersenne Twister MT19937.
Definition mertwi.c:153
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
double mertwiRandomDouble1(MERTWI *mt)
Generate a 64-bit double precision floating point pseudo-random number in the range of [0,...
Definition mertwi.c:216
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 num...
Definition mertwi.c:113
double mertwiRandomGaussian(MERTWI *mt)
Generate a 64-bit double precision floating point pseudo-random number with normal (Gaussian) distrib...
Definition mertwi.c:354
double mertwiRandomExponential(MERTWI *mt, double mean)
Generate pseudo-random number with exponential distribution and specified mean.
Definition mertwi.c:322
uint64_t mertwiSeed64(void)
Make uint64_t seed for pseudo-random number generators.
Definition mertwi.c:76
double mertwiRandomDouble2(MERTWI *mt)
Generate a 64-bit double precision floating point pseudo-random number in the range of [0,...
Definition mertwi.c:232
void mertwiInit(MERTWI *mt)
Definition mertwi.c:28
int64_t mertwiRandomInt63(MERTWI *mt)
Generate a random number on [0, 2^63-1]-interval using Mersenne Twister MT19937.
Definition mertwi.c:197
double mertwiRandomDouble3(MERTWI *mt)
Generate a 64-bit double precision floating point pseudo-random number in the range of (0,...
Definition mertwi.c:248
uint32_t mertwiSeed32(void)
Make uint32_t seed for pseudo-random number generators.
Definition mertwi.c:48
uint64_t mt[TPCCLIB_MERTWI_NN]
Definition tpcrand.h:44
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
Header file for library libtpcextensions.
Header file for libtpcrand.
#define TPCCLIB_MERTWI_NN
Definition tpcrand.h:27
#define TPCCLIB_MERTWI_A
Definition tpcrand.h:29