17
18
#include <ecl/ecl.h>
26
* Crappy random number generator
32
return (cl_object)time(0);
36
generate_double(cl_object rs)
40
+ (rs->random.value<<2)
41
+ (rs->random.value<<17)
42
+ (rs->random.value<<27);
43
rs->random.value = rs->random.value & 0xffffffff;
44
return (double)(rs->random.value>>1) / (4294967296.0/2.0);
50
* Mersenne-Twister random number generator
53
/* Period parameters */
56
#define MATRIX_A 0x9908b0dfUL /* constant vector a */
57
#define UPPER_MASK 0x80000000UL /* most significant w-r bits */
58
#define LOWER_MASK 0x7fffffffUL /* least significant r bits */
60
#define ulong unsigned long
65
cl_index bytes = sizeof(ulong) * (MT_N + 1);
66
cl_object a = cl_alloc_simple_base_string(bytes);
67
ulong *mt = (ulong*)a->base_string.self;
69
#if !defined(_MSC_VER) && !defined(mingw32)
70
FILE *fp = fopen("/dev/urandom","r");
72
fread(mt, sizeof(*mt), MT_N, fp);
73
for (j=0; j < MT_N; j++){
74
mt[j] &= 0xffffffffUL;
80
/* cant get urandom, use crappy source */
81
mt[0] = (rand() + time(0)) & 0xffffffffUL;
82
for (j=1; j < MT_N; j++){
83
mt[j] = (1812433253UL * (mt[j-1] ^ (mt[j-1] >> 30)) + j);
84
mt[j] &= 0xffffffffUL;
92
generate_int32(cl_object state)
94
static ulong mag01[2]={0x0UL, MATRIX_A};
96
ulong *mt = (ulong*)state->base_string.self;
97
if (mt[MT_N] >= MT_N){
100
for (kk=0; kk < (MT_N - MT_M); kk++) {
101
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
102
mt[kk] = mt[kk + MT_M] ^ (y >> 1) ^ mag01[y & 0x1UL];
104
for (; kk < (MT_N - 1); kk++) {
105
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
106
mt[kk] = mt[kk+(MT_M-MT_N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
108
y = (mt[MT_N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
109
mt[MT_N-1] = mt[MT_M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];
112
/* get random 32 bit num */
116
y ^= (y << 7) & 0x9d2c5680UL;
117
y ^= (y << 15) & 0xefc60000UL;
123
generate_double(cl_object state)
125
return generate_int32(state) * (1.0 / 4294967296.0);
21
131
rando(cl_object x, cl_object rs)
24
double d = (double)(rs->random.value>>1) / (4294967296.0/2.0);
134
double d = generate_double(rs->random.value);
26
136
if (!ecl_plusp(x)) {
72
181
if (type_of(rs) != t_random) {
73
182
FEwrong_type_argument(@'random-state', rs);
75
z->random.value = rs->random.value;
184
z->random.value = cl_copy_seq(rs->random.value);
81
advance_random_state(cl_object rs)
85
+ (rs->random.value<<2)
86
+ (rs->random.value<<17)
87
+ (rs->random.value<<27);
88
rs->random.value = rs->random.value & 0xffffffff;
92
189
@(defun random (x &optional (rs ecl_symbol_value(@'*random-state*')))
94
191
rs = ecl_check_cl_type(@'random', rs, t_random);
95
advance_random_state(rs);
96
192
@(return rando(x, rs));