Sign in to follow this  
  • entries
    90
  • comments
    66
  • views
    72544

Mersenne Twister

Sign in to follow this  

145 views

Here is the code for the Mersenne Twister class I use to generate seeded pseudo-random numbers.


/*
A C-program for MT19937, with initialization improved 2002/1/26.
Coded by Takuji Nishimura and Makoto Matsumoto.

Before using, initialize the state by using init_genrand(seed)
or init_by_array(init_key, key_length).

Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

3. The names of its contributors may not be used to endorse or promote
products derived from this software without specific prior written
permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


Any feedback is very welcome.
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)

-------------------

Converted to Actionscript 2006 by John Winkelman
Feedback welcome at john@eccesignum.org
*/



/* Period parameters */
class MersenneTwister {
private var N:Number = 624;
private var M:Number = 397;
private var MATRIX_A:Number = 0x9908b0df; /* constant vector a */
private var UPPER_MASK:Number = 0x80000000; /* most significant w-r bits */
private var LOWER_MASK:Number = 0x7fffffff; /* least significant r bits */

private var mt:Array; /* the array for the state vector */
private var mti:Number;

private var seed:Number;
private var returnLength:Number;
private var maxSize:Number;

private var returnArray:Array;


public function MersenneTwister() {

}

public function twist($seed,$returnLength,$maxSize):Array { // seed number, number of values to return ,max size of returned number
seed = $seed;
returnLength = $returnLength;
maxSize = $maxSize;
mt = new Array();

returnArray = [];

mti = N+1; /* mti==N+1 means mt[N] is not initialized */
var i;
var initArray=(0x123, 0x234, 0x345, 0x456);
init_by_array(initArray,initArray.length);
for (i=0; i returnArray = genrand_int32()%maxSize;
}
//returnArray.sort(16);
//trace(returnArray);
/*
trace("\n1000 outputs of genrand_real2()\n");
for (i=0; i trace(" " + genrand_real2());
if (i%5==4) trace("\n");
}
*/

return returnArray;

}


/* initializes mt[N] with a seed */
private function init_genrand($seed)
{
mt[0]= $seed & 0xffffffff;
for (mti=1; mti mt[mti] = (1812433253 * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
mt[mti] &= 0xffffffff;
/* for >32 bit machines */
}
}

/* initialize by an array with array-length */
/* init_key is the array for initializing keys */
/* key_length is its length */
/* slight change for C++, 2004/2/26 */
// void init_by_array(unsigned long init_key[], int key_length)

private function init_by_array($seedArray:Array,$seedArrayLength:Number){
var i = 1;
var j = 0;
init_genrand(seed);
//init_genrand(19650218);
var k = (N>$seedArrayLength) ? N : $seedArrayLength;
for (k; k>0; k--) {
mt = (mt ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525)) + $seedArray[j] + j; /* non linear */
mt &= 0xffffffff; /* for WORDSIZE > 32 machines */
i++;
j++;
if (i >= N) {
mt[0] = mt[N-1];
i=1;
}
if (j >= $seedArrayLength) j=0;
}
for (k=N-1; k; k--) {
mt = (mt ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941)) - i; /* non linear */
mt &= 0xffffffff; /* for WORDSIZE > 32 machines */
i++;
if (i>=N) {
mt[0] = mt[N-1];
i=1;
}
}

mt[0] = 0x80000000; /* MSB is 1; assuring non-zero initial array */
}

/* generates a random number on [0,0xffffffff]-interval */
private function genrand_int32():Number {
var y:Number;
var mag01=[0x0, MATRIX_A];
/* mag01[x] = x * MATRIX_A for x=0,1 */

if (mti >= N) { /* generate N words at one time */
var kk:Number;

if (mti == N+1) /* if init_genrand() has not been called, */
init_genrand(5489); /* a default initial seed is used */

for (kk=0;kk y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1];
}
for (;kk1
;kk++) {
y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1];
}
y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1];

mti = 0;
}

y = mt[mti++];

/* Tempering */
y ^= (y >> 11);
y ^= (y << 7) & 0x9d2c5680;
y ^= (y << 15) & 0xefc60000;
y ^= (y >> 18);

return y;
}

/* generates a random number on [0,0x7fffffff]-interval */
private function genrand_int31():Number {
return (genrand_int32()>>1);
}

/* generates a random number on [0,1]-real-interval */
private function genrand_real1():Number {
return genrand_int32()*(1.0/4294967295.0);
/* divided by 2^32-1 */
}

/* generates a random number on [0,1)-real-interval */
private function genrand_real2():Number {
return genrand_int32()*(1.0/4294967296.0);
/* divided by 2^32 */
}

/* generates a random number on (0,1)-real-interval */
private function genrand_real3():Number {
return ((genrand_int32()) + 0.5)*(1.0/4294967296.0);
/* divided by 2^32 */
}

/* generates a random number on [0,1) with 53-bit resolution*/
private function genrand_res53():Number {
var a = genrand_int32()>>5;
var b = genrand_int32()>>6;
return(a*67108864.0+b)*(1.0/9007199254740992.0);
}
/* These real versions are due to Isaku Wada, 2002/01/09 added */
}



There is one public function: twist();, which returns an array of numbers

After the class is instantiated, call twist as follows:


twister = new MersenneTwister();
var numbers:Array = twister.twist(seed,return_length,max_size);


...where seed is the initial seed value, return_length is the number of values you wish returned form this seed, and max_size is the maximum value of each of the returned numbers.

Happy New Year!
Sign in to follow this  


0 Comments


Recommended Comments

There are no comments to display.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now