// @(#)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 #include "Math/TRandomEngine.h" #include #include #include namespace ROOT { namespace Math { /** Random number generator class based on M. Matsumoto and T. Nishimura, Mersenne Twister: A 623-dimensionally 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 - relatively 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); } ~MersenneTwisterEngine() override {} void SetSeed(Result_t seed); double Rndm() override { return Rndm_impl(); } inline double operator() () { return Rndm_impl(); } uint32_t IntRndm() { return IntRndm_impl(); } /// minimum integer that can be generated static unsigned int MinInt() { return 0; } /// maximum integer that 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 & 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 & 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 */