66 const uint32_t& num_samples,
67 const uint32_t& discard = 100000) {
68 std::vector<double> samples;
69 samples.reserve(num_samples);
71 double x_t = start_point;
73 std::default_random_engine generator;
74 std::uniform_real_distribution<double> uniform(0.0, 1.0);
75 std::normal_distribution<double> normal(0.0, 1.0);
76 generator.seed(time(
nullptr));
78 for (uint32_t t = 0; t < num_samples + discard; ++t) {
81 double x_dash = normal(generator) + x_t;
82 double acceptance_probability = std::min(pdf(x_dash) / pdf(x_t), 1.0);
83 double u = uniform(generator);
86 if (u <= acceptance_probability) {
91 samples.push_back(x_t);
134 std::cout <<
"Disclaimer: Because this is a randomized algorithm,"
137 <<
"it may happen that singular samples deviate from the true result."
142 math::monte_carlo::Function f;
143 math::monte_carlo::Function pdf;
145 double lower_bound = 0, upper_bound = 0;
148 f = [&](
double& x) {
return -x * x + 4.0; };
152 pdf = [&](
double& x) {
153 if (x >= lower_bound && x <= -1.0) {
156 if (x <= upper_bound && x >= 1.0) {
159 if (x > -1.0 && x < 1.0) {
165 integral = math::monte_carlo::integral_monte_carlo(
166 (upper_bound - lower_bound) / 2.0, f, pdf);
168 std::cout <<
"This number should be close to 10.666666: " << integral
172 f = [&](
double& x) {
return std::exp(x); };
176 pdf = [&](
double& x) {
177 if (x >= lower_bound && x <= 0.2) {
180 if (x > 0.2 && x <= 0.4) {
183 if (x > 0.4 && x < upper_bound) {
189 integral = math::monte_carlo::integral_monte_carlo(
190 (upper_bound - lower_bound) / 2.0, f, pdf);
192 std::cout <<
"This number should be close to 1.7182818: " << integral
199 f = [&](
double& x) {
return std::sin(M_PI * x) / (M_PI * x); };
201 pdf = [&](
double& x) {
202 return 1.0 / std::sqrt(2.0 * M_PI) * std::exp(-x * x / 2.0);
205 integral = math::monte_carlo::integral_monte_carlo(0.0, f, pdf, 10000000);
207 std::cout <<
"This number should be close to 1.0: " << integral
std::vector< double > generate_samples(const double &start_point, const Function &pdf, const uint32_t &num_samples, const uint32_t &discard=100000)
short-hand for std::functions used in this implementation
double integral_monte_carlo(const double &start_point, const Function &function, const Function &pdf, const uint32_t &num_samples=1000000)
Compute an approximation of an integral using Monte Carlo integration.