TheAlgorithms/C++ 1.0.0
All the algorithms implemented in C++
Loading...
Searching...
No Matches
geometric_dist.cpp File Reference

Geometric Distribution More...

#include <cassert>
#include <cmath>
#include <cstdint>
#include <ctime>
#include <iostream>
#include <limits>
#include <random>
#include <vector>
Include dependency graph for geometric_dist.cpp:

Go to the source code of this file.

Classes

class  probability::geometric_dist::geometric_distribution
 A class to model the geometric distribution. More...
 

Namespaces

namespace  probability
 Probability algorithms.
 
namespace  geometric_dist
 Functions for the Geometric Distribution algorithm implementation.
 

Functions

float probability::geometric_dist::generate_uniform ()
 Returns a random number between [0,1].
 
void sample_test (const probability::geometric_dist::geometric_distribution &dist)
 Tests the sampling method of the geometric distribution.
 
static void test ()
 Self-test implementations.
 
int main ()
 Main function.
 

Detailed Description

Geometric Distribution

The geometric distribution models the experiment of doing Bernoulli trials until a sucess was observed. There are two formulations of the geometric distribution: 1) The probability distribution of the number X of Bernoulli trials needed to get one success, supported on the set { 1, 2, 3, ... } 2) The probability distribution of the number Y = X − 1 of failures before the first success, supported on the set { 0, 1, 2, 3, ... } Here, the first one is implemented.

Common variables used: p - The success probability k - The number of tries

Author
Domenic Zingsheim

Definition in file geometric_dist.cpp.

Function Documentation

◆ generate_uniform()

float probability::geometric_dist::generate_uniform ( )

Returns a random number between [0,1].

Returns
A uniformly distributed random number between 0 (included) and 1 (included)

Definition at line 48 of file geometric_dist.cpp.

48 {
49 return static_cast<float>(rand()) / static_cast<float>(RAND_MAX);
50}

◆ main()

int main ( void )

Main function.

Returns
0 on exit

Definition at line 256 of file geometric_dist.cpp.

256 {
257 srand(time(nullptr));
258 test(); // run self-test implementations
259 return 0;
260}
static void test()
Self-test implementations.

◆ sample_test()

void sample_test ( const probability::geometric_dist::geometric_distribution & dist)

Tests the sampling method of the geometric distribution.

Draws 1000000 random samples and estimates mean and variance These should be close to the expected value and variance of the given distribution to pass.

Parameters
distThe distribution to test

Definition at line 165 of file geometric_dist.cpp.

166 {
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}
float expected_value() const
The expected value of a geometrically distributed random variable X.
uint32_t draw_sample() const
Generates a (discrete) sample according to the geometrical distribution.
float variance() const
The variance of a geometrically distributed random variable X.

◆ test()

static void test ( )
static

Self-test implementations.

Returns
void

Definition at line 197 of file geometric_dist.cpp.

197 {
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
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
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}
A class to model the geometric distribution.
void sample_test(const probability::geometric_dist::geometric_distribution &dist)
Tests the sampling method of the geometric distribution.