// @(#)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_LCGEngine
#define ROOT_Math_LCGEngine

#include <cstdint>
#include <vector>
#include <cassert>

class TRandomEngine  {
public:
   virtual double Rndm() = 0;
   virtual ~TRandomEngine() {}
};


namespace ROOT {

   namespace Math {

      
      class LCGEngine : public TRandomEngine {


      public:

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

         LCGEngine() : fSeed(65539) { }

         virtual ~LCGEngine() {}

         void SetSeed(uint32_t seed) { fSeed = seed; }

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

         uint32_t IntRndm() {
            fSeed = (1103515245 * fSeed + 12345) & 0x7fffffffUL;
            return fSeed; 
         }

         /// 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
         /// Size of the generator state
         static int Size() { return 1; }
         /// Name of the generator
         static std::string Name() { return "LCGEngine"; }
      protected:
         // for testing all generators
         void SetState(const std::vector<uint32_t> & state) {
            assert(!state.empty());
            fSeed = state[0]; 
         }

         void GetState(std::vector<uint32_t> & state) {
            state.resize(1);
            state[0] = fSeed;
         }
         int Counter() const { return 0; }         
      private:

         double Rndm_impl() {
            const double kCONS = 4.6566128730774E-10; // (1/pow(2,31)
            unsigned int rndm = IntRndm(); // generate integer number 
            if (rndm != 0) return  kCONS*rndm;
            return Rndm_impl();
         }
         
         uint32_t fSeed;
      };
      

   } // end namespace Math

} // end namespace ROOT


#endif /* ROOT_Math_LCGEngine */
 LCGEngine.h:1
 LCGEngine.h:2
 LCGEngine.h:3
 LCGEngine.h:4
 LCGEngine.h:5
 LCGEngine.h:6
 LCGEngine.h:7
 LCGEngine.h:8
 LCGEngine.h:9
 LCGEngine.h:10
 LCGEngine.h:11
 LCGEngine.h:12
 LCGEngine.h:13
 LCGEngine.h:14
 LCGEngine.h:15
 LCGEngine.h:16
 LCGEngine.h:17
 LCGEngine.h:18
 LCGEngine.h:19
 LCGEngine.h:20
 LCGEngine.h:21
 LCGEngine.h:22
 LCGEngine.h:23
 LCGEngine.h:24
 LCGEngine.h:25
 LCGEngine.h:26
 LCGEngine.h:27
 LCGEngine.h:28
 LCGEngine.h:29
 LCGEngine.h:30
 LCGEngine.h:31
 LCGEngine.h:32
 LCGEngine.h:33
 LCGEngine.h:34
 LCGEngine.h:35
 LCGEngine.h:36
 LCGEngine.h:37
 LCGEngine.h:38
 LCGEngine.h:39
 LCGEngine.h:40
 LCGEngine.h:41
 LCGEngine.h:42
 LCGEngine.h:43
 LCGEngine.h:44
 LCGEngine.h:45
 LCGEngine.h:46
 LCGEngine.h:47
 LCGEngine.h:48
 LCGEngine.h:49
 LCGEngine.h:50
 LCGEngine.h:51
 LCGEngine.h:52
 LCGEngine.h:53
 LCGEngine.h:54
 LCGEngine.h:55
 LCGEngine.h:56
 LCGEngine.h:57
 LCGEngine.h:58
 LCGEngine.h:59
 LCGEngine.h:60
 LCGEngine.h:61
 LCGEngine.h:62
 LCGEngine.h:63
 LCGEngine.h:64
 LCGEngine.h:65
 LCGEngine.h:66
 LCGEngine.h:67
 LCGEngine.h:68
 LCGEngine.h:69
 LCGEngine.h:70
 LCGEngine.h:71
 LCGEngine.h:72
 LCGEngine.h:73
 LCGEngine.h:74
 LCGEngine.h:75
 LCGEngine.h:76
 LCGEngine.h:77
 LCGEngine.h:78
 LCGEngine.h:79
 LCGEngine.h:80
 LCGEngine.h:81
 LCGEngine.h:82
 LCGEngine.h:83
 LCGEngine.h:84
 LCGEngine.h:85
 LCGEngine.h:86
 LCGEngine.h:87
 LCGEngine.h:88
 LCGEngine.h:89
 LCGEngine.h:90
 LCGEngine.h:91
 LCGEngine.h:92
 LCGEngine.h:93
 LCGEngine.h:94
 LCGEngine.h:95
 LCGEngine.h:96