From 5a951bdf1e9058b09567447833a2d3bbb88f8a2c Mon Sep 17 00:00:00 2001 From: ewd00010 <78011234+ewd00010@users.noreply.github.com> Date: Sun, 2 Jul 2023 16:24:50 +0100 Subject: [PATCH] Update approximate_pi.cpp --- math/approximate_pi.cpp | 79 ++++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 37 deletions(-) diff --git a/math/approximate_pi.cpp b/math/approximate_pi.cpp index 2b7c16d8a..d3df92a75 100644 --- a/math/approximate_pi.cpp +++ b/math/approximate_pi.cpp @@ -1,22 +1,26 @@ /** * @file - * @brief Implementation to calculate an estimate of the [number π (Pi)](https://en.wikipedia.org/wiki/File:Pi_30K.gif). + * @brief + * Implementation to calculate an estimate of the [number π + * (Pi)](https://en.wikipedia.org/wiki/File:Pi_30K.gif). * * @details - * We take a random point P with coordinates (x, y) such that 0 ≤ x ≤ 1 and 0 ≤ y ≤ 1. If x² + y² ≤ 1, then the - * point is inside the quarter disk of radius 1, otherwise the point is outside. - * We know that the probability of the point being inside the quarter disk is equal to π/4 - * double approx(vector &pts) which will use the points pts (drawn at random) to - * return an estimate of the number π - * \note This implementation is better than naive recursive or iterative + * We take a random point P with coordinates (x, y) such that 0 ≤ x ≤ 1 and 0 ≤ + * y ≤ 1. If x² + y² ≤ 1, then the point is inside the quarter disk of radius 1, + * else the point is outside. We know that the probability of the point being + * inside the quarter disk is equal to π/4 double approx(vector &pts) + * which will use the points pts (drawn at random) to return an estimate of the + * number π + * @note This implementation is better than naive recursive or iterative * approach. * * @author [Qannaf AL-SAHMI](https://github.com/Qannaf) */ +#include /// for assert +#include /// for std::rand #include /// for IO operations #include /// for std::vector -#include /// for std::rand /** * @namespace math @@ -24,55 +28,56 @@ */ namespace math { - /** - * structure of points containing two numbers, respectively x and y such that 0 ≤ x ≤ 1 and 0 ≤ y ≤ 1. - */ - typedef struct { +/** + * @brief structure of points containing two numbers, x and y, such that 0 ≤ x ≤ + * 1 and 0 ≤ y ≤ 1. + */ +typedef struct { double x; double y; - } Point; +} Point; - double approximate_pi(const std::vector &pts) { - /** - * This function use the points pts (drawn at random) to return an estimate of the number π using the given points - * @param pts Each item of pts contains a point. A point is represented by a structure containing exactly - * two numbers, respectively x and y such that 0 ≤ x ≤ 1 and 0 ≤ y ≤ 1. - * pts always contains at least one item - * @return an estimate of the number π - */ - { - int count =0; // Points in cercle - for(Point p:pts) - if(p.x * p.x + p.y*p.y <= 1) - ++count; - - return 4.0*count/pts.size(); +/** + * @brief This function uses the points in a given vector 'pts' (drawn at + * random) to return an approximation of the number π. + * @param pts Each item of pts contains a point. A point is represented by the + * point structure (coded above). + * @return an estimate of the number π. + */ +double approximate_pi(const std::vector &pts) { + double count = 0; // Points in circle + for (Point p : pts) { + if ((p.x * p.x) + (p.y * p.y) <= 1) { + count++; } } + return 4.0 * count / static_cast(pts.size()); +} } // namespace math /** * @brief Self-test implementations * @returns void */ -static void test() { - std::vector rands; +static void tests() { + std::vector rands; for (std::size_t i = 0; i < 100000; i++) { math::Point p; - p.x = rand() / (double)RAND_MAX; // 0 <= x <= 1 - p.y = rand() / (double)RAND_MAX; // 0 <= y <= 1 + p.x = rand() / static_cast(RAND_MAX); // 0 <= x <= 1 + p.y = rand() / static_cast(RAND_MAX); // 0 <= y <= 1 rands.push_back(p); } - std::cout << math::approximate_pi(rands) << std::endl; // ~3.14 + assert(math::approximate_pi(rands) > 3.135); + assert(math::approximate_pi(rands) < 3.145); + + std::cout << "All tests have successfully passed!" << std::endl; } /** * @brief Main function - * @param argc commandline argument count (ignored) - * @param argv commandline array of arguments (ignored) * @returns 0 on exit */ -int main(int argc, char *argv[]) { - test(); // run self-test implementations +int main() { + tests(); // run self-test implementations return 0; }