CLHEP/Random/TripleRand.h

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

Class Library for High Energy Physics (version 1.8)