Zeel commited on
Commit
0437308
1 Parent(s): 2d3d92e

pi with monte carlo

Browse files
Files changed (2) hide show
  1. app.py +126 -0
  2. requirements.txt +4 -0
app.py ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ from pyDOE2.doe_lhs import lhs
3
+ import matplotlib.pyplot as plt
4
+ import streamlit as st
5
+ import mpmath
6
+
7
+ # Set the precision to 50 decimal places
8
+ mpmath.mp.dps = 50
9
+
10
+ # Compute the value of pi with 50 decimal places of precision
11
+ pi = mpmath.pi
12
+
13
+ st.title("Compute Pi with Monte Carlo")
14
+
15
+ st.markdown(
16
+ r"""
17
+ We know that area of a circle is $\pi r^2$. If we enclose the circle in a square of side $2r$, then the area of the square is $4r^2$. The ratio of the area of the circle to the area of the square is $\frac{\pi r^2}{4r^2} = \frac{\pi}{4}$. If we randomly sample points in the square, then the ratio of the number of points in the circle to the total number of points is also $\frac{\pi}{4}$.
18
+ """
19
+ )
20
+
21
+
22
+ # draw a circle with matplotlib
23
+ def draw_the_plot():
24
+ fig, ax = plt.subplots()
25
+ ax.set_aspect("equal")
26
+ # draw a square with matplotlib
27
+ square = plt.Rectangle(
28
+ (-1, -1), 2, 2, facecolor="lightblue", edgecolor="r", linewidth=2
29
+ )
30
+ ax.add_artist(square)
31
+ # add a two sides arrow outside the square to indicate the length of the side
32
+ upper_margin = 1.05
33
+ ax.arrow(
34
+ -1,
35
+ upper_margin,
36
+ 2,
37
+ 0,
38
+ head_width=0.05,
39
+ color="k",
40
+ length_includes_head=True,
41
+ clip_on=False,
42
+ )
43
+ ax.arrow(
44
+ 1,
45
+ upper_margin,
46
+ -2,
47
+ 0,
48
+ head_width=0.05,
49
+ color="k",
50
+ length_includes_head=True,
51
+ clip_on=False,
52
+ )
53
+ # annotate the arrow
54
+ ax.annotate(
55
+ "$2r$",
56
+ xy=(0, upper_margin),
57
+ xytext=(0, upper_margin),
58
+ horizontalalignment="center",
59
+ verticalalignment="bottom",
60
+ )
61
+ circle = plt.Circle((0, 0), 1, facecolor="lightgreen", edgecolor="b", linewidth=2)
62
+ ax.add_artist(circle)
63
+ # draw a horizontal arrow from the center to the edge
64
+ ax.arrow(0, 0, 1, 0, head_width=0.05, color="k", length_includes_head=True)
65
+ # annotate the arrow
66
+ ax.annotate(
67
+ "$r$",
68
+ xy=(0.5, 0),
69
+ xytext=(0.5, -0.1),
70
+ horizontalalignment="center",
71
+ verticalalignment="bottom",
72
+ )
73
+
74
+ ax.set_xlim(-1.1, 1.1)
75
+ ax.set_ylim(-1.1, 1.1)
76
+ ax.set_xticks([])
77
+ ax.set_yticks([])
78
+ # remove the x and y axis
79
+ ax.spines["left"].set_visible(False)
80
+ ax.spines["right"].set_visible(False)
81
+ ax.spines["top"].set_visible(False)
82
+ ax.spines["bottom"].set_visible(False)
83
+
84
+ return fig, ax
85
+
86
+
87
+ fig, ax = draw_the_plot()
88
+ st.pyplot(fig)
89
+
90
+ st.subheader("Monte Carlo Simulation")
91
+
92
+ seed = st.number_input("Random seed", min_value=0, max_value=10000000, value=0, step=1)
93
+ N = st.number_input(
94
+ "Number of points", min_value=1, max_value=10000000, value=10000, step=1
95
+ )
96
+ type = st.selectbox("Type of sampling", ["Random", "Grid"])
97
+
98
+ if type == "Random":
99
+ samples = lhs(2, samples=N, random_state=seed) * 2 - 1
100
+ else:
101
+ samples = np.linspace(-1, 1, int(np.sqrt(N)))
102
+ samples = np.array(np.meshgrid(samples, samples)).T.reshape(-1, 2)
103
+
104
+ # compute the distance of each point from the origin
105
+ distances = np.linalg.norm(samples, axis=1)
106
+
107
+ # compute the number of points inside the circle
108
+ inside = samples[distances < 1, :]
109
+ print(samples.shape, inside.shape)
110
+
111
+ st.markdown(
112
+ f"""
113
+ Points inside the circle: = {len(inside)}\n
114
+ Ratio: = {len(inside)} / {len(samples)} = {len(inside) / len(samples)}\n
115
+ $\pi$ = {len(inside) / len(samples)} * 4\n
116
+ | $\pi$ | value |
117
+ | --- | --- |
118
+ | estimated $\pi$ | {len(inside) / len(samples) * 4:.50f} |
119
+ | real $\pi$ | {pi} |
120
+ """
121
+ )
122
+
123
+ fig, ax = draw_the_plot()
124
+ ax.scatter(samples[:, 0], samples[:, 1], s=0.1, color="r")
125
+ ax.scatter(inside[:, 0], inside[:, 1], s=0.1, color="b")
126
+ st.pyplot(fig)
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ numpy
2
+ matplotlib
3
+ mpmath
4
+ pyDOE2