1
1
"""
2
2
@author: MatteoRaso
3
3
"""
4
- from numpy import pi , sqrt
4
+ from math import pi , sqrt
5
5
from random import uniform
6
6
from statistics import mean
7
+ from typing import Callable
7
8
8
9
9
10
def pi_estimator (iterations : int ):
@@ -18,58 +19,107 @@ def pi_estimator(iterations: int):
18
19
6. Print the estimated and numpy value of pi
19
20
"""
20
21
# A local function to see if a dot lands in the circle.
21
- def in_circle (x : float , y : float ) -> bool :
22
+ def is_in_circle (x : float , y : float ) -> bool :
22
23
distance_from_centre = sqrt ((x ** 2 ) + (y ** 2 ))
23
24
# Our circle has a radius of 1, so a distance
24
25
# greater than 1 would land outside the circle.
25
26
return distance_from_centre <= 1
26
27
27
28
# The proportion of guesses that landed in the circle
28
29
proportion = mean (
29
- int (in_circle (uniform (- 1.0 , 1.0 ), uniform (- 1.0 , 1.0 ))) for _ in range (iterations )
30
+ int (is_in_circle (uniform (- 1.0 , 1.0 ), uniform (- 1.0 , 1.0 )))
31
+ for _ in range (iterations )
30
32
)
31
33
# The ratio of the area for circle to square is pi/4.
32
34
pi_estimate = proportion * 4
33
- print ("The estimated value of pi is " , pi_estimate )
34
- print ("The numpy value of pi is " , pi )
35
- print ("The total error is " , abs (pi - pi_estimate ))
35
+ print (f "The estimated value of pi is { pi_estimate } " )
36
+ print (f "The numpy value of pi is { pi } " )
37
+ print (f "The total error is { abs (pi - pi_estimate )} " )
36
38
37
39
38
- def area_under_line_estimator (iterations : int ,
39
- min_value : float = 0.0 ,
40
- max_value : float = 1.0 ) -> float :
40
+ def area_under_curve_estimator (
41
+ iterations : int ,
42
+ function_to_integrate : Callable [[float ], float ],
43
+ min_value : float = 0.0 ,
44
+ max_value : float = 1.0 ,
45
+ ) -> float :
41
46
"""
42
47
An implementation of the Monte Carlo method to find area under
43
- y = x where x lies between min_value to max_value
44
- 1. Let x be a uniformly distributed random variable between min_value to max_value
45
- 2. Expected value of x = (integration of x from min_value to max_value) / (max_value - min_value)
46
- 3. Finding expected value of x:
48
+ a single variable non-negative real-valued continuous function,
49
+ say f(x), where x lies within a continuous bounded interval,
50
+ say [min_value, max_value], where min_value and max_value are
51
+ finite numbers
52
+ 1. Let x be a uniformly distributed random variable between min_value to
53
+ max_value
54
+ 2. Expected value of f(x) =
55
+ (integrate f(x) from min_value to max_value)/(max_value - min_value)
56
+ 3. Finding expected value of f(x):
47
57
a. Repeatedly draw x from uniform distribution
48
- b. Expected value = average of those values
49
- 4. Actual value = (max_value^2 - min_value^2) / 2
58
+ b. Evaluate f(x) at each of the drawn x values
59
+ c. Expected value = average of the function evaluations
60
+ 4. Estimated value of integral = Expected value * (max_value - min_value)
50
61
5. Returns estimated value
51
62
"""
52
- return mean (uniform (min_value , max_value ) for _ in range (iterations )) * (max_value - min_value )
53
63
64
+ return mean (
65
+ function_to_integrate (uniform (min_value , max_value )) for _ in range (iterations )
66
+ ) * (max_value - min_value )
54
67
55
- def area_under_line_estimator_check (iterations : int ,
56
- min_value : float = 0.0 ,
57
- max_value : float = 1.0 ) -> None :
68
+
69
+ def area_under_line_estimator_check (
70
+ iterations : int , min_value : float = 0.0 , max_value : float = 1.0
71
+ ) -> None :
58
72
"""
59
- Checks estimation error for area_under_line_estimator func
60
- 1. Calls "area_under_line_estimator" function
73
+ Checks estimation error for area_under_curve_estimator function
74
+ for f(x) = x where x lies within min_value to max_value
75
+ 1. Calls "area_under_curve_estimator" function
61
76
2. Compares with the expected value
62
77
3. Prints estimated, expected and error value
63
78
"""
64
-
65
- estimated_value = area_under_line_estimator (iterations , min_value , max_value )
66
- expected_value = (max_value * max_value - min_value * min_value ) / 2
67
-
79
+
80
+ def identity_function (x : float ) -> float :
81
+ """
82
+ Represents identity function
83
+ >>> [function_to_integrate(x) for x in [-2.0, -1.0, 0.0, 1.0, 2.0]]
84
+ [-2.0, -1.0, 0.0, 1.0, 2.0]
85
+ """
86
+ return x
87
+
88
+ estimated_value = area_under_curve_estimator (
89
+ iterations , identity_function , min_value , max_value
90
+ )
91
+ expected_value = (max_value * max_value - min_value * min_value ) / 2
92
+
93
+ print ("******************" )
94
+ print (f"Estimating area under y=x where x varies from { min_value } to { max_value } " )
95
+ print (f"Estimated value is { estimated_value } " )
96
+ print (f"Expected value is { expected_value } " )
97
+ print (f"Total error is { abs (estimated_value - expected_value )} " )
98
+ print ("******************" )
99
+
100
+
101
+ def pi_estimator_using_area_under_curve (iterations : int ) -> None :
102
+ """
103
+ Area under curve y = sqrt(4 - x^2) where x lies in 0 to 2 is equal to pi
104
+ """
105
+
106
+ def function_to_integrate (x : float ) -> float :
107
+ """
108
+ Represents semi-circle with radius 2
109
+ >>> [function_to_integrate(x) for x in [-2.0, 0.0, 2.0]]
110
+ [0.0, 2.0, 0.0]
111
+ """
112
+ return sqrt (4.0 - x * x )
113
+
114
+ estimated_value = area_under_curve_estimator (
115
+ iterations , function_to_integrate , 0.0 , 2.0
116
+ )
117
+
68
118
print ("******************" )
69
- print ("Estimating area under y=x where x varies from " , min_value , " to " , max_value )
70
- print ("Estimated value is " , estimated_value )
71
- print ("Expected value is " , expected_value )
72
- print ("Total error is " , abs (estimated_value - expected_value ) )
119
+ print ("Estimating pi using area_under_curve_estimator" )
120
+ print (f "Estimated value is { estimated_value } " )
121
+ print (f "Expected value is { pi } " )
122
+ print (f "Total error is { abs (estimated_value - pi ) } " )
73
123
print ("******************" )
74
124
75
125
0 commit comments