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