• entries
90
66
• views
72667

Mersenne Twister

159 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!

There are no comments to display.