Update approximate_pi.cpp

This commit is contained in:
ewd00010 2023-07-02 16:24:50 +01:00 committed by GitHub
parent e3f0551f98
commit 5a951bdf1e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,22 +1,26 @@
/** /**
* @file * @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 * @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 * We take a random point P with coordinates (x, y) such that 0 x 1 and 0
* point is inside the quarter disk of radius 1, otherwise the point is outside. * y 1. If x² + y² 1, then the point is inside the quarter disk of radius 1,
* We know that the probability of the point being inside the quarter disk is equal to π/4 * else the point is outside. We know that the probability of the point being
* double approx(vector<Point> &pts) which will use the points pts (drawn at random) to * inside the quarter disk is equal to π/4 double approx(vector<Point> &pts)
* return an estimate of the number π * which will use the points pts (drawn at random) to return an estimate of the
* \note This implementation is better than naive recursive or iterative * number π
* @note This implementation is better than naive recursive or iterative
* approach. * approach.
* *
* @author [Qannaf AL-SAHMI](https://github.com/Qannaf) * @author [Qannaf AL-SAHMI](https://github.com/Qannaf)
*/ */
#include <cassert> /// for assert
#include <cstdlib> /// for std::rand
#include <iostream> /// for IO operations #include <iostream> /// for IO operations
#include <vector> /// for std::vector #include <vector> /// for std::vector
#include <cstdlib> /// for std::rand
/** /**
* @namespace math * @namespace math
@ -24,55 +28,56 @@
*/ */
namespace math { namespace math {
/** /**
* structure of points containing two numbers, respectively x and y such that 0 x 1 and 0 y 1. * @brief structure of points containing two numbers, x and y, such that 0 x
*/ * 1 and 0 y 1.
typedef struct { */
typedef struct {
double x; double x;
double y; double y;
} Point; } Point;
double approximate_pi(const std::vector<Point> &pts) { /**
/** * @brief This function uses the points in a given vector 'pts' (drawn at
* This function use the points pts (drawn at random) to return an estimate of the number π using the given points * random) to return an approximation of the number π.
* @param pts Each item of pts contains a point. A point is represented by a structure containing exactly * @param pts Each item of pts contains a point. A point is represented by the
* two numbers, respectively x and y such that 0 x 1 and 0 y 1. * point structure (coded above).
* pts always contains at least one item * @return an estimate of the number π.
* @return an estimate of the number π */
*/ double approximate_pi(const std::vector<Point> &pts) {
{ double count = 0; // Points in circle
int count =0; // Points in cercle for (Point p : pts) {
for(Point p:pts) if ((p.x * p.x) + (p.y * p.y) <= 1) {
if(p.x * p.x + p.y*p.y <= 1) count++;
++count;
return 4.0*count/pts.size();
} }
} }
return 4.0 * count / static_cast<double>(pts.size());
}
} // namespace math } // namespace math
/** /**
* @brief Self-test implementations * @brief Self-test implementations
* @returns void * @returns void
*/ */
static void test() { static void tests() {
std::vector<math::Point> rands; std::vector<math::Point> rands;
for (std::size_t i = 0; i < 100000; i++) { for (std::size_t i = 0; i < 100000; i++) {
math::Point p; math::Point p;
p.x = rand() / (double)RAND_MAX; // 0 <= x <= 1 p.x = rand() / static_cast<double>(RAND_MAX); // 0 <= x <= 1
p.y = rand() / (double)RAND_MAX; // 0 <= y <= 1 p.y = rand() / static_cast<double>(RAND_MAX); // 0 <= y <= 1
rands.push_back(p); 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 * @brief Main function
* @param argc commandline argument count (ignored)
* @param argv commandline array of arguments (ignored)
* @returns 0 on exit * @returns 0 on exit
*/ */
int main(int argc, char *argv[]) { int main() {
test(); // run self-test implementations tests(); // run self-test implementations
return 0; return 0;
} }