|
| 1 | +""" |
| 2 | +@author: MatteoRaso |
| 3 | +""" |
| 4 | +from numpy import pi, sqrt |
| 5 | +from random import uniform |
| 6 | +from statistics import mean |
| 7 | + |
| 8 | + |
| 9 | +def pi_estimator(iterations: int): |
| 10 | + """ |
| 11 | + An implementation of the Monte Carlo method used to find pi. |
| 12 | + 1. Draw a 2x2 square centred at (0,0). |
| 13 | + 2. Inscribe a circle within the square. |
| 14 | + 3. For each iteration, place a dot anywhere in the square. |
| 15 | + a. Record the number of dots within the circle. |
| 16 | + 4. After all the dots are placed, divide the dots in the circle by the total. |
| 17 | + 5. Multiply this value by 4 to get your estimate of pi. |
| 18 | + 6. Print the estimated and numpy value of pi |
| 19 | + """ |
| 20 | + # A local function to see if a dot lands in the circle. |
| 21 | + def in_circle(x: float, y: float) -> bool: |
| 22 | + distance_from_centre = sqrt((x ** 2) + (y ** 2)) |
| 23 | + # Our circle has a radius of 1, so a distance |
| 24 | + # greater than 1 would land outside the circle. |
| 25 | + return distance_from_centre <= 1 |
| 26 | + |
| 27 | + # The proportion of guesses that landed in the circle |
| 28 | + proportion = mean( |
| 29 | + int(in_circle(uniform(-1.0, 1.0), uniform(-1.0, 1.0))) for _ in range(iterations) |
| 30 | + ) |
| 31 | + # The ratio of the area for circle to square is pi/4. |
| 32 | + 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)) |
| 36 | + |
| 37 | + |
| 38 | +def area_under_line_estimator(iterations: int, |
| 39 | + min_value: float=0.0, |
| 40 | + max_value: float=1.0) -> float: |
| 41 | + """ |
| 42 | + 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 |
| 46 | + 3. Finding expected value of x: |
| 47 | + a. Repeatedly draw x from uniform distribution |
| 48 | + b. Expected value = average of those values |
| 49 | + 4. Actual value = 1/2 |
| 50 | + 5. Returns estimated value |
| 51 | + """ |
| 52 | + return mean(uniform(min_value, max_value) for _ in range(iterations)) |
| 53 | + |
| 54 | + |
| 55 | +def area_under_line_estimator_check(iterations: int) -> None: |
| 56 | + """ |
| 57 | + Checks estimation error for area_under_line_estimator func |
| 58 | + 1. Calls "area_under_line_estimator" function |
| 59 | + 2. Compares with the expected value |
| 60 | + 3. Prints estimated, expected and error value |
| 61 | + """ |
| 62 | + estimate = area_under_line_estimator(iterations) |
| 63 | + print("******************") |
| 64 | + print("Estimating area under y=x where x varies from 0 to 1") |
| 65 | + print("Expected value is ", 0.5) |
| 66 | + print("Estimated value is ", estimate) |
| 67 | + print("Total error is ", abs(estimate - 0.5)) |
| 68 | + print("******************") |
| 69 | + |
| 70 | + |
| 71 | +if __name__ == "__main__": |
| 72 | + import doctest |
| 73 | + |
| 74 | + doctest.testmod() |
0 commit comments