Monte Carlo Approximation of $\pi$

Ben Sattelberg, October 29, 2019

In this notebook is an implementation of Monte Carlo method for calculating $\pi$.

In [4]:
import numpy as np
import multiprocessing
import itertools

from sage.repl.image import Image
from sage.plot.circle import Circle
from sage.plot.polygon import Polygon
from sage.plot.plot3d.base import SHOW_DEFAULTS
from IPython import display
SHOW_DEFAULTS['aspect_ratio'] = (1,1,1)
SHOW_DEFAULTS['frame_aspect_ratio'] = (1,1,1)
SHOW_DEFAULTS['perspective_depth'] = false
from sage.plot.scatter_plot import ScatterPlot

The proportion of points calculated to be inside the circle is an approximation of the ratio of the area of a circle to a square. Since the area of the square is $(2r)^2$ and the area of the circle is $\pi r^2$, that ratio is $$ \frac{\text{# samples in}}{\text{# samples out}} \approx \frac{\pi r^2}{(2r)^2} = \frac{\pi}{4}$$ This means that we can approximate $\pi$ as $$ \pi \approx 4 \frac{\text{# samples in}}{\text{# samples out}}$$

In [6]:
# Next two parameters control total samples and display update
total_samples = 10000
display_interval = 500

points = []
numInCircle = 0

circlePlot = circle((0, 0), 1)
squarePlot = polygon2d(((1,1), (1,-1), (-1,-1), (-1,1)), fill=False)

for i in range(1, total_samples+1):
    point = np.random.uniform(-1, 1, 2)
    points.append(point)
    if np.dot(point, point) < 1:
        numInCircle += 1
    if mod(i,display_interval) == 0 :    
        piApprox = 4*numInCircle/i
        title = 'Pi is roughly ' + str(piApprox.n()) + ' with ' + str(i) + ' samples'
        pointPlot = scatter_plot(points, marker='.', aspect_ratio=1, figsize=10, title=title)
        display.clear_output(wait=True)
        display.display(sum([pointPlot, circlePlot, squarePlot]))
In [ ]: