MTGP  1.1.1
mtgp32-fast.h
Go to the documentation of this file.
1 #ifndef MTGP32_FAST_H
2 #define MTGP32_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 
47 typedef struct MTGP32_PARAMS_FAST_T {
48  int mexp;
49  int pos;
50  int sh1;
51  int sh2;
52  uint32_t tbl[16];
53  uint32_t tmp_tbl[16];
54  uint32_t flt_tmp_tbl[16];
56  uint32_t mask;
57  unsigned char poly_sha1[21];
59 
75 typedef struct MTGP32_STATUS_FAST_T {
76  int idx;
77  int size;
78  int large_size;
79  int large_mask;
80  uint32_t array[];
82 
87 typedef struct MTGP32_FAST_T {
91 
107 
108 int mtgp32_init(mtgp32_fast_t *mtgp32,
109  const mtgp32_params_fast_t *para, uint32_t seed);
110 void mtgp32_init_state(uint32_t array[],
111  const mtgp32_params_fast_t *para, uint32_t seed);
113  const mtgp32_params_fast_t *para,
114  uint32_t *array, int length);
116  const mtgp32_params_fast_t *para,
117  char *str);
118 void mtgp32_free(mtgp32_fast_t *mtgp32);
119 void mtgp32_print_idstring(const mtgp32_fast_t *mtgp32, FILE *fp);
120 
121 inline static void mtgp32_do_recursion(uint32_t *r, uint32_t x1,
122  uint32_t x2, uint32_t y,
123  int sh1, int sh2,
124  uint32_t mask, uint32_t tbl[16]);
125 inline static void mtgp32_next_state(mtgp32_fast_t *mtgp32);
126 inline static uint32_t mtgp32_genrand_uint32(mtgp32_fast_t *mtgp32);
127 inline static float mtgp32_genrand_close1_open2(mtgp32_fast_t *mtgp32);
128 inline static float mtgp32_genrand_close_open(mtgp32_fast_t *mtgp32);
129 inline static float mtgp32_genrand_open_close(mtgp32_fast_t *mtgp32);
130 inline static float mtgp32_genrand_open_open(mtgp32_fast_t *mtgp32);
131 
132 /*
133  * PRIVATE INLINE FUNCTIONS
134  */
149 inline static void mtgp32_do_recursion(uint32_t *r, uint32_t x1,
150  uint32_t x2, uint32_t y,
151  int sh1, int sh2,
152  uint32_t mask, uint32_t tbl[16]) {
153  uint32_t x;
154 
155  x = (x1 & mask) ^ x2;
156  x ^= x << sh1;
157  y = x ^ (y >> sh2);
158  *r = y ^ tbl[y & 0x0f];
159 }
160 
165 inline static void mtgp32_next_state(mtgp32_fast_t *mtgp32) {
166  uint32_t *array = mtgp32->status->array;
167  int idx;
168  int pos = mtgp32->params.pos;
169  int large_size = mtgp32->status->large_size;
170  uint32_t large_mask = mtgp32->status->large_mask;
171  int size = mtgp32->status->size;
172 
173  mtgp32->status->idx = (mtgp32->status->idx + 1) & large_mask;
174  idx = mtgp32->status->idx;
175  mtgp32_do_recursion(&(array[idx]),
176  array[(idx - size + large_size) & large_mask],
177  array[(idx - size + large_size + 1) & large_mask],
178  array[(idx + pos - size + large_size) & large_mask],
179  mtgp32->params.sh1,
180  mtgp32->params.sh2,
181  mtgp32->params.mask,
182  mtgp32->params.tbl);
183 }
184 
192 inline static uint32_t mtgp32_temper(const uint32_t tmp_tbl[16],
193  uint32_t r, uint32_t t) {
194  t ^= t >> 16;
195  t ^= t >> 8;
196  r ^= tmp_tbl[t & 0x0f];
197  return r;
198 }
199 
207 inline static float mtgp32_temper_float(const uint32_t flt_tmp_tbl[16],
208  uint32_t r, uint32_t t) {
209  union {
210  uint32_t u;
211  float f;
212  } x;
213  t ^= t >> 16;
214  t ^= t >> 8;
215  r = r >> 9;
216  x.u = r ^ flt_tmp_tbl[t & 0x0f];
217  return x.f;
218 }
219 
228 inline static float mtgp32_temper_float_open(const uint32_t flt_tmp_tbl[16],
229  uint32_t r, uint32_t t) {
230  union {
231  uint32_t u;
232  float f;
233  } x;
234  t ^= t >> 16;
235  t ^= t >> 8;
236  r = r >> 9;
237  x.u = (r ^ flt_tmp_tbl[t & 0x0f]) | 1;
238  return x.f;
239 }
240 
241 /*
242  * PUBLIC INLINE FUNCTIONS
243  */
252 inline static uint32_t mtgp32_genrand_uint32(mtgp32_fast_t *mtgp32) {
253  int idx;
254  uint32_t *tmp_tbl = mtgp32->params.tmp_tbl;
255  uint32_t *array = mtgp32->status->array;
256  int pos = mtgp32->params.pos;
257  int large_size = mtgp32->status->large_size;
258  int size = mtgp32->status->size;
259  uint32_t large_mask = mtgp32->status->large_mask;
260 
261  mtgp32_next_state(mtgp32);
262  idx = mtgp32->status->idx;
263  return mtgp32_temper(tmp_tbl,
264  array[idx],
265  array[(idx + pos - 1 - size + large_size)
266  & large_mask]);
267 }
268 
278 inline static float mtgp32_genrand_close1_open2(mtgp32_fast_t *mtgp32) {
279  int idx;
280  uint32_t *flt_tmp_tbl = mtgp32->params.flt_tmp_tbl;
281  uint32_t *array = mtgp32->status->array;
282  int pos = mtgp32->params.pos;
283  int large_size = mtgp32->status->large_size;
284  int size = mtgp32->status->size;
285  uint32_t large_mask = mtgp32->status->large_mask;
286 
287  mtgp32_next_state(mtgp32);
288  idx = mtgp32->status->idx;
289  return mtgp32_temper_float(flt_tmp_tbl,
290  array[idx],
291  array[(idx + pos - 1 - size + large_size)
292  & large_mask]);
293 }
294 
304 inline static float mtgp32_genrand_close_open(mtgp32_fast_t *mtgp32) {
305  return mtgp32_genrand_close1_open2(mtgp32) - 1.0F;
306 }
307 
317 inline static float mtgp32_genrand_open_close(mtgp32_fast_t *mtgp32) {
318  return 2.0F - mtgp32_genrand_close1_open2(mtgp32);
319 }
320 
330 inline static float mtgp32_genrand_open_open(mtgp32_fast_t *mtgp32) {
331  float r;
332  int idx;
333  uint32_t *flt_tmp_tbl = mtgp32->params.flt_tmp_tbl;
334  uint32_t *array = mtgp32->status->array;
335  int pos = mtgp32->params.pos;
336  int large_size = mtgp32->status->large_size;
337  int size = mtgp32->status->size;
338  uint32_t large_mask = mtgp32->status->large_mask;
339  mtgp32_next_state(mtgp32);
340  idx = mtgp32->status->idx;
341  r = mtgp32_temper_float_open(flt_tmp_tbl,
342  array[idx],
343  array[(idx + pos - 1 - size + large_size)
344  & large_mask]);
345  return r - 1.0F;
346 }
347 #if defined(__cplusplus)
348 }
349 #endif
350 
351 #endif