00001 // $Id: Ranlux64Engine.h,v 1.8 2002/04/12 15:02:45 evc Exp $ 00002 // -*- C++ -*- 00003 // 00004 // ----------------------------------------------------------------------- 00005 // HEP Random 00006 // --- Ranlux64Engine --- 00007 // class header file 00008 // ----------------------------------------------------------------------- 00009 // The algorithm for this random engine has been taken from the notes of 00010 // a double-precision ranlux implementation by Martin Luscher, dated 00011 // November 1997. 00012 // 00013 // Like the previous ranlux generator, this one also has "luxury" levels, 00014 // determining how many pseudo-random numbers are discarded for every 00015 // twelve values used. Three levels are given, with the note that Luscher 00016 // himself advocates only the highest two levels for this engine. 00017 // level 0 (p=109): Throw away 109 values for every 12 used 00018 // level 1 (p=202): (default) Throw away 202 values for every 12 used 00019 // level 2 (p=397): Throw away 397 values for every 12 used 00020 // 00021 // The initialization is carried out using a Multiplicative Congruential 00022 // generator using formula constants of L'Ecuyer as described in "F.James, 00023 // Comp. Phys. Comm. 60 (1990) 329-344". 00024 // ======================================================================= 00025 // Ken Smith - Created Initial draft: 14th Jul 1998 00026 // - Added conversion operators: 6th Aug 1998 00027 // Mark Fischler 00028 // 9/9/98 - Added update() routine to allow computation of many at once 00029 // - Replaced algorithm with jone exactly matching Luscher: 00030 // 48-bits generated 00031 // skip n-12 instead of n numbers 00032 // - Corrected protection agains overflow 00033 // 00034 // ======================================================================= 00035 00036 #ifndef Ranlux64Engine_h 00037 #define Ranlux64Engine_h 00038 00039 #include "CLHEP/Random/RandomEngine.h" 00040 00045 class Ranlux64Engine : public HepRandomEngine { 00046 00047 public: 00048 00049 Ranlux64Engine( HepStd::istream& is ); 00050 Ranlux64Engine(); 00051 Ranlux64Engine( long seed, int lux = 1 ); 00052 Ranlux64Engine( int rowIndex, int colIndex, int lux ); 00053 virtual ~Ranlux64Engine(); 00054 // Constructors and destructor 00055 00056 Ranlux64Engine(const Ranlux64Engine &p); 00057 // Copy constructor 00058 00059 Ranlux64Engine & operator = (const Ranlux64Engine &p); 00060 // Overloaded assignment operator, to retrieve the engine status. 00061 00062 double flat(); 00063 // It returns a pseudo random number between 0 and 1, 00064 // excluding the end points. 00065 00066 void flatArray (const int size, double* vect); 00067 // Fills the array "vect" of specified size with flat random values. 00068 00069 void setSeed(long seed, int lux=1); 00070 // Sets the state of the algorithm according to seed. 00071 00072 void setSeeds(const long * seeds, int lux=1); 00073 // Sets the state of the algorithm according to the zero terminated 00074 // array of seeds. Only the first seed is used. 00075 00076 void saveStatus( const char filename[] = "Ranlux64.conf" ) const; 00077 // Saves in named file the current engine status. 00078 00079 void restoreStatus( const char filename[] = "Ranlux64.conf" ); 00080 // Reads from named file the last saved engine status and restores it. 00081 00082 void showStatus() const; 00083 // Dumps the engine status on the screen. 00084 00085 int getLuxury() const { return luxury; } 00086 // Gets the luxury level. 00087 00088 friend HepStd::ostream& operator<< (HepStd::ostream& os, const Ranlux64Engine& e); 00089 friend HepStd::istream& operator>> (HepStd::istream& is, Ranlux64Engine& e); 00090 00091 private: 00092 00093 void update(); 00094 void advance(int dozens); 00095 00096 int pDiscard; // separate sequence by p-r = p-12 discarded elements 00097 int pDozens; // pDiscard / 12; 00098 int endIters; // pDiscard % 12; 00099 int luxury; 00100 00101 int index; 00102 double randoms[12]; // randoms [i] is the x[n-i] of Luscher's note 00103 double carry; 00104 00105 static int numEngines; 00106 static int maxIndex; 00107 00108 static double twoToMinus_32; 00109 static double twoToMinus_48; 00110 static double twoToMinus_49; 00111 00112 }; // Ranlux64Engine 00113 00114 #endif // Ranlux64Engine_h