src/Utility/RNGLattice.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_LATTICE_H
00012 #define RNG_LATTICE_H
00013 
00014 /***********************************************************************
00015  * 
00016  * class RNGLattice
00017  * class RNGLatticeSequence : public SequenceGen<RNGLattice>
00018  *
00019  * Lattice class that implements random number generator by just
00020  * providing an evenly spaced set of points between two endpoints.
00021  * 
00022  * Note that this only works properly automatically on 1 PE; with multipple PE's
00023  * you'll get a redundant set of points, the same on every PE, unless you take
00024  * care to provide appropriate different seeds for each PE and call SetSeed
00025  * before using it.
00026  * Use RNGLattice as a scalar or container element, and use
00027  * RNGLatticeSequence when you need a sequence of numbers to fill a container.
00028  *
00029  ***********************************************************************/
00030 
00031 #include "Utility/SequenceGen.h"
00032 
00033 
00034 template<class T>
00035 class RNGLattice {
00036 
00037 public:
00038   // return type
00039   typedef T Return_t;
00040 
00041   // constructor
00042   RNGLattice(T minval, T maxval, unsigned long numpoints,
00043              bool includeEndpoints = true)
00044     : MinVal(minval), MaxVal(maxval), CurrPoint(0), NumPoints(numpoints),
00045       IncludeEndpoints(includeEndpoints)
00046   {
00047     if (IncludeEndpoints) {
00048       if (NumPoints == 0 || NumPoints == 1) {
00049         Spacing = 0;
00050       }
00051       else {
00052         Spacing = (MaxVal - MinVal)/(NumPoints - 1);
00053       }
00054     }
00055     else {
00056       if (NumPoints == 0) {
00057         Spacing = 0;
00058       }
00059       else {
00060         Spacing = (MaxVal - MinVal)/NumPoints;
00061       }
00062     }
00063   }
00064 
00065   // copy constructor
00066   RNGLattice(const RNGLattice<T>& rng)
00067     : MinVal(rng.MinVal), MaxVal(rng.MaxVal), CurrPoint(rng.CurrPoint),
00068       Spacing(rng.Spacing), NumPoints(rng.NumPoints),
00069       IncludeEndpoints(rng.IncludeEndpoints) {}
00070 
00071   // destructor
00072   ~RNGLattice(void) {}
00073 
00074   // advance current point by n, modulo NumPoints
00075   inline void AdvanceSeed(unsigned long n = 0) {
00076     CurrPoint = (CurrPoint + n) % NumPoints;
00077     return;
00078   }
00079 
00080   // set current point to nth point, modulo NumPoints
00081   inline void SetSeed(unsigned long n = 0) {
00082     CurrPoint = n % NumPoints;
00083   }
00084 
00085   // get current point 
00086   inline unsigned long GetSeed(void) const { return CurrPoint; }
00087 
00088   // return the next pseudo-random number (from MinVal ... MaxVal)
00089   inline Return_t GetRandom(void) const {
00090     Return_t currVal;
00091     if (IncludeEndpoints)
00092       currVal = MinVal + CurrPoint * Spacing;
00093     else
00094       currVal = MinVal + (CurrPoint + 0.5) * Spacing;
00095     CurrPoint++;
00096     if (CurrPoint == NumPoints) CurrPoint = 0;
00097     return currVal;
00098   }
00099 
00100   // pseudonym for GetRandom()
00101   inline Return_t operator()(void) const { return GetRandom(); }
00102 
00103   // conversion to Return_t, same as GetRandom()
00104   inline operator Return_t() const { return GetRandom(); }
00105 
00106   // return the period of the RNG
00107   unsigned long GetRandMax(void) const { return NumPoints; }
00108 
00109 private:
00110   T MinVal, MaxVal, Spacing;
00111   mutable unsigned long CurrPoint;
00112   unsigned long NumPoints;
00113   bool IncludeEndpoints;
00114 };
00115 
00116 #ifdef IPPL_USE_SINGLE_PRECISION
00117 RNG_BASIC_MATH(RNGLattice<float>)
00118 #else
00119 RNG_BASIC_MATH(RNGLattice<double>)
00120 #endif
00121 
00122 // A version of RNGLattice with extra constructors to make using this
00123 // class easier.  This is the version that people should use to fill
00124 // containers with a random number sequence in an expression.  This
00125 // class is PETE-aware via its inheritance from SequenceGen.
00126 
00127 template<class T>
00128 class RNGLatticeSequence : public SequenceGen< RNGLattice<T> > {
00129 
00130 public:
00131   // constructor
00132   RNGLatticeSequence(T minval, T maxval, unsigned long numpoints,
00133                      bool includeEndpoints = true)
00134     : SequenceGen< RNGLattice<T> >(RNGLattice<T>(minval,maxval,numpoints,
00135                                                  includeEndpoints)) {}
00136 
00137   // copy constructor
00138   RNGLatticeSequence(const RNGLatticeSequence<T>& rngseq)
00139     : SequenceGen< RNGLattice<T> >(rngseq.getGenerator()) {}
00140 
00141   // destructor
00142   ~RNGLatticeSequence(void) {}
00143 
00144   // wrappers around RNG generator functions
00145   inline void     AdvanceSeed(unsigned long adv = 0) {
00146       this->getGenerator().AdvanceSeed(adv);
00147   }
00148   inline void     SetSeed(unsigned long seed) { this->getGenerator().SetSeed(seed); }
00149   inline unsigned long GetSeed(void) const { return this->getGenerator().GetSeed(); }
00150   inline
00151   typename RNGLattice<T>::Return_t
00152   GetRandom(void) { return this->getGenerator().GetRandom(); }
00153   inline
00154   typename RNGLattice<T>::Return_t
00155   operator()(void) { return this->getGenerator().GetRandom(); }
00156   unsigned long GetRandMax(void) const { return this->getGenerator().GetRandMax(); }
00157 };
00158 
00159 
00160 #endif // RNG_LATTICE_H
00161 
00162 /***************************************************************************
00163  * $RCSfile: RNGLattice.h,v $   $Author: adelmann $
00164  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:33 $
00165  * IPPL_VERSION_ID: $Id: RNGLattice.h,v 1.1.1.1 2003/01/23 07:40:33 adelmann Exp $ 
00166  ***************************************************************************/
00167 

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