OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
RNGXDiv.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 /***************************************************************************
3  *
4  * The IPPL Framework
5  *
6  *
7  * Visit http://people.web.psi.ch/adelmann/ for more details
8  *
9  ***************************************************************************/
10 
11 #ifndef RNG_XDIV_H
12 #define RNG_XDIV_H
13 
14 /***********************************************************************
15  *
16  * class RNGXDiv
17  * class RNGXDivSequence : public SequenceGen<RNGXDiv>
18  *
19  * Simple class that implements random number generator from LANL
20  * X-Division folks, in the range [0...1]. The first class may be
21  * used standalone, or as a template parameter to SequenceGen. The
22  * second class is derived from SequenceGen, and makes it easier to
23  * use this RNG in expressions.
24  * Use RNGXDiv as a scalar or container element, and use
25  * RNGXDivSequence when you need a sequence of numbers to fill a container.
26  *
27  ***********************************************************************/
28 
29 // include files
30 #include "Utility/SequenceGen.h"
31 
32 #ifdef IPPL_USE_SINGLE_PRECISION
33  #define CTYPE float
34 #else
35  #define CTYPE double
36 #endif
37 
38 class RNGXDiv {
39 
40 public:
41  // return type
42  typedef CTYPE Return_t;
43 
44 public:
45  // default constructor
46  RNGXDiv(int advance = 0) {
47  // set the first random number, composed of
48  // SeedUpper (top 24 bits) and SeedLower (bottom 24 bits).
49  SeedUpper = static_cast<double>(long(FirstSeed * INV_SQR_RANMAX));
51  AdvanceSeed(advance); // advance the seed
52  }
53 
54  // copy constructor
55  RNGXDiv(const RNGXDiv& rng)
58 
59  // destructor
60  ~RNGXDiv(void) {}
61 
62  // advance indicates number of times to advance random number source
63  inline void AdvanceSeed(int advance = 0) {
64  for (int iadv=0; iadv<advance; iadv++)
65  advijk();
66  // set sequence to new source
69  }
70 
71  // set seed to user-specified value, plus shift to ensure it is large
72  inline void SetSeed(unsigned long seed) {
73  Return_t rijk = Return_t(seed) + FirstSeed;
74  SeedUpper = static_cast<double>(long(rijk * INV_SQR_RANMAX));
75  SeedLower = rijk - SeedUpper * SQR_RANMAX;
76  // set sequence to new source
79  }
80 
81  // get seed value
82  inline unsigned long GetSeed(void) const {
83  // invert process for setting seed
85  unsigned long seed = (unsigned long) (rijk - FirstSeed);
86  return seed;
87  }
88 
89  // return the next pseudo-random number
90  inline Return_t GetRandom(void) const {
92  Return_t b = RandMultUpper * RandLower +
94  RandLower = a - long(a * INV_SQR_RANMAX) * SQR_RANMAX;
95  RandUpper = b - long(b * INV_SQR_RANMAX) * SQR_RANMAX;
96  return ( (RandUpper * SQR_RANMAX + RandLower) * INV_RANMAX );
97  }
98 
99  // pseudonym for GetRandom()
100  inline Return_t operator()(void) const { return GetRandom(); }
101 
102  // conversion to Return_t, same as GetRandom()
103  inline operator Return_t() const { return GetRandom(); }
104 
105  // return the period of the RNG
106  static Return_t GetRandMax(void) { return Return_t(RANDOM_MAX); }
107 
108 private:
110  mutable double RandLower, RandUpper;
111 
112  // advance random number seed for sequence
113  inline void advijk(void) {
115  Return_t b = (SeedMultUpper * SeedLower -
116  long(SeedMultUpper * SeedLower * INV_SQR_RANMAX) * SQR_RANMAX) +
118  long(SeedMultLower * SeedUpper * INV_SQR_RANMAX) * SQR_RANMAX) +
119  long(a * INV_SQR_RANMAX);
120  SeedLower = a - long(a * INV_SQR_RANMAX) * SQR_RANMAX;
121  SeedUpper = b - long(b * INV_SQR_RANMAX) * SQR_RANMAX;
122  }
123 
124  static const double RANDOM_MAX;
125  static const double SQR_RANMAX;
126  static const double INV_SQR_RANMAX;
127  static const double INV_RANMAX;
128  static const double SeedMultUpper;
129  static const double SeedMultLower;
130  static const double RandMultUpper;
131  static const double RandMultLower;
132  static const double FirstSeed;
133 };
134 
136 
137 
138 // A version of SequenceGen with extra constructors to make using this
139 // class easier. This is the version that people should use to fill
140 // containers with a random number sequence in an expression. This
141 // class is PETE-aware via its inheritance from SequenceGen.
142 
144 
145 public:
146  // default constructor
147  RNGXDivSequence(int advance = 0)
148  : SequenceGen<RNGXDiv>(RNGXDiv(advance)) {}
149 
150  // copy constructor
152  : SequenceGen<RNGXDiv>(rngseq.getGenerator()) {}
153 
154  // destructor
156 
157  // wrappers around RNG generator functions
158  inline void AdvanceSeed(int adv = 0) { getGenerator().AdvanceSeed(adv); }
159  inline void SetSeed(unsigned long seed) { getGenerator().SetSeed(seed); }
160  inline unsigned long GetSeed(void) const { return getGenerator().GetSeed(); }
161  inline Return_t GetRandom(void) { return getGenerator().GetRandom(); }
162  inline Return_t operator()(void) { return getGenerator().GetRandom(); }
163  static Return_t GetRandMax(void) { return RNGXDiv::GetRandMax(); }
164 };
165 
166 
167 #endif // RNG_XDIV_H
168 
169 /***************************************************************************
170  * $RCSfile: RNGXDiv.h,v $ $Author: adelmann $
171  * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:33 $
172  * IPPL_VERSION_ID: $Id: RNGXDiv.h,v 1.1.1.1 2003/01/23 07:40:33 adelmann Exp $
173  ***************************************************************************/
174 
int seed
The current random seed.
Definition: Options.cpp:41
Return_t operator()(void)
Definition: RNGXDiv.h:162
void SetSeed(unsigned long seed)
Definition: RNGXDiv.h:159
void advijk(void)
Definition: RNGXDiv.h:113
#define RNG_BASIC_MATH(GEN)
Definition: SequenceGen.h:65
static const double SeedMultUpper
Definition: RNGXDiv.h:128
Return_t GetRandom(void) const
Definition: RNGXDiv.h:90
static const double RandMultUpper
Definition: RNGXDiv.h:130
static const double RANDOM_MAX
Definition: RNGXDiv.h:124
Return_t GetRandom(void)
Definition: RNGXDiv.h:161
static Return_t GetRandMax(void)
Definition: RNGXDiv.h:163
~RNGXDiv(void)
Definition: RNGXDiv.h:60
static const double RandMultLower
Definition: RNGXDiv.h:131
double Return_t
Definition: RNGXDiv.h:42
static const double INV_SQR_RANMAX
Definition: RNGXDiv.h:126
void SetSeed(unsigned long seed)
Definition: RNGXDiv.h:72
RNGXDiv::Return_t Return_t
Definition: SequenceGen.h:89
RNGXDiv(const RNGXDiv &rng)
Definition: RNGXDiv.h:55
static Return_t GetRandMax(void)
Definition: RNGXDiv.h:106
static const double FirstSeed
Definition: RNGXDiv.h:132
RNGXDivSequence(int advance=0)
Definition: RNGXDiv.h:147
RNGXDivSequence(const RNGXDivSequence &rngseq)
Definition: RNGXDiv.h:151
static const double SeedMultLower
Definition: RNGXDiv.h:129
double RandUpper
Definition: RNGXDiv.h:110
double SeedUpper
Definition: RNGXDiv.h:109
unsigned long GetSeed(void) const
Definition: RNGXDiv.h:82
void AdvanceSeed(int adv=0)
Definition: RNGXDiv.h:158
Return_t operator()(void) const
Definition: RNGXDiv.h:100
unsigned long GetSeed(void) const
Definition: RNGXDiv.h:160
static const double INV_RANMAX
Definition: RNGXDiv.h:127
double SeedLower
Definition: RNGXDiv.h:109
static const double SQR_RANMAX
Definition: RNGXDiv.h:125
~RNGXDivSequence(void)
Definition: RNGXDiv.h:155
double RandLower
Definition: RNGXDiv.h:110
#define CTYPE
Definition: RNGXDiv.h:35
RNGXDiv(int advance=0)
Definition: RNGXDiv.h:46
void AdvanceSeed(int advance=0)
Definition: RNGXDiv.h:63