Helios++
Helios software for LiDAR simulations
RandomnessGenerator.h
1 #pragma once
2 
3 #include <memory>
4 #include <HeliosException.h>
5 /*
6  * Random device, mersenne twister, and distributions were changes from
7  * std::random to boost::random because the latter ones are consistent among
8  * different platforms
9  */
10 // #include <random> // std::random include, no longer used
11 #include <boost/random/mersenne_twister.hpp>
12 #include <boost/random/uniform_real_distribution.hpp>
13 #include <boost/random/normal_distribution.hpp>
14 #include <boost/random/random_device.hpp>
15 
22 void setDefaultRandomnessGeneratorSeed(std::string const seed = "");
23 
33 template <typename RealType>
35 protected:
36  // *** ATTRIBUTES *** //
37  // ******************** //
47  std::string mode;
48 
52  double doubleSeed = 0;
56  long longSeed = 0;
57 
61  std::unique_ptr<boost::mt19937> urdGen = nullptr;
65  std::unique_ptr<
66  boost::random::uniform_real_distribution<RealType>
67  > urd = nullptr;
68 
72  std::unique_ptr<boost::mt19937> ndGen = nullptr;
76  std::unique_ptr<boost::normal_distribution<RealType>> nd = nullptr;
77 
78 
79  // *** INTERNAL SEED FUNCTIONS *** //
80  // ********************************* //
87  double getDoubleSeed(){return doubleSeed;}
94  long getLongSeed(){return longSeed;}
95 public:
96  // *** CONSTRUCTION *** //
97  // ********************** //
102  RandomnessGenerator():mode("AUTO_SEED"){};
103 
108  explicit RandomnessGenerator(double seed) :
109  mode("FIXED_SEED_DOUBLE"),
110  doubleSeed(seed)
111  {}
117  explicit RandomnessGenerator(float seed) :
118  mode("FIXED_SEED_DOUBLE"),
119  doubleSeed((double)seed)
120  {}
121 
126  explicit RandomnessGenerator(long seed) :
127  mode("FIXED_SEED_LONG"),
128  longSeed(seed)
129  {}
135  explicit RandomnessGenerator(int seed) :
136  mode("FIXED_SEED_LONG"),
137  longSeed((long)seed)
138  {}
139 
149  explicit RandomnessGenerator(std::string const &seedstr);
150 
162 
168 
169  // *** ASSIGNMENT OPERATORS *** //
170  // ****************************** //
183 
184  // *** S W A P *** //
185  // ******************* //
191  void swap(
192  RandomnessGenerator &rgA,
194  );
195 
196  // *** RANDOMNESS METHODS *** //
197  // **************************** //
206  RealType lowerBound, RealType upperBound
207  );
224  void computeNormalDistribution(RealType mean, RealType stdev);
236 
237 
238 };
239 
240 // *** DEFAULT RANDOMNESS GENERATOR *** //
241 // ************************************** //
242 extern bool DEFAULT_RG_MODIFIED_FLAG;
243 extern std::unique_ptr<RandomnessGenerator<double>> DEFAULT_RG;
244 
245 
246 
247 
248 // *** CLASS IMPLEMENTATION *** //
249 // ********************************* //
250 
251 // *** CONSTRUCTION *** //
252 // ********************** //
253 template<typename RealType>
255  bool isTimestamp = false;
256  bool isDouble = false;
257  for(size_t i = 0 ; i < seedstr.length() ; i++){
258  if(seedstr[i] == ':') isTimestamp = true;
259  if(seedstr[i] == '.') isDouble = true;
260  }
261 
262  if(isTimestamp){
263  mode = "FIXED_SEED_LONG";
264  longSeed = 0;
265  longSeed += (std::stol(seedstr.substr(0,4))-1970)*31104000;
266  longSeed += std::stol(seedstr.substr(5,2))*2592000;
267  longSeed += std::stol(seedstr.substr(8,2))*86400;
268  longSeed += std::stol(seedstr.substr(11,2))*3600;
269  longSeed += std::stol(seedstr.substr(14,2))*60;
270  longSeed += std::stol(seedstr.substr(17,2));
271  }
272  else if(isDouble){
273  mode = "FIXED_SEED_DOUBLE";
274  doubleSeed = std::stod(seedstr);
275  }
276  else{
277  mode = "FIXED_SEED_LONG";
278  longSeed = std::stol(seedstr);
279  }
280 }
281 
282 template<typename RealType>
284  RandomnessGenerator const &rg
285 ){
286  this->mode = rg.mode;
287  this->doubleSeed = rg.doubleSeed;
288  this->longSeed = rg.longSeed;
289 
290  if(rg.urdGen == nullptr) this->urdGen = nullptr;
291  else this->urdGen = std::unique_ptr<boost::mt19937>(
292  new boost::mt19937(*rg.urdGen)
293  );
294  if(rg.urd == nullptr) this->urdGen = nullptr;
295  else this->urd =
296  std::unique_ptr<boost::random::uniform_real_distribution<RealType>>(
297  new boost::random::uniform_real_distribution<RealType>(*rg.urd)
298  );
299 
300  if(rg.ndGen == nullptr) this->ndGen = nullptr;
301  else this->ndGen = std::unique_ptr<boost::mt19937>(
302  new boost::mt19937(*rg.ndGen)
303  );
304  if(rg.nd == nullptr) this->nd = nullptr;
305  else this->nd = std::unique_ptr<boost::normal_distribution<RealType>>(
306  new boost::normal_distribution<RealType>(*rg.nd)
307  );
308 }
309 
310 template<typename RealType>
313 )noexcept{
314  swap(*this, rg);
315 }
316 
317 // *** ASSIGNMENT OPERATORS *** //
318 // ****************************** //
319 template<typename RealType>
323 ){
325  swap(*this, rgCopy);
326  return *this;
327 }
328 template<typename RealType>
331  swap(*this, rg);
332  return *this;
333 }
334 
335 // *** S W A P *** //
336 // ******************* //
337 template<typename RealType>
341 ){
342  std::swap(rgA.mode, rgB.mode);
343  std::swap(rgA.doubleSeed, rgB.doubleSeed);
344  std::swap(rgA.longSeed, rgB.longSeed);
345  std::swap(rgA.urdGen, rgB.urdGen);
346  std::swap(rgA.urd, rgB.urd);
347  std::swap(rgA.ndGen, rgB.ndGen);
348  std::swap(rgA.nd, rgB.nd);
349 }
350 
351 // *** RANDOMNESS METHODS *** //
352 // **************************** //
353 template <typename RealType>
355  RealType lowerBound, RealType upperBound
356 ){
357  if(mode == "AUTO_SEED") {
358  boost::random_device rd;
359  urdGen = std::unique_ptr<boost::mt19937>(new boost::mt19937(rd()));
360  urd = std::unique_ptr<
361  boost::random::uniform_real_distribution<RealType>
362  >(
363  new boost::random::uniform_real_distribution<RealType>(
364  lowerBound, upperBound
365  )
366  );
367  }
368  else if(mode == "FIXED_SEED_DOUBLE"){
369  urdGen = std::unique_ptr<boost::mt19937>(
370  new boost::mt19937(getDoubleSeed())
371  );
372  urd = std::unique_ptr<
373  boost::random::uniform_real_distribution<RealType>
374  >(
375  new boost::random::uniform_real_distribution<RealType>(
376  lowerBound, upperBound
377  )
378  );
379  }
380  else if(mode == "FIXED_SEED_LONG"){
381  urdGen = std::unique_ptr<boost::mt19937>(
382  new boost::mt19937(getLongSeed())
383  );
384  urd = std::unique_ptr<
385  boost::random::uniform_real_distribution<RealType>
386  >(
387  new boost::random::uniform_real_distribution<RealType>(
388  lowerBound, upperBound
389  )
390  );
391  }
392 }
393 template <typename RealType>
395  if(urd == nullptr) computeUniformRealDistribution(0.0, 1.0);
396  return (*urd)(*urdGen);
397 }
398 
399 template <typename RealType>
401  RealType mean, RealType stdev
402 ){
403  if(mode == "AUTO_SEED") {
404  boost::random_device rd;
405  ndGen = std::unique_ptr<boost::mt19937>(new boost::mt19937(rd()));
406  nd = std::unique_ptr<boost::normal_distribution<RealType>>(
407  new boost::normal_distribution<RealType>(
408  mean, stdev
409  ));
410  }
411  else if(mode == "FIXED_SEED_DOUBLE"){
412  ndGen = std::unique_ptr<boost::mt19937>(
413  new boost::mt19937(getDoubleSeed())
414  );
415  nd = std::unique_ptr<boost::normal_distribution<RealType>>(
416  new boost::normal_distribution<RealType>(
417  mean, stdev
418  ));
419  }
420  else if(mode == "FIXED_SEED_LONG"){
421  ndGen = std::unique_ptr<boost::mt19937>(
422  new boost::mt19937(getLongSeed())
423  );
424  nd = std::unique_ptr<boost::normal_distribution<RealType>>(
425  new boost::normal_distribution<RealType>(
426  mean, stdev
427  ));
428  }
429 }
430 
431 template <typename RealType>
433  if(nd == nullptr) computeNormalDistribution(0.0, 1.0);
434  return (*nd)(*ndGen);
435 }
Class to generate random numbers.
Definition: RandomnessGenerator.h:34
RandomnessGenerator()
Creates a RandomnessGenerator which will use an automatically computed seed.
Definition: RandomnessGenerator.h:102
std::unique_ptr< boost::random::uniform_real_distribution< RealType > > urd
Uniform Real Distribution.
Definition: RandomnessGenerator.h:67
std::unique_ptr< boost::mt19937 > ndGen
Normal Distribution Generator.
Definition: RandomnessGenerator.h:72
RealType uniformRealDistributionNext()
Obtain the next value in the computed uniform real distribution.
Definition: RandomnessGenerator.h:394
void swap(RandomnessGenerator &rgA, RandomnessGenerator &rgB)
Swap two RandomnessGenerator.
Definition: RandomnessGenerator.h:338
void computeUniformRealDistribution(RealType lowerBound, RealType upperBound)
Compute a uniform real distribution using the specified real data type.
Definition: RandomnessGenerator.h:354
RandomnessGenerator(float seed)
Like RandomnessGenerator(double) constructor, the float is casted to a double.
Definition: RandomnessGenerator.h:117
RandomnessGenerator(RandomnessGenerator &&rg) noexcept
Move constructor for RandomnessGenerator.
Definition: RandomnessGenerator.h:311
RealType normalDistributionNext()
Obtain the next value in the computed normal distribution.
Definition: RandomnessGenerator.h:432
RandomnessGenerator(std::string const &seedstr)
Creates a RandomnessGenerator by parsing the string to automatically extract the seed and define the ...
Definition: RandomnessGenerator.h:254
RandomnessGenerator(int seed)
Like RandomnessGenerator(long) constructor, the integer is casted to a long.
Definition: RandomnessGenerator.h:135
RandomnessGenerator(double seed)
Creates a RandomnessGenerator which will use a double seed.
Definition: RandomnessGenerator.h:108
std::unique_ptr< boost::mt19937 > urdGen
Uniform Real Distribution Generator.
Definition: RandomnessGenerator.h:61
std::string mode
RandomnessGenerator mode.
Definition: RandomnessGenerator.h:47
void computeNormalDistribution(RealType mean, RealType stdev)
Compute a normal distribution using the specified real data type.
Definition: RandomnessGenerator.h:400
long getLongSeed()
Obtain the seed in long format. This getter is expected to be used with mode FIXED_SEED_LONG.
Definition: RandomnessGenerator.h:94
double getDoubleSeed()
Obtain the seed in double format. This getter is expected to be used with mode FIXED_SEED_DOUBLE.
Definition: RandomnessGenerator.h:87
RandomnessGenerator(long seed)
Creates a RandomnessGenerator which will use a long seed.
Definition: RandomnessGenerator.h:126
RandomnessGenerator & operator=(RandomnessGenerator const &rg)
Copy assignment operator.
Definition: RandomnessGenerator.h:321
RandomnessGenerator(RandomnessGenerator const &rg)
Copy constructor for RandomnessGenerator.
Definition: RandomnessGenerator.h:283
long longSeed
Long seed for randomness.
Definition: RandomnessGenerator.h:56
RandomnessGenerator & operator=(RandomnessGenerator &&rg)
Move assignment operator.
Definition: RandomnessGenerator.h:330
std::unique_ptr< boost::normal_distribution< RealType > > nd
Normal Distribution.
Definition: RandomnessGenerator.h:76
double doubleSeed
Double seed for randomness.
Definition: RandomnessGenerator.h:52