From fe6ed5e8fd13615692637bb0106b95016f61342c Mon Sep 17 00:00:00 2001 From: Varun <1990.singlav@gmail.com> Date: Sun, 23 Feb 2020 06:20:49 +0530 Subject: [PATCH 1/3] estimate area under a curve defined by non-negative real-valued continuous function within a continuous interval using monte-carlo --- maths/monte_carlo.py | 53 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 10 deletions(-) diff --git a/maths/monte_carlo.py b/maths/monte_carlo.py index 6a407e98badd..19c8157a4db8 100644 --- a/maths/monte_carlo.py +++ b/maths/monte_carlo.py @@ -4,6 +4,7 @@ from numpy import pi, sqrt from random import uniform from statistics import mean +from typing import Callable def pi_estimator(iterations: int): @@ -35,34 +36,43 @@ def in_circle(x: float, y: float) -> bool: print("The total error is ", abs(pi - pi_estimate)) -def area_under_line_estimator(iterations: int, +def area_under_curve_estimator(iterations: int, + function_to_integrate: Callable[[float], float], min_value: float=0.0, max_value: float=1.0) -> float: """ An implementation of the Monte Carlo method to find area under - y = x where x lies between min_value to max_value + a single variable non-negative real-valued continuous function, say f(x), + where x lies within a continuous bounded interval, say [min_value, max_value], + where min_value and max_value are finite numbers 1. Let x be a uniformly distributed random variable between min_value to max_value - 2. Expected value of x = (integration of x from min_value to max_value) / (max_value - min_value) - 3. Finding expected value of x: + 2. Expected value of f(x) = (integration of f(x) from min_value to max_value) / (max_value - min_value) + 3. Finding expected value of f(x): a. Repeatedly draw x from uniform distribution - b. Expected value = average of those values - 4. Actual value = (max_value^2 - min_value^2) / 2 + b. Evaluate f(x) at each of the drawn x values + c. Expected value = average of the function evaluations + 4. Estimated value of integral = Expected value * (max_value - min_value) 5. Returns estimated value """ - return mean(uniform(min_value, max_value) for _ in range(iterations)) * (max_value - min_value) + + return mean(function_to_integrate(uniform(min_value, max_value)) for _ in range(iterations)) * (max_value - min_value) def area_under_line_estimator_check(iterations: int, min_value: float=0.0, max_value: float=1.0) -> None: """ - Checks estimation error for area_under_line_estimator func - 1. Calls "area_under_line_estimator" function + Checks estimation error for area_under_curve_estimator function + for f(x) = x where x lies in 0 to 1 + 1. Calls "area_under_curve_estimator" function 2. Compares with the expected value 3. Prints estimated, expected and error value """ - estimated_value = area_under_line_estimator(iterations, min_value, max_value) + def identity_function(x: float) -> float: + return x + + estimated_value = area_under_curve_estimator(iterations, identity_function, min_value, max_value) expected_value = (max_value*max_value - min_value*min_value) / 2 print("******************") @@ -72,6 +82,29 @@ def area_under_line_estimator_check(iterations: int, print("Total error is ", abs(estimated_value - expected_value)) print("******************") + return + + +def pi_estimator_using_area_under_curve(iterations: int) -> None: + """ + Area under curve y = sqrt(4 - x^2) where x lies in 0 to 2 + is equal to pi + """ + + def function_to_integrate(x: float) -> float: + return sqrt(4.0 - x*x) + + estimated_value = area_under_curve_estimator(iterations, function_to_integrate, 0.0, 2.0) + + print("******************") + print("Estimating pi using area_under_curve_estimator") + print("Estimated value is ", estimated_value) + print("Expected value is ", pi) + print("Total error is ", abs(estimated_value - pi)) + print("******************") + + return + if __name__ == "__main__": import doctest From 250abb1382114b203001571bc5aba14268be28ad Mon Sep 17 00:00:00 2001 From: Varun <1990.singlav@gmail.com> Date: Sun, 23 Feb 2020 11:47:11 +0530 Subject: [PATCH 2/3] run black; update comments --- maths/monte_carlo.py | 78 +++++++++++++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 27 deletions(-) diff --git a/maths/monte_carlo.py b/maths/monte_carlo.py index 19c8157a4db8..4e5adc22c363 100644 --- a/maths/monte_carlo.py +++ b/maths/monte_carlo.py @@ -27,7 +27,8 @@ def in_circle(x: float, y: float) -> bool: # The proportion of guesses that landed in the circle proportion = mean( - int(in_circle(uniform(-1.0, 1.0), uniform(-1.0, 1.0))) for _ in range(iterations) + int(in_circle(uniform(-1.0, 1.0), uniform(-1.0, 1.0))) + for _ in range(iterations) ) # The ratio of the area for circle to square is pi/4. pi_estimate = proportion * 4 @@ -36,17 +37,22 @@ def in_circle(x: float, y: float) -> bool: print("The total error is ", abs(pi - pi_estimate)) -def area_under_curve_estimator(iterations: int, - function_to_integrate: Callable[[float], float], - min_value: float=0.0, - max_value: float=1.0) -> float: +def area_under_curve_estimator( + iterations: int, + function_to_integrate: Callable[[float], float], + min_value: float = 0.0, + max_value: float = 1.0, +) -> float: """ An implementation of the Monte Carlo method to find area under - a single variable non-negative real-valued continuous function, say f(x), - where x lies within a continuous bounded interval, say [min_value, max_value], - where min_value and max_value are finite numbers - 1. Let x be a uniformly distributed random variable between min_value to max_value - 2. Expected value of f(x) = (integration of f(x) from min_value to max_value) / (max_value - min_value) + a single variable non-negative real-valued continuous function, + say f(x), where x lies within a continuous bounded interval, + say [min_value, max_value], where min_value and max_value are + finite numbers + 1. Let x be a uniformly distributed random variable between min_value to + max_value + 2. Expected value of f(x) = + (integrate f(x) from min_value to max_value)/(max_value - min_value) 3. Finding expected value of f(x): a. Repeatedly draw x from uniform distribution b. Evaluate f(x) at each of the drawn x values @@ -54,29 +60,40 @@ def area_under_curve_estimator(iterations: int, 4. Estimated value of integral = Expected value * (max_value - min_value) 5. Returns estimated value """ - - return mean(function_to_integrate(uniform(min_value, max_value)) for _ in range(iterations)) * (max_value - min_value) + return mean( + function_to_integrate(uniform(min_value, max_value)) for _ in range(iterations) + ) * (max_value - min_value) -def area_under_line_estimator_check(iterations: int, - min_value: float=0.0, - max_value: float=1.0) -> None: + +def area_under_line_estimator_check( + iterations: int, min_value: float = 0.0, max_value: float = 1.0 +) -> None: """ Checks estimation error for area_under_curve_estimator function - for f(x) = x where x lies in 0 to 1 + for f(x) = x where x lies within min_value to max_value 1. Calls "area_under_curve_estimator" function 2. Compares with the expected value 3. Prints estimated, expected and error value """ - + def identity_function(x: float) -> float: + """ + Represents identity function + >>> [function_to_integrate(x) for x in [-2.0, -1.0, 0.0, 1.0, 2.0]] + [-2.0, -1.0, 0.0, 1.0, 2.0] + """ return x - - estimated_value = area_under_curve_estimator(iterations, identity_function, min_value, max_value) - expected_value = (max_value*max_value - min_value*min_value) / 2 - + + estimated_value = area_under_curve_estimator( + iterations, identity_function, min_value, max_value + ) + expected_value = (max_value * max_value - min_value * min_value) / 2 + print("******************") - print("Estimating area under y=x where x varies from ",min_value, " to ",max_value) + print( + "Estimating area under y=x where x varies from ", min_value, " to ", max_value + ) print("Estimated value is ", estimated_value) print("Expected value is ", expected_value) print("Total error is ", abs(estimated_value - expected_value)) @@ -92,17 +109,24 @@ def pi_estimator_using_area_under_curve(iterations: int) -> None: """ def function_to_integrate(x: float) -> float: - return sqrt(4.0 - x*x) - - estimated_value = area_under_curve_estimator(iterations, function_to_integrate, 0.0, 2.0) - + """ + Represents semi-circle with radius 2 + >>> [function_to_integrate(x) for x in [-2.0, 0.0, 2.0]] + [0.0, 2.0, 0.0] + """ + return sqrt(4.0 - x * x) + + estimated_value = area_under_curve_estimator( + iterations, function_to_integrate, 0.0, 2.0 + ) + print("******************") print("Estimating pi using area_under_curve_estimator") print("Estimated value is ", estimated_value) print("Expected value is ", pi) print("Total error is ", abs(estimated_value - pi)) print("******************") - + return From 7f0106cf408d60546f946e7456ebeb6280146a03 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Sun, 23 Feb 2020 08:00:17 +0100 Subject: [PATCH 3/3] =?UTF-8?q?Use=20f=E2=80=9Dstrings=E2=80=9D=20and=20dr?= =?UTF-8?q?op=20unnecessary=20returns?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- maths/monte_carlo.py | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/maths/monte_carlo.py b/maths/monte_carlo.py index 4e5adc22c363..dedca9f6cdf5 100644 --- a/maths/monte_carlo.py +++ b/maths/monte_carlo.py @@ -1,7 +1,7 @@ """ @author: MatteoRaso """ -from numpy import pi, sqrt +from math import pi, sqrt from random import uniform from statistics import mean from typing import Callable @@ -19,7 +19,7 @@ def pi_estimator(iterations: int): 6. Print the estimated and numpy value of pi """ # A local function to see if a dot lands in the circle. - def in_circle(x: float, y: float) -> bool: + def is_in_circle(x: float, y: float) -> bool: distance_from_centre = sqrt((x ** 2) + (y ** 2)) # Our circle has a radius of 1, so a distance # greater than 1 would land outside the circle. @@ -27,14 +27,14 @@ def in_circle(x: float, y: float) -> bool: # The proportion of guesses that landed in the circle proportion = mean( - int(in_circle(uniform(-1.0, 1.0), uniform(-1.0, 1.0))) + int(is_in_circle(uniform(-1.0, 1.0), uniform(-1.0, 1.0))) for _ in range(iterations) ) # The ratio of the area for circle to square is pi/4. pi_estimate = proportion * 4 - print("The estimated value of pi is ", pi_estimate) - print("The numpy value of pi is ", pi) - print("The total error is ", abs(pi - pi_estimate)) + print(f"The estimated value of pi is {pi_estimate}") + print(f"The numpy value of pi is {pi}") + print(f"The total error is {abs(pi - pi_estimate)}") def area_under_curve_estimator( @@ -91,21 +91,16 @@ def identity_function(x: float) -> float: expected_value = (max_value * max_value - min_value * min_value) / 2 print("******************") - print( - "Estimating area under y=x where x varies from ", min_value, " to ", max_value - ) - print("Estimated value is ", estimated_value) - print("Expected value is ", expected_value) - print("Total error is ", abs(estimated_value - expected_value)) + print(f"Estimating area under y=x where x varies from {min_value} to {max_value}") + print(f"Estimated value is {estimated_value}") + print(f"Expected value is {expected_value}") + print(f"Total error is {abs(estimated_value - expected_value)}") print("******************") - return - def pi_estimator_using_area_under_curve(iterations: int) -> None: """ - Area under curve y = sqrt(4 - x^2) where x lies in 0 to 2 - is equal to pi + Area under curve y = sqrt(4 - x^2) where x lies in 0 to 2 is equal to pi """ def function_to_integrate(x: float) -> float: @@ -122,13 +117,11 @@ def function_to_integrate(x: float) -> float: print("******************") print("Estimating pi using area_under_curve_estimator") - print("Estimated value is ", estimated_value) - print("Expected value is ", pi) - print("Total error is ", abs(estimated_value - pi)) + print(f"Estimated value is {estimated_value}") + print(f"Expected value is {pi}") + print(f"Total error is {abs(estimated_value - pi)}") print("******************") - return - if __name__ == "__main__": import doctest