Skip to content

Instantly share code, notes, and snippets.

@vlovo
Created March 5, 2017 14:01
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 vlovo/2aa6c746d40b176b7f7cb0717448f45d to your computer and use it in GitHub Desktop.
Save vlovo/2aa6c746d40b176b7f7cb0717448f45d to your computer and use it in GitHub Desktop.
fluent cpp pi::challenge
/* Copyright 2017, Markus Leitz. All rights reserved.
* http://techblog.boptics.de
* MLeitz(at)boptics.de
* Redistribution and use in source and binary forms are permitted, with or without modification.
*/
#include <time.h>
#include <iostream>
#include <boost/random.hpp>
#include <boost/random/uniform_real_distribution.hpp>
#include <cmath>
#include <cstdint>
#include <list>
namespace pi
{
///
class PiEstimation
{
public:
PiEstimation(size_t n,int r,float pi_ref):N(n),R(r),R2(r*r),ref(pi_ref)
{
};
void estimatePI(size_t frequency)
{
Pi = 4.0f* static_cast<float> (frequency)/ static_cast<float>(N);
error = std::fabs(ref - Pi);
}
size_t N;
size_t R;
size_t R2;
float Pi;
float error;
float ref;
};
std::ostream& operator<<(std::ostream& os, const PiEstimation& est)
{
os << "N: " <<est.N << '/' << "R: " << est.R << '/' << "error: " << est.error;
return os;
}
std::list<PiEstimation> initializeEstimators()
{
const float PI_REF = 3.14159265359; // according to challenge
std::list<PiEstimation> list;
for(size_t n=10; n < 1e7; n*=10) // range according to challenge
{
for(size_t r=10;r < 1e9; r*=10) // range according to challenge
{
list.push_back(PiEstimation(n,r,PI_REF));
}
}
return list;
}
int generate_random_data(float r, size_t N, std::vector<float> &data)
{
std::time_t now = std::time(0);
boost::random::mt19937 gen(static_cast<std::uint32_t>(now));
boost::random::uniform_real_distribution<float> dist(-r,r);
data.clear();
for(size_t i =0; i<N;++i)
{
float r2 = pow(dist(gen),2.0f) + pow(dist(gen),2.0f);
data.push_back(r2);
}
return 0;
}
}
int main(int argc, char *argv[])
{
// store the combinations of R and N
std::list<pi::PiEstimation> estimators = pi::initializeEstimators();
std::for_each(estimators.begin(),
estimators.end(),
[](pi::PiEstimation &estimator_element)
{
std::vector<float> random_data;
pi::generate_random_data(estimator_element.R,estimator_element.N,random_data);
auto statisticalFrequency = std::count_if(random_data.begin(),
random_data.end(),
[&estimator_element](float random_element)
{
return (random_element < estimator_element.R2); // is inside circle ?
}
);
estimator_element.estimatePI(statisticalFrequency);
std::cout << estimator_element << "\n";
}
);
estimators.sort([](pi::PiEstimation &a,pi::PiEstimation &b)
{
return a.error < b.error;
}
);
std::cout << " the winner this time is: " << *(estimators.begin());
return 0;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment