Skip to content

Commit c9b4e34

Browse files
committed
Update pi monte carlo script to run tests with fixed seed.
1 parent 0c8cf8e commit c9b4e34

1 file changed

Lines changed: 21 additions & 12 deletions

File tree

maths/pi_monte_carlo_estimation.py

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,20 @@ def is_in_unit_circle(self) -> bool:
1111
True, if the point lies in the unit circle
1212
False, otherwise
1313
"""
14+
1415
return (self.x**2 + self.y**2) <= 1
1516

1617
@classmethod
17-
def random_unit_square(cls):
18+
def random_unit_square(cls, ran: random.Random):
1819
"""
19-
Generates a point randomly drawn from the unit square [0, 1) x [0, 1).
20+
Generates a point randomly drawn from the unit square [0, 1) x [0, 1),
21+
using 'ran' random number generator
2022
"""
21-
return cls(x=random.random(), y=random.random())
23+
24+
return cls(x=ran.random(), y=ran.random())
2225

2326

24-
def estimate_pi(number_of_simulations: int) -> float:
27+
def estimate_pi(number_of_simulations: int, seed: int | None = None) -> float:
2528
"""
2629
Generates an estimate of the mathematical constant PI.
2730
See https://en.wikipedia.org/wiki/Monte_Carlo_method#Overview
@@ -42,13 +45,24 @@ def estimate_pi(number_of_simulations: int) -> float:
4245
2. Repeat the first step n times and count the number of points in the unit
4346
circle, which is called m.
4447
3. An estimate of P[U in unit circle] is m/n
48+
49+
'seed' provides seed for the number generator - if None, no seed is used.
50+
51+
>>> estimate_pi(100, 1)
52+
3.2
53+
>>> estimate_pi(1000, 11)
54+
3.156
55+
>>> estimate_pi(1000000, 111)
56+
3.139892
57+
4558
"""
4659
if number_of_simulations < 1:
4760
raise ValueError("At least one simulation is necessary to estimate PI.")
4861

4962
number_in_unit_circle = 0
63+
ran = random.Random(seed)
5064
for _ in range(number_of_simulations):
51-
random_point = Point.random_unit_square()
65+
random_point = Point.random_unit_square(ran)
5266

5367
if random_point.is_in_unit_circle():
5468
number_in_unit_circle += 1
@@ -57,11 +71,6 @@ def estimate_pi(number_of_simulations: int) -> float:
5771

5872

5973
if __name__ == "__main__":
60-
# import doctest
61-
62-
# doctest.testmod()
63-
from math import pi
74+
import doctest
6475

65-
prompt = "Please enter the desired number of Monte Carlo simulations: "
66-
my_pi = estimate_pi(int(input(prompt).strip()))
67-
print(f"An estimate of PI is {my_pi} with an error of {abs(my_pi - pi)}")
76+
doctest.testmod()

0 commit comments

Comments
 (0)