EGSnrc C++ class library  Report PIRS-898 (2021)
Iwan Kawrakow, Ernesto Mainegra-Hing, Frederic Tessier, Reid Townson and Blake Walters
egs_rndm.h
Go to the documentation of this file.
1 /*
2 ###############################################################################
3 #
4 # EGSnrc egs++ random number generators headers
5 # Copyright (C) 2015 National Research Council Canada
6 #
7 # This file is part of EGSnrc.
8 #
9 # EGSnrc is free software: you can redistribute it and/or modify it under
10 # the terms of the GNU Affero General Public License as published by the
11 # Free Software Foundation, either version 3 of the License, or (at your
12 # option) any later version.
13 #
14 # EGSnrc is distributed in the hope that it will be useful, but WITHOUT ANY
15 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
17 # more details.
18 #
19 # You should have received a copy of the GNU Affero General Public License
20 # along with EGSnrc. If not, see <http://www.gnu.org/licenses/>.
21 #
22 ###############################################################################
23 #
24 # Author: Iwan Kawrakow, 2005
25 #
26 # Contributors: Reid Townson
27 #
28 ###############################################################################
29 */
30 
31 
37 #ifndef EGS_RANDOM_GENERATOR_
38 #define EGS_RANDOM_GENERATOR_
39 
40 #include "egs_libconfig.h"
41 #include "egs_math.h"
42 #include "egs_functions.h"
43 #include "egs_input_struct.h"
44 
45 class EGS_Input;
46 
47 inline void addRngDefinitionBlockImpl(EGS_BlockInput &rngBlock) {
48  rngBlock.addSingleInput("type", true, "Algorithm used for RNG. Defaults to ranmar", {"ranmar"});
49  rngBlock.addSingleInput("initial seeds", true, "Two integers that represent the inital seed. The same input file running on the same computer will give idential results for the same seeds, and statistically independent for different seeds. Parallel runs automatically vary the seeds for each job.");
50  rngBlock.addSingleInput("high resolution", false, "Defaults to no. Microscale simulations may require high resolution RNG.", {"No", "Yes"});
51 }
52 
53 inline void addRngDefinitionBlock(const std::shared_ptr<EGS_InputStruct> &blockPtr) {
54  auto rngBlock = blockPtr->addBlockInput("rng definition");
55  addRngDefinitionBlockImpl(*rngBlock);
56 }
57 
58 inline void addRngDefinitionBlock(const std::shared_ptr<EGS_BlockInput> &blockPtr) {
59  auto rngBlock = blockPtr->addBlockInput("rng definition");
60  addRngDefinitionBlockImpl(*blockPtr);
61 }
62 
63 inline string addRngDefinitionExample() {
64  string example = {
65  R"(
66 :start rng definition:
67  type = ranmar
68  initial seeds = 33 97
69  high resolution = no
70 :stop rng definition:
71 )"};
72  return example;
73 }
74 
97 
98 public:
99 
107  EGS_RandomGenerator(int n=128);
108 
114  EGS_RandomGenerator(const EGS_RandomGenerator &r) : np(0) {
115  copyBaseState(r);
116  };
117 
122  virtual ~EGS_RandomGenerator() {
123  delete [] rarray;
124  };
125 
132  inline EGS_Float getUniform() {
133  if (ip >= np) {
134  fillArray(np,rarray);
135  ip = 0;
136  }
137  return rarray[ip++];
138  };
139 
145  EGS_I64 numbersGenerated() const {
146  return count;
147  };
148 
154  EGS_I64 numbersUsed() const {
155  return ip<np ? count - np + ip : count;
156  };
157 
167  inline void getAzimuth(EGS_Float &cphi, EGS_Float &sphi) {
168 #ifndef FAST_SINCOS
169  EGS_Float xphi,xphi2,yphi,yphi2,rhophi;
170  do {
171  xphi = 2*getUniform() - 1;
172  xphi2 = xphi*xphi;
173  yphi = getUniform();
174  yphi2 = yphi*yphi;
175  rhophi = xphi2 + yphi2;
176  }
177  while (rhophi > 1);
178  cphi = (xphi2 - yphi2)/rhophi;
179  sphi = 2*xphi*yphi/rhophi;
180 #else
181  EGS_Float phi = 2*M_PI*getUniform();
182  cphi = cos(phi);
183  sphi = sin(phi);
184 #endif
185  };
186 
190  inline EGS_Float getGaussian() {
191  if (have_x) {
192  have_x = false;
193  return the_x;
194  }
195  EGS_Float r = sqrt(-2*log(1-getUniform()));
196  EGS_Float cphi, sphi;
197  getAzimuth(cphi,sphi);
198  have_x = true;
199  the_x = r*sphi;
200  return r*cphi;
201  };
202 
217  static EGS_RandomGenerator *createRNG(EGS_Input *inp, int sequence=0);
218 
225  static EGS_RandomGenerator *defaultRNG(int sequence=0);
226 
238  virtual void fillArray(int n, EGS_Float *array) = 0;
239 
241 
256  bool storeState(ostream &data);
257  bool setState(istream &data);
258  bool addState(istream &data);
259  void resetCounter() {
260  count = 0;
261  };
263 
265  virtual EGS_RandomGenerator *getCopy() = 0;
266 
268  virtual void setState(EGS_RandomGenerator *r) = 0;
269 
271  virtual void saveState() = 0;
272 
274  virtual void resetState() = 0;
275 
277  virtual int rngSize() const = 0;
278 
285  virtual void describeRNG() const {};
286 
287 protected:
288 
289  EGS_I64 count;
290  int np;
291  int ip;
292  EGS_Float *rarray;
293 
303  virtual bool storePrivateState(ostream &data) = 0;
304 
312  virtual bool setPrivateState(istream &data) = 0;
313 
314  void copyBaseState(const EGS_RandomGenerator &r);
315 
316  void allocate(int n);
317 
319  int baseSize() const {
320  return 2*sizeof(EGS_I32) + sizeof(EGS_I64) + sizeof(bool) +
321  sizeof(EGS_Float) + np*sizeof(EGS_Float);
322  };
323 
324 
325 private:
326 
327  bool have_x;
328  EGS_Float the_x;
329 
330 };
331 
332 #endif
A class to represent an egsinp input block.
shared_ptr< EGS_BlockInput > addBlockInput(string blockTit, bool isReq=false)
Add an input block to be nested inside this one.
shared_ptr< EGS_SingleInput > addSingleInput(string inputTag, bool isReq, const string desc, const vector< string > vals=vector< string >())
Add a single input.
A class for storing information in a tree-like structure of key-value pairs. This class is used throu...
Definition: egs_input.h:182
Base random number generator class. All random number generators should be derived from this class.
Definition: egs_rndm.h:90
Global egspp functions header file.
The input struct header file.
Defines the EGS_EXPORT and EGS_LOCAL macros.
#define EGS_EXPORT
Export symbols from the egspp library.
Definition: egs_libconfig.h:90
Attempts to fix broken math header files.