Skip to content

Instantly share code, notes, and snippets.

@AriLFrankel
Last active September 16, 2018 19:18
Show Gist options
  • Save AriLFrankel/342166917dd0133127e72c7c8c63d90d to your computer and use it in GitHub Desktop.
Save AriLFrankel/342166917dd0133127e72c7c8c63d90d to your computer and use it in GitHub Desktop.
monte carlo estimation of Pi
// a random number that includes both min and max
const trueRandom = (min = 0, max) => Math.random() * (max + Number.MIN_VALUE) + min;
// a class for tracking running average
const runningProportion = function(num = 1, den = 1) {
// numerator
this.num = num;
// denominator
this.den = den;
this.add = (num, den) => {
if (typeof num === 'number') this.num += num;
if (typeof den === 'number') this.den += den;
return this;
}
this.get = () => this.num / this.den;
}
// non blocking while loop so that we can get a ton of values without crashing the process
// convenient choice
const r = 0.5
// geometry
const distance = point => Math.sqrt(point.x**2 + point.y**2)
const inCircle = point => distance(point) < r
const randomPoint = () => ({ x: trueRandom(-r, r), y: trueRandom(-r, r) });
// The area of a circle of radius 0.5 is Pi / 4 and the area of a square of side length 1 is 1
// The assumption is that a random point in the square should have a probability of landing in the cirlce = area of circle / area of square = Pi/4 / 1 = Pi/4
// That assumption informs the following estimation of Pi:
// sample tons of random points inside the square
// track the ratio of points inside the circle to out, and use that to approximate Pi with the following equation: Pi / 4 = approximation => Pi = 4 * approximation
const monteCarlo = () => {
const pro = new runningProportion();
let i = 0;
while(i < 1000000) {
if(inCircle(randomPoint())) pro.add(1);
else pro.add(0, 1);
i++
}
return 4 * pro.get();
}
monteCarlo()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment