/* C# Version Copyright (C) 2001 Akihilo Kramot (Takel). */ /* C# porting from a C-program for MT19937, originaly coded by */ /* Takuji Nishimura, considering the suggestions by */ /* Topher Cooper and Marc Rieffel in July-Aug. 1997. */ /* This library is free software under the Artistic license: */ /* */ /* You can find the original C-program at */ /* http://www.math.keio.ac.jp/~matumoto/mt.html */ /* */ using System; namespace jp.takel.PseudoRandom { public class MersenneTwister : System.Random { /* Period parameters */ private const int N = 624; private const int M = 397; private const uint MATRIX_A = 0x9908b0df; /* constant vector a */ private const uint UPPER_MASK = 0x80000000; /* most significant w-r bits */ private const uint LOWER_MASK = 0x7fffffff; /* least significant r bits */ /* Tempering parameters */ private const uint TEMPERING_MASK_B = 0x9d2c5680; private const uint TEMPERING_MASK_C = 0xefc60000; private static uint TEMPERING_SHIFT_U (uint y) { return (y >> 11); } private static uint TEMPERING_SHIFT_S (uint y) { return (y << 7); } private static uint TEMPERING_SHIFT_T (uint y) { return (y << 15); } private static uint TEMPERING_SHIFT_L (uint y) { return (y >> 18); } private uint[] mt = new uint[N]; /* the array for the state vector */ private short mti; private static uint[] mag01 = {0x0, MATRIX_A}; /* initializing the array with a NONZERO seed */ public MersenneTwister( uint seed) { /* setting initial seeds to mt[N] using */ /* the generator Line 25 of Table 1 in */ /* [KNUTH 1981, The Art of Computer Programming */ /* Vol. 2 (2nd Ed.), pp102] */ mt[0] = seed & 0xffffffffU; for ( mti=1; mti= N) /* generate N words at one time */ { short kk; for (kk=0;kk> 1) ^ mag01[y & 0x1]; } for (;kk> 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++]; y ^= TEMPERING_SHIFT_U(y); y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B; y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C; y ^= TEMPERING_SHIFT_L(y); return y; } public virtual uint NextUInt() { return this.GenerateUInt(); } public virtual uint NextUInt( uint maxValue) { return (uint)( this.GenerateUInt() / ( (double)uint.MaxValue / maxValue ) ); } public virtual uint NextUInt( uint minValue, uint maxValue) /* throws ArgumentOutOfRangeException */ { if ( minValue >= maxValue) { throw new ArgumentOutOfRangeException(); } return (uint)( this.GenerateUInt() / ( (double)uint.MaxValue / (maxValue - minValue) ) + minValue ); } public override int Next () { return (int)(this.GenerateUInt() / 2); } public override int Next ( int maxValue) /* throws ArgumentOutOfRangeException */ { if ( maxValue <= 0) { if ( 0 == maxValue) { return 0; } else { throw new ArgumentOutOfRangeException(); } } return (int)(this.GenerateUInt() / (uint.MaxValue / maxValue)); } public override int Next ( int minValue, int maxValue) /* ArgumentOutOfRangeException */ { if ( minValue >= maxValue) { throw new ArgumentOutOfRangeException(); } return (int)( this.GenerateUInt() / ( (double)uint.MaxValue / (maxValue - minValue) ) + minValue ); } public override void NextBytes ( byte[] buffer) /* throws ArgumentNullException*/ { int bufLen = buffer.Length; if ( null == buffer) { throw new ArgumentNullException(); } for ( int idx = 0; idx < bufLen; idx++) { buffer[idx] = (byte)(this.GenerateUInt() / (uint.MaxValue / byte.MaxValue)); } } public override double NextDouble () { return (double)this.GenerateUInt() / uint.MaxValue; } } }