mbed I/F binding for mruby

Dependents:   mruby_mbed_web mirb_mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mt19937ar.c Source File

mt19937ar.c

00001 /*
00002 ** mt19937ar.c - MT Random functions
00003 **
00004 ** See Copyright Notice in mruby.h
00005 */
00006 
00007 #include "mruby.h"
00008 #include "mt19937ar.h"
00009 
00010 /* Period parameters */
00011 /* #define N 624 */
00012 #define M 397
00013 #define MATRIX_A 0x9908b0dfUL   /* constant vector a */
00014 #define UPPER_MASK 0x80000000UL /* most significant w-r bits */
00015 #define LOWER_MASK 0x7fffffffUL /* least significant r bits */
00016 
00017 #if 0 /* dead_code */
00018 static unsigned long mt[N]; /* the array for the state vector  */
00019 static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */
00020 #endif /* dead_code */
00021 
00022 void mrb_random_init_genrand(mt_state *t, unsigned long s)
00023 {
00024     t->mt[0]= s & 0xffffffffUL;
00025     for (t->mti=1; t->mti<N; t->mti++) {
00026         t->mt[t->mti] =
00027         (1812433253UL * (t->mt[t->mti-1] ^ (t->mt[t->mti-1] >> 30)) + t->mti);
00028         t->mt[t->mti] &= 0xffffffffUL;
00029     }
00030 }
00031 
00032 unsigned long mrb_random_genrand_int32(mt_state *t)
00033 {
00034     unsigned long y;
00035     static const unsigned long mag01[2]={0x0UL, MATRIX_A};
00036     /* mag01[x] = x * MATRIX_A  for x=0,1 */
00037 
00038     if (t->mti >= N) { /* generate N words at one time */
00039         int kk;
00040 
00041         if (t->mti == N+1)   /* if init_genrand() has not been called, */
00042             mrb_random_init_genrand(t, 5489UL); /* a default initial seed is used */
00043 
00044         for (kk=0;kk<N-M;kk++) {
00045             y = (t->mt[kk]&UPPER_MASK)|(t->mt[kk+1]&LOWER_MASK);
00046             t->mt[kk] = t->mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL];
00047         }
00048         for (;kk<N-1;kk++) {
00049             y = (t->mt[kk]&UPPER_MASK)|(t->mt[kk+1]&LOWER_MASK);
00050             t->mt[kk] = t->mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
00051         }
00052         y = (t->mt[N-1]&UPPER_MASK)|(t->mt[0]&LOWER_MASK);
00053         t->mt[N-1] = t->mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];
00054 
00055         t->mti = 0;
00056     }
00057 
00058     y = t->mt[t->mti++];
00059 
00060     /* Tempering */
00061     y ^= (y >> 11);
00062     y ^= (y << 7) & 0x9d2c5680UL;
00063     y ^= (y << 15) & 0xefc60000UL;
00064     y ^= (y >> 18);
00065 
00066     t->gen.int_ = y;
00067 
00068     return y;
00069 }
00070 
00071 double mrb_random_genrand_real1(mt_state *t)
00072 {
00073     mrb_random_genrand_int32(t);
00074     t->gen.double_ =  t->gen.int_*(1.0/4294967295.0);
00075     return t->gen.double_;
00076     /* divided by 2^32-1 */
00077 }
00078 
00079 #if 0 /* dead_code */
00080 /* initializes mt[N] with a seed */
00081 void init_genrand(unsigned long s)
00082 {
00083     mt[0]= s & 0xffffffffUL;
00084     for (mti=1; mti<N; mti++) {
00085         mt[mti] =
00086         (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
00087         /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
00088         /* In the previous versions, MSBs of the seed affect   */
00089         /* only MSBs of the array mt[].                        */
00090         /* 2002/01/09 modified by Makoto Matsumoto             */
00091         mt[mti] &= 0xffffffffUL;
00092         /* for >32 bit machines */
00093     }
00094 }
00095 
00096 /* initialize by an array with array-length */
00097 /* init_key is the array for initializing keys */
00098 /* key_length is its length */
00099 /* slight change for C++, 2004/2/26 */
00100 void init_by_array(unsigned long init_key[], int key_length)
00101 {
00102     int i, j, k;
00103     init_genrand(19650218UL);
00104     i=1; j=0;
00105     k = (N>key_length ? N : key_length);
00106     for (; k; k--) {
00107         mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL))
00108           + init_key[j] + j; /* non linear */
00109         mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
00110         i++; j++;
00111         if (i>=N) { mt[0] = mt[N-1]; i=1; }
00112         if (j>=key_length) j=0;
00113     }
00114     for (k=N-1; k; k--) {
00115         mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL))
00116           - i; /* non linear */
00117         mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
00118         i++;
00119         if (i>=N) { mt[0] = mt[N-1]; i=1; }
00120     }
00121 
00122     mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */
00123 }
00124 
00125 /* generates a random number on [0,0xffffffff]-interval */
00126 unsigned long genrand_int32(void)
00127 {
00128     unsigned long y;
00129     static const unsigned long mag01[2]={0x0UL, MATRIX_A};
00130     /* mag01[x] = x * MATRIX_A  for x=0,1 */
00131 
00132     if (mti >= N) { /* generate N words at one time */
00133         int kk;
00134 
00135         if (mti == N+1)   /* if init_genrand() has not been called, */
00136             init_genrand(5489UL); /* a default initial seed is used */
00137 
00138         for (kk=0;kk<N-M;kk++) {
00139             y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
00140             mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL];
00141         }
00142         for (;kk<N-1;kk++) {
00143             y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
00144             mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
00145         }
00146         y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
00147         mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];
00148 
00149         mti = 0;
00150     }
00151 
00152     y = mt[mti++];
00153 
00154     /* Tempering */
00155     y ^= (y >> 11);
00156     y ^= (y << 7) & 0x9d2c5680UL;
00157     y ^= (y << 15) & 0xefc60000UL;
00158     y ^= (y >> 18);
00159 
00160     return y;
00161 }
00162 
00163 /* generates a random number on [0,0x7fffffff]-interval */
00164 long genrand_int31(void)
00165 {
00166     return (long)(genrand_int32()>>1);
00167 }
00168 
00169 /* generates a random number on [0,1]-real-interval */
00170 double genrand_real1(void)
00171 {
00172     return genrand_int32()*(1.0/4294967295.0);
00173     /* divided by 2^32-1 */
00174 }
00175 
00176 /* generates a random number on [0,1)-real-interval */
00177 double genrand_real2(void)
00178 {
00179     return genrand_int32()*(1.0/4294967296.0);
00180     /* divided by 2^32 */
00181 }
00182 
00183 /* generates a random number on (0,1)-real-interval */
00184 double genrand_real3(void)
00185 {
00186     return (((double)genrand_int32()) + 0.5)*(1.0/4294967296.0);
00187     /* divided by 2^32 */
00188 }
00189 
00190 /* generates a random number on [0,1) with 53-bit resolution*/
00191 double genrand_res53(void)
00192 {
00193     unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6;
00194     return(a*67108864.0+b)*(1.0/9007199254740992.0);
00195 }
00196 /* These real versions are due to Isaku Wada, 2002/01/09 added */
00197 #endif /* dead_code */
00198