// @(#)root/mathcore:$Id$
// Author: L. Moneta Tue Aug 4 2015

/**********************************************************************
 *                                                                    *
 * Copyright (c) 2015  LCG ROOT Math Team, CERN/PH-SFT                *
 *                                                                    *
 *                                                                    *
 **********************************************************************/

// random engines based on ROOT 

#ifndef ROOT_Math_MersenneTwisterEngine
#define ROOT_Math_MersenneTwisterEngine

#ifndef ROOT_Math_TRandomEngine
#include "Math/TRandomEngine.h"
#endif

#include <cstdint>
#include <vector>
#include <string>

namespace ROOT {

   namespace Math {

      /**
         Random number generator class based on
         M. Matsumoto and T. Nishimura,
         Mersenne Twister: A 623-diminsionally equidistributed
         uniform pseudorandom number generator
         ACM Transactions on Modeling and Computer Simulation,
         Vol. 8, No. 1, January 1998, pp 3--30.

         For more information see the Mersenne Twister homepage
         [http://www.math.keio.ac.jp/~matumoto/emt.html]

         Advantage: 

         -  large period 2**19937 -1
         -  relativly fast (slightly slower than TRandom1 and TRandom2 but much faster than TRandom1)

         Note that this is a 32 bit implementation. Only 32 bits of the returned double numbers are random.
         in case more precision is needed, one should use an engine providing at least 48 random bits. 

         Drawback:  a relative large internal state of 624 integers

         @ingroup Random
      */

      class MersenneTwisterEngine : public TRandomEngine {


      public:

         typedef  TRandomEngine BaseType;
         typedef  uint32_t Result_t;
         typedef  uint32_t StateInt_t;


         MersenneTwisterEngine(uint32_t seed=4357)  {
            SetSeed(seed);
         }

         virtual ~MersenneTwisterEngine() {}

         void SetSeed(Result_t seed);

         virtual double Rndm() {
            return Rndm_impl();
         }
         inline double operator() () { return Rndm_impl(); }

         uint32_t IntRndm() {
            return IntRndm_impl();
         }
       
         /// minimum integer taht can be generated
         static unsigned int MinInt() { return 0; }
         /// maximum integer taht can be generated
         static unsigned int MaxInt() { return 0xffffffff; }  //  2^32 -1

         static int Size() { return kSize; }

         static std::string Name() {
            return "MersenneTwisterEngine";
         }

      protected:
         // functions used for testing
         
         void SetState(const std::vector<uint32_t> & state) {
            for (unsigned int i = 0; i < kSize; ++i)
               fMt[i] = state[i];
            fCount624 = kSize; // to make sure we re-iterate on the new state
         }

         void GetState(std::vector<uint32_t> & state) {
            state.resize(kSize);
            for (unsigned int i = 0; i < kSize; ++i)
               state[i] = fMt[i];
         }

         int Counter() const { return fCount624; }


      private:

         double Rndm_impl();
         uint32_t IntRndm_impl(); 

         enum { 
            kSize=624
         };
         uint32_t  fMt[kSize];
         int fCount624;
      };


   } // end namespace Math

} // end namespace ROOT


#endif /* ROOT_Math_TRandomEngines */
 MersenneTwisterEngine.h:1
 MersenneTwisterEngine.h:2
 MersenneTwisterEngine.h:3
 MersenneTwisterEngine.h:4
 MersenneTwisterEngine.h:5
 MersenneTwisterEngine.h:6
 MersenneTwisterEngine.h:7
 MersenneTwisterEngine.h:8
 MersenneTwisterEngine.h:9
 MersenneTwisterEngine.h:10
 MersenneTwisterEngine.h:11
 MersenneTwisterEngine.h:12
 MersenneTwisterEngine.h:13
 MersenneTwisterEngine.h:14
 MersenneTwisterEngine.h:15
 MersenneTwisterEngine.h:16
 MersenneTwisterEngine.h:17
 MersenneTwisterEngine.h:18
 MersenneTwisterEngine.h:19
 MersenneTwisterEngine.h:20
 MersenneTwisterEngine.h:21
 MersenneTwisterEngine.h:22
 MersenneTwisterEngine.h:23
 MersenneTwisterEngine.h:24
 MersenneTwisterEngine.h:25
 MersenneTwisterEngine.h:26
 MersenneTwisterEngine.h:27
 MersenneTwisterEngine.h:28
 MersenneTwisterEngine.h:29
 MersenneTwisterEngine.h:30
 MersenneTwisterEngine.h:31
 MersenneTwisterEngine.h:32
 MersenneTwisterEngine.h:33
 MersenneTwisterEngine.h:34
 MersenneTwisterEngine.h:35
 MersenneTwisterEngine.h:36
 MersenneTwisterEngine.h:37
 MersenneTwisterEngine.h:38
 MersenneTwisterEngine.h:39
 MersenneTwisterEngine.h:40
 MersenneTwisterEngine.h:41
 MersenneTwisterEngine.h:42
 MersenneTwisterEngine.h:43
 MersenneTwisterEngine.h:44
 MersenneTwisterEngine.h:45
 MersenneTwisterEngine.h:46
 MersenneTwisterEngine.h:47
 MersenneTwisterEngine.h:48
 MersenneTwisterEngine.h:49
 MersenneTwisterEngine.h:50
 MersenneTwisterEngine.h:51
 MersenneTwisterEngine.h:52
 MersenneTwisterEngine.h:53
 MersenneTwisterEngine.h:54
 MersenneTwisterEngine.h:55
 MersenneTwisterEngine.h:56
 MersenneTwisterEngine.h:57
 MersenneTwisterEngine.h:58
 MersenneTwisterEngine.h:59
 MersenneTwisterEngine.h:60
 MersenneTwisterEngine.h:61
 MersenneTwisterEngine.h:62
 MersenneTwisterEngine.h:63
 MersenneTwisterEngine.h:64
 MersenneTwisterEngine.h:65
 MersenneTwisterEngine.h:66
 MersenneTwisterEngine.h:67
 MersenneTwisterEngine.h:68
 MersenneTwisterEngine.h:69
 MersenneTwisterEngine.h:70
 MersenneTwisterEngine.h:71
 MersenneTwisterEngine.h:72
 MersenneTwisterEngine.h:73
 MersenneTwisterEngine.h:74
 MersenneTwisterEngine.h:75
 MersenneTwisterEngine.h:76
 MersenneTwisterEngine.h:77
 MersenneTwisterEngine.h:78
 MersenneTwisterEngine.h:79
 MersenneTwisterEngine.h:80
 MersenneTwisterEngine.h:81
 MersenneTwisterEngine.h:82
 MersenneTwisterEngine.h:83
 MersenneTwisterEngine.h:84
 MersenneTwisterEngine.h:85
 MersenneTwisterEngine.h:86
 MersenneTwisterEngine.h:87
 MersenneTwisterEngine.h:88
 MersenneTwisterEngine.h:89
 MersenneTwisterEngine.h:90
 MersenneTwisterEngine.h:91
 MersenneTwisterEngine.h:92
 MersenneTwisterEngine.h:93
 MersenneTwisterEngine.h:94
 MersenneTwisterEngine.h:95
 MersenneTwisterEngine.h:96
 MersenneTwisterEngine.h:97
 MersenneTwisterEngine.h:98
 MersenneTwisterEngine.h:99
 MersenneTwisterEngine.h:100
 MersenneTwisterEngine.h:101
 MersenneTwisterEngine.h:102
 MersenneTwisterEngine.h:103
 MersenneTwisterEngine.h:104
 MersenneTwisterEngine.h:105
 MersenneTwisterEngine.h:106
 MersenneTwisterEngine.h:107
 MersenneTwisterEngine.h:108
 MersenneTwisterEngine.h:109
 MersenneTwisterEngine.h:110
 MersenneTwisterEngine.h:111
 MersenneTwisterEngine.h:112
 MersenneTwisterEngine.h:113
 MersenneTwisterEngine.h:114
 MersenneTwisterEngine.h:115
 MersenneTwisterEngine.h:116
 MersenneTwisterEngine.h:117
 MersenneTwisterEngine.h:118
 MersenneTwisterEngine.h:119
 MersenneTwisterEngine.h:120
 MersenneTwisterEngine.h:121
 MersenneTwisterEngine.h:122
 MersenneTwisterEngine.h:123
 MersenneTwisterEngine.h:124
 MersenneTwisterEngine.h:125
 MersenneTwisterEngine.h:126