Skip to content

Instantly share code, notes, and snippets.

@vcato
Last active March 11, 2017 16:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vcato/4fdecd703261fb17bc843905017e9ac0 to your computer and use it in GitHub Desktop.
Save vcato/4fdecd703261fb17bc843905017e9ac0 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <vector>
#include <cmath>
#include <random>
using Real = double;
using RandomEngine = std::mt19937;
using Coordinate = int32_t;
using SquaredCoordinate = int64_t;
using PointCount = int;
struct RealTable {
std::vector<std::vector<Real>> rows;
RealTable(size_t n_rows,size_t n_columns)
: rows(n_rows,std::vector<Real>(n_columns))
{
}
void printOn(std::ostream &stream)
{
for (const auto &row : rows) {
for (const auto &value : row) {
stream.width(20);
stream << value;
}
stream << '\n';
}
}
};
struct PiApproximator {
Coordinate radius;
RandomEngine &engine;
Real calculateUsing(PointCount n_points_in_square)
{
PointCount n_points_in_circle = 0;
for (PointCount i=0; i!=n_points_in_square; ++i) {
if (isInCircle(randomPointInSquare())) {
++n_points_in_circle;
}
}
return Real(n_points_in_circle)/Real(n_points_in_square) * 4;
}
private:
struct Point {
Coordinate x,y;
};
bool isInCircle(const Point &point)
{
SquaredCoordinate x = point.x;
SquaredCoordinate y = point.y;
SquaredCoordinate r = radius;
return x*x + y*y <= r*r;
}
Coordinate randomCoordinate()
{
using distribution = std::uniform_int_distribution<Coordinate>;
return distribution(-radius,radius)(engine);
}
Point randomPointInSquare()
{
Coordinate x = randomCoordinate();
Coordinate y = randomCoordinate();
return {x,y};
}
};
static Real
piApproximation(Coordinate radius,PointCount n_points,RandomEngine &engine)
{
return PiApproximator{radius,engine}.calculateUsing(n_points);
}
static RealTable piApproximationErrorTable()
{
int n_rows = 9;
int n_columns = 7;
RealTable result(n_rows,n_columns);
Real reference_value = 3.14159265359;
RandomEngine engine;
for (int row=0; row!=n_rows; ++row) {
for (int column=0; column!=n_columns; ++column) {
Coordinate radius = std::pow(10,row);
PointCount n_points = std::pow(10,column);
Real approximation = piApproximation(radius,n_points,engine);
Real error = std::abs(approximation-reference_value);
result.rows[row][column] = error;
}
}
return result;
}
int main()
{
piApproximationErrorTable().printOn(std::cout);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment