From c9b4e3442539c7d29082772ad20313766f147e06 Mon Sep 17 00:00:00 2001 From: mindaugl Date: Sat, 17 May 2025 17:18:59 +0100 Subject: [PATCH] Update pi monte carlo script to run tests with fixed seed. --- maths/pi_monte_carlo_estimation.py | 33 +++++++++++++++++++----------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/maths/pi_monte_carlo_estimation.py b/maths/pi_monte_carlo_estimation.py index 29b679907239..44a538d50b28 100644 --- a/maths/pi_monte_carlo_estimation.py +++ b/maths/pi_monte_carlo_estimation.py @@ -11,17 +11,20 @@ def is_in_unit_circle(self) -> bool: True, if the point lies in the unit circle False, otherwise """ + return (self.x**2 + self.y**2) <= 1 @classmethod - def random_unit_square(cls): + def random_unit_square(cls, ran: random.Random): """ - Generates a point randomly drawn from the unit square [0, 1) x [0, 1). + Generates a point randomly drawn from the unit square [0, 1) x [0, 1), + using 'ran' random number generator """ - return cls(x=random.random(), y=random.random()) + + return cls(x=ran.random(), y=ran.random()) -def estimate_pi(number_of_simulations: int) -> float: +def estimate_pi(number_of_simulations: int, seed: int | None = None) -> float: """ Generates an estimate of the mathematical constant PI. See https://en.wikipedia.org/wiki/Monte_Carlo_method#Overview @@ -42,13 +45,24 @@ def estimate_pi(number_of_simulations: int) -> float: 2. Repeat the first step n times and count the number of points in the unit circle, which is called m. 3. An estimate of P[U in unit circle] is m/n + + 'seed' provides seed for the number generator - if None, no seed is used. + + >>> estimate_pi(100, 1) + 3.2 + >>> estimate_pi(1000, 11) + 3.156 + >>> estimate_pi(1000000, 111) + 3.139892 + """ if number_of_simulations < 1: raise ValueError("At least one simulation is necessary to estimate PI.") number_in_unit_circle = 0 + ran = random.Random(seed) for _ in range(number_of_simulations): - random_point = Point.random_unit_square() + random_point = Point.random_unit_square(ran) if random_point.is_in_unit_circle(): number_in_unit_circle += 1 @@ -57,11 +71,6 @@ def estimate_pi(number_of_simulations: int) -> float: if __name__ == "__main__": - # import doctest - - # doctest.testmod() - from math import pi + import doctest - prompt = "Please enter the desired number of Monte Carlo simulations: " - my_pi = estimate_pi(int(input(prompt).strip())) - print(f"An estimate of PI is {my_pi} with an error of {abs(my_pi - pi)}") + doctest.testmod()