blob: 1a0c9647c13bd39d6b04abcc0a0706381984dbd3 (
plain)
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
|
/* Psoudo-random number generator
*
* Uses xorshift1024 from “An experimental exploration of Marsaglia’s xorshift
* generators, scrambled”, Sebastiano Vigna
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include <unistd.h>
#include "random.h"
uint64_t rand_u64 (randctx * const st) {
uint64_t s0 = st->s[ st->p ];
uint64_t s1 = st->s[ st->p = ( st->p + 1 ) & (XORSHIFT_S-1) ];
s1 ^= s1 << 31; // a
s1 ^= s1 >> 11; // b
s0 ^= s0 >> 30; // c
return ( st->s[ st->p ] = s0 ^ s1 ) * 1181783497276652981LL;
}
/* Generate random double in [0,1]
*/
double rand_d01 (randctx * const st) {
return (double) rand_u64 (st) / (double) UINT64_MAX;
}
/* Generate random double in [-1,1]
*/
double rand_d11 (randctx * const st) {
return rand_d01 (st) * 2.0 - 1.0;
}
/* Random boolean value in {0,1}
*/
int rand_bool (randctx * const st) {
return rand_u64 (st) & 1;
}
/* Seed rng with rdrand
*/
void rand_seed (randctx * const st) {
int fd = open ("/dev/urandom", O_RDONLY);
assert (fd != -1);
int ret = read (fd, &st->s, sizeof (st->s));
assert (ret != -1);
close (fd);
st->p = 0;
}
#if 0
uint64_t xorshift_step (randctx * const st) {
uint64_t x = st->s[0];
x ^= x >> 12; // a
x ^= x << 25; // b
x ^= x >> 27; // c
st->s[0] = x;
return x * 2685821657736338717LL;
}
#endif
|