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 /****************************************************************************/
16 //
17 /****************************************************************************/
18 #ifndef RandHelper_h
19 #define RandHelper_h
20 
21 
22 // ===========================================================================
23 // included modules
24 // ===========================================================================
25 #include <cassert>
26 #include <vector>
27 #include <map>
28 #include <random>
29 #include <sstream>
30 #include <iostream>
31 
32 //#define DEBUG_RANDCALLS
33 
34 // ===========================================================================
35 // class definitions
36 // ===========================================================================
41 class RandHelper {
42 public:
44  static void insertRandOptions();
45 
47  static void initRand(std::mt19937* which = 0, const bool random = false, const int seed = 23423);
48 
50  static void initRandGlobal(std::mt19937* which = 0);
51 
53  static inline double rand(std::mt19937* rng = 0) {
54  if (rng == 0) {
56  }
57  const double res = double((*rng)() / 4294967296.0);
58 #ifdef DEBUG_RANDCALLS
59  myCallCount[rng]++;
60  if (myCallCount[rng] == myDebugIndex) {
61  std::cout << "DEBUG\n"; // for setting breakpoint
62  }
63  std::stringstream stream; // to reduce output interleaving from different threads
64  stream << " rng" << myRngId.find(rng)->second << " rand call=" << myCallCount[rng] << " val=" << res << "\n";
65  std::cout << stream.str();
66 #endif
67  return res;
68  }
69 
71  static inline double rand(double maxV, std::mt19937* rng = 0) {
72  return maxV * rand(rng);
73  }
74 
76  static inline double rand(double minV, double maxV, std::mt19937* rng = 0) {
77  return minV + (maxV - minV) * rand(rng);
78  }
79 
81  static inline int rand(int maxV, std::mt19937* rng = 0) {
82  if (rng == 0) {
84  }
85  unsigned int usedBits = maxV - 1;
86  usedBits |= usedBits >> 1;
87  usedBits |= usedBits >> 2;
88  usedBits |= usedBits >> 4;
89  usedBits |= usedBits >> 8;
90  usedBits |= usedBits >> 16;
91 
92  // Draw numbers until one is found in [0, maxV-1]
93  int result;
94  do {
95  result = (*rng)() & usedBits;
96  } while (result >= maxV);
97  return result;
98  }
99 
101  static inline int rand(int minV, int maxV, std::mt19937* rng = 0) {
102  return minV + rand(maxV - minV, rng);
103  }
104 
106  static inline long long int rand(long long int maxV, std::mt19937* rng = 0) {
107  if (maxV <= std::numeric_limits<int>::max()) {
108  return rand((int)maxV, rng);
109  }
110  if (rng == 0) {
112  }
113  unsigned long long int usedBits = maxV - 1;
114  usedBits |= usedBits >> 1;
115  usedBits |= usedBits >> 2;
116  usedBits |= usedBits >> 4;
117  usedBits |= usedBits >> 8;
118  usedBits |= usedBits >> 16;
119  usedBits |= usedBits >> 32;
120 
121  // Draw numbers until one is found in [0, maxV-1]
122  long long int result;
123  do {
124  result = (((unsigned long long int)(*rng)() << 32) | (*rng)()) & usedBits; // toss unused bits to shorten search
125  } while (result >= maxV);
126  return result;
127  }
128 
130  static inline long long int rand(long long int minV, long long int maxV, std::mt19937* rng = 0) {
131  return minV + rand(maxV - minV, rng);
132  }
133 
135  static inline double randNorm(double mean, double variance, std::mt19937* rng = 0) {
136  // Polar method to avoid cosine
137  double u, q;
138  do {
139  u = rand(2.0, rng) - 1;
140  const double v = rand(2.0, rng) - 1;
141  q = u * u + v * v;
142  } while (q == 0.0 || q >= 1.0);
143  return (double)(mean + variance * u * sqrt(-2 * log(q) / q));
144  }
145 
147  template<class T>
148  static inline const T&
149  getRandomFrom(const std::vector<T>& v, std::mt19937* rng = 0) {
150  assert(v.size() > 0);
151  return v[rand((int)v.size(), rng)];
152  }
153 
155  static std::string saveState(std::mt19937* rng = 0) {
156  if (rng == 0) {
158  }
159  std::ostringstream oss;
160  oss << (*rng);
161  return oss.str();
162  }
163 
165  static void loadState(const std::string& state, std::mt19937* rng = 0) {
166  if (rng == 0) {
168  }
169  std::istringstream iss(state);
170  iss >> (*rng);
171  }
172 
173 
174 protected:
176  static std::mt19937 myRandomNumberGenerator;
177 
178 #ifdef DEBUG_RANDCALLS
179  static std::map<std::mt19937*, int> myCallCount;
180  static std::map<std::mt19937*, int> myRngId;
181  static int myDebugIndex;
182 #endif
183 
184 };
185 
186 #endif
187 
188 /****************************************************************************/
RandHelper::saveState
static std::string saveState(std::mt19937 *rng=0)
save rng state to string
Definition: RandHelper.h:155
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:135
RandHelper
Utility functions for using a global, resetable random number generator.
Definition: RandHelper.h:41
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:130
RandHelper::rand
static double rand(std::mt19937 *rng=0)
Returns a random real number in [0, 1)
Definition: RandHelper.h:53
RandHelper::rand
static int rand(int minV, int maxV, std::mt19937 *rng=0)
Returns a random integer in [minV, maxV-1].
Definition: RandHelper.h:101
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:106
RandHelper::rand
static int rand(int maxV, std::mt19937 *rng=0)
Returns a random integer in [0, maxV-1].
Definition: RandHelper.h:81
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:149
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:77
RandHelper::myRandomNumberGenerator
static std::mt19937 myRandomNumberGenerator
the random number generator to use
Definition: RandHelper.h:176
RandHelper::loadState
static void loadState(const std::string &state, std::mt19937 *rng=0)
load rng state from string
Definition: RandHelper.h:165
RandHelper::rand
static double rand(double minV, double maxV, std::mt19937 *rng=0)
Returns a random real number in [minV, maxV)
Definition: RandHelper.h:76
RandHelper::insertRandOptions
static void insertRandOptions()
Initialises the given options container with random number options.
Definition: RandHelper.cpp:45
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:61
RandHelper::rand
static double rand(double maxV, std::mt19937 *rng=0)
Returns a random real number in [0, maxV)
Definition: RandHelper.h:71