GENEIAL  0.2=/
 All Classes Pages
Random.hpp
1 #pragma once
2 
3 #include <geneial/utility/Random.h>
4 
5 #include <stdio.h> /* printf, scanf, puts, NULL */
6 #include <stdlib.h> /* srand, rand */
7 #include <time.h> /* time */
8 #include <cstdlib> /* RAND_MAX */
9 #include <limits> /* min, max of float, double */
10 #include <random>
11 #include <iostream>
12 #include <cassert>
13 
14 
15 
16 //TODO (bewo) benchmark and possibly use new c++11 random functions
17 
18 geneial_private_namespace(geneial)
19 {
20 geneial_private_namespace(utility)
21 {
22 
23 //Assures we have positive mod every time. (because in cpp -6 % 5 = -1)
24 inline int mymod(int k, const int n)
25 {
26  return ((k %= n) < 0) ? k + n : k;
27 }
28 
29 geneial_export_namespace
30 {
31 
32 template<>
33 inline int Random::generate(const int min, const int max)
34 {
35  checkInitialized();
36  assert(min <= max);
37  int sign = 1;
38  if (min < 0)
39  {
40  sign *= -(rand() % 2);
41  }
42  const int result = mymod(sign * rand(), (max - min + 1)) + min;
43  return result;
44 }
45 
46 
47 
48 template<>
49 inline unsigned int Random::generate(const unsigned int min, const unsigned int max)
50 {
51  checkInitialized();
52  assert(min <= max);
53  const unsigned int result = mymod(rand(), (max - min + 1)) + min;
54  return result;
55 }
56 
57 template<>
58 inline int Random::generate()
59 {
60  checkInitialized();
61  return rand();
62 }
63 
64 template<>
65 inline double Random::generate(const double min, const double max)
66 {
67  checkInitialized();
68  assert(min <= max);
69  int sign = 1;
70  if (min < 0)
71  {
72  sign *= -(rand() % 2);
73  }
74  const double range = (max - min);
75  const double div = RAND_MAX / range;
76  const double random = min + (rand() / div);
77  return random;
78 }
79 
80 
81 
82 template<>
83 inline double Random::generate()
84 {
85  checkInitialized();
86  return Random::generate<double>(std::numeric_limits<double>::min(), std::numeric_limits<double>::max());
87 }
88 
89 template<>
90 inline float Random::generate(const float min, const float max)
91 {
92  checkInitialized();
93  assert(min <= max);
94  const float range = (max - min);
95  const float div = ((float) RAND_MAX) / range;
96  const float random = min + (((float) rand()) / div);
97  return random;
98 }
99 
100 template<>
101 inline float Random::generate()
102 {
103  checkInitialized();
104  return Random::generate(std::numeric_limits<float>::min(), std::numeric_limits<float>::max());
105 
106 }
107 
108 bool Random::generateBit()
109 {
110  checkInitialized();
111  return rand() & 1;
112 }
113 
114 bool Random::decision(const double probability)
115 {
116  checkInitialized();
117  assert(0.0 <= probability);
118  assert(1.0 >= probability);
119  const double reference = generate<double>(0.0, 1.0);
120  if (probability == 0.0)
121  {
122  return false;
123  }
124  else
125  {
126  return reference <= probability;
127  }
128 }
129 
130 inline void Random::initialize()
131 {
132  srand(static_cast<unsigned>(time(0)));
133  sInitialized = true;
134 }
135 } /* geneial_export_namespace */
136 } /* private namespace utility */
137 } /* private namespace geneial */