From 33e1f17d1a19dfc9ca3ac2aa38c14beecdbbc384 Mon Sep 17 00:00:00 2001 From: Bendik Samseth Date: Mon, 6 Aug 2018 21:53:00 +0200 Subject: [PATCH 1/4] Implement C++ version of Monte Carlo integration. --- .../code/c++/monte_carlo.cpp | 48 +++++++++++++++++++ .../monte_carlo_integration.md | 4 ++ 2 files changed, 52 insertions(+) create mode 100644 contents/monte_carlo_integration/code/c++/monte_carlo.cpp diff --git a/contents/monte_carlo_integration/code/c++/monte_carlo.cpp b/contents/monte_carlo_integration/code/c++/monte_carlo.cpp new file mode 100644 index 000000000..858cdf92a --- /dev/null +++ b/contents/monte_carlo_integration/code/c++/monte_carlo.cpp @@ -0,0 +1,48 @@ +#include +#include +#include + +constexpr double PI = 3.14159265358979323846264338; + +/** + * Check if the point (x, y) is within a circle of a given radius. + * @param x coordinate one + * @param y coordinate two + * @param r radius of the circle (optional) + * @return true if (x, y) is within the circle. + */ +inline bool in_circle(double x, double y, double r = 1) { + return x * x + y * y < r * r; +} + +/** + * Return an estimate of PI using Monte Carlo integration. + * @param samples number of iterations to use + * @return estimate of pi + */ +double monte_carlo_pi(unsigned samples) { + static std::default_random_engine generator; + static std::uniform_real_distribution dist(-1, 1); + + unsigned count = 0; + for (unsigned i = 0; i < samples; ++i) { + double x = dist(generator); + double y = dist(generator); + + if (x*x + y*y < 1) + ++count; + } + + return 4.0 * count / (double) samples; +} + +int main() { + unsigned samples; + + std::cout << "Enter samples to use: "; + std::cin >> samples; + + double pi = monte_carlo_pi(samples); + printf("Pi = %f\n", pi); + printf("Percent error is: %g %%\n", 100 * std::abs(pi - PI) / PI); +} diff --git a/contents/monte_carlo_integration/monte_carlo_integration.md b/contents/monte_carlo_integration/monte_carlo_integration.md index 8a8544e73..631462eff 100644 --- a/contents/monte_carlo_integration/monte_carlo_integration.md +++ b/contents/monte_carlo_integration/monte_carlo_integration.md @@ -43,6 +43,8 @@ each point is tested to see whether it's in the circle or not: [import:3-10, lang:"clojure"](code/clojure/monte_carlo.clj) {% sample lang="c" %} [import:7-9, lang:"c_cpp"](code/c/monte_carlo.c) +{% sample lang="cpp" %} +[import:7-16, lang:"c_cpp"](code/c++/monte_carlo.cpp) {% sample lang="js" %} [import:2-6, lang:"javascript"](code/javascript/monte_carlo.js) {% sample lang="hs" %} @@ -100,6 +102,8 @@ Feel free to submit your version via pull request, and thanks for reading! [import, lang:"clojure"](code/clojure/monte_carlo.clj) {% sample lang="c" %} [import, lang:"c_cpp"](code/c/monte_carlo.c) +{% sample lang="cpp" %} +[import, lang:"c_cpp"](code/c++/monte_carlo.cpp) {% sample lang="js" %} [import, lang:"javascript"](code/javascript/monte_carlo.js) {% sample lang="hs" %} From f9fcc5f8a8671b5ea00ff35e434157c1eb558c52 Mon Sep 17 00:00:00 2001 From: Bendik Samseth Date: Mon, 6 Aug 2018 21:54:52 +0200 Subject: [PATCH 2/4] Update CONTRIBUTORS.md --- CONTRIBUTORS.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 6b3d1ec61..f188deacc 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -54,4 +54,6 @@ Arun Sahadeo
NIFR91
-Michal Hanajik \ No newline at end of file +Michal Hanajik +
+Bendik Samseth From 54aac6794d6dfc6cfc93f7c40479902ebf7dfd21 Mon Sep 17 00:00:00 2001 From: Bendik Samseth Date: Tue, 7 Aug 2018 08:11:58 +0200 Subject: [PATCH 3/4] Update C++ Monte Carlo implementation. --- .../monte_carlo_integration/code/c++/monte_carlo.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/contents/monte_carlo_integration/code/c++/monte_carlo.cpp b/contents/monte_carlo_integration/code/c++/monte_carlo.cpp index 858cdf92a..8b12522a4 100644 --- a/contents/monte_carlo_integration/code/c++/monte_carlo.cpp +++ b/contents/monte_carlo_integration/code/c++/monte_carlo.cpp @@ -22,7 +22,7 @@ inline bool in_circle(double x, double y, double r = 1) { */ double monte_carlo_pi(unsigned samples) { static std::default_random_engine generator; - static std::uniform_real_distribution dist(-1, 1); + static std::uniform_real_distribution dist(0, 1); unsigned count = 0; for (unsigned i = 0; i < samples; ++i) { @@ -33,7 +33,7 @@ double monte_carlo_pi(unsigned samples) { ++count; } - return 4.0 * count / (double) samples; + return 4.0 * count / samples; } int main() { @@ -42,7 +42,7 @@ int main() { std::cout << "Enter samples to use: "; std::cin >> samples; - double pi = monte_carlo_pi(samples); - printf("Pi = %f\n", pi); - printf("Percent error is: %g %%\n", 100 * std::abs(pi - PI) / PI); + double pi_estimate = monte_carlo_pi(samples); + std::cout << "Pi = " << pi_estimate << '\n'; + std::cout << "Percent error is: " << 100 * std::abs(pi_estimate - PI) / PI << " %\n"; } From ed8b7dfcd8177a2299b1f2b41f5af7d750d459a7 Mon Sep 17 00:00:00 2001 From: Bendik Samseth Date: Tue, 7 Aug 2018 08:16:52 +0200 Subject: [PATCH 4/4] Actually use the `in_circle` function. --- contents/monte_carlo_integration/code/c++/monte_carlo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contents/monte_carlo_integration/code/c++/monte_carlo.cpp b/contents/monte_carlo_integration/code/c++/monte_carlo.cpp index 8b12522a4..beff97170 100644 --- a/contents/monte_carlo_integration/code/c++/monte_carlo.cpp +++ b/contents/monte_carlo_integration/code/c++/monte_carlo.cpp @@ -29,7 +29,7 @@ double monte_carlo_pi(unsigned samples) { double x = dist(generator); double y = dist(generator); - if (x*x + y*y < 1) + if (in_circle(x, y)) ++count; }