MTGP 1.1
mtgp32-fast.h
Go to the documentation of this file.
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