Skip to content

Instantly share code, notes, and snippets.

@dereckmezquita
Last active November 13, 2021 23:32
Show Gist options
  • Save dereckmezquita/890961b93363115a854ebb9aee1bfdd2 to your computer and use it in GitHub Desktop.
Save dereckmezquita/890961b93363115a854ebb9aee1bfdd2 to your computer and use it in GitHub Desktop.
Different methods in C++/Rcpp code for calculating the constant Pi: Gregory Leibniz, Nilakantha, and Monte Carlo. Plotting is done in R.
#include <Rcpp.h>
#include <iostream>
#include <random>
#include <chrono>
#include <math.h>
using namespace Rcpp;
// [[Rcpp::export]]
long double gregoryLeibnizCpp(int iterations) {
long double pi = 1;
bool op = true;
for(int i = 3; iterations > i; i = i + 2) {
if(op) {
pi = pi - (1 / (long double) i);
op = false;
} else {
pi = pi + (1 / (long double) i);
op = true;
}
}
return pi * 4;
}
// [[Rcpp::export]]
long double nilakanthaCpp(int iterations) {
long double pi = 3;
bool op = true;
for(long double i = 2; iterations > i; i = i + 2) {
if(op) {
pi = pi + (4 / (i * (i + 1) * (i + 2)));
op = false;
} else {
pi = pi - (4 / (i * (i + 1) * (i + 2)));
op = true;
}
}
return pi;
}
std::mt19937 rng(std::chrono::steady_clock::now().time_since_epoch().count());
// [[Rcpp::export]]
DataFrame monteCarloPi(double iterations) {
NumericVector x(iterations);
NumericVector y(iterations);
NumericVector colour(iterations);
double circle = 0;
double width = 1;
for(int i = 0; i < iterations; i++) {
x[i] = std::uniform_real_distribution<double>(0, width)(rng);
y[i] = std::uniform_real_distribution<double>(0, width)(rng);
if(std::sqrt(x[i] * x[i] + y[i] * y[i]) <= width) {
circle++;
colour[i] = 1;
} else {
colour[i] = 0;
}
}
double pi = (circle / iterations) * 4.0;
std::cout << pi << std::endl;
return DataFrame::create(_["x"] = x, _["y"] = y, _["colour"] = colour);
}
@dereckmezquita
Copy link
Author

Plot Monte Carlo results:

res <- monteCarloPi(100000)

par(bg = "black", mar = rep(0, 4))
plot(res[res$colour != 1, "x"], res[res$colour != 1, "y"], cex = 0.1, col = "gray")
points(res[res$colour == 1, "x"], res[res$colour == 1, "y"], cex = 0.1, col = "red")

test

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment