I need my program to simulate bernoulli (p) random variables with ability to change p. If i write smth like this
#include <random>
#include <iostream>
#include <chrono>
int main()
{
double prob = 0.1; //let it be const for now, no need to change it in this example
std::mt19937 gen(std::chrono::steady_clock::now().time_since_epoch().count());
std::bernoulli_distribution coin(prob);
int success = 0;
for (int i = 0; i < 1000; ++i) {
if (coin(prob)) ++success;
}
std::cout << success << "\n";
return 0;
}
it works perfectly fine. But i need to change parameter p, so i decided to create a function which takes some switcher, simulates random variable with parameter depending on switcher, and returns true or false. Here is my code:
#include <random>
#include <iostream>
#include <chrono>
bool coin_flip(int switcher) {
double prob;
switch (switcher) {
case 1: {
prob = 0.1;
std::mt19937 gen(std::chrono::steady_clock::now().time_since_epoch().count());
std::bernoulli_distribution coin(prob);
return coin(gen);
}
case 2: {
prob = 0.2;
std::mt19937 gen(std::chrono::steady_clock::now().time_since_epoch().count());
std::bernoulli_distribution coin(prob);
return coin(gen);
}
}
}
int main()
{
int success = 0;
for (int i = 0; i < 1000; ++i) {
if (coin_flip(1)) {
++success;
}
}
std::cout << success << "\n";
return 0;
}
The for loop in the main body counts number of successes among 1000 tries and i expect it to be around 100, but i do get wierd results. Too many zeroes and large numbers.
So my question is why does coin(prob) breaks when passes to the output of a function?
Also, if you have good ideas, i would be grateful for any suggestions on how to simulate sequence of bernoulli r.v's with different parameters p (e.g. we are in a loop where p depends on counter i)
Thank you for your time
You should not create a new random number generator for every roll, that breaks the whole pseudo-randomness.
Create a global(-ish) generator and reuse it in every function call:
bool coin_flip(int switcher) {
static std::mt19937 gen(std::chrono::steady_clock::now().time_since_epoch().count());
switch(switcher)
{
case 1:
std::bernoulli_distribution coin(0.1);
return coin(gen);
case 2:
std::bernoulli_distribution coin(0.2);
return coin(gen);
}
throw std::invalid_argument{"Incorrect switcher value"};
}
static
local variables are only initialized once, during first function call, and remain accessible in every other function call. They are global in terms of lifetime (they will only die when the program finishes), but only accessible from within this function.