00001 // $Id: RanshiEngine.h,v 1.9 2002/04/12 15:02:45 evc Exp $ 00002 // -*- C++ -*- 00003 // 00004 // ----------------------------------------------------------------------- 00005 // HEP Random 00006 // --- RanshiEngine --- 00007 // class header file 00008 // ----------------------------------------------------------------------- 00009 // 00010 // 00011 // The algorithm for this random engine was taken from "F.Gutbrod, Comp. 00012 // Phys. Comm. 87 (1995) 291-306". 00013 // 00014 // The algorithm can be imagined as a physical system as follows: Imagine 00015 // 512 "black balls" each with their own unique spin, and positions char- 00016 // acterized by disrete angles, where the spin is a 32-bit unsigned integer. 00017 // A "red ball" collides based upon the angle determined by the last 8 bits 00018 // of its spin, and the spin of the colliding ball is taken as the output 00019 // random number. The spin of the colliding ball is replaced then with the 00020 // left circular shift of the black ball's spin XOR'd with the red ball's 00021 // spin. The black ball's old spin becomes the red ball's. 00022 // 00023 // To avoid the traps presented, two measures are taken: first, the red 00024 // ball will oscillate between hitting the lower half of the buffer on one 00025 // turn and the upper half on another; second, the red ball's spin is 00026 // incremented by a counter of the number of random numbers produced. 00027 // 00028 // The result is scaled to a double precision floating point number to which 00029 // is added another random double further scaled 2^(53-32) places to the 00030 // right in order to ensure that the remaining bits of the result are not 00031 // left empty due to the mere 32 bits representation used internally. 00032 00033 // ======================================================================= 00034 // Ken Smith - Created: 9th June 1998 00035 // - Removed pow() from flat method: 21st Jul 1998 00036 // - Added conversion operators: 6th Aug 1998 00037 // ======================================================================= 00038 00039 #ifndef HepRanshiEngine_h 00040 #define HepRanshiEngine_h 00041 00042 #include "CLHEP/Random/RandomEngine.h" 00043 00048 class RanshiEngine: public HepRandomEngine { 00049 00050 public: 00051 00052 RanshiEngine(); 00053 RanshiEngine(HepStd::istream &is); 00054 RanshiEngine(long seed); 00055 RanshiEngine(int rowIndex, int colIndex); 00056 virtual ~RanshiEngine(); 00057 // Constructors and destructor 00058 00059 RanshiEngine(const RanshiEngine &p); 00060 RanshiEngine & operator = (const RanshiEngine &p); 00061 // Copy constructor and operator= 00062 00063 double flat(); 00064 // Returns a pseudo random number between 0 and 1 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); 00070 // Sets the state of the algorithm according to seed. 00071 00072 void setSeeds(const long* seeds, int); 00073 // Sets the state of the algorithm according to the zero-terminated 00074 // array of seeds. 00075 00076 void saveStatus(const char filename[] = "RanshiEngine.conf") const; 00077 // Saves on named file the current engine status 00078 00079 void restoreStatus(const char filename[] = "RanshiEngine.conf"); 00080 // Reads from named file the last saved engine status 00081 // and restores it. 00082 00083 void showStatus() const; 00084 // Dumps the engine status on the screen 00085 00086 operator float(); // flat value, without worrying about filling bits 00087 operator unsigned int(); // 32-bit flat value, quickest of all 00088 00089 friend HepStd::ostream& operator<< (HepStd::ostream& os, const RanshiEngine& e); 00090 friend HepStd::istream& operator>> (HepStd::istream& is, RanshiEngine& e); 00091 00092 private: 00093 static double twoToMinus_32; 00094 static double twoToMinus_53; 00095 static double nearlyTwoToMinus_54; 00096 void powersOfTwo(); 00097 00098 static int numEngines; 00099 enum {numBuff = 512}; 00100 00101 unsigned int halfBuff, numFlats; 00102 unsigned int buffer[numBuff]; 00103 unsigned int redSpin; 00104 00105 }; // RanshiEngine 00106 00107 #endif // HepRanshiEngine_h