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-2018 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 #include <config.h>
27 
28 #include <cassert>
29 #include <vector>
30 #include <random>
31 #include <sstream>
32 #include <iostream>
33 
34 //#define DEBUG_RANDCALLS
35 
36 // ===========================================================================
37 // class declarations
38 // ===========================================================================
39 class OptionsCont;
40 
41 
42 // ===========================================================================
43 // class definitions
44 // ===========================================================================
49 class RandHelper {
50 public:
52  static void insertRandOptions();
53 
55  static void initRand(std::mt19937* which = 0, const bool random = false, const int seed = 23423);
56 
58  static void initRandGlobal(std::mt19937* which = 0);
59 
61  static inline double rand(std::mt19937* rng = 0) {
62  if (rng == 0) {
64  }
65  const double res = double((*rng)() / 4294967296.0);
66 #ifdef DEBUG_RANDCALLS
67  myCallCount++;
68  if (myCallCount == myDebugIndex) {
69  std::cout << "DEBUG\n"; // for setting breakpoint
70  }
71  std::cout << " rand call=" << myCallCount << " val=" << res << "\n";
72 #endif
73  return res;
74  }
75 
77  static inline double rand(double maxV, std::mt19937* rng = 0) {
78  return maxV * rand(rng);
79  }
80 
82  static inline double rand(double minV, double maxV, std::mt19937* rng = 0) {
83  return minV + (maxV - minV) * rand(rng);
84  }
85 
87  static inline int rand(int maxV, std::mt19937* rng = 0) {
88  if (rng == 0) {
90  }
91  unsigned int usedBits = maxV - 1;
92  usedBits |= usedBits >> 1;
93  usedBits |= usedBits >> 2;
94  usedBits |= usedBits >> 4;
95  usedBits |= usedBits >> 8;
96  usedBits |= usedBits >> 16;
97 
98  // Draw numbers until one is found in [0, maxV-1]
99  int result;
100  do {
101  result = (*rng)() & usedBits;
102  } while (result >= maxV);
103  return result;
104  }
105 
107  static inline int rand(int minV, int maxV, std::mt19937* rng = 0) {
108  return minV + rand(maxV - minV, rng);
109  }
110 
112  static inline long long int rand(long long int maxV, std::mt19937* rng = 0) {
113  if (maxV <= std::numeric_limits<int>::max()) {
114  return rand((int)maxV, rng);
115  }
116  if (rng == 0) {
118  }
119  unsigned long long int usedBits = maxV - 1;
120  usedBits |= usedBits >> 1;
121  usedBits |= usedBits >> 2;
122  usedBits |= usedBits >> 4;
123  usedBits |= usedBits >> 8;
124  usedBits |= usedBits >> 16;
125  usedBits |= usedBits >> 32;
126 
127  // Draw numbers until one is found in [0, maxV-1]
128  long long int result;
129  do {
130  result = (((unsigned long long int)(*rng)() << 32) | (*rng)()) & usedBits; // toss unused bits to shorten search
131  } while (result >= maxV);
132  return result;
133  }
134 
136  static inline long long int rand(long long int minV, long long int maxV, std::mt19937* rng = 0) {
137  return minV + rand(maxV - minV, rng);
138  }
139 
141  static inline double randNorm(double mean, double variance, std::mt19937* rng = 0) {
142  // Polar method to avoid cosine
143  double u, q;
144  do {
145  u = rand(2.0, rng) - 1;
146  const double v = rand(2.0, rng) - 1;
147  q = u * u + v * v;
148  } while (q == 0.0 || q >= 1.0);
149  return (double)(mean + variance * u * sqrt(-2 * log(q) / q));
150  }
151 
153  template<class T>
154  static inline const T&
155  getRandomFrom(const std::vector<T>& v, std::mt19937* rng = 0) {
156  assert(v.size() > 0);
157  return v[rand((int)v.size(), rng)];
158  }
159 
161  static std::string saveState(std::mt19937* rng = 0) {
162  if (rng == 0) {
164  }
165  std::ostringstream oss;
166  oss << (*rng);
167  return oss.str();
168  }
169 
171  static void loadState(const std::string& state, std::mt19937* rng = 0) {
172  if (rng == 0) {
174  }
175  std::istringstream iss(state);
176  iss >> (*rng);
177  }
178 
179 
180 protected:
182  static std::mt19937 myRandomNumberGenerator;
183 
185  static int myCallCount;
186  static int myDebugIndex;
187 
188 };
189 
190 #endif
191 
192 /****************************************************************************/
static std::string saveState(std::mt19937 *rng=0)
save rng state to string
Definition: RandHelper.h:161
static double rand(double minV, double maxV, std::mt19937 *rng=0)
Returns a random real number in [minV, maxV)
Definition: RandHelper.h:82
static void insertRandOptions()
Initialises the given options container with random number options.
Definition: RandHelper.cpp:43
static double rand(double maxV, std::mt19937 *rng=0)
Returns a random real number in [0, maxV)
Definition: RandHelper.h:77
static double rand(std::mt19937 *rng=0)
Returns a random real number in [0, 1)
Definition: RandHelper.h:61
static int rand(int minV, int maxV, std::mt19937 *rng=0)
Returns a random integer in [minV, maxV-1].
Definition: RandHelper.h:107
static int myCallCount
only used for debugging;
Definition: RandHelper.h:185
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:112
Utility functions for using a global, resetable random number generator.
Definition: RandHelper.h:49
static int rand(int maxV, std::mt19937 *rng=0)
Returns a random integer in [0, maxV-1].
Definition: RandHelper.h:87
static double randNorm(double mean, double variance, std::mt19937 *rng=0)
Access to a random number from a normal distribution.
Definition: RandHelper.h:141
static int myDebugIndex
Definition: RandHelper.h:186
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:136
static std::mt19937 myRandomNumberGenerator
the random number generator to use
Definition: RandHelper.h:182
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
static const T & getRandomFrom(const std::vector< T > &v, std::mt19937 *rng=0)
Returns a random element from the given vector.
Definition: RandHelper.h:155
A storage for options typed value containers)
Definition: OptionsCont.h:92
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
static void loadState(const std::string &state, std::mt19937 *rng=0)
load rng state from string
Definition: RandHelper.h:171