SFMT
1.4
|
00001 #pragma once 00002 00035 #ifndef SFMTST_H 00036 #define SFMTST_H 00037 #if defined(__cplusplus) 00038 extern "C" { 00039 #endif 00040 00041 #include <stdio.h> 00042 #include <assert.h> 00043 00044 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) 00045 #include <inttypes.h> 00046 #elif defined(_MSC_VER) || defined(__BORLANDC__) 00047 typedef unsigned int uint32_t; 00048 typedef unsigned __int64 uint64_t; 00049 #define inline __inline 00050 #else 00051 #include <inttypes.h> 00052 #if defined(__GNUC__) 00053 #define inline __inline__ 00054 #endif 00055 #endif 00056 00057 #ifndef PRIu64 00058 #if defined(_MSC_VER) || defined(__BORLANDC__) 00059 #define PRIu64 "I64u" 00060 #define PRIx64 "I64x" 00061 #else 00062 #define PRIu64 "llu" 00063 #define PRIx64 "llx" 00064 #endif 00065 #endif 00066 00067 #include "SFMT-params.h" 00068 00069 /*------------------------------------------ 00070 128-bit SIMD like data type for standard C 00071 ------------------------------------------*/ 00072 #if defined(HAVE_ALTIVEC) 00073 #if !defined(__APPLE__) 00074 #include <altivec.h> 00075 #endif 00076 00077 union W128_T { 00078 vector unsigned int s; 00079 uint32_t u[4]; 00080 uint64_t u64[2]; 00081 }; 00082 #elif defined(HAVE_SSE2) 00083 #include <emmintrin.h> 00084 00086 union W128_T { 00087 uint32_t u[4]; 00088 uint64_t u64[2]; 00089 __m128i si; 00090 }; 00091 #else 00092 00093 union W128_T { 00094 uint32_t u[4]; 00095 uint64_t u64[2]; 00096 }; 00097 #endif 00098 00100 typedef union W128_T w128_t; 00101 00105 struct SFMT_T { 00107 w128_t state[SFMT_N]; 00109 int idx; 00110 }; 00111 00112 typedef struct SFMT_T sfmt_t; 00113 00114 void sfmt_fill_array32(sfmt_t * sfmt, uint32_t * array, int size); 00115 void sfmt_fill_array64(sfmt_t * sfmt, uint64_t * array, int size); 00116 void sfmt_init_gen_rand(sfmt_t * sfmt, uint32_t seed); 00117 void sfmt_init_by_array(sfmt_t * sfmt, uint32_t * init_key, int key_length); 00118 const char * sfmt_get_idstring(sfmt_t * sfmt); 00119 int sfmt_get_min_array_size32(sfmt_t * sfmt); 00120 int sfmt_get_min_array_size64(sfmt_t * sfmt); 00121 void sfmt_gen_rand_all(sfmt_t * sfmt); 00122 00123 #ifndef ONLY64 00124 00130 inline static uint32_t sfmt_genrand_uint32(sfmt_t * sfmt) { 00131 uint32_t r; 00132 uint32_t * psfmt32 = &sfmt->state[0].u[0]; 00133 00134 if (sfmt->idx >= SFMT_N32) { 00135 sfmt_gen_rand_all(sfmt); 00136 sfmt->idx = 0; 00137 } 00138 r = psfmt32[sfmt->idx++]; 00139 return r; 00140 } 00141 #endif 00142 00150 inline static uint64_t sfmt_genrand_uint64(sfmt_t * sfmt) { 00151 #if defined(BIG_ENDIAN64) && !defined(ONLY64) 00152 uint32_t * psfmt32 = &sfmt->state[0].u[0]; 00153 uint32_t r1, r2; 00154 #else 00155 uint64_t r; 00156 #endif 00157 uint64_t * psfmt64 = &sfmt->state[0].u64[0]; 00158 assert(sfmt->idx % 2 == 0); 00159 00160 if (sfmt->idx >= SFMT_N32) { 00161 sfmt_gen_rand_all(sfmt); 00162 sfmt->idx = 0; 00163 } 00164 #if defined(BIG_ENDIAN64) && !defined(ONLY64) 00165 r1 = psfmt32[sfmt->idx]; 00166 r2 = psfmt32[sfmt->idx + 1]; 00167 sfmt->idx += 2; 00168 return ((uint64_t)r2 << 32) | r1; 00169 #else 00170 r = psfmt64[sfmt->idx / 2]; 00171 sfmt->idx += 2; 00172 return r; 00173 #endif 00174 } 00175 00176 /* ================================================= 00177 The following real versions are due to Isaku Wada 00178 ================================================= */ 00184 inline static double sfmt_to_real1(uint32_t v) 00185 { 00186 return v * (1.0/4294967295.0); 00187 /* divided by 2^32-1 */ 00188 } 00189 00195 inline static double sfmt_genrand_real1(sfmt_t * sfmt) 00196 { 00197 return sfmt_to_real1(sfmt_genrand_uint32(sfmt)); 00198 } 00199 00205 inline static double sfmt_to_real2(uint32_t v) 00206 { 00207 return v * (1.0/4294967296.0); 00208 /* divided by 2^32 */ 00209 } 00210 00216 inline static double sfmt_genrand_real2(sfmt_t * sfmt) 00217 { 00218 return sfmt_to_real2(sfmt_genrand_uint32(sfmt)); 00219 } 00220 00226 inline static double sfmt_to_real3(uint32_t v) 00227 { 00228 return (((double)v) + 0.5)*(1.0/4294967296.0); 00229 /* divided by 2^32 */ 00230 } 00231 00237 inline static double sfmt_genrand_real3(sfmt_t * sfmt) 00238 { 00239 return sfmt_to_real3(sfmt_genrand_uint32(sfmt)); 00240 } 00241 00248 inline static double sfmt_to_res53(uint64_t v) 00249 { 00250 return v * (1.0/18446744073709551616.0L); 00251 } 00252 00258 inline static double sfmt_genrand_res53(sfmt_t * sfmt) 00259 { 00260 return sfmt_to_res53(sfmt_genrand_uint64(sfmt)); 00261 } 00262 00263 00264 /* ================================================= 00265 The following function are added by Saito. 00266 ================================================= */ 00271 inline static double sfmt_to_res53_mix(uint32_t x, uint32_t y) 00272 { 00273 return sfmt_to_res53(x | ((uint64_t)y << 32)); 00274 } 00275 00282 inline static double sfmt_genrand_res53_mix(sfmt_t * sfmt) 00283 { 00284 uint32_t x, y; 00285 00286 x = sfmt_genrand_uint32(sfmt); 00287 y = sfmt_genrand_uint32(sfmt); 00288 return sfmt_to_res53_mix(x, y); 00289 } 00290 00291 #if defined(__cplusplus) 00292 } 00293 #endif 00294 00295 #endif