00001 #ifndef MTGP64_FAST_H
00002 #define MTGP64_FAST_H
00003
00018 #include <string.h>
00019 #include <assert.h>
00020 #include <stdio.h>
00021 #include <stdint.h>
00022
00043 typedef struct MTGP64_PARAMS_FAST_T {
00044 int mexp;
00045 int pos;
00046 int sh1;
00047 int sh2;
00048 uint64_t tbl[16];
00049 uint64_t tmp_tbl[16];
00050 uint64_t dbl_tmp_tbl[16];
00052 uint64_t mask;
00053 unsigned char poly_sha1[21];
00054 } mtgp64_params_fast_t;
00055
00071 typedef struct MTGP64_STATUS_FAST_T {
00072 int idx;
00073 int size;
00074 int large_size;
00075 int large_mask;
00076 uint64_t array[];
00077 } mtgp64_status_fast_t;
00078
00083 typedef struct MTGP64_FAST_T {
00084 mtgp64_params_fast_t params;
00085 mtgp64_status_fast_t *status;
00086 } mtgp64_fast_t;
00087
00092 extern mtgp64_params_fast_t mtgp64_params_fast_23209[128];
00097 extern mtgp64_params_fast_t mtgp64_params_fast_44497[128];
00102 extern mtgp64_params_fast_t mtgp64_params_fast_110503[128];
00103
00104 int mtgp64_init(mtgp64_fast_t *mtgp64,
00105 const mtgp64_params_fast_t *para, uint64_t seed);
00106 void mtgp64_init_state(uint64_t array[],
00107 const mtgp64_params_fast_t *para, uint64_t seed);
00108 int mtgp64_init_by_array(mtgp64_fast_t *mtgp64,
00109 const mtgp64_params_fast_t *para,
00110 uint64_t *array, int length);
00111 int mtgp64_init_by_str(mtgp64_fast_t *mtgp64,
00112 const mtgp64_params_fast_t *para,
00113 char *str);
00114 void mtgp64_free(mtgp64_fast_t *mtgp64);
00115 void mtgp64_print_idstring(const mtgp64_fast_t *mtgp64, FILE *fp);
00116
00117 inline static void mtgp64_do_recursion(uint64_t *r, uint64_t x1,
00118 uint64_t x2, uint64_t y,
00119 int sh1, int sh2,
00120 uint64_t mask, uint64_t tbl[16]);
00121 inline static void mtgp64_next_state(mtgp64_fast_t *mtgp64);
00122 inline static uint64_t mtgp64_genrand_uint64(mtgp64_fast_t *mtgp64);
00123 inline static double mtgp64_genrand_close1_open2(mtgp64_fast_t *mtgp64);
00124 inline static double mtgp64_genrand_close_open(mtgp64_fast_t *mtgp64);
00125 inline static double mtgp64_genrand_open_close(mtgp64_fast_t *mtgp64);
00126 inline static double mtgp64_genrand_open_open(mtgp64_fast_t *mtgp64);
00127
00128
00129
00130
00145 inline static void mtgp64_do_recursion(uint64_t *r, uint64_t x1,
00146 uint64_t x2, uint64_t y,
00147 int sh1, int sh2,
00148 uint64_t mask, uint64_t tbl[16]) {
00149 uint64_t x;
00150 uint32_t xh;
00151 uint32_t xl;
00152 uint32_t yh;
00153 uint32_t yl;
00154
00155 x = (x1 & mask) ^ x2;
00156 xh = (uint32_t)(x >> 32);
00157 xl = (uint32_t)(x & 0xffffffffU);
00158 yh = (uint32_t)(y >> 32);
00159 yl = (uint32_t)(y & 0xffffffffU);
00160 xh ^= xh << sh1;
00161 xl ^= xl << sh1;
00162 yh = xl ^ (yh >> sh2);
00163 yl = xh ^ (yl >> sh2);
00164 *r = ((uint64_t)yh << 32) | yl;
00165 *r ^= tbl[yl & 0x0f];
00166 }
00167
00172 inline static void mtgp64_next_state(mtgp64_fast_t *mtgp64) {
00173 uint64_t *array = mtgp64->status->array;
00174 int idx;
00175 int pos = mtgp64->params.pos;
00176 int large_size = mtgp64->status->large_size;
00177 uint64_t large_mask = mtgp64->status->large_mask;
00178 int size = mtgp64->status->size;
00179
00180 mtgp64->status->idx = (mtgp64->status->idx + 1) & large_mask;
00181 idx = mtgp64->status->idx;
00182 mtgp64_do_recursion(&(array[idx]),
00183 array[(idx - size + large_size) & large_mask],
00184 array[(idx - size + large_size + 1) & large_mask],
00185 array[(idx + pos - size + large_size) & large_mask],
00186 mtgp64->params.sh1,
00187 mtgp64->params.sh2,
00188 mtgp64->params.mask,
00189 mtgp64->params.tbl);
00190 }
00191
00199 inline static uint64_t mtgp64_temper(const uint64_t tmp_tbl[16],
00200 uint64_t r, uint64_t t) {
00201 t ^= t >> 16;
00202 t ^= t >> 8;
00203 r ^= tmp_tbl[t & 0x0f];
00204 return r;
00205 }
00206
00214 inline static double mtgp64_temper_double(const uint64_t dbl_tmp_tbl[16],
00215 uint64_t r, uint64_t t) {
00216 union {
00217 uint64_t u;
00218 double d;
00219 } x;
00220 t ^= t >> 16;
00221 t ^= t >> 8;
00222 r = r >> 12;
00223 x.u = r ^ dbl_tmp_tbl[t & 0x0f];
00224 return x.d;
00225 }
00226
00235 inline static double mtgp64_temper_double_open(const uint64_t dbl_tmp_tbl[16],
00236 uint64_t r, uint64_t t) {
00237 union {
00238 uint64_t u;
00239 double d;
00240 } x;
00241 t ^= t >> 16;
00242 t ^= t >> 8;
00243 r = (r >> 12) | 1;
00244 x.u = r ^ dbl_tmp_tbl[t & 0x0f];
00245 return x.d;
00246 }
00247
00248
00249
00250
00259 inline static uint64_t mtgp64_genrand_uint64(mtgp64_fast_t *mtgp64) {
00260 int idx;
00261 uint64_t *tmp_tbl = mtgp64->params.tmp_tbl;
00262 uint64_t *array = mtgp64->status->array;
00263 int pos = mtgp64->params.pos;
00264 int large_size = mtgp64->status->large_size;
00265 int size = mtgp64->status->size;
00266 uint64_t large_mask = mtgp64->status->large_mask;
00267
00268 mtgp64_next_state(mtgp64);
00269 idx = mtgp64->status->idx;
00270 return mtgp64_temper(tmp_tbl,
00271 array[idx],
00272 array[(idx + pos - 1 - size + large_size)
00273 & large_mask]);
00274 }
00275
00285 inline static double mtgp64_genrand_close1_open2(mtgp64_fast_t *mtgp64) {
00286 int idx;
00287 uint64_t *dbl_tmp_tbl = mtgp64->params.dbl_tmp_tbl;
00288 uint64_t *array = mtgp64->status->array;
00289 int pos = mtgp64->params.pos;
00290 int large_size = mtgp64->status->large_size;
00291 int size = mtgp64->status->size;
00292 uint64_t large_mask = mtgp64->status->large_mask;
00293
00294 mtgp64_next_state(mtgp64);
00295 idx = mtgp64->status->idx;
00296 return mtgp64_temper_double(dbl_tmp_tbl,
00297 array[idx],
00298 array[(idx + pos - 1 - size + large_size)
00299 & large_mask]);
00300 }
00301
00311 inline static double mtgp64_genrand_close_open(mtgp64_fast_t *mtgp64) {
00312 return mtgp64_genrand_close1_open2(mtgp64) - 1.0;
00313 }
00314
00324 inline static double mtgp64_genrand_open_close(mtgp64_fast_t *mtgp64) {
00325 return 2.0 - mtgp64_genrand_close1_open2(mtgp64);
00326 }
00327
00337 inline static double mtgp64_genrand_open_open(mtgp64_fast_t *mtgp64) {
00338 double r;
00339 int idx;
00340 uint64_t *dbl_tmp_tbl = mtgp64->params.dbl_tmp_tbl;
00341 uint64_t *array = mtgp64->status->array;
00342 int pos = mtgp64->params.pos;
00343 int large_size = mtgp64->status->large_size;
00344 int size = mtgp64->status->size;
00345 uint64_t large_mask = mtgp64->status->large_mask;
00346 mtgp64_next_state(mtgp64);
00347 idx = mtgp64->status->idx;
00348 r = mtgp64_temper_double_open(dbl_tmp_tbl,
00349 array[idx],
00350 array[(idx + pos - 1 - size + large_size)
00351 & large_mask]);
00352 return r - 1.0;
00353 }
00354
00355 #endif