src/Utility/RNGRand.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /***************************************************************************
00003  *
00004  * The IPPL Framework
00005  * 
00006  *
00007  * Visit http://people.web.psi.ch/adelmann/ for more details
00008  *
00009  ***************************************************************************/
00010 
00011 #ifndef RNG_RAND_H
00012 #define RNG_RAND_H
00013 
00014 /***********************************************************************
00015  * 
00016  * class RNGRand
00017  * class RNGRandSequence : public SequenceGen<RNGRand>
00018  *
00019  * Simple wrapper around C rand() function, to generate random numbers
00020  * in the range [0...1].  The first class may be
00021  * used standalone, or as a template parameter to SequenceGen.  The
00022  * second class is derived from SequenceGen, and makes it easier to
00023  * use this RNG in expressions.
00024  * Use RNGRand as a scalar or container element, and use
00025  * RNGRandSequence when you need a sequence of numbers to fill a container.
00026  *
00027  ***********************************************************************/
00028 
00029 // include files
00030 #include "Utility/SequenceGen.h"
00031 
00032 #include <stdlib.h>
00033 
00034 class RNGRand {
00035 
00036 public:
00037   // return type
00038   typedef double Return_t;
00039 
00040 public:
00041   // default constructor
00042   RNGRand(int advance = 0) : CurrentSeed(1U) { AdvanceSeed(advance); }
00043 
00044   // copy constructor
00045   RNGRand(const RNGRand& rng) : CurrentSeed(rng.CurrentSeed) {}
00046 
00047   // destructor
00048   ~RNGRand(void) {}
00049 
00050   // advance indicates number of times to advance random number source
00051   // there's no standard way to do this with rand(), so make one up!
00052   // just require one-to-one correspondence of old and new seeds
00053   inline void AdvanceSeed(int advance = 0) {
00054     for (int iadv=0; iadv<advance; iadv++) {
00055       // first reseed with current seed
00056       srand(CurrentSeed);
00057       // use first random number as seed step
00058       int seedstep = rand();
00059       CurrentSeed = (CurrentSeed + seedstep) % RAND_MAX;
00060     }
00061     // finally, reseed with new seed value
00062     srand(CurrentSeed);
00063   }
00064 
00065   // set seed to user-specified value (any shifting is done by srand)
00066   inline void SetSeed(unsigned int seed) {
00067     CurrentSeed = seed;
00068     srand(CurrentSeed);
00069   }
00070 
00071   // get seed value
00072   inline unsigned int GetSeed(void) const { return CurrentSeed; }
00073 
00074   // return the next pseudo-random number (from 0 ... 1)
00075   inline Return_t GetRandom(void) const {
00076     return ( (Return_t(rand())) / (Return_t(RAND_MAX)+1) );
00077   }
00078 
00079   // pseudonym for GetRandom()
00080   inline Return_t operator()(void) const { return GetRandom(); }
00081 
00082   // conversion to Return_t, same as GetRandom()
00083   inline operator Return_t() const { return GetRandom(); }
00084 
00085   // return the period of the RNG
00086   static Return_t GetRandMax(void) { return Return_t(RAND_MAX)+1; }
00087 
00088 private:
00089   unsigned int CurrentSeed;
00090 };
00091 
00092 RNG_BASIC_MATH(RNGRand)
00093 
00094 
00095 // A version of SequenceGen with extra constructors to make using this
00096 // class easier.  This is the version that people should use to fill
00097 // containers with a random number sequence in an expression.  This
00098 // class is PETE-aware via its inheritance from SequenceGen.
00099 
00100 class RNGRandSequence : public SequenceGen<RNGRand> {
00101 
00102 public:
00103   // default constructor
00104   RNGRandSequence(int advance = 0)
00105     : SequenceGen<RNGRand>(RNGRand(advance)) {}
00106 
00107   // copy constructor
00108   RNGRandSequence(const RNGRandSequence& rngseq)
00109     : SequenceGen<RNGRand>(rngseq.getGenerator()) {}
00110 
00111   // destructor
00112   ~RNGRandSequence(void) {}
00113 
00114   // wrappers around RNG generator functions
00115   inline void     AdvanceSeed(int adv = 0) { getGenerator().AdvanceSeed(adv); }
00116   inline void     SetSeed(unsigned int seed) { getGenerator().SetSeed(seed); }
00117   inline unsigned int GetSeed(void) const { return getGenerator().GetSeed(); }
00118   inline Return_t GetRandom(void) { return getGenerator().GetRandom(); }
00119   inline Return_t operator()(void) { return getGenerator().GetRandom(); }
00120   static Return_t GetRandMax(void) { return RNGRand::GetRandMax(); }
00121 };
00122 
00123 
00124 #endif // RNG_RAND_H
00125 
00126 /***************************************************************************
00127  * $RCSfile: RNGRand.h,v $   $Author: adelmann $
00128  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:33 $
00129  * IPPL_VERSION_ID: $Id: RNGRand.h,v 1.1.1.1 2003/01/23 07:40:33 adelmann Exp $ 
00130  ***************************************************************************/
00131 

Generated on Mon Jan 16 13:23:59 2006 for IPPL by  doxygen 1.4.6