mbed I/F binding for mruby
Dependents: mruby_mbed_web mirb_mbed
mbed-mruby
How to use
Class
mrbgems/mruby-random/mt19937ar.c@1:8ccd1d494a4b, 2015-04-13 (annotated)
- Committer:
- mzta
- Date:
- Mon Apr 13 05:20:15 2015 +0000
- Revision:
- 1:8ccd1d494a4b
- Parent:
- 0:158c61bb030f
- code refactoring.; - add SPI, SPISlave, I2C class to mruby-mbed (Incomplete).
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mzta | 0:158c61bb030f | 1 | /* |
mzta | 0:158c61bb030f | 2 | ** mt19937ar.c - MT Random functions |
mzta | 0:158c61bb030f | 3 | ** |
mzta | 0:158c61bb030f | 4 | ** See Copyright Notice in mruby.h |
mzta | 0:158c61bb030f | 5 | */ |
mzta | 0:158c61bb030f | 6 | |
mzta | 0:158c61bb030f | 7 | #include "mruby.h" |
mzta | 0:158c61bb030f | 8 | #include "mt19937ar.h" |
mzta | 0:158c61bb030f | 9 | |
mzta | 0:158c61bb030f | 10 | /* Period parameters */ |
mzta | 0:158c61bb030f | 11 | /* #define N 624 */ |
mzta | 0:158c61bb030f | 12 | #define M 397 |
mzta | 0:158c61bb030f | 13 | #define MATRIX_A 0x9908b0dfUL /* constant vector a */ |
mzta | 0:158c61bb030f | 14 | #define UPPER_MASK 0x80000000UL /* most significant w-r bits */ |
mzta | 0:158c61bb030f | 15 | #define LOWER_MASK 0x7fffffffUL /* least significant r bits */ |
mzta | 0:158c61bb030f | 16 | |
mzta | 0:158c61bb030f | 17 | #if 0 /* dead_code */ |
mzta | 0:158c61bb030f | 18 | static unsigned long mt[N]; /* the array for the state vector */ |
mzta | 0:158c61bb030f | 19 | static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */ |
mzta | 0:158c61bb030f | 20 | #endif /* dead_code */ |
mzta | 0:158c61bb030f | 21 | |
mzta | 0:158c61bb030f | 22 | void mrb_random_init_genrand(mt_state *t, unsigned long s) |
mzta | 0:158c61bb030f | 23 | { |
mzta | 0:158c61bb030f | 24 | t->mt[0]= s & 0xffffffffUL; |
mzta | 0:158c61bb030f | 25 | for (t->mti=1; t->mti<N; t->mti++) { |
mzta | 0:158c61bb030f | 26 | t->mt[t->mti] = |
mzta | 0:158c61bb030f | 27 | (1812433253UL * (t->mt[t->mti-1] ^ (t->mt[t->mti-1] >> 30)) + t->mti); |
mzta | 0:158c61bb030f | 28 | t->mt[t->mti] &= 0xffffffffUL; |
mzta | 0:158c61bb030f | 29 | } |
mzta | 0:158c61bb030f | 30 | } |
mzta | 0:158c61bb030f | 31 | |
mzta | 0:158c61bb030f | 32 | unsigned long mrb_random_genrand_int32(mt_state *t) |
mzta | 0:158c61bb030f | 33 | { |
mzta | 0:158c61bb030f | 34 | unsigned long y; |
mzta | 0:158c61bb030f | 35 | static const unsigned long mag01[2]={0x0UL, MATRIX_A}; |
mzta | 0:158c61bb030f | 36 | /* mag01[x] = x * MATRIX_A for x=0,1 */ |
mzta | 0:158c61bb030f | 37 | |
mzta | 0:158c61bb030f | 38 | if (t->mti >= N) { /* generate N words at one time */ |
mzta | 0:158c61bb030f | 39 | int kk; |
mzta | 0:158c61bb030f | 40 | |
mzta | 0:158c61bb030f | 41 | if (t->mti == N+1) /* if init_genrand() has not been called, */ |
mzta | 0:158c61bb030f | 42 | mrb_random_init_genrand(t, 5489UL); /* a default initial seed is used */ |
mzta | 0:158c61bb030f | 43 | |
mzta | 0:158c61bb030f | 44 | for (kk=0;kk<N-M;kk++) { |
mzta | 0:158c61bb030f | 45 | y = (t->mt[kk]&UPPER_MASK)|(t->mt[kk+1]&LOWER_MASK); |
mzta | 0:158c61bb030f | 46 | t->mt[kk] = t->mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL]; |
mzta | 0:158c61bb030f | 47 | } |
mzta | 0:158c61bb030f | 48 | for (;kk<N-1;kk++) { |
mzta | 0:158c61bb030f | 49 | y = (t->mt[kk]&UPPER_MASK)|(t->mt[kk+1]&LOWER_MASK); |
mzta | 0:158c61bb030f | 50 | t->mt[kk] = t->mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL]; |
mzta | 0:158c61bb030f | 51 | } |
mzta | 0:158c61bb030f | 52 | y = (t->mt[N-1]&UPPER_MASK)|(t->mt[0]&LOWER_MASK); |
mzta | 0:158c61bb030f | 53 | t->mt[N-1] = t->mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL]; |
mzta | 0:158c61bb030f | 54 | |
mzta | 0:158c61bb030f | 55 | t->mti = 0; |
mzta | 0:158c61bb030f | 56 | } |
mzta | 0:158c61bb030f | 57 | |
mzta | 0:158c61bb030f | 58 | y = t->mt[t->mti++]; |
mzta | 0:158c61bb030f | 59 | |
mzta | 0:158c61bb030f | 60 | /* Tempering */ |
mzta | 0:158c61bb030f | 61 | y ^= (y >> 11); |
mzta | 0:158c61bb030f | 62 | y ^= (y << 7) & 0x9d2c5680UL; |
mzta | 0:158c61bb030f | 63 | y ^= (y << 15) & 0xefc60000UL; |
mzta | 0:158c61bb030f | 64 | y ^= (y >> 18); |
mzta | 0:158c61bb030f | 65 | |
mzta | 0:158c61bb030f | 66 | t->gen.int_ = y; |
mzta | 0:158c61bb030f | 67 | |
mzta | 0:158c61bb030f | 68 | return y; |
mzta | 0:158c61bb030f | 69 | } |
mzta | 0:158c61bb030f | 70 | |
mzta | 0:158c61bb030f | 71 | double mrb_random_genrand_real1(mt_state *t) |
mzta | 0:158c61bb030f | 72 | { |
mzta | 0:158c61bb030f | 73 | mrb_random_genrand_int32(t); |
mzta | 0:158c61bb030f | 74 | t->gen.double_ = t->gen.int_*(1.0/4294967295.0); |
mzta | 0:158c61bb030f | 75 | return t->gen.double_; |
mzta | 0:158c61bb030f | 76 | /* divided by 2^32-1 */ |
mzta | 0:158c61bb030f | 77 | } |
mzta | 0:158c61bb030f | 78 | |
mzta | 0:158c61bb030f | 79 | #if 0 /* dead_code */ |
mzta | 0:158c61bb030f | 80 | /* initializes mt[N] with a seed */ |
mzta | 0:158c61bb030f | 81 | void init_genrand(unsigned long s) |
mzta | 0:158c61bb030f | 82 | { |
mzta | 0:158c61bb030f | 83 | mt[0]= s & 0xffffffffUL; |
mzta | 0:158c61bb030f | 84 | for (mti=1; mti<N; mti++) { |
mzta | 0:158c61bb030f | 85 | mt[mti] = |
mzta | 0:158c61bb030f | 86 | (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti); |
mzta | 0:158c61bb030f | 87 | /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ |
mzta | 0:158c61bb030f | 88 | /* In the previous versions, MSBs of the seed affect */ |
mzta | 0:158c61bb030f | 89 | /* only MSBs of the array mt[]. */ |
mzta | 0:158c61bb030f | 90 | /* 2002/01/09 modified by Makoto Matsumoto */ |
mzta | 0:158c61bb030f | 91 | mt[mti] &= 0xffffffffUL; |
mzta | 0:158c61bb030f | 92 | /* for >32 bit machines */ |
mzta | 0:158c61bb030f | 93 | } |
mzta | 0:158c61bb030f | 94 | } |
mzta | 0:158c61bb030f | 95 | |
mzta | 0:158c61bb030f | 96 | /* initialize by an array with array-length */ |
mzta | 0:158c61bb030f | 97 | /* init_key is the array for initializing keys */ |
mzta | 0:158c61bb030f | 98 | /* key_length is its length */ |
mzta | 0:158c61bb030f | 99 | /* slight change for C++, 2004/2/26 */ |
mzta | 0:158c61bb030f | 100 | void init_by_array(unsigned long init_key[], int key_length) |
mzta | 0:158c61bb030f | 101 | { |
mzta | 0:158c61bb030f | 102 | int i, j, k; |
mzta | 0:158c61bb030f | 103 | init_genrand(19650218UL); |
mzta | 0:158c61bb030f | 104 | i=1; j=0; |
mzta | 0:158c61bb030f | 105 | k = (N>key_length ? N : key_length); |
mzta | 0:158c61bb030f | 106 | for (; k; k--) { |
mzta | 0:158c61bb030f | 107 | mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL)) |
mzta | 0:158c61bb030f | 108 | + init_key[j] + j; /* non linear */ |
mzta | 0:158c61bb030f | 109 | mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ |
mzta | 0:158c61bb030f | 110 | i++; j++; |
mzta | 0:158c61bb030f | 111 | if (i>=N) { mt[0] = mt[N-1]; i=1; } |
mzta | 0:158c61bb030f | 112 | if (j>=key_length) j=0; |
mzta | 0:158c61bb030f | 113 | } |
mzta | 0:158c61bb030f | 114 | for (k=N-1; k; k--) { |
mzta | 0:158c61bb030f | 115 | mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL)) |
mzta | 0:158c61bb030f | 116 | - i; /* non linear */ |
mzta | 0:158c61bb030f | 117 | mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ |
mzta | 0:158c61bb030f | 118 | i++; |
mzta | 0:158c61bb030f | 119 | if (i>=N) { mt[0] = mt[N-1]; i=1; } |
mzta | 0:158c61bb030f | 120 | } |
mzta | 0:158c61bb030f | 121 | |
mzta | 0:158c61bb030f | 122 | mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */ |
mzta | 0:158c61bb030f | 123 | } |
mzta | 0:158c61bb030f | 124 | |
mzta | 0:158c61bb030f | 125 | /* generates a random number on [0,0xffffffff]-interval */ |
mzta | 0:158c61bb030f | 126 | unsigned long genrand_int32(void) |
mzta | 0:158c61bb030f | 127 | { |
mzta | 0:158c61bb030f | 128 | unsigned long y; |
mzta | 0:158c61bb030f | 129 | static const unsigned long mag01[2]={0x0UL, MATRIX_A}; |
mzta | 0:158c61bb030f | 130 | /* mag01[x] = x * MATRIX_A for x=0,1 */ |
mzta | 0:158c61bb030f | 131 | |
mzta | 0:158c61bb030f | 132 | if (mti >= N) { /* generate N words at one time */ |
mzta | 0:158c61bb030f | 133 | int kk; |
mzta | 0:158c61bb030f | 134 | |
mzta | 0:158c61bb030f | 135 | if (mti == N+1) /* if init_genrand() has not been called, */ |
mzta | 0:158c61bb030f | 136 | init_genrand(5489UL); /* a default initial seed is used */ |
mzta | 0:158c61bb030f | 137 | |
mzta | 0:158c61bb030f | 138 | for (kk=0;kk<N-M;kk++) { |
mzta | 0:158c61bb030f | 139 | y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK); |
mzta | 0:158c61bb030f | 140 | mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL]; |
mzta | 0:158c61bb030f | 141 | } |
mzta | 0:158c61bb030f | 142 | for (;kk<N-1;kk++) { |
mzta | 0:158c61bb030f | 143 | y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK); |
mzta | 0:158c61bb030f | 144 | mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL]; |
mzta | 0:158c61bb030f | 145 | } |
mzta | 0:158c61bb030f | 146 | y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); |
mzta | 0:158c61bb030f | 147 | mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL]; |
mzta | 0:158c61bb030f | 148 | |
mzta | 0:158c61bb030f | 149 | mti = 0; |
mzta | 0:158c61bb030f | 150 | } |
mzta | 0:158c61bb030f | 151 | |
mzta | 0:158c61bb030f | 152 | y = mt[mti++]; |
mzta | 0:158c61bb030f | 153 | |
mzta | 0:158c61bb030f | 154 | /* Tempering */ |
mzta | 0:158c61bb030f | 155 | y ^= (y >> 11); |
mzta | 0:158c61bb030f | 156 | y ^= (y << 7) & 0x9d2c5680UL; |
mzta | 0:158c61bb030f | 157 | y ^= (y << 15) & 0xefc60000UL; |
mzta | 0:158c61bb030f | 158 | y ^= (y >> 18); |
mzta | 0:158c61bb030f | 159 | |
mzta | 0:158c61bb030f | 160 | return y; |
mzta | 0:158c61bb030f | 161 | } |
mzta | 0:158c61bb030f | 162 | |
mzta | 0:158c61bb030f | 163 | /* generates a random number on [0,0x7fffffff]-interval */ |
mzta | 0:158c61bb030f | 164 | long genrand_int31(void) |
mzta | 0:158c61bb030f | 165 | { |
mzta | 0:158c61bb030f | 166 | return (long)(genrand_int32()>>1); |
mzta | 0:158c61bb030f | 167 | } |
mzta | 0:158c61bb030f | 168 | |
mzta | 0:158c61bb030f | 169 | /* generates a random number on [0,1]-real-interval */ |
mzta | 0:158c61bb030f | 170 | double genrand_real1(void) |
mzta | 0:158c61bb030f | 171 | { |
mzta | 0:158c61bb030f | 172 | return genrand_int32()*(1.0/4294967295.0); |
mzta | 0:158c61bb030f | 173 | /* divided by 2^32-1 */ |
mzta | 0:158c61bb030f | 174 | } |
mzta | 0:158c61bb030f | 175 | |
mzta | 0:158c61bb030f | 176 | /* generates a random number on [0,1)-real-interval */ |
mzta | 0:158c61bb030f | 177 | double genrand_real2(void) |
mzta | 0:158c61bb030f | 178 | { |
mzta | 0:158c61bb030f | 179 | return genrand_int32()*(1.0/4294967296.0); |
mzta | 0:158c61bb030f | 180 | /* divided by 2^32 */ |
mzta | 0:158c61bb030f | 181 | } |
mzta | 0:158c61bb030f | 182 | |
mzta | 0:158c61bb030f | 183 | /* generates a random number on (0,1)-real-interval */ |
mzta | 0:158c61bb030f | 184 | double genrand_real3(void) |
mzta | 0:158c61bb030f | 185 | { |
mzta | 0:158c61bb030f | 186 | return (((double)genrand_int32()) + 0.5)*(1.0/4294967296.0); |
mzta | 0:158c61bb030f | 187 | /* divided by 2^32 */ |
mzta | 0:158c61bb030f | 188 | } |
mzta | 0:158c61bb030f | 189 | |
mzta | 0:158c61bb030f | 190 | /* generates a random number on [0,1) with 53-bit resolution*/ |
mzta | 0:158c61bb030f | 191 | double genrand_res53(void) |
mzta | 0:158c61bb030f | 192 | { |
mzta | 0:158c61bb030f | 193 | unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6; |
mzta | 0:158c61bb030f | 194 | return(a*67108864.0+b)*(1.0/9007199254740992.0); |
mzta | 0:158c61bb030f | 195 | } |
mzta | 0:158c61bb030f | 196 | /* These real versions are due to Isaku Wada, 2002/01/09 added */ |
mzta | 0:158c61bb030f | 197 | #endif /* dead_code */ |
mzta | 0:158c61bb030f | 198 |