Björn Stenberg | 529e166 | 2002-07-17 23:07:45 +0000 | [diff] [blame] | 1 | /* |
Jens Arnold | c05cd167 | 2006-01-20 01:21:26 +0000 | [diff] [blame] | 2 | A C-program for MT19937, with initialization improved 2002/2/10. |
| 3 | Coded by Takuji Nishimura and Makoto Matsumoto. |
| 4 | This is a faster version by taking Shawn Cokus's optimization, |
| 5 | Matthe Bellew's simplification. |
Björn Stenberg | 529e166 | 2002-07-17 23:07:45 +0000 | [diff] [blame] | 6 | |
Jens Arnold | c05cd167 | 2006-01-20 01:21:26 +0000 | [diff] [blame] | 7 | Before using, initialize the state by using srand(seed). |
| 8 | |
| 9 | Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, |
| 10 | All rights reserved. |
| 11 | |
| 12 | Redistribution and use in source and binary forms, with or without |
| 13 | modification, are permitted provided that the following conditions |
| 14 | are met: |
| 15 | |
| 16 | 1. Redistributions of source code must retain the above copyright |
| 17 | notice, this list of conditions and the following disclaimer. |
| 18 | |
| 19 | 2. Redistributions in binary form must reproduce the above copyright |
| 20 | notice, this list of conditions and the following disclaimer in the |
| 21 | documentation and/or other materials provided with the distribution. |
| 22 | |
| 23 | 3. The names of its contributors may not be used to endorse or promote |
| 24 | products derived from this software without specific prior written |
| 25 | permission. |
| 26 | |
| 27 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 28 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 29 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 30 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
| 31 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| 32 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| 33 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| 34 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
| 35 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| 36 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| 37 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 38 | |
| 39 | Any feedback is very welcome. |
| 40 | http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html |
| 41 | email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) |
| 42 | */ |
| 43 | |
| 44 | /* |
| 45 | Adapted to Rockbox by Jens Arnold |
| 46 | */ |
| 47 | |
Björn Stenberg | 529e166 | 2002-07-17 23:07:45 +0000 | [diff] [blame] | 48 | #include <stdlib.h> |
| 49 | |
Jens Arnold | c05cd167 | 2006-01-20 01:21:26 +0000 | [diff] [blame] | 50 | /* Period parameters */ |
| 51 | #define N 624 |
| 52 | #define M 397 |
| 53 | #define MATRIX_A 0x9908b0dfUL /* constant vector a */ |
| 54 | #define UMASK 0x80000000UL /* most significant w-r bits */ |
| 55 | #define LMASK 0x7fffffffUL /* least significant r bits */ |
| 56 | #define MIXBITS(u,v) ( ((u) & UMASK) | ((v) & LMASK) ) |
| 57 | #define TWIST(u,v) ((MIXBITS(u,v) >> 1) ^ ((v)&1UL ? MATRIX_A : 0UL)) |
Björn Stenberg | 529e166 | 2002-07-17 23:07:45 +0000 | [diff] [blame] | 58 | |
Jens Arnold | c05cd167 | 2006-01-20 01:21:26 +0000 | [diff] [blame] | 59 | static unsigned long state[N]; /* the array for the state vector */ |
| 60 | static int left = 0; |
| 61 | static unsigned long *next; |
Björn Stenberg | 529e166 | 2002-07-17 23:07:45 +0000 | [diff] [blame] | 62 | |
Jens Arnold | c05cd167 | 2006-01-20 01:21:26 +0000 | [diff] [blame] | 63 | /* initializes state[N] with a seed */ |
Jean-Philippe Bernardy | effb196 | 2005-02-15 13:28:39 +0000 | [diff] [blame] | 64 | void srand(unsigned int seed) |
Björn Stenberg | 529e166 | 2002-07-17 23:07:45 +0000 | [diff] [blame] | 65 | { |
Jens Arnold | c05cd167 | 2006-01-20 01:21:26 +0000 | [diff] [blame] | 66 | unsigned long x = seed & 0xffffffffUL; |
| 67 | unsigned long *s = state; |
Björn Stenberg | 529e166 | 2002-07-17 23:07:45 +0000 | [diff] [blame] | 68 | int j; |
| 69 | |
Jens Arnold | c05cd167 | 2006-01-20 01:21:26 +0000 | [diff] [blame] | 70 | for (*s++ = x, j = 1; j < N; j++) { |
| 71 | x = (1812433253UL * (x ^ (x >> 30)) + j) & 0xffffffffUL; |
| 72 | *s++ = x; |
| 73 | /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ |
| 74 | /* In the previous versions, MSBs of the seed affect */ |
| 75 | /* only MSBs of the array state[]. */ |
| 76 | /* 2002/01/09 modified by Makoto Matsumoto */ |
| 77 | } |
| 78 | left = 1; |
Björn Stenberg | 529e166 | 2002-07-17 23:07:45 +0000 | [diff] [blame] | 79 | } |
| 80 | |
Jens Arnold | c05cd167 | 2006-01-20 01:21:26 +0000 | [diff] [blame] | 81 | static void next_state(void) |
Björn Stenberg | 529e166 | 2002-07-17 23:07:45 +0000 | [diff] [blame] | 82 | { |
Jens Arnold | c05cd167 | 2006-01-20 01:21:26 +0000 | [diff] [blame] | 83 | unsigned long *p = state; |
Björn Stenberg | 529e166 | 2002-07-17 23:07:45 +0000 | [diff] [blame] | 84 | int j; |
Jens Arnold | c05cd167 | 2006-01-20 01:21:26 +0000 | [diff] [blame] | 85 | |
| 86 | /* if srand() has not been called, */ |
| 87 | /* a default initial seed is used */ |
| 88 | if (left < 0) |
| 89 | srand(5489UL); |
| 90 | |
| 91 | left = N; |
| 92 | next = state; |
| 93 | |
| 94 | for (j = N - M + 1; --j; p++) |
| 95 | *p = p[M] ^ TWIST(p[0], p[1]); |
| 96 | |
| 97 | for (j = M; --j; p++) |
| 98 | *p = p[M-N] ^ TWIST(p[0], p[1]); |
| 99 | |
| 100 | *p = p[M-N] ^ TWIST(p[0], state[0]); |
Björn Stenberg | 529e166 | 2002-07-17 23:07:45 +0000 | [diff] [blame] | 101 | } |
| 102 | |
Jens Arnold | c05cd167 | 2006-01-20 01:21:26 +0000 | [diff] [blame] | 103 | /* generates a random number on [0,RAND_MAX]-interval */ |
Jean-Philippe Bernardy | effb196 | 2005-02-15 13:28:39 +0000 | [diff] [blame] | 104 | int rand(void) |
Björn Stenberg | 529e166 | 2002-07-17 23:07:45 +0000 | [diff] [blame] | 105 | { |
Jean-Philippe Bernardy | a161ef49 | 2005-02-15 11:13:00 +0000 | [diff] [blame] | 106 | unsigned long y; |
Jens Arnold | c05cd167 | 2006-01-20 01:21:26 +0000 | [diff] [blame] | 107 | |
| 108 | if (--left <= 0) |
| 109 | next_state(); |
| 110 | y = *next++; |
| 111 | |
| 112 | /* Tempering */ |
| 113 | y ^= (y >> 11); |
| 114 | y ^= (y << 7) & 0x9d2c5680UL; |
| 115 | y ^= (y << 15) & 0xefc60000UL; |
| 116 | y ^= (y >> 18); |
Björn Stenberg | 25e92bd | 2002-07-18 00:03:47 +0000 | [diff] [blame] | 117 | |
Jean-Philippe Bernardy | effb196 | 2005-02-15 13:28:39 +0000 | [diff] [blame] | 118 | return ((unsigned int)y) >> 1; |
Björn Stenberg | 529e166 | 2002-07-17 23:07:45 +0000 | [diff] [blame] | 119 | } |