potion  0.2
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
mt19937ar.c
Go to the documentation of this file.
1 
48 #include <stdio.h>
49 #include "potion.h"
50 
51 /* Period parameters */
52 #define N 624
53 #define M 397
54 #define MATRIX_A 0x9908b0dfUL /* constant vector a */
55 #define UMASK 0x80000000UL /* most significant w-r bits */
56 #define LMASK 0x7fffffffUL /* least significant r bits */
57 #define MIXBITS(u,v) ( ((u) & UMASK) | ((v) & LMASK) )
58 #define TWIST(u,v) ((MIXBITS(u,v) >> 1) ^ ((v)&1UL ? MATRIX_A : 0UL))
59 
60 static unsigned long state[N]; /* the array for the state vector */
61 static int left = 1;
62 static int initf = 0;
63 static unsigned long *next;
64 
65 /* initializes state[N] with a seed */
66 void init_genrand(unsigned long s) {
67  int j;
68  state[0]= s & 0xffffffffUL;
69  for (j=1; j<N; j++) {
70  state[j] = (1812433253UL * (state[j-1] ^ (state[j-1] >> 30)) + j);
71  /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
72  /* In the previous versions, MSBs of the seed affect */
73  /* only MSBs of the array state[]. */
74  /* 2002/01/09 modified by Makoto Matsumoto */
75  state[j] &= 0xffffffffUL; /* for >32 bit machines */
76  }
77  left = 1; initf = 1;
78 }
79 
80 /* initialize by an array with array-length */
81 /* init_key is the array for initializing keys */
82 /* key_length is its length */
83 /* slight change for C++, 2004/2/26 */
84 void init_by_array(unsigned long init_key[], int key_length) {
85  int i, j, k;
86  init_genrand(19650218UL);
87  i=1; j=0;
88  k = (N>key_length ? N : key_length);
89  for (; k; k--) {
90  state[i] = (state[i] ^ ((state[i-1] ^ (state[i-1] >> 30)) * 1664525UL))
91  + init_key[j] + j; /* non linear */
92  state[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
93  i++; j++;
94  if (i>=N) { state[0] = state[N-1]; i=1; }
95  if (j>=key_length) j=0;
96  }
97  for (k=N-1; k; k--) {
98  state[i] = (state[i] ^ ((state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL))
99  - i; /* non linear */
100  state[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
101  i++;
102  if (i>=N) { state[0] = state[N-1]; i=1; }
103  }
104 
105  state[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */
106  left = 1; initf = 1;
107 }
108 
109 static void next_state(void) {
110  unsigned long *p=state;
111  int j;
112 
113  /* if init_genrand() has not been called, */
114  /* a default initial seed is used */
115  if (initf==0) init_genrand(5489UL);
116 
117  left = N;
118  next = state;
119 
120  for (j=N-M+1; --j; p++) {
121  /*@ assert Value: mem_access: \valid_read(p+1); */
122  /*@ assert Value: mem_access: \valid_read(p+397); */
123  *p = p[M] ^ TWIST(p[0], p[1]);
124  }
125 
126  for (j=M; --j; p++) {
127  /*@ assert Value: mem_access: \valid_read(p+1); */
128  /*@ assert Value: mem_access: \valid_read(p+(int)(397-624)); */
129  *p = p[M-N] ^ TWIST(p[0], p[1]);
130  }
131 
132  /*@ assert Value: mem_access: \valid(p); */
133  /*@ assert Value: mem_access: \valid_read(p+(int)(397-624)); */
134  *p = p[M-N] ^ TWIST(p[0], state[0]);
135 }
136 
138 unsigned long potion_rand_int(void) {
139  unsigned long y;
140 
141  if (--left == 0) next_state();
142  y = *next++;
143 
144  /* Tempering */
145  y ^= (y >> 11);
146  y ^= (y << 7) & 0x9d2c5680UL;
147  y ^= (y << 15) & 0xefc60000UL;
148  y ^= (y >> 18);
149 
150  return y;
151 }
152 
154 double potion_rand_double(void) {
155  unsigned long a=potion_rand_int()>>5, b=potion_rand_int()>>6;
156  return(a*67108864.0+b)*(1.0/9007199254740992.0);
157 }
163 PN potion_srand(Potion *P, PN cl, PN self, PN seed) {
164  init_genrand(PN_INT(seed));
165  return self;
166 }
167 
173 PN potion_rand(Potion *P, PN cl, PN self) {
174  return PN_NUM(potion_rand_int());
175 }
176 
182 PN potion_num_rand(Potion *P, PN cl, PN self) {
183  return PN_NUM(potion_rand_double());
184 }
static int left
Definition: mt19937ar.c:61
PN potion_rand(Potion *P, PN cl, PN self)
Definition: mt19937ar.c:173
#define TWIST(u, v)
Definition: mt19937ar.c:58
void init_genrand(unsigned long s)
Definition: mt19937ar.c:66
unsigned long potion_rand_int(void)
generates a random number on [0,0xffffffff]-interval
Definition: mt19937ar.c:138
#define N
Definition: mt19937ar.c:52
#define PN_INT(x)
Definition: potion.h:205
#define PN_NUM(i)
Definition: potion.h:204
PN potion_num_rand(Potion *P, PN cl, PN self)
Definition: mt19937ar.c:182
static int initf
Definition: mt19937ar.c:62
#define M
Definition: mt19937ar.c:53
void init_by_array(unsigned long init_key[], int key_length)
Definition: mt19937ar.c:84
double potion_rand_double(void)
generates a random number on [0,1) with 53-bit resolution
Definition: mt19937ar.c:154
static unsigned long state[N]
Definition: mt19937ar.c:60
the global interpreter state P. currently singleton (not threads yet)
Definition: potion.h:644
The potion API.
static unsigned long * next
Definition: mt19937ar.c:63
PN potion_srand(Potion *P, PN cl, PN self, PN seed)
Definition: mt19937ar.c:163
static void next_state(void)
Definition: mt19937ar.c:109
volatile _PN PN
Definition: potion.h:81