pi can be approximated by throwing darts at a circle in a square, and calculating the ratio of darts landing on the circle vs the square.
In [200]:
import math
import random
First, we generate a bunch of throws by using random.random()
We are throwing darts in only the top right quadrant of the square, so the origin is the center of the square, and the diameter of the circle is 2.
We figure out if the points are in the circle by using the pythogeras theorem to calculate the distance of each point from the origin (0,0)
. If the distance is greater than the radius of the circle, it's outside.
In [209]:
darths_thrown = 10000
throws = [[random.random(), random.random()] for i in range(darths_thrown)]
in_circle=0
out_circle=0
for throw in throws:
if math.sqrt(throw[0]**2 + throw[1]**2) <= 1:
in_circle +=1
else:
out_circle += 1
pi_estimate = in_circle/len(throws) * 4
print(f'estimate: {pi_estimate}')
print(f'actual: {math.pi}')
print(f'difference is {abs(pi_estimate-math.pi)}')
In [210]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
df = pd.DataFrame(np.random.rand(darths_thrown,2)*2, columns=["x", "y"])
df.head()
Out[210]:
In [211]:
def is_in_circle(row):
x = row['x']
y = row['y']
if math.sqrt((x-1)**2 + (y-1)**2) <= 1:
return True
else:
return False
df['In_Circle'] = df.apply(is_in_circle, axis=1)
df.head()
Out[211]:
In [242]:
plt.scatter(df['x'], df['y'], c=[within and 'blue' or 'red' for within in df['In_Circle']], alpha=0.4,s= 25)
fig = plt.gcf()
fig.set_size_inches(9,9);
the ratio of the area of the circle divided by the area of the square gives us pi/4:
In [205]:
pi_estimate = df['In_Circle'].sum() / len(df) * 4
pi_estimate
Out[205]:
In [206]:
pi_estimate - math.pi
Out[206]:
So the estimate is pretty close! Neat, since all it took was some very simple maths and a random number generator.
In [ ]: