| [221] | 1 | /***************************************************************************
 | 
|---|
 | 2 |  * blitz/rand-tt800.h      Matsumoto and Kurita's TT800 uniform random 
 | 
|---|
 | 3 |  *                         number generator.
 | 
|---|
 | 4 |  *
 | 
|---|
 | 5 |  * $Id: rand-tt800.h,v 1.1.1.1 1999-04-09 17:59:01 ansari Exp $
 | 
|---|
 | 6 |  *
 | 
|---|
 | 7 |  ***************************************************************************
 | 
|---|
 | 8 |  *
 | 
|---|
 | 9 |  * The class TT800 encapsulates Makoto Matsumoto and Yoshiharu Kurita's 
 | 
|---|
 | 10 |  * TT800 twisted generalized feedback shift register (TGFSR) random number 
 | 
|---|
 | 11 |  * generator.  The generator has period 2^800 - 1.
 | 
|---|
 | 12 |  *
 | 
|---|
 | 13 |  * Contact: M. Matsumoto <matumoto@math.keio.ac.jp>
 | 
|---|
 | 14 |  *
 | 
|---|
 | 15 |  * See: M. Matsumoto and Y. Kurita, Twisted GFSR Generators II, 
 | 
|---|
 | 16 |  *      ACM Transactions on Modelling and Computer Simulation,
 | 
|---|
 | 17 |  *      Vol. 4, No. 3, 1994, pages 254-266.
 | 
|---|
 | 18 |  *
 | 
|---|
 | 19 |  * (c) 1994 Association for Computing Machinery.  
 | 
|---|
 | 20 |  *
 | 
|---|
 | 21 |  * Distributed with consent of the authors.
 | 
|---|
 | 22 |  *
 | 
|---|
 | 23 |  ***************************************************************************
 | 
|---|
 | 24 |  *
 | 
|---|
 | 25 |  * $Log: not supported by cvs2svn $
 | 
|---|
 | 26 |  * Revision 1.2  1997/07/16 14:51:20  tveldhui
 | 
|---|
 | 27 |  * Update: Alpha release 0.2 (Arrays)
 | 
|---|
 | 28 |  *
 | 
|---|
 | 29 |  * Revision 1.1  1997/02/28 13:39:51  tveldhui
 | 
|---|
 | 30 |  * Initial revision
 | 
|---|
 | 31 |  *
 | 
|---|
 | 32 |  */
 | 
|---|
 | 33 | 
 | 
|---|
 | 34 | #ifndef BZ_RAND_TT800_H
 | 
|---|
 | 35 | #define BZ_RAND_TT800_H
 | 
|---|
 | 36 | 
 | 
|---|
 | 37 | #ifndef BZ_RANDOM_H
 | 
|---|
 | 38 |  #include <blitz/random.h>
 | 
|---|
 | 39 | #endif
 | 
|---|
 | 40 | 
 | 
|---|
 | 41 | BZ_NAMESPACE(blitz)
 | 
|---|
 | 42 | 
 | 
|---|
 | 43 | class TT800 {
 | 
|---|
 | 44 | 
 | 
|---|
 | 45 | public:
 | 
|---|
 | 46 |     typedef double T_numtype;
 | 
|---|
 | 47 | 
 | 
|---|
 | 48 |     TT800(double low = 0.0, double high = 1.0, double = 0.0)
 | 
|---|
 | 49 |         : low_(low), length_(high-low)
 | 
|---|
 | 50 |     { 
 | 
|---|
 | 51 |         // Initial 25 seeds
 | 
|---|
 | 52 |         x[0] = 0x95f24dab; x[1] = 0x0b685215; x[2] = 0xe76ccae7;
 | 
|---|
 | 53 |         x[3] = 0xaf3ec239; x[4] = 0x715fad23; x[5] = 0x24a590ad;
 | 
|---|
 | 54 |         x[6] = 0x69e4b5ef; x[7] = 0xbf456141; x[8] = 0x96bc1b7b;
 | 
|---|
 | 55 |         x[9] = 0xa7bdf825; x[10] = 0xc1de75b7; x[11] = 0x8858a9c9;
 | 
|---|
 | 56 |         x[12] = 0x2da87693; x[13] = 0xb657f9dd; x[14] = 0xffdc8a9f;
 | 
|---|
 | 57 |         x[15] = 0x8121da71; x[16] = 0x8b823ecb; x[17] = 0x885d05f5;
 | 
|---|
 | 58 |         x[18] = 0x4e20cd47; x[19] = 0x5a9ad5d9; x[20] = 0x512c0c03;
 | 
|---|
 | 59 |         x[21] = 0xea857ccd; x[22] = 0x4cc1d30f; x[23] = 0x8891a8a1;
 | 
|---|
 | 60 |         x[24] = 0xa6b7aadb;
 | 
|---|
 | 61 | 
 | 
|---|
 | 62 |         // Magic vector 'a', don't change
 | 
|---|
 | 63 |         mag01[0] = 0;
 | 
|---|
 | 64 |         mag01[1] = 0x8ebfd028;
 | 
|---|
 | 65 | 
 | 
|---|
 | 66 |         k = 0;
 | 
|---|
 | 67 |     }
 | 
|---|
 | 68 | 
 | 
|---|
 | 69 |     void randomize() 
 | 
|---|
 | 70 |     { 
 | 
|---|
 | 71 |         BZ_NOT_IMPLEMENTED();            // NEEDS_WORK
 | 
|---|
 | 72 |     }
 | 
|---|
 | 73 |   
 | 
|---|
 | 74 |     double random()
 | 
|---|
 | 75 |     { 
 | 
|---|
 | 76 |         if (k==N) 
 | 
|---|
 | 77 |             generate();
 | 
|---|
 | 78 | 
 | 
|---|
 | 79 |         unsigned long y = x[k];
 | 
|---|
 | 80 |         y ^= (y << 7) & 0x2b5b2500; /* s and b, magic vectors */
 | 
|---|
 | 81 |         y ^= (y << 15) & 0xdb8b0000; /* t and c, magic vectors */
 | 
|---|
 | 82 |         y &= 0xffffffff; /* you may delete this line if word size = 32 */
 | 
|---|
 | 83 | 
 | 
|---|
 | 84 |         // the following line was added by Makoto Matsumoto in the 1996 version
 | 
|---|
 | 85 |         // to improve lower bit's corellation.
 | 
|---|
 | 86 |         // Delete this line to use the code published in 1994.
 | 
|---|
 | 87 | 
 | 
|---|
 | 88 |         y ^= (y >> 16); /* added to the 1994 version */
 | 
|---|
 | 89 |         k++;
 | 
|---|
 | 90 | 
 | 
|---|
 | 91 |         // NEEDS_WORK: this only generates a random number with
 | 
|---|
 | 92 |         // 15 bits of precision.  Need 48 bits for double.
 | 
|---|
 | 93 |         return low_ + length_ * ( (double) y / (unsigned long) 0xffffffff);
 | 
|---|
 | 94 |     } 
 | 
|---|
 | 95 | 
 | 
|---|
 | 96 | protected:
 | 
|---|
 | 97 |     void generate()
 | 
|---|
 | 98 |     {
 | 
|---|
 | 99 |         /* generate N words at one time */
 | 
|---|
 | 100 |         int kk;
 | 
|---|
 | 101 |         for (kk=0;kk<N-M;kk++) {
 | 
|---|
 | 102 |             x[kk] = x[kk+M] ^ (x[kk] >> 1) ^ mag01[x[kk] % 2];
 | 
|---|
 | 103 |         }
 | 
|---|
 | 104 |         for (; kk<N;kk++) {
 | 
|---|
 | 105 |             x[kk] = x[kk+(M-N)] ^ (x[kk] >> 1) ^ mag01[x[kk] % 2];
 | 
|---|
 | 106 |         }
 | 
|---|
 | 107 |         k=0;
 | 
|---|
 | 108 |     }
 | 
|---|
 | 109 | 
 | 
|---|
 | 110 | private:
 | 
|---|
 | 111 |     enum { N = 25, M = 7 };
 | 
|---|
 | 112 | 
 | 
|---|
 | 113 |     double low_, length_;
 | 
|---|
 | 114 |     int k;
 | 
|---|
 | 115 |     unsigned long x[N];
 | 
|---|
 | 116 |     unsigned long mag01[2];
 | 
|---|
 | 117 | };
 | 
|---|
 | 118 | 
 | 
|---|
 | 119 | BZ_NAMESPACE_END
 | 
|---|
 | 120 | 
 | 
|---|
 | 121 | #endif // BZ_RAND_TT800_H
 | 
|---|
 | 122 | 
 | 
|---|