Created
March 5, 2017 14:01
-
-
Save vlovo/2aa6c746d40b176b7f7cb0717448f45d to your computer and use it in GitHub Desktop.
fluent cpp pi::challenge
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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