MTGP  1.1.1
mtgp64-fast.h
Go to the documentation of this file.
1 #ifndef MTGP64_FAST_H
2 #define MTGP64_FAST_H
3 
18 #include <string.h>
19 #include <assert.h>
20 #include <stdio.h>
21 #include <stdint.h>
22 
23 #if defined(__cplusplus)
24 extern "C" {
25 #endif
26 
46 typedef struct MTGP64_PARAMS_FAST_T {
47  int mexp;
48  int pos;
49  int sh1;
50  int sh2;
51  uint64_t tbl[16];
52  uint64_t tmp_tbl[16];
53  uint64_t dbl_tmp_tbl[16];
55  uint64_t mask;
56  unsigned char poly_sha1[21];
58 
74 typedef struct MTGP64_STATUS_FAST_T {
75  int idx;
76  int size;
77  int large_size;
78  int large_mask;
79  uint64_t array[];
81 
86 typedef struct MTGP64_FAST_T {
90 
106 
107 int mtgp64_init(mtgp64_fast_t *mtgp64,
108  const mtgp64_params_fast_t *para, uint64_t seed);
109 void mtgp64_init_state(uint64_t array[],
110  const mtgp64_params_fast_t *para, uint64_t seed);
112  const mtgp64_params_fast_t *para,
113  uint64_t *array, int length);
115  const mtgp64_params_fast_t *para,
116  char *str);
117 void mtgp64_free(mtgp64_fast_t *mtgp64);
118 void mtgp64_print_idstring(const mtgp64_fast_t *mtgp64, FILE *fp);
119 
120 inline static void mtgp64_do_recursion(uint64_t *r, uint64_t x1,
121  uint64_t x2, uint64_t y,
122  int sh1, int sh2,
123  uint64_t mask, uint64_t tbl[16]);
124 inline static void mtgp64_next_state(mtgp64_fast_t *mtgp64);
125 inline static uint64_t mtgp64_genrand_uint64(mtgp64_fast_t *mtgp64);
126 inline static double mtgp64_genrand_close1_open2(mtgp64_fast_t *mtgp64);
127 inline static double mtgp64_genrand_close_open(mtgp64_fast_t *mtgp64);
128 inline static double mtgp64_genrand_open_close(mtgp64_fast_t *mtgp64);
129 inline static double mtgp64_genrand_open_open(mtgp64_fast_t *mtgp64);
130 
131 /*
132  * PRIVATE INLINE FUNCTIONS
133  */
148 inline static void mtgp64_do_recursion(uint64_t *r, uint64_t x1,
149  uint64_t x2, uint64_t y,
150  int sh1, int sh2,
151  uint64_t mask, uint64_t tbl[16]) {
152  uint64_t x;
153  uint32_t xh;
154  uint32_t xl;
155  uint32_t yh;
156  uint32_t yl;
157 
158  x = (x1 & mask) ^ x2;
159  xh = (uint32_t)(x >> 32);
160  xl = (uint32_t)(x & 0xffffffffU);
161  yh = (uint32_t)(y >> 32);
162  yl = (uint32_t)(y & 0xffffffffU);
163  xh ^= xh << sh1;
164  xl ^= xl << sh1;
165  yh = xl ^ (yh >> sh2);
166  yl = xh ^ (yl >> sh2);
167  *r = ((uint64_t)yh << 32) | yl;
168  *r ^= tbl[yl & 0x0f];
169 }
170 
175 inline static void mtgp64_next_state(mtgp64_fast_t *mtgp64) {
176  uint64_t *array = mtgp64->status->array;
177  int idx;
178  int pos = mtgp64->params.pos;
179  int large_size = mtgp64->status->large_size;
180  uint64_t large_mask = mtgp64->status->large_mask;
181  int size = mtgp64->status->size;
182 
183  mtgp64->status->idx = (mtgp64->status->idx + 1) & large_mask;
184  idx = mtgp64->status->idx;
185  mtgp64_do_recursion(&(array[idx]),
186  array[(idx - size + large_size) & large_mask],
187  array[(idx - size + large_size + 1) & large_mask],
188  array[(idx + pos - size + large_size) & large_mask],
189  mtgp64->params.sh1,
190  mtgp64->params.sh2,
191  mtgp64->params.mask,
192  mtgp64->params.tbl);
193 }
194 
202 inline static uint64_t mtgp64_temper(const uint64_t tmp_tbl[16],
203  uint64_t r, uint64_t t) {
204  t ^= t >> 16;
205  t ^= t >> 8;
206  r ^= tmp_tbl[t & 0x0f];
207  return r;
208 }
209 
217 inline static double mtgp64_temper_double(const uint64_t dbl_tmp_tbl[16],
218  uint64_t r, uint64_t t) {
219  union {
220  uint64_t u;
221  double d;
222  } x;
223  t ^= t >> 16;
224  t ^= t >> 8;
225  r = r >> 12;
226  x.u = r ^ dbl_tmp_tbl[t & 0x0f];
227  return x.d;
228 }
229 
238 inline static double mtgp64_temper_double_open(const uint64_t dbl_tmp_tbl[16],
239  uint64_t r, uint64_t t) {
240  union {
241  uint64_t u;
242  double d;
243  } x;
244  t ^= t >> 16;
245  t ^= t >> 8;
246  r = (r >> 12) | 1;
247  x.u = r ^ dbl_tmp_tbl[t & 0x0f];
248  return x.d;
249 }
250 
251 /*
252  * PUBLIC INLINE FUNCTIONS
253  */
262 inline static uint64_t mtgp64_genrand_uint64(mtgp64_fast_t *mtgp64) {
263  int idx;
264  uint64_t *tmp_tbl = mtgp64->params.tmp_tbl;
265  uint64_t *array = mtgp64->status->array;
266  int pos = mtgp64->params.pos;
267  int large_size = mtgp64->status->large_size;
268  int size = mtgp64->status->size;
269  uint64_t large_mask = mtgp64->status->large_mask;
270 
271  mtgp64_next_state(mtgp64);
272  idx = mtgp64->status->idx;
273  return mtgp64_temper(tmp_tbl,
274  array[idx],
275  array[(idx + pos - 1 - size + large_size)
276  & large_mask]);
277 }
278 
288 inline static double mtgp64_genrand_close1_open2(mtgp64_fast_t *mtgp64) {
289  int idx;
290  uint64_t *dbl_tmp_tbl = mtgp64->params.dbl_tmp_tbl;
291  uint64_t *array = mtgp64->status->array;
292  int pos = mtgp64->params.pos;
293  int large_size = mtgp64->status->large_size;
294  int size = mtgp64->status->size;
295  uint64_t large_mask = mtgp64->status->large_mask;
296 
297  mtgp64_next_state(mtgp64);
298  idx = mtgp64->status->idx;
299  return mtgp64_temper_double(dbl_tmp_tbl,
300  array[idx],
301  array[(idx + pos - 1 - size + large_size)
302  & large_mask]);
303 }
304 
314 inline static double mtgp64_genrand_close_open(mtgp64_fast_t *mtgp64) {
315  return mtgp64_genrand_close1_open2(mtgp64) - 1.0;
316 }
317 
327 inline static double mtgp64_genrand_open_close(mtgp64_fast_t *mtgp64) {
328  return 2.0 - mtgp64_genrand_close1_open2(mtgp64);
329 }
330 
340 inline static double mtgp64_genrand_open_open(mtgp64_fast_t *mtgp64) {
341  double r;
342  int idx;
343  uint64_t *dbl_tmp_tbl = mtgp64->params.dbl_tmp_tbl;
344  uint64_t *array = mtgp64->status->array;
345  int pos = mtgp64->params.pos;
346  int large_size = mtgp64->status->large_size;
347  int size = mtgp64->status->size;
348  uint64_t large_mask = mtgp64->status->large_mask;
349  mtgp64_next_state(mtgp64);
350  idx = mtgp64->status->idx;
351  r = mtgp64_temper_double_open(dbl_tmp_tbl,
352  array[idx],
353  array[(idx + pos - 1 - size + large_size)
354  & large_mask]);
355  return r - 1.0;
356 }
357 
358 #if defined(__cplusplus)
359 }
360 #endif
361 
362 #endif