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
00043 typedef struct MTGP32_PARAMS_FAST_T {
00044 int mexp;
00045 int pos;
00046 int sh1;
00047 int sh2;
00048 uint32_t tbl[16];
00049 uint32_t tmp_tbl[16];
00050 uint32_t flt_tmp_tbl[16];
00052 uint32_t mask;
00053 unsigned char poly_sha1[21];
00054 } mtgp32_params_fast_t;
00055
00071 typedef struct MTGP32_STATUS_FAST_T {
00072 int idx;
00073 int size;
00074 int large_size;
00075 int large_mask;
00076 uint32_t array[];
00077 } mtgp32_status_fast_t;
00078
00083 typedef struct MTGP32_FAST_T {
00084 mtgp32_params_fast_t params;
00085 mtgp32_status_fast_t *status;
00086 } mtgp32_fast_t;
00087
00092 extern mtgp32_params_fast_t mtgp32_params_fast_11213[128];
00097 extern mtgp32_params_fast_t mtgp32_params_fast_23209[128];
00102 extern mtgp32_params_fast_t mtgp32_params_fast_44497[128];
00103
00104 int mtgp32_init(mtgp32_fast_t *mtgp32,
00105 const mtgp32_params_fast_t *para, uint32_t seed);
00106 void mtgp32_init_state(uint32_t array[],
00107 const mtgp32_params_fast_t *para, uint32_t seed);
00108 int mtgp32_init_by_array(mtgp32_fast_t *mtgp32,
00109 const mtgp32_params_fast_t *para,
00110 uint32_t *array, int length);
00111 int mtgp32_init_by_str(mtgp32_fast_t *mtgp32,
00112 const mtgp32_params_fast_t *para,
00113 char *str);
00114 void mtgp32_free(mtgp32_fast_t *mtgp32);
00115 void mtgp32_print_idstring(const mtgp32_fast_t *mtgp32, FILE *fp);
00116
00117 inline static void mtgp32_do_recursion(uint32_t *r, uint32_t x1,
00118 uint32_t x2, uint32_t y,
00119 int sh1, int sh2,
00120 uint32_t mask, uint32_t tbl[16]);
00121 inline static void mtgp32_next_state(mtgp32_fast_t *mtgp32);
00122 inline static uint32_t mtgp32_genrand_uint32(mtgp32_fast_t *mtgp32);
00123 inline static float mtgp32_genrand_close1_open2(mtgp32_fast_t *mtgp32);
00124 inline static float mtgp32_genrand_close_open(mtgp32_fast_t *mtgp32);
00125 inline static float mtgp32_genrand_open_close(mtgp32_fast_t *mtgp32);
00126 inline static float mtgp32_genrand_open_open(mtgp32_fast_t *mtgp32);
00127
00128
00129
00130
00145 inline static void mtgp32_do_recursion(uint32_t *r, uint32_t x1,
00146 uint32_t x2, uint32_t y,
00147 int sh1, int sh2,
00148 uint32_t mask, uint32_t tbl[16]) {
00149 uint32_t x;
00150
00151 x = (x1 & mask) ^ x2;
00152 x ^= x << sh1;
00153 y = x ^ (y >> sh2);
00154 *r = y ^ tbl[y & 0x0f];
00155 }
00156
00161 inline static void mtgp32_next_state(mtgp32_fast_t *mtgp32) {
00162 uint32_t *array = mtgp32->status->array;
00163 int idx;
00164 int pos = mtgp32->params.pos;
00165 int large_size = mtgp32->status->large_size;
00166 uint32_t large_mask = mtgp32->status->large_mask;
00167 int size = mtgp32->status->size;
00168
00169 mtgp32->status->idx = (mtgp32->status->idx + 1) & large_mask;
00170 idx = mtgp32->status->idx;
00171 mtgp32_do_recursion(&(array[idx]),
00172 array[(idx - size + large_size) & large_mask],
00173 array[(idx - size + large_size + 1) & large_mask],
00174 array[(idx + pos - size + large_size) & large_mask],
00175 mtgp32->params.sh1,
00176 mtgp32->params.sh2,
00177 mtgp32->params.mask,
00178 mtgp32->params.tbl);
00179 }
00180
00188 inline static uint32_t mtgp32_temper(const uint32_t tmp_tbl[16],
00189 uint32_t r, uint32_t t) {
00190 t ^= t >> 16;
00191 t ^= t >> 8;
00192 r ^= tmp_tbl[t & 0x0f];
00193 return r;
00194 }
00195
00203 inline static float mtgp32_temper_float(const uint32_t flt_tmp_tbl[16],
00204 uint32_t r, uint32_t t) {
00205 union {
00206 uint32_t u;
00207 float f;
00208 } x;
00209 t ^= t >> 16;
00210 t ^= t >> 8;
00211 r = r >> 9;
00212 x.u = r ^ flt_tmp_tbl[t & 0x0f];
00213 return x.f;
00214 }
00215
00224 inline static float mtgp32_temper_float_open(const uint32_t flt_tmp_tbl[16],
00225 uint32_t r, uint32_t t) {
00226 union {
00227 uint32_t u;
00228 float f;
00229 } x;
00230 t ^= t >> 16;
00231 t ^= t >> 8;
00232 r = r >> 9;
00233 x.u = (r ^ flt_tmp_tbl[t & 0x0f]) | 1;
00234 return x.f;
00235 }
00236
00237
00238
00239
00248 inline static uint32_t mtgp32_genrand_uint32(mtgp32_fast_t *mtgp32) {
00249 int idx;
00250 uint32_t *tmp_tbl = mtgp32->params.tmp_tbl;
00251 uint32_t *array = mtgp32->status->array;
00252 int pos = mtgp32->params.pos;
00253 int large_size = mtgp32->status->large_size;
00254 int size = mtgp32->status->size;
00255 uint32_t large_mask = mtgp32->status->large_mask;
00256
00257 mtgp32_next_state(mtgp32);
00258 idx = mtgp32->status->idx;
00259 return mtgp32_temper(tmp_tbl,
00260 array[idx],
00261 array[(idx + pos - 1 - size + large_size)
00262 & large_mask]);
00263 }
00264
00274 inline static float mtgp32_genrand_close1_open2(mtgp32_fast_t *mtgp32) {
00275 int idx;
00276 uint32_t *flt_tmp_tbl = mtgp32->params.flt_tmp_tbl;
00277 uint32_t *array = mtgp32->status->array;
00278 int pos = mtgp32->params.pos;
00279 int large_size = mtgp32->status->large_size;
00280 int size = mtgp32->status->size;
00281 uint32_t large_mask = mtgp32->status->large_mask;
00282
00283 mtgp32_next_state(mtgp32);
00284 idx = mtgp32->status->idx;
00285 return mtgp32_temper_float(flt_tmp_tbl,
00286 array[idx],
00287 array[(idx + pos - 1 - size + large_size)
00288 & large_mask]);
00289 }
00290
00300 inline static float mtgp32_genrand_close_open(mtgp32_fast_t *mtgp32) {
00301 return mtgp32_genrand_close1_open2(mtgp32) - 1.0F;
00302 }
00303
00313 inline static float mtgp32_genrand_open_close(mtgp32_fast_t *mtgp32) {
00314 return 2.0F - mtgp32_genrand_close1_open2(mtgp32);
00315 }
00316
00326 inline static float mtgp32_genrand_open_open(mtgp32_fast_t *mtgp32) {
00327 float r;
00328 int idx;
00329 uint32_t *flt_tmp_tbl = mtgp32->params.flt_tmp_tbl;
00330 uint32_t *array = mtgp32->status->array;
00331 int pos = mtgp32->params.pos;
00332 int large_size = mtgp32->status->large_size;
00333 int size = mtgp32->status->size;
00334 uint32_t large_mask = mtgp32->status->large_mask;
00335 mtgp32_next_state(mtgp32);
00336 idx = mtgp32->status->idx;
00337 r = mtgp32_temper_float_open(flt_tmp_tbl,
00338 array[idx],
00339 array[(idx + pos - 1 - size + large_size)
00340 & large_mask]);
00341 return r - 1.0F;
00342 }
00343
00344 #endif