Helios++
Helios software for LiDAR simulations
RandomnessGenerator.h
1 #pragma once
2 
3 #include <random>
4 #include <memory>
5 #include <HeliosException.h>
6 
13 void setDefaultRandomnessGeneratorSeed(std::string const seed = "");
14 
24 template <typename RealType>
26 protected:
27  // *** ATTRIBUTES *** //
28  // ******************** //
38  std::string mode;
39 
43  double doubleSeed = 0;
47  long longSeed = 0;
48 
52  std::unique_ptr<std::mt19937> urdGen = nullptr;
56  std::unique_ptr<std::uniform_real_distribution<RealType>> urd = nullptr;
57 
61  std::unique_ptr<std::mt19937> ndGen = nullptr;
65  std::unique_ptr<std::normal_distribution<RealType>> nd = nullptr;
66 
67 
68  // *** INTERNAL SEED FUNCTIONS *** //
69  // ********************************* //
76  double getDoubleSeed(){return doubleSeed;}
83  long getLongSeed(){return longSeed;}
84 public:
85  // *** CONSTRUCTION *** //
86  // ********************** //
91  RandomnessGenerator():mode("AUTO_SEED"){};
92 
97  explicit RandomnessGenerator(double seed) :
98  mode("FIXED_SEED_DOUBLE"),
99  doubleSeed(seed)
100  {}
106  explicit RandomnessGenerator(float seed) :
107  mode("FIXED_SEED_DOUBLE"),
108  doubleSeed((double)seed)
109  {}
110 
115  explicit RandomnessGenerator(long seed) :
116  mode("FIXED_SEED_LONG"),
117  longSeed(seed)
118  {}
124  explicit RandomnessGenerator(int seed) :
125  mode("FIXED_SEED_LONG"),
126  longSeed((long)seed)
127  {}
128 
138  explicit RandomnessGenerator(std::string const &seedstr);
139 
151 
157 
158  // *** ASSIGNMENT OPERATORS *** //
159  // ****************************** //
172 
173  // *** S W A P *** //
174  // ******************* //
180  void swap(
181  RandomnessGenerator &rgA,
183  );
184 
185  // *** RANDOMNESS METHODS *** //
186  // **************************** //
195  RealType lowerBound, RealType upperBound
196  );
207  RealType uniformRealDistributionNext();
213  void computeNormalDistribution(RealType mean, RealType stdev);
224  RealType normalDistributionNext();
225 
226 
227 };
228 
229 // *** DEFAULT RANDOMNESS GENERATOR *** //
230 // ************************************** //
231 extern bool DEFAULT_RG_MODIFIED_FLAG;
232 extern std::unique_ptr<RandomnessGenerator<double>> DEFAULT_RG;
233 
234 
235 
236 
237 // *** CLASS IMPLEMENTATION *** //
238 // ********************************* //
239 
240 // *** CONSTRUCTION *** //
241 // ********************** //
242 template<typename RealType>
244  bool isTimestamp = false;
245  bool isDouble = false;
246  for(size_t i = 0 ; i < seedstr.length() ; i++){
247  if(seedstr[i] == ':') isTimestamp = true;
248  if(seedstr[i] == '.') isDouble = true;
249  }
250 
251  if(isTimestamp){
252  mode = "FIXED_SEED_LONG";
253  longSeed = 0;
254  longSeed += (std::stol(seedstr.substr(0,4))-1970)*31104000;
255  longSeed += std::stol(seedstr.substr(5,2))*2592000;
256  longSeed += std::stol(seedstr.substr(8,2))*86400;
257  longSeed += std::stol(seedstr.substr(11,2))*3600;
258  longSeed += std::stol(seedstr.substr(14,2))*60;
259  longSeed += std::stol(seedstr.substr(17,2));
260  }
261  else if(isDouble){
262  mode = "FIXED_SEED_DOUBLE";
263  doubleSeed = std::stod(seedstr);
264  }
265  else{
266  mode = "FIXED_SEED_LONG";
267  longSeed = std::stol(seedstr);
268  }
269 }
270 
271 template<typename RealType>
273  RandomnessGenerator const &rg
274 ){
275  this->mode = rg.mode;
276  this->doubleSeed = rg.doubleSeed;
277  this->longSeed = rg.longSeed;
278 
279  if(rg.urdGen == nullptr) this->urdGen = nullptr;
280  else this->urdGen = std::unique_ptr<std::mt19937>(
281  new std::mt19937(*rg.urdGen)
282  );
283  if(rg.urd == nullptr) this->urdGen = nullptr;
284  else this->urd =
285  std::unique_ptr<std::uniform_real_distribution<RealType>>(
286  new std::uniform_real_distribution<RealType>(*rg.urd)
287  );
288 
289  if(rg.ndGen == nullptr) this->ndGen = nullptr;
290  else this->ndGen = std::unique_ptr<std::mt19937>(
291  new std::mt19937(*rg.ndGen)
292  );
293  if(rg.nd == nullptr) this->nd = nullptr;
294  else this->nd = std::unique_ptr<std::normal_distribution<RealType>>(
295  new std::normal_distribution<RealType>(*rg.nd)
296  );
297 }
298 
299 template<typename RealType>
302 )noexcept{
303  swap(*this, rg);
304 }
305 
306 // *** ASSIGNMENT OPERATORS *** //
307 // ****************************** //
308 template<typename RealType>
312 ){
314  swap(*this, rgCopy);
315  return *this;
316 }
317 template<typename RealType>
320  swap(*this, rg);
321  return *this;
322 }
323 
324 // *** S W A P *** //
325 // ******************* //
326 template<typename RealType>
330 ){
331  std::swap(rgA.mode, rgB.mode);
332  std::swap(rgA.doubleSeed, rgB.doubleSeed);
333  std::swap(rgA.longSeed, rgB.longSeed);
334  std::swap(rgA.urdGen, rgB.urdGen);
335  std::swap(rgA.urd, rgB.urd);
336  std::swap(rgA.ndGen, rgB.ndGen);
337  std::swap(rgA.nd, rgB.nd);
338 }
339 
340 // *** RANDOMNESS METHODS *** //
341 // **************************** //
342 template <typename RealType>
344  RealType lowerBound, RealType upperBound
345 ){
346  if(mode == "AUTO_SEED") {
347  std::random_device rd;
348  urdGen = std::unique_ptr<std::mt19937>(new std::mt19937(rd()));
349  urd = std::unique_ptr<std::uniform_real_distribution<RealType>>(
350  new std::uniform_real_distribution<RealType>(
351  lowerBound, upperBound
352  ));
353  }
354  else if(mode == "FIXED_SEED_DOUBLE"){
355  urdGen = std::unique_ptr<std::mt19937>(
356  new std::mt19937(getDoubleSeed())
357  );
358  urd = std::unique_ptr<std::uniform_real_distribution<RealType>>(
359  new std::uniform_real_distribution<RealType>(
360  lowerBound, upperBound
361  ));
362  }
363  else if(mode == "FIXED_SEED_LONG"){
364  urdGen = std::unique_ptr<std::mt19937>(
365  new std::mt19937(getLongSeed())
366  );
367  urd = std::unique_ptr<std::uniform_real_distribution<RealType>>(
368  new std::uniform_real_distribution<RealType>(
369  lowerBound, upperBound
370  ));
371  }
372 }
373 template <typename RealType>
375  if(urd == nullptr) computeUniformRealDistribution(0.0, 1.0);
376  return (*urd)(*urdGen);
377 }
378 
379 template <typename RealType>
381  RealType mean, RealType stdev
382 ){
383  if(mode == "AUTO_SEED") {
384  std::random_device rd;
385  ndGen = std::unique_ptr<std::mt19937>(new std::mt19937(rd()));
386  nd = std::unique_ptr<std::normal_distribution<RealType>>(
387  new std::normal_distribution<RealType>(
388  mean, stdev
389  ));
390  }
391  else if(mode == "FIXED_SEED_DOUBLE"){
392  ndGen = std::unique_ptr<std::mt19937>(
393  new std::mt19937(getDoubleSeed())
394  );
395  nd = std::unique_ptr<std::normal_distribution<RealType>>(
396  new std::normal_distribution<RealType>(
397  mean, stdev
398  ));
399  }
400  else if(mode == "FIXED_SEED_LONG"){
401  ndGen = std::unique_ptr<std::mt19937>(
402  new std::mt19937(getLongSeed())
403  );
404  nd = std::unique_ptr<std::normal_distribution<RealType>>(
405  new std::normal_distribution<RealType>(
406  mean, stdev
407  ));
408  }
409 }
410 
411 template <typename RealType>
413  if(nd == nullptr) computeNormalDistribution(0.0, 1.0);
414  return (*nd)(*ndGen);
415 }
Class to generate random numbers.
Definition: RandomnessGenerator.h:25
std::unique_ptr< std::mt19937 > ndGen
Normal Distribution Generator.
Definition: RandomnessGenerator.h:61
RandomnessGenerator()
Creates a RandomnessGenerator which will use an automatically computed seed.
Definition: RandomnessGenerator.h:91
RandomnessGenerator(long seed)
Creates a RandomnessGenerator which will use a long seed.
Definition: RandomnessGenerator.h:115
std::unique_ptr< std::uniform_real_distribution< RealType > > urd
Uniform Real Distribution.
Definition: RandomnessGenerator.h:56
double doubleSeed
Double seed for randomness.
Definition: RandomnessGenerator.h:43
std::unique_ptr< std::mt19937 > urdGen
Uniform Real Distribution Generator.
Definition: RandomnessGenerator.h:52
long longSeed
Long seed for randomness.
Definition: RandomnessGenerator.h:47
RandomnessGenerator(double seed)
Creates a RandomnessGenerator which will use a double seed.
Definition: RandomnessGenerator.h:97
RandomnessGenerator & operator=(RandomnessGenerator const &rg)
Copy assignment operator.
Definition: RandomnessGenerator.h:310
std::string mode
RandomnessGenerator mode.
Definition: RandomnessGenerator.h:38
std::unique_ptr< std::normal_distribution< RealType > > nd
Normal Distribution.
Definition: RandomnessGenerator.h:65
RandomnessGenerator(float seed)
Like RandomnessGenerator(double) constructor, the float is casted to a double.
Definition: RandomnessGenerator.h:106
double getDoubleSeed()
Obtain the seed in double format. This getter is expected to be used with mode FIXED_SEED_DOUBLE.
Definition: RandomnessGenerator.h:76
RandomnessGenerator(int seed)
Like RandomnessGenerator(long) constructor, the integer is casted to a long.
Definition: RandomnessGenerator.h:124
void swap(RandomnessGenerator &rgA, RandomnessGenerator &rgB)
Swap two RandomnessGenerator.
Definition: RandomnessGenerator.h:327
long getLongSeed()
Obtain the seed in long format. This getter is expected to be used with mode FIXED_SEED_LONG.
Definition: RandomnessGenerator.h:83
RealType uniformRealDistributionNext()
Obtain the next value in the computed uniform real distribution.
Definition: RandomnessGenerator.h:374
RealType normalDistributionNext()
Obtain the next value in the computed normal distribution.
Definition: RandomnessGenerator.h:412
void computeNormalDistribution(RealType mean, RealType stdev)
Compute a normal distribution using the specified real data type.
Definition: RandomnessGenerator.h:380
void computeUniformRealDistribution(RealType lowerBound, RealType upperBound)
Compute a uniform real distribution using the specified real data type.
Definition: RandomnessGenerator.h:343