Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add approximate_pi.cpp file #1860

Merged
merged 16 commits into from
Jan 19, 2022
78 changes: 78 additions & 0 deletions math/approximate_pi.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/**
* @file
* @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<Point> &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 <iostream> /// for IO operations
#include <vector> /// for std::vector
#include <cstdlib> /// for std::rand

/**
* @namespace math
* @brief Mathematical algorithms
*/
namespace math {

/**
* structure of points containing two numbers, respectively x and y such that 0 ≤ x ≤ 1 and 0 ≤ y ≤ 1.
*/
typedef struct {
double x;
double y;
} Point;

double approximate_pi(const std::vector<Point> &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();
}
}
} // namespace math

Panquesito7 marked this conversation as resolved.
Show resolved Hide resolved
/**
* @brief Self-test implementations
* @returns void
*/
static void test() {
std::vector<math::Point> 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
rands.push_back(p);
}
std::cout << math::approximate_pi(rands) << std::endl; // ~3.14
}

Qannaf marked this conversation as resolved.
Show resolved Hide resolved
/**
* @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
return 0;
}