Eclipse SUMO - Simulation of Urban MObility
RandHelper.h
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2005-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
17 //
18 /****************************************************************************/
19 #ifndef RandHelper_h
20 #define RandHelper_h
21 
22 
23 // ===========================================================================
24 // included modules
25 // ===========================================================================
26 
27 #include <cassert>
28 #include <vector>
29 #include <random>
30 #include <sstream>
31 #include <iostream>
32 
33 //#define DEBUG_RANDCALLS
34 
35 // ===========================================================================
36 // class declarations
37 // ===========================================================================
38 class OptionsCont;
39 
40 
41 // ===========================================================================
42 // class definitions
43 // ===========================================================================
48 class RandHelper {
49 public:
51  static void insertRandOptions();
52 
54  static void initRand(std::mt19937* which = 0, const bool random = false, const int seed = 23423);
55 
57  static void initRandGlobal(std::mt19937* which = 0);
58 
60  static inline double rand(std::mt19937* rng = 0) {
61  if (rng == 0) {
63  }
64  const double res = double((*rng)() / 4294967296.0);
65 #ifdef DEBUG_RANDCALLS
66  myCallCount++;
67  if (myCallCount == myDebugIndex) {
68  std::cout << "DEBUG\n"; // for setting breakpoint
69  }
70  std::cout << " rand call=" << myCallCount << " val=" << res << "\n";
71 #endif
72  return res;
73  }
74 
76  static inline double rand(double maxV, std::mt19937* rng = 0) {
77  return maxV * rand(rng);
78  }
79 
81  static inline double rand(double minV, double maxV, std::mt19937* rng = 0) {
82  return minV + (maxV - minV) * rand(rng);
83  }
84 
86  static inline int rand(int maxV, std::mt19937* rng = 0) {
87  if (rng == 0) {
89  }
90  unsigned int usedBits = maxV - 1;
91  usedBits |= usedBits >> 1;
92  usedBits |= usedBits >> 2;
93  usedBits |= usedBits >> 4;
94  usedBits |= usedBits >> 8;
95  usedBits |= usedBits >> 16;
96 
97  // Draw numbers until one is found in [0, maxV-1]
98  int result;
99  do {
100  result = (*rng)() & usedBits;
101  } while (result >= maxV);
102  return result;
103  }
104 
106  static inline int rand(int minV, int maxV, std::mt19937* rng = 0) {
107  return minV + rand(maxV - minV, rng);
108  }
109 
111  static inline long long int rand(long long int maxV, std::mt19937* rng = 0) {
112  if (maxV <= std::numeric_limits<int>::max()) {
113  return rand((int)maxV, rng);
114  }
115  if (rng == 0) {
117  }
118  unsigned long long int usedBits = maxV - 1;
119  usedBits |= usedBits >> 1;
120  usedBits |= usedBits >> 2;
121  usedBits |= usedBits >> 4;
122  usedBits |= usedBits >> 8;
123  usedBits |= usedBits >> 16;
124  usedBits |= usedBits >> 32;
125 
126  // Draw numbers until one is found in [0, maxV-1]
127  long long int result;
128  do {
129  result = (((unsigned long long int)(*rng)() << 32) | (*rng)()) & usedBits; // toss unused bits to shorten search
130  } while (result >= maxV);
131  return result;
132  }
133 
135  static inline long long int rand(long long int minV, long long int maxV, std::mt19937* rng = 0) {
136  return minV + rand(maxV - minV, rng);
137  }
138 
140  static inline double randNorm(double mean, double variance, std::mt19937* rng = 0) {
141  // Polar method to avoid cosine
142  double u, q;
143  do {
144  u = rand(2.0, rng) - 1;
145  const double v = rand(2.0, rng) - 1;
146  q = u * u + v * v;
147  } while (q == 0.0 || q >= 1.0);
148  return (double)(mean + variance * u * sqrt(-2 * log(q) / q));
149  }
150 
152  template<class T>
153  static inline const T&
154  getRandomFrom(const std::vector<T>& v, std::mt19937* rng = 0) {
155  assert(v.size() > 0);
156  return v[rand((int)v.size(), rng)];
157  }
158 
160  static std::string saveState(std::mt19937* rng = 0) {
161  if (rng == 0) {
163  }
164  std::ostringstream oss;
165  oss << (*rng);
166  return oss.str();
167  }
168 
170  static void loadState(const std::string& state, std::mt19937* rng = 0) {
171  if (rng == 0) {
173  }
174  std::istringstream iss(state);
175  iss >> (*rng);
176  }
177 
178 
179 protected:
181  static std::mt19937 myRandomNumberGenerator;
182 
184  static int myCallCount;
185  static int myDebugIndex;
186 
187 };
188 
189 #endif
190 
191 /****************************************************************************/
RandHelper::saveState
static std::string saveState(std::mt19937 *rng=0)
save rng state to string
Definition: RandHelper.h:160
RandHelper::randNorm
static double randNorm(double mean, double variance, std::mt19937 *rng=0)
Access to a random number from a normal distribution.
Definition: RandHelper.h:140
RandHelper
Utility functions for using a global, resetable random number generator.
Definition: RandHelper.h:48
RandHelper::rand
static long long int rand(long long int minV, long long int maxV, std::mt19937 *rng=0)
Returns a random 64 bit integer in [minV, maxV-1].
Definition: RandHelper.h:135
RandHelper::rand
static double rand(std::mt19937 *rng=0)
Returns a random real number in [0, 1)
Definition: RandHelper.h:60
RandHelper::rand
static int rand(int minV, int maxV, std::mt19937 *rng=0)
Returns a random integer in [minV, maxV-1].
Definition: RandHelper.h:106
RandHelper::myCallCount
static int myCallCount
only used for debugging;
Definition: RandHelper.h:184
RandHelper::rand
static long long int rand(long long int maxV, std::mt19937 *rng=0)
Returns a random 64 bit integer in [0, maxV-1].
Definition: RandHelper.h:111
RandHelper::rand
static int rand(int maxV, std::mt19937 *rng=0)
Returns a random integer in [0, maxV-1].
Definition: RandHelper.h:86
RandHelper::getRandomFrom
static const T & getRandomFrom(const std::vector< T > &v, std::mt19937 *rng=0)
Returns a random element from the given vector.
Definition: RandHelper.h:154
OptionsCont
A storage for options typed value containers)
Definition: OptionsCont.h:90
RandHelper::myDebugIndex
static int myDebugIndex
Definition: RandHelper.h:185
RandHelper::initRandGlobal
static void initRandGlobal(std::mt19937 *which=0)
Reads the given random number options and initialises the random number generator in accordance.
Definition: RandHelper.cpp:72
RandHelper::myRandomNumberGenerator
static std::mt19937 myRandomNumberGenerator
the random number generator to use
Definition: RandHelper.h:181
RandHelper::loadState
static void loadState(const std::string &state, std::mt19937 *rng=0)
load rng state from string
Definition: RandHelper.h:170
RandHelper::rand
static double rand(double minV, double maxV, std::mt19937 *rng=0)
Returns a random real number in [minV, maxV)
Definition: RandHelper.h:81
RandHelper::insertRandOptions
static void insertRandOptions()
Initialises the given options container with random number options.
Definition: RandHelper.cpp:43
RandHelper::initRand
static void initRand(std::mt19937 *which=0, const bool random=false, const int seed=23423)
Initialises the random number generator with hardware randomness or seed.
Definition: RandHelper.cpp:59
RandHelper::rand
static double rand(double maxV, std::mt19937 *rng=0)
Returns a random real number in [0, maxV)
Definition: RandHelper.h:76