-
Notifications
You must be signed in to change notification settings - Fork 3
/
rand.h
87 lines (69 loc) · 1.79 KB
/
rand.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
#ifndef RAND_H
#define RAND_H
#include <time.h>
#include <stdlib.h>
#include <stdint.h>
#include <float.h>
#include <stdbool.h>
#include <math.h>
#define USE_FAST_RNG
#ifdef USE_FAST_RNG
#define ROTL(d,lrot) ((d<<(lrot)) | (d>>(8*sizeof(d)-(lrot))))
#define TWO31 0x80000000u
#define TWO32f (TWO31*2.0)
#endif
#define sigma 0.03
#define mu 0.5
#define two_pi 2*M_PI
bool initialized = false;
uint64_t xState = 0x0DDB1A5E5BAD5EEDull,
yState = 0x519fb20ce6a199bbull; // set to nonzero seed
void rand_init() {
#ifdef USE_FAST_RNG
if (!initialized){
srand(time(NULL));
xState = (((uint64_t)(unsigned int)rand() << 32) + (uint64_t)(unsigned int)rand());
yState = (((uint64_t)(unsigned int)rand() << 32) + (uint64_t)(unsigned int)rand());
}
#else
if (!initialized) srand(time(NULL)):
#endif
}
uint64_t romuDuoJr_random () {
uint64_t xp = xState;
xState = 15241094284759029579u * yState;
yState = yState - xp; yState = ROTL(yState,27);
return xp;
}
inline double rand_32_double() {
#ifdef USE_FAST_RNG
unsigned int in = (unsigned int) romuDuoJr_random();
double y = (double) in;
return y/TWO32f;
#else
return (double) rand() / RAND_MAX;
#endif
}
unsigned int rand_32_int (unsigned int max) {
#ifdef USE_FAST_RNG
unsigned int in = (unsigned int) romuDuoJr_random();
#else
unsigned int in = rand()
#endif
return in % max;
}
inline double rand_32_double_gauss() {
double epsilon = DBL_EPSILON;
double u1, u2;
do
{
u1 = rand_32_double();
u2 = rand_32_double();
}
while (u1 <= epsilon);
double z0 = sqrt(-2.0 * log(u1)) * cos(two_pi * u2);
// auto z1 = sqrt(-2.0 * log(u1)) * sin(two_pi * u2); // not used here!
//
return fmin(fmax(z0 * sigma + mu, 0.0), 1.0);
}
#endif