00001 // $Id: TripleRand.h,v 1.10 2002/04/12 15:02:45 evc Exp $ 00002 // -*- C++ -*- 00003 // 00004 // ----------------------------------------------------------------------- 00005 // Hep Random 00006 // --- TripleRand --- 00007 // class header file 00008 // ----------------------------------------------------------------------- 00009 // A canopy pseudo-random number generator. Using the Tausworthe 00010 // exclusive-or shift register, a simple Integer Coungruence generator, and 00011 // the Hurd 288 total bit shift register, all XOR'd with each other, we 00012 // provide an engine that should be a fairly good "mother" generator. 00013 // 00014 // This is similar to DualRand, with the addition of the Hurd288Engine. 00015 // From DualRand, we have the following: 00016 // Exclusive or of a feedback shift register and integer congruence 00017 // random number generator. The feedback shift register uses offsets 00018 // 127 and 97. The integer congruence generator uses a different 00019 // multiplier for each stream. The multipliers are chosen to give 00020 // full period and maximum "potency" for modulo 2^32. The period of 00021 // the combined random number generator is 2^159 - 2^32, and the 00022 // sequences are different for each stream (not just started in a 00023 // different place). 00024 // The above is then amended to also add in the exclusive or of the 00025 // 288-total bit Hurd engine which in this case is a series of 32 00026 // interconnected 9-bit shift registers, with the newest bit of each register 00027 // formed by the XOR of the previous bit and some bit b-d from a previous 00028 // register where d is chosen to create a primitive polynomial to maximize 00029 // the period. 00030 // ======================================================================= 00031 // Ken Smith - Initial draft started: 23rd Jul 1998 00032 // - Added conversion operators: 6th Aug 1998 00033 // M Fischler - Big merge with CLHEP 13 May 1999 00034 // - Elimination of unused Taus() and Cong() accessors 00035 // ======================================================================= 00036 00037 #ifndef TripleRand_h 00038 #define TripleRand_h 00039 00040 #include "CLHEP/Random/RandomEngine.h" 00041 #include "CLHEP/Random/Hurd288Engine.h" 00042 00047 class TripleRand: public HepRandomEngine { 00048 00049 public: 00050 00051 TripleRand(); 00052 TripleRand( long seed ); 00053 TripleRand( HepStd::istream & is ); 00054 TripleRand( int rowIndex, int colIndex ); 00055 virtual ~TripleRand(); 00056 // Constructors and destructor 00057 00058 TripleRand( const TripleRand & p ); 00059 TripleRand & operator=( const TripleRand & p ); 00060 // Copy constructor and operator= 00061 00062 double flat(); 00063 // 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 an 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[] = "TripleRand.conf" ) const; 00077 // Saves on named file the current engine status. 00078 00079 void restoreStatus( const char filename[] = "TripleRand.conf" ); 00080 // Reads from named file the last saved engine status and restores it. 00081 00082 void showStatus() const; 00083 // Dumps the current engine status on the screen. 00084 00085 operator float(); // flat value, without worrying about filling bits 00086 operator unsigned int(); // 32-bit flat value, quickest of all 00087 00088 friend HepStd::ostream & operator<<( HepStd::ostream & os, const TripleRand & e ); 00089 friend HepStd::istream & operator>>( HepStd::istream & is, TripleRand & e ); 00090 00091 private: 00092 00093 static int numEngines; 00094 00099 class Tausworthe { 00100 public: 00101 00102 Tausworthe(); 00103 Tausworthe(unsigned int seed); 00104 00105 operator unsigned int(); 00106 00107 void put( HepStd::ostream & os ) const; 00108 void get( HepStd::istream & is ); 00109 00110 private: 00111 00112 int wordIndex; 00113 unsigned int words[4]; 00114 }; // Tausworthe 00115 00120 class IntegerCong { 00121 public: 00122 00123 IntegerCong(); 00124 IntegerCong(unsigned int seed, int streamNumber); 00125 00126 operator unsigned int(); 00127 00128 void put( HepStd::ostream & os ) const; 00129 void get( HepStd::istream & is ); 00130 00131 private: 00132 00133 unsigned int state, multiplier, addend; 00134 }; // IntegerCong 00135 00136 static double twoToMinus_32; 00137 static double twoToMinus_53; 00138 static double nearlyTwoToMinus_54; 00139 void powersOfTwo(); 00140 00141 Hurd288Engine & Hurd(); // retrieve the constituent engine for input 00142 00143 const Tausworthe & ConstTaus() const; // Same as above 00144 const IntegerCong & ConstCong() const; // necessary for 00145 const Hurd288Engine & ConstHurd() const; // output 00146 00147 Tausworthe tausworthe; // Instances of each of the 00148 IntegerCong integerCong; // three engines that combine to make 00149 Hurd288Engine hurd; // one TripleRand instance 00150 00151 }; // TripleRand 00152 00153 #endif // TripleRand_h