SFMT  1.4
SFMT.h
Go to the documentation of this file.
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