TheAlgorithms/C++
1.0.0
All the algorithms implemented in C++
Toggle main menu visibility
Loading...
Searching...
No Matches
geometric_dist.cpp
Go to the documentation of this file.
1
21
22
#include <cassert>
23
#include <cmath>
24
#include <cstdint>
25
#include <ctime>
26
#include <iostream>
27
#include <limits>
28
#include <random>
29
#include <vector>
30
35
namespace
probability
{
42
namespace
geometric_dist
{
48
float
generate_uniform
() {
49
return
static_cast<
float
>
(rand()) /
static_cast<
float
>
(RAND_MAX);
50
}
51
55
class
geometric_distribution
{
56
private
:
57
float
p
;
58
59
public
:
64
explicit
geometric_distribution
(
const
float
&
p
) :
p
(
p
) {}
65
71
float
expected_value
()
const
{
return
1.0f /
p
; }
72
77
float
variance
()
const
{
return
(1.0f -
p
) / (
p
*
p
); }
78
84
float
standard_deviation
()
const
{
return
std::sqrt(
variance
()); }
85
93
float
probability_density
(
const
uint32_t& k)
const
{
94
return
std::pow((1.0f -
p
),
static_cast<
float
>
(k - 1)) *
p
;
95
}
96
104
float
cumulative_distribution
(
const
uint32_t& k)
const
{
105
return
1.0f - std::pow((1.0f -
p
),
static_cast<
float
>
(k));
106
}
107
116
float
inverse_cumulative_distribution
(
const
float
& cdf)
const
{
117
return
std::log(1.0f - cdf) / std::log(1.0f -
p
);
118
}
119
125
uint32_t
draw_sample
()
const
{
126
float
uniform_sample =
generate_uniform
();
127
return
static_cast<
uint32_t
>
(
128
inverse_cumulative_distribution
(uniform_sample)) +
129
1;
130
}
131
145
float
range_tries
(
const
uint32_t& min_tries = 1,
146
const
uint32_t& max_tries =
147
std::numeric_limits<uint32_t>::max())
const
{
148
float
cdf_lower =
cumulative_distribution
(min_tries - 1);
149
float
cdf_upper = max_tries == std::numeric_limits<uint32_t>::max()
150
? 1.0f
151
:
cumulative_distribution
(max_tries);
152
return
cdf_upper - cdf_lower;
153
}
154
};
155
}
// namespace geometric_dist
156
}
// namespace probability
157
165
void
sample_test
(
166
const
probability::geometric_dist::geometric_distribution
& dist) {
167
uint32_t n_tries = 1000000;
168
std::vector<float> tries;
169
tries.resize(n_tries);
170
171
float
mean = 0.0f;
172
for
(uint32_t i = 0; i < n_tries; ++i) {
173
tries[i] =
static_cast<
float
>
(dist.
draw_sample
());
174
mean += tries[i];
175
}
176
177
mean /=
static_cast<
float
>
(n_tries);
178
179
float
var = 0.0f;
180
for
(uint32_t i = 0; i < n_tries; ++i) {
181
var += (tries[i] - mean) * (tries[i] - mean);
182
}
183
184
// Unbiased estimate of variance
185
var /=
static_cast<
float
>
(n_tries - 1);
186
187
std::cout <<
"This value should be near "
<< dist.
expected_value
() <<
": "
188
<< mean << std::endl;
189
std::cout <<
"This value should be near "
<< dist.
variance
() <<
": "
<< var
190
<< std::endl;
191
}
192
197
static
void
test
() {
198
probability::geometric_dist::geometric_distribution
dist(0.3);
199
200
const
float
threshold = 1e-3f;
201
202
std::cout <<
"Starting tests for p = 0.3..."
<< std::endl;
203
assert(std::abs(dist.
expected_value
() - 3.33333333f) < threshold);
204
assert(std::abs(dist.
variance
() - 7.77777777f) < threshold);
205
assert(std::abs(dist.
standard_deviation
() - 2.788866755) < threshold);
206
assert(std::abs(dist.
probability_density
(5) - 0.07203) < threshold);
207
assert(std::abs(dist.
cumulative_distribution
(6) - 0.882351) < threshold);
208
assert(std::abs(dist.
inverse_cumulative_distribution
(
209
dist.
cumulative_distribution
(8)) -
210
8) < threshold);
211
assert(std::abs(dist.
range_tries
() - 1.0f) < threshold);
212
assert(std::abs(dist.
range_tries
(3) - 0.49f) < threshold);
213
assert(std::abs(dist.
range_tries
(5, 11) - 0.2203267f) < threshold);
214
std::cout <<
"All tests passed"
<< std::endl;
215
sample_test
(dist);
216
217
dist =
probability::geometric_dist::geometric_distribution
(0.5f);
218
219
std::cout <<
"Starting tests for p = 0.5..."
<< std::endl;
220
assert(std::abs(dist.
expected_value
() - 2.0f) < threshold);
221
assert(std::abs(dist.
variance
() - 2.0f) < threshold);
222
assert(std::abs(dist.
standard_deviation
() - 1.4142135f) < threshold);
223
assert(std::abs(dist.
probability_density
(5) - 0.03125) < threshold);
224
assert(std::abs(dist.
cumulative_distribution
(6) - 0.984375) < threshold);
225
assert(std::abs(dist.
inverse_cumulative_distribution
(
226
dist.
cumulative_distribution
(8)) -
227
8) < threshold);
228
assert(std::abs(dist.
range_tries
() - 1.0f) < threshold);
229
assert(std::abs(dist.
range_tries
(3) - 0.25f) < threshold);
230
assert(std::abs(dist.
range_tries
(5, 11) - 0.062011f) < threshold);
231
std::cout <<
"All tests passed"
<< std::endl;
232
sample_test
(dist);
233
234
dist =
probability::geometric_dist::geometric_distribution
(0.8f);
235
236
std::cout <<
"Starting tests for p = 0.8..."
<< std::endl;
237
assert(std::abs(dist.
expected_value
() - 1.25f) < threshold);
238
assert(std::abs(dist.
variance
() - 0.3125f) < threshold);
239
assert(std::abs(dist.
standard_deviation
() - 0.559016f) < threshold);
240
assert(std::abs(dist.
probability_density
(5) - 0.00128) < threshold);
241
assert(std::abs(dist.
cumulative_distribution
(6) - 0.999936) < threshold);
242
assert(std::abs(dist.
inverse_cumulative_distribution
(
243
dist.
cumulative_distribution
(8)) -
244
8) < threshold);
245
assert(std::abs(dist.
range_tries
() - 1.0f) < threshold);
246
assert(std::abs(dist.
range_tries
(3) - 0.04f) < threshold);
247
assert(std::abs(dist.
range_tries
(5, 11) - 0.00159997f) < threshold);
248
std::cout <<
"All tests have successfully passed!"
<< std::endl;
249
sample_test
(dist);
250
}
251
256
int
main
() {
257
srand(time(
nullptr
));
258
test
();
// run self-test implementations
259
return
0;
260
}
test
void test()
Definition
caesar_cipher.cpp:100
probability::geometric_dist::geometric_distribution
A class to model the geometric distribution.
Definition
geometric_dist.cpp:55
probability::geometric_dist::geometric_distribution::cumulative_distribution
float cumulative_distribution(const uint32_t &k) const
The cumulative distribution function.
Definition
geometric_dist.cpp:104
probability::geometric_dist::geometric_distribution::standard_deviation
float standard_deviation() const
The standard deviation of a geometrically distributed random variable X.
Definition
geometric_dist.cpp:84
probability::geometric_dist::geometric_distribution::expected_value
float expected_value() const
The expected value of a geometrically distributed random variable X.
Definition
geometric_dist.cpp:71
probability::geometric_dist::geometric_distribution::range_tries
float range_tries(const uint32_t &min_tries=1, const uint32_t &max_tries=std::numeric_limits< uint32_t >::max()) const
This function computes the probability to have success in a given range of tries.
Definition
geometric_dist.cpp:145
probability::geometric_dist::geometric_distribution::draw_sample
uint32_t draw_sample() const
Generates a (discrete) sample according to the geometrical distribution.
Definition
geometric_dist.cpp:125
probability::geometric_dist::geometric_distribution::geometric_distribution
geometric_distribution(const float &p)
Constructor for the geometric distribution.
Definition
geometric_dist.cpp:64
probability::geometric_dist::geometric_distribution::inverse_cumulative_distribution
float inverse_cumulative_distribution(const float &cdf) const
The inverse cumulative distribution function.
Definition
geometric_dist.cpp:116
probability::geometric_dist::geometric_distribution::p
float p
The succes probability p.
Definition
geometric_dist.cpp:57
probability::geometric_dist::geometric_distribution::variance
float variance() const
The variance of a geometrically distributed random variable X.
Definition
geometric_dist.cpp:77
probability::geometric_dist::geometric_distribution::probability_density
float probability_density(const uint32_t &k) const
The probability density function.
Definition
geometric_dist.cpp:93
main
int main()
Main function.
Definition
generate_parentheses.cpp:110
sample_test
void sample_test(const probability::geometric_dist::geometric_distribution &dist)
Tests the sampling method of the geometric distribution.
Definition
geometric_dist.cpp:165
probability::geometric_dist::generate_uniform
float generate_uniform()
Returns a random number between [0,1].
Definition
geometric_dist.cpp:48
geometric_dist
Functions for the Geometric Distribution algorithm implementation.
probability
for std::string
probability
geometric_dist.cpp
Generated by
1.18.0