TPCCLIB
Loading...
Searching...
No Matches
mertwi.c
Go to the documentation of this file.
1
8/*****************************************************************************/
9#include <stdio.h>
10#include <stdlib.h>
11#include <math.h>
12#include <unistd.h>
13#include <time.h>
14#include <sys/time.h>
15/*****************************************************************************/
16#include "libtpcmodel.h"
17/*****************************************************************************/
18
19/*****************************************************************************/
24 MERTWI *mt
25) {
26 mt->n=TPCCLIB_MERTWI_NN; // Length of mt array
27 mt->m=mt->n/2; // N/2
29 mt->um=UINT64_C(0xFFFFFFFF80000000);
30 mt->lm=UINT64_C(0x7FFFFFFF);
31 mt->mti=mt->n+1; // means that mt[] is not initialized
32}
33/*****************************************************************************/
34
35/*****************************************************************************/
43uint32_t mertwiSeed32(void)
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}
64/*****************************************************************************/
72uint64_t mertwiSeed64(void)
73{
74 uint32_t li;
75 uint64_t lli;
76 lli=li=mertwiSeed32();
77 lli=li; lli<<=32; lli+=li;
78 return(lli);
79}
80/*****************************************************************************/
81
82/*****************************************************************************/
93 MERTWI *mt,
95 uint64_t seed
96) {
97 mt->mt[0]=seed;
98 for(mt->mti=1; mt->mti<mt->n; mt->mti++)
99 mt->mt[mt->mti]=
100 (UINT64_C(6364136223846793005)*(mt->mt[mt->mti-1] ^ (mt->mt[mt->mti-1]>>62)) + mt->mti);
101}
102/*****************************************************************************/
113 MERTWI *mt,
115 uint64_t init_key[],
117 uint64_t key_length
118) {
119 unsigned int i, j;
120 uint64_t k;
121 mertwiInitWithSeed64(mt, UINT64_C(19650218));
122 i=1; j=0; if(mt->n>key_length) k=mt->n; else k=key_length;
123 for(; k; k--) {
124 mt->mt[i] =
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--) {
132 mt->mt[i]=
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; /* MSB is 1; assuring non-zero initial array */
139}
140/*****************************************************************************/
141
142/*****************************************************************************/
154 MERTWI *mt
155) {
156 unsigned int i;
157 uint64_t x;
158 static uint64_t mag01[2]={UINT64_C(0), TPCCLIB_MERTWI_A};
159
160 if(mt->mti>=mt->n) { /* generate NN words at one time */
161
162 /* if init_genrand64() has not been called, a default initial seed is used */
163 if(mt->mti==mt->n+1) mertwiInitWithSeed64(mt, UINT64_C(5489));
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))];
175 mt->mti=0;
176 }
177 x = mt->mt[mt->mti];
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);
183 mt->mti++;
184
185 return(x);
186}
187/*****************************************************************************/
199 MERTWI *mt
200) {
201 return(int64_t)(mertwiRandomInt64(mt) >> 1);
202}
203/*****************************************************************************/
220 MERTWI *mt
221) {
222 return(mertwiRandomInt64(mt) >> 11) * (1.0/9007199254740991.0);
223}
224/*****************************************************************************/
237 MERTWI *mt
238) {
239 return(mertwiRandomInt64(mt) >> 11) * (1.0/9007199254740992.0);
240}
241/*****************************************************************************/
254 MERTWI *mt
255) {
256 return((mertwiRandomInt64(mt) >> 12) + 0.5) * (1.0/4503599627370496.0);
257}
258/*****************************************************************************/
259
260/*****************************************************************************/
277 MERTWI *mt,
279 unsigned int nr,
281 double *d,
283 double low,
285 double up,
287 int type
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) {
302 for(i=0; i<nr; i++) d[i] = mertwiRandomDouble1(mt)*dif + low;
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++) {
308 v=mertwiRandomDouble1(mt)*dif+stl; d[i]=copysign(v*v, v);
309 }
310 }
311
312 return(0);
313}
314/*****************************************************************************/
315
316/*****************************************************************************/
331 MERTWI *mt,
333 double mean
334) {
335 double r;
336 do {r=mertwiRandomDouble1(mt);} while(r==0.0);
337 return(-mean*log(r));
338}
339/*****************************************************************************/
340
341/*****************************************************************************/
365 MERTWI *mt
366) {
367 static int ready=0;
368 static double dev;
369 double fac, rsq, a, b;
370
371 /* If we don't have deviate already, then we'll have to make one */
372 if(!ready) {
373 do {
374 a = 2.*mertwiRandomDouble1(mt) - 1.0;
375 b = 2.*mertwiRandomDouble1(mt) - 1.0;
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 { /* dev is ready so return it */
383 ready=0;
384 return(dev);
385 }
386}
387/*****************************************************************************/
388
389/*****************************************************************************/
Header file for libtpcmodel.
#define TPCCLIB_MERTWI_NN
Definition libtpcmodel.h:41
#define TPCCLIB_MERTWI_A
Definition libtpcmodel.h:43
int mean(double *x, double *y, int nr, double *xmean, double *xsd, double *ymean, double *ysd)
Definition pearson.c:341
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:275
uint64_t mertwiRandomInt64(MERTWI *mt)
Generate a random number on [0, 2^64-1]-interval using Mersenne Twister MT19937.
Definition mertwi.c:152
void mertwiInitWithSeed64(MERTWI *mt, uint64_t seed)
Initialize the state vector mt[] inside data struct for Mersenne Twister MT19937 pseudorandom number ...
Definition mertwi.c:91
double mertwiRandomDouble1(MERTWI *mt)
Generate a 64-bit double precision floating point pseudorandom number in the range of [0,...
Definition mertwi.c:218
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 ...
Definition mertwi.c:111
double mertwiRandomGaussian(MERTWI *mt)
Generate a 64-bit double precision floating point pseudorandom number in the range of [0,...
Definition mertwi.c:363
double mertwiRandomExponential(MERTWI *mt, double mean)
Generate pseudo-random number with exponential distribution and specified mean.
Definition mertwi.c:329
uint64_t mertwiSeed64(void)
Make uint64_t seed for pseudorandom number generators.
Definition mertwi.c:72
double mertwiRandomDouble2(MERTWI *mt)
Generate a 64-bit double precision floating point pseudorandom number in the range of [0,...
Definition mertwi.c:235
void mertwiInit(MERTWI *mt)
Definition mertwi.c:23
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 pseudorandom number in the range of (0,...
Definition mertwi.c:252
uint32_t mertwiSeed32(void)
Make uint32_t seed for pseudorandom number generators.
Definition mertwi.c:43
uint64_t mt[TPCCLIB_MERTWI_NN]
Definition libtpcmodel.h:58
uint64_t mti
Definition libtpcmodel.h:60
unsigned int m
Definition libtpcmodel.h:50
uint64_t lm
Definition libtpcmodel.h:56
uint64_t a
Definition libtpcmodel.h:52
uint64_t um
Definition libtpcmodel.h:54
unsigned int n
Definition libtpcmodel.h:48