MTGP 1.1
|
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 00023 #if defined(__cplusplus) 00024 extern "C" { 00025 #endif 00026 00046 typedef struct MTGP64_PARAMS_FAST_T { 00047 int mexp; 00048 int pos; 00049 int sh1; 00050 int sh2; 00051 uint64_t tbl[16]; 00052 uint64_t tmp_tbl[16]; 00053 uint64_t dbl_tmp_tbl[16]; 00055 uint64_t mask; 00056 unsigned char poly_sha1[21]; 00057 } mtgp64_params_fast_t; 00058 00074 typedef struct MTGP64_STATUS_FAST_T { 00075 int idx; 00076 int size; 00077 int large_size; 00078 int large_mask; 00079 uint64_t array[]; 00080 } mtgp64_status_fast_t; 00081 00086 typedef struct MTGP64_FAST_T { 00087 mtgp64_params_fast_t params; 00088 mtgp64_status_fast_t *status; 00089 } mtgp64_fast_t; 00090 00095 extern mtgp64_params_fast_t mtgp64_params_fast_23209[128]; 00100 extern mtgp64_params_fast_t mtgp64_params_fast_44497[128]; 00105 extern mtgp64_params_fast_t mtgp64_params_fast_110503[128]; 00106 00107 int mtgp64_init(mtgp64_fast_t *mtgp64, 00108 const mtgp64_params_fast_t *para, uint64_t seed); 00109 void mtgp64_init_state(uint64_t array[], 00110 const mtgp64_params_fast_t *para, uint64_t seed); 00111 int mtgp64_init_by_array(mtgp64_fast_t *mtgp64, 00112 const mtgp64_params_fast_t *para, 00113 uint64_t *array, int length); 00114 int mtgp64_init_by_str(mtgp64_fast_t *mtgp64, 00115 const mtgp64_params_fast_t *para, 00116 char *str); 00117 void mtgp64_free(mtgp64_fast_t *mtgp64); 00118 void mtgp64_print_idstring(const mtgp64_fast_t *mtgp64, FILE *fp); 00119 00120 inline static void mtgp64_do_recursion(uint64_t *r, uint64_t x1, 00121 uint64_t x2, uint64_t y, 00122 int sh1, int sh2, 00123 uint64_t mask, uint64_t tbl[16]); 00124 inline static void mtgp64_next_state(mtgp64_fast_t *mtgp64); 00125 inline static uint64_t mtgp64_genrand_uint64(mtgp64_fast_t *mtgp64); 00126 inline static double mtgp64_genrand_close1_open2(mtgp64_fast_t *mtgp64); 00127 inline static double mtgp64_genrand_close_open(mtgp64_fast_t *mtgp64); 00128 inline static double mtgp64_genrand_open_close(mtgp64_fast_t *mtgp64); 00129 inline static double mtgp64_genrand_open_open(mtgp64_fast_t *mtgp64); 00130 00131 /* 00132 * PRIVATE INLINE FUNCTIONS 00133 */ 00148 inline static void mtgp64_do_recursion(uint64_t *r, uint64_t x1, 00149 uint64_t x2, uint64_t y, 00150 int sh1, int sh2, 00151 uint64_t mask, uint64_t tbl[16]) { 00152 uint64_t x; 00153 uint32_t xh; 00154 uint32_t xl; 00155 uint32_t yh; 00156 uint32_t yl; 00157 00158 x = (x1 & mask) ^ x2; 00159 xh = (uint32_t)(x >> 32); 00160 xl = (uint32_t)(x & 0xffffffffU); 00161 yh = (uint32_t)(y >> 32); 00162 yl = (uint32_t)(y & 0xffffffffU); 00163 xh ^= xh << sh1; 00164 xl ^= xl << sh1; 00165 yh = xl ^ (yh >> sh2); 00166 yl = xh ^ (yl >> sh2); 00167 *r = ((uint64_t)yh << 32) | yl; 00168 *r ^= tbl[yl & 0x0f]; 00169 } 00170 00175 inline static void mtgp64_next_state(mtgp64_fast_t *mtgp64) { 00176 uint64_t *array = mtgp64->status->array; 00177 int idx; 00178 int pos = mtgp64->params.pos; 00179 int large_size = mtgp64->status->large_size; 00180 uint64_t large_mask = mtgp64->status->large_mask; 00181 int size = mtgp64->status->size; 00182 00183 mtgp64->status->idx = (mtgp64->status->idx + 1) & large_mask; 00184 idx = mtgp64->status->idx; 00185 mtgp64_do_recursion(&(array[idx]), 00186 array[(idx - size + large_size) & large_mask], 00187 array[(idx - size + large_size + 1) & large_mask], 00188 array[(idx + pos - size + large_size) & large_mask], 00189 mtgp64->params.sh1, 00190 mtgp64->params.sh2, 00191 mtgp64->params.mask, 00192 mtgp64->params.tbl); 00193 } 00194 00202 inline static uint64_t mtgp64_temper(const uint64_t tmp_tbl[16], 00203 uint64_t r, uint64_t t) { 00204 t ^= t >> 16; 00205 t ^= t >> 8; 00206 r ^= tmp_tbl[t & 0x0f]; 00207 return r; 00208 } 00209 00217 inline static double mtgp64_temper_double(const uint64_t dbl_tmp_tbl[16], 00218 uint64_t r, uint64_t t) { 00219 union { 00220 uint64_t u; 00221 double d; 00222 } x; 00223 t ^= t >> 16; 00224 t ^= t >> 8; 00225 r = r >> 12; 00226 x.u = r ^ dbl_tmp_tbl[t & 0x0f]; 00227 return x.d; 00228 } 00229 00238 inline static double mtgp64_temper_double_open(const uint64_t dbl_tmp_tbl[16], 00239 uint64_t r, uint64_t t) { 00240 union { 00241 uint64_t u; 00242 double d; 00243 } x; 00244 t ^= t >> 16; 00245 t ^= t >> 8; 00246 r = (r >> 12) | 1; 00247 x.u = r ^ dbl_tmp_tbl[t & 0x0f]; 00248 return x.d; 00249 } 00250 00251 /* 00252 * PUBLIC INLINE FUNCTIONS 00253 */ 00262 inline static uint64_t mtgp64_genrand_uint64(mtgp64_fast_t *mtgp64) { 00263 int idx; 00264 uint64_t *tmp_tbl = mtgp64->params.tmp_tbl; 00265 uint64_t *array = mtgp64->status->array; 00266 int pos = mtgp64->params.pos; 00267 int large_size = mtgp64->status->large_size; 00268 int size = mtgp64->status->size; 00269 uint64_t large_mask = mtgp64->status->large_mask; 00270 00271 mtgp64_next_state(mtgp64); 00272 idx = mtgp64->status->idx; 00273 return mtgp64_temper(tmp_tbl, 00274 array[idx], 00275 array[(idx + pos - 1 - size + large_size) 00276 & large_mask]); 00277 } 00278 00288 inline static double mtgp64_genrand_close1_open2(mtgp64_fast_t *mtgp64) { 00289 int idx; 00290 uint64_t *dbl_tmp_tbl = mtgp64->params.dbl_tmp_tbl; 00291 uint64_t *array = mtgp64->status->array; 00292 int pos = mtgp64->params.pos; 00293 int large_size = mtgp64->status->large_size; 00294 int size = mtgp64->status->size; 00295 uint64_t large_mask = mtgp64->status->large_mask; 00296 00297 mtgp64_next_state(mtgp64); 00298 idx = mtgp64->status->idx; 00299 return mtgp64_temper_double(dbl_tmp_tbl, 00300 array[idx], 00301 array[(idx + pos - 1 - size + large_size) 00302 & large_mask]); 00303 } 00304 00314 inline static double mtgp64_genrand_close_open(mtgp64_fast_t *mtgp64) { 00315 return mtgp64_genrand_close1_open2(mtgp64) - 1.0; 00316 } 00317 00327 inline static double mtgp64_genrand_open_close(mtgp64_fast_t *mtgp64) { 00328 return 2.0 - mtgp64_genrand_close1_open2(mtgp64); 00329 } 00330 00340 inline static double mtgp64_genrand_open_open(mtgp64_fast_t *mtgp64) { 00341 double r; 00342 int idx; 00343 uint64_t *dbl_tmp_tbl = mtgp64->params.dbl_tmp_tbl; 00344 uint64_t *array = mtgp64->status->array; 00345 int pos = mtgp64->params.pos; 00346 int large_size = mtgp64->status->large_size; 00347 int size = mtgp64->status->size; 00348 uint64_t large_mask = mtgp64->status->large_mask; 00349 mtgp64_next_state(mtgp64); 00350 idx = mtgp64->status->idx; 00351 r = mtgp64_temper_double_open(dbl_tmp_tbl, 00352 array[idx], 00353 array[(idx + pos - 1 - size + large_size) 00354 & large_mask]); 00355 return r - 1.0; 00356 } 00357 00358 #if defined(__cplusplus) 00359 } 00360 #endif 00361 00362 #endif