MTGP 1.1
|
00001 #ifndef MTGP32_FAST_H 00002 #define MTGP32_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 00047 typedef struct MTGP32_PARAMS_FAST_T { 00048 int mexp; 00049 int pos; 00050 int sh1; 00051 int sh2; 00052 uint32_t tbl[16]; 00053 uint32_t tmp_tbl[16]; 00054 uint32_t flt_tmp_tbl[16]; 00056 uint32_t mask; 00057 unsigned char poly_sha1[21]; 00058 } mtgp32_params_fast_t; 00059 00075 typedef struct MTGP32_STATUS_FAST_T { 00076 int idx; 00077 int size; 00078 int large_size; 00079 int large_mask; 00080 uint32_t array[]; 00081 } mtgp32_status_fast_t; 00082 00087 typedef struct MTGP32_FAST_T { 00088 mtgp32_params_fast_t params; 00089 mtgp32_status_fast_t *status; 00090 } mtgp32_fast_t; 00091 00096 extern mtgp32_params_fast_t mtgp32_params_fast_11213[128]; 00101 extern mtgp32_params_fast_t mtgp32_params_fast_23209[128]; 00106 extern mtgp32_params_fast_t mtgp32_params_fast_44497[128]; 00107 00108 int mtgp32_init(mtgp32_fast_t *mtgp32, 00109 const mtgp32_params_fast_t *para, uint32_t seed); 00110 void mtgp32_init_state(uint32_t array[], 00111 const mtgp32_params_fast_t *para, uint32_t seed); 00112 int mtgp32_init_by_array(mtgp32_fast_t *mtgp32, 00113 const mtgp32_params_fast_t *para, 00114 uint32_t *array, int length); 00115 int mtgp32_init_by_str(mtgp32_fast_t *mtgp32, 00116 const mtgp32_params_fast_t *para, 00117 char *str); 00118 void mtgp32_free(mtgp32_fast_t *mtgp32); 00119 void mtgp32_print_idstring(const mtgp32_fast_t *mtgp32, FILE *fp); 00120 00121 inline static void mtgp32_do_recursion(uint32_t *r, uint32_t x1, 00122 uint32_t x2, uint32_t y, 00123 int sh1, int sh2, 00124 uint32_t mask, uint32_t tbl[16]); 00125 inline static void mtgp32_next_state(mtgp32_fast_t *mtgp32); 00126 inline static uint32_t mtgp32_genrand_uint32(mtgp32_fast_t *mtgp32); 00127 inline static float mtgp32_genrand_close1_open2(mtgp32_fast_t *mtgp32); 00128 inline static float mtgp32_genrand_close_open(mtgp32_fast_t *mtgp32); 00129 inline static float mtgp32_genrand_open_close(mtgp32_fast_t *mtgp32); 00130 inline static float mtgp32_genrand_open_open(mtgp32_fast_t *mtgp32); 00131 00132 /* 00133 * PRIVATE INLINE FUNCTIONS 00134 */ 00149 inline static void mtgp32_do_recursion(uint32_t *r, uint32_t x1, 00150 uint32_t x2, uint32_t y, 00151 int sh1, int sh2, 00152 uint32_t mask, uint32_t tbl[16]) { 00153 uint32_t x; 00154 00155 x = (x1 & mask) ^ x2; 00156 x ^= x << sh1; 00157 y = x ^ (y >> sh2); 00158 *r = y ^ tbl[y & 0x0f]; 00159 } 00160 00165 inline static void mtgp32_next_state(mtgp32_fast_t *mtgp32) { 00166 uint32_t *array = mtgp32->status->array; 00167 int idx; 00168 int pos = mtgp32->params.pos; 00169 int large_size = mtgp32->status->large_size; 00170 uint32_t large_mask = mtgp32->status->large_mask; 00171 int size = mtgp32->status->size; 00172 00173 mtgp32->status->idx = (mtgp32->status->idx + 1) & large_mask; 00174 idx = mtgp32->status->idx; 00175 mtgp32_do_recursion(&(array[idx]), 00176 array[(idx - size + large_size) & large_mask], 00177 array[(idx - size + large_size + 1) & large_mask], 00178 array[(idx + pos - size + large_size) & large_mask], 00179 mtgp32->params.sh1, 00180 mtgp32->params.sh2, 00181 mtgp32->params.mask, 00182 mtgp32->params.tbl); 00183 } 00184 00192 inline static uint32_t mtgp32_temper(const uint32_t tmp_tbl[16], 00193 uint32_t r, uint32_t t) { 00194 t ^= t >> 16; 00195 t ^= t >> 8; 00196 r ^= tmp_tbl[t & 0x0f]; 00197 return r; 00198 } 00199 00207 inline static float mtgp32_temper_float(const uint32_t flt_tmp_tbl[16], 00208 uint32_t r, uint32_t t) { 00209 union { 00210 uint32_t u; 00211 float f; 00212 } x; 00213 t ^= t >> 16; 00214 t ^= t >> 8; 00215 r = r >> 9; 00216 x.u = r ^ flt_tmp_tbl[t & 0x0f]; 00217 return x.f; 00218 } 00219 00228 inline static float mtgp32_temper_float_open(const uint32_t flt_tmp_tbl[16], 00229 uint32_t r, uint32_t t) { 00230 union { 00231 uint32_t u; 00232 float f; 00233 } x; 00234 t ^= t >> 16; 00235 t ^= t >> 8; 00236 r = r >> 9; 00237 x.u = (r ^ flt_tmp_tbl[t & 0x0f]) | 1; 00238 return x.f; 00239 } 00240 00241 /* 00242 * PUBLIC INLINE FUNCTIONS 00243 */ 00252 inline static uint32_t mtgp32_genrand_uint32(mtgp32_fast_t *mtgp32) { 00253 int idx; 00254 uint32_t *tmp_tbl = mtgp32->params.tmp_tbl; 00255 uint32_t *array = mtgp32->status->array; 00256 int pos = mtgp32->params.pos; 00257 int large_size = mtgp32->status->large_size; 00258 int size = mtgp32->status->size; 00259 uint32_t large_mask = mtgp32->status->large_mask; 00260 00261 mtgp32_next_state(mtgp32); 00262 idx = mtgp32->status->idx; 00263 return mtgp32_temper(tmp_tbl, 00264 array[idx], 00265 array[(idx + pos - 1 - size + large_size) 00266 & large_mask]); 00267 } 00268 00278 inline static float mtgp32_genrand_close1_open2(mtgp32_fast_t *mtgp32) { 00279 int idx; 00280 uint32_t *flt_tmp_tbl = mtgp32->params.flt_tmp_tbl; 00281 uint32_t *array = mtgp32->status->array; 00282 int pos = mtgp32->params.pos; 00283 int large_size = mtgp32->status->large_size; 00284 int size = mtgp32->status->size; 00285 uint32_t large_mask = mtgp32->status->large_mask; 00286 00287 mtgp32_next_state(mtgp32); 00288 idx = mtgp32->status->idx; 00289 return mtgp32_temper_float(flt_tmp_tbl, 00290 array[idx], 00291 array[(idx + pos - 1 - size + large_size) 00292 & large_mask]); 00293 } 00294 00304 inline static float mtgp32_genrand_close_open(mtgp32_fast_t *mtgp32) { 00305 return mtgp32_genrand_close1_open2(mtgp32) - 1.0F; 00306 } 00307 00317 inline static float mtgp32_genrand_open_close(mtgp32_fast_t *mtgp32) { 00318 return 2.0F - mtgp32_genrand_close1_open2(mtgp32); 00319 } 00320 00330 inline static float mtgp32_genrand_open_open(mtgp32_fast_t *mtgp32) { 00331 float r; 00332 int idx; 00333 uint32_t *flt_tmp_tbl = mtgp32->params.flt_tmp_tbl; 00334 uint32_t *array = mtgp32->status->array; 00335 int pos = mtgp32->params.pos; 00336 int large_size = mtgp32->status->large_size; 00337 int size = mtgp32->status->size; 00338 uint32_t large_mask = mtgp32->status->large_mask; 00339 mtgp32_next_state(mtgp32); 00340 idx = mtgp32->status->idx; 00341 r = mtgp32_temper_float_open(flt_tmp_tbl, 00342 array[idx], 00343 array[(idx + pos - 1 - size + large_size) 00344 & large_mask]); 00345 return r - 1.0F; 00346 } 00347 #if defined(__cplusplus) 00348 } 00349 #endif 00350 00351 #endif