"Fossies" - the Fresh Open Source Software Archive

Member "xdelta3-3.0.11/testing/random.h" (24 Mar 2015, 3463 Bytes) of package /linux/misc/xdelta3-3.0.11.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /* -*- Mode: C++ -*-  */
    2 /* This is public-domain Mersenne Twister code,
    3  * attributed to Michael Brundage.  Thanks!
    4  * http://www.qbrundage.com/michaelb/pubs/essays/random_number_generation.html
    5  */
    6 #undef MT_LEN
    7 #undef MT_IA
    8 class MTRandom {
    9  public:
   10   enum Constants { 
   11     MT_LEN = 624,
   12     MT_IA = 397
   13   };
   14 
   15   static const uint32_t TEST_SEED1;
   16   static const uint32_t UPPER_MASK;
   17   static const uint32_t LOWER_MASK;
   18   static const uint32_t MATRIX_A;
   19 
   20   MTRandom() {
   21     Init(TEST_SEED1);
   22   }
   23 
   24   explicit MTRandom(uint32_t seed) {
   25     Init(seed);
   26   }
   27 
   28   uint32_t Rand32 () {
   29     uint32_t y;
   30     static unsigned long mag01[2] = { 
   31       0 , MATRIX_A
   32     };
   33 
   34     if (mt_index_ >= MT_LEN) {
   35       int kk;
   36 
   37       for (kk = 0; kk < MT_LEN - MT_IA; kk++) {
   38     y = (mt_buffer_[kk] & UPPER_MASK) | (mt_buffer_[kk + 1] & LOWER_MASK);
   39     mt_buffer_[kk] = mt_buffer_[kk + MT_IA] ^ (y >> 1) ^ mag01[y & 0x1UL];
   40       }
   41       for (;kk < MT_LEN - 1; kk++) {
   42     y = (mt_buffer_[kk] & UPPER_MASK) | (mt_buffer_[kk + 1] & LOWER_MASK);
   43     mt_buffer_[kk] = mt_buffer_[kk + (MT_IA - MT_LEN)] ^ (y >> 1) ^ mag01[y & 0x1UL];
   44       }
   45       y = (mt_buffer_[MT_LEN - 1] & UPPER_MASK) | (mt_buffer_[0] & LOWER_MASK);
   46       mt_buffer_[MT_LEN - 1] = mt_buffer_[MT_IA - 1] ^ (y >> 1) ^ mag01[y & 0x1UL];
   47 
   48       mt_index_ = 0;
   49     }
   50   
   51     y = mt_buffer_[mt_index_++];
   52 
   53     y ^= (y >> 11);
   54     y ^= (y << 7) & 0x9d2c5680UL;
   55     y ^= (y << 15) & 0xefc60000UL;
   56     y ^= (y >> 18);
   57 
   58     return y;
   59   }
   60 
   61   uint32_t ExpRand32(uint32_t mean) {
   62     double mean_d = mean;
   63     double erand  = log (1.0 / (Rand32() / (double)UINT32_MAX));
   64     uint32_t x = (uint32_t) (mean_d * erand + 0.5);
   65     return x;
   66   }
   67 
   68   uint64_t Rand64() {
   69     return ((uint64_t)Rand32() << 32) | Rand32();
   70   }
   71 
   72   uint64_t ExpRand64(uint64_t mean) {
   73     double mean_d = mean;
   74     double erand  = log (1.0 / (Rand64() / (double)UINT32_MAX));
   75     uint64_t x = (uint64_t) (mean_d * erand + 0.5);
   76     return x;
   77   }
   78 
   79   template <typename T>
   80   T Rand() {
   81     switch (sizeof(T)) {
   82     case sizeof(uint32_t):
   83       return Rand32();
   84     case sizeof(uint64_t):
   85       return Rand64();
   86     default:
   87       cerr << "Invalid sizeof T" << endl;
   88       abort();
   89     }
   90   }
   91 
   92   template <typename T>
   93   T ExpRand(T mean) {
   94     switch (sizeof(T)) {
   95     case sizeof(uint32_t):
   96       return ExpRand32(mean);
   97     case sizeof(uint64_t):
   98       return ExpRand64(mean);
   99     default:
  100       cerr << "Invalid sizeof T" << endl;
  101       abort();
  102     }
  103   }
  104 
  105  private:
  106   void Init(uint32_t seed) {
  107     mt_buffer_[0] = seed;
  108     mt_index_ = MT_LEN;
  109     for (int i = 1; i < MT_LEN; i++) {
  110       /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
  111       /* In the previous versions, MSBs of the seed affect   */
  112       /* only MSBs of the array mt[].                        */
  113       /* 2002/01/09 modified by Makoto Matsumoto             */
  114       mt_buffer_[i] = 
  115     (1812433253UL * (mt_buffer_[i-1] ^ (mt_buffer_[i-1] >> 30)) + i);
  116     }
  117   }
  118 
  119   int mt_index_;
  120   uint32_t mt_buffer_[MT_LEN];
  121 };
  122 
  123 const uint32_t MTRandom::TEST_SEED1 = 5489UL;
  124 const uint32_t MTRandom::UPPER_MASK = 0x80000000;
  125 const uint32_t MTRandom::LOWER_MASK = 0x7FFFFFFF;
  126 const uint32_t MTRandom::MATRIX_A = 0x9908B0DF;
  127 
  128 class MTRandom8 {
  129 public:
  130   MTRandom8(MTRandom *rand)
  131     : rand_(rand) {
  132   }
  133 
  134   uint8_t Rand8() {
  135     uint32_t r = rand_->Rand32();
  136 
  137     // TODO: make this use a single byte at a time?
  138     return (r & 0xff) ^ (r >> 7) ^ (r >> 15) ^ (r >> 21);
  139   }
  140 
  141 private:
  142   MTRandom *rand_;
  143 };