1 // $Id: Ranlux64Engine.h,v 1.5 2010/06/16 17:24:53 garren Exp $
2 // -*- C++ -*-
3 //
4 // -----------------------------------------------------------------------
5 //                             HEP Random
6 //                        --- Ranlux64Engine ---
7 //                          class header file
8 // -----------------------------------------------------------------------
9 // The algorithm for this random engine has been taken from the notes of
10 // a double-precision ranlux implementation by Martin Luscher, dated
11 // November 1997.
12 //
13 // Like the previous ranlux generator, this one also has "luxury" levels,
14 // determining how many pseudo-random numbers are discarded for every
15 // twelve values used. Three levels are given, with the note that Luscher
16 // himself advocates only the highest two levels for this engine.
17 //  level 0  (p=109):              Throw away 109 values for every 12 used
18 //  level 1  (p=202):   (default)  Throw away 202 values for every 12 used
19 //  level 2  (p=397):              Throw away 397 values for every 12 used
20 //
21 // The initialization is carried out using a Multiplicative Congruential
22 // generator using formula constants of L'Ecuyer as described in "F.James,
23 // Comp. Phys. Comm. 60 (1990) 329-344".
24 // =======================================================================
25 // Ken Smith      - Created Initial draft: 14th Jul 1998
26 //                - Added conversion operators:  6th Aug 1998
27 // Mark Fischler
28 // 9/9/98	  - Added update() routine to allow computation of many at once
29 //		  - Replaced algorithm with jone exactly matching Luscher:
30 //			48-bits generated
31 //			skip n-12 instead of n numbers
32 //		  - Corrected protection agains overflow
33 // 12/8/04        - Methods for instance save/restore
34 // 12/27/04       - methods for anonymous save/restore 12/27/04
35 //
36 // =======================================================================
37 
38 #ifndef Ranlux64Engine_h
39 #define Ranlux64Engine_h
40 
41 #include "CLHEP/Random/defs.h"
42 #include "CLHEP/Random/RandomEngine.h"
43 
44 namespace CLHEP {
45 
46 /**
47  * @author
48  * @ingroup random
49  */
50 class Ranlux64Engine : public HepRandomEngine {
51 
52 public:
53 
54   Ranlux64Engine( std::istream& is );
55   Ranlux64Engine();
56   Ranlux64Engine( long seed, int lux = 1 );
57   Ranlux64Engine( int rowIndex, int colIndex, int lux );
58   virtual ~Ranlux64Engine();
59   // Constructors and destructor
60 
61   double flat();
62   // It returns a pseudo random number between 0 and 1,
63   // excluding the end points.
64 
65   void flatArray (const int size, double* vect);
66   // Fills the array "vect" of specified size with flat random values.
67 
68   void setSeed(long seed, int lux=1);
69   // Sets the state of the algorithm according to seed.
70 
71   void setSeeds(const long * seeds, int lux=1);
72   // Sets the state of the algorithm according to the zero terminated
73   // array of seeds.  Only the first seed is used.
74 
75   void saveStatus( const char filename[] = "Ranlux64.conf" ) const;
76   // Saves in named file the current engine status.
77 
78   void restoreStatus( const char filename[] = "Ranlux64.conf" );
79   // Reads from named file the last saved engine status and restores it.
80 
81   void showStatus() const;
82   // Dumps the engine status on the screen.
83 
getLuxury()84   int getLuxury() const { return luxury; }
85   // Gets the luxury level.
86 
87   virtual std::ostream & put (std::ostream & os) const;
88   virtual std::istream & get (std::istream & is);
89   static  std::string beginTag ( );
90   virtual std::istream & getState ( std::istream & is );
91 
92   std::string name() const;
engineName()93   static std::string engineName() {return "Ranlux64Engine";}
94 
95   std::vector<unsigned long> put () const;
96   bool get (const std::vector<unsigned long> & v);
97   bool getState (const std::vector<unsigned long> & v);
98 
99   static const unsigned int VECTOR_STATE_SIZE = 30;
100 
101 private:
102 
103   void update();
104   void advance(int dozens);
105 
106   int pDiscard;     // separate sequence by p-r = p-12 discarded elements
107   int pDozens;      // pDiscard / 12;
108   int endIters;     // pDiscard % 12;
109   int luxury;
110 
111   int index;
112   double randoms[12]; // randoms [i] is the x[n-i] of Luscher's note
113   double carry;
114 
115 }; // Ranlux64Engine
116 
117 }  // namespace CLHEP
118 
119 #ifdef ENABLE_BACKWARDS_COMPATIBILITY
120 //  backwards compatibility will be enabled ONLY in CLHEP 1.9
121 using namespace CLHEP;
122 #endif
123 
124 #endif // Ranlux64Engine_h
125