1.
import random
import = bring in something from outside the current file.
random = the module we need to generate random numbers.
📌 What it does in this code:
Later in the loop, you see:
python
x, y = [Link](-1, 1), [Link](-1, 1)
This uses [Link]() to create a random decimal number between -1 and 1.
These are the (x, y) coordinates of points.
import [Link] as plt
[Link] = the graph-drawing part of the matplotlib library.
as plt = allows us to use a shorter name, plt, when we draw the graph later.
📌 Used in:
python
[Link](figsize=(6,6))
[Link](...)
NUM_POINTS = 10000
NUM_POINTS = variable name (constant style, written in uppercase).
= 10000 = we want to generate 10,000 random points.
📌 Used in:
python
for _ in range(NUM_POINTS):
This tells the program to repeat the loop 10,000 times to generate 10,000 points.
inside_circle = 0
We are setting up a counter.
It starts at 0.
It will increase by 1 each time a point falls inside the circle.
📌 Example from your code:
python
if distance <= 1:
inside_circle += 1
If the random point is in the circle, we add 1 to inside_circle.
x_inside = []
y_inside = []
These are empty lists.
They will store all the x and y coordinates for points inside the circle.
📌 Used in:
python
x_inside.append(x)
y_inside.append(y)
So if a point like (0.3, 0.7) is inside, x_inside becomes [0.3], and y_inside becomes [0.7].
x_outside = []
y_outside = []
These are also empty lists.
They store points that fall outside the circle.
📌 Example:
If a point (0.9, 0.9) is outside, then:
python
x_outside.append(0.9)
y_outside.append(0.9)
for _ in range(NUM_POINTS):
for = loop keyword.
_ = used when we don’t care about the loop number.
range(NUM_POINTS) = create numbers from 0 to 9999.
📌 This loop runs 10,000 times, once for each random point.
x, y = [Link](-1, 1), [Link](-1, 1)
x, y = two variables to hold coordinates.
[Link](-1, 1) = pick a random decimal between -1 and 1.
📌 Example values:
python
x = 0.6
y = -0.2
So we just created the point (0.6, -0.2) inside the square.
distance = x**2 + y**2
x**2 = x squared (means x × x)
y**2 = y squared
We don’t use square root because we just want to check if the distance squared
is ≤ 1
📌 Example using x = 0.6, y = -0.2:
makefile
x**2 = 0.36
y**2 = 0.04
distance = 0.36 + 0.04 = 0.4
So the point is inside the circle.
if distance <= 1:
if = decision-making.
We check if the point is inside the unit circle (radius = 1).
📌 In our example:
kotlin
distance = 0.4 → this is less than 1 → so the point is inside
inside_circle += 1
We add 1 to the inside_circle counter.
📌 If it was 2580 before, it becomes 2581 now.
x_inside.append(x)
y_inside.append(y)
These lines store the coordinates of this point, because it's inside the circle.
📌 Using our earlier values:
python
x_inside.append(0.6)
y_inside.append(-0.2)
Lists now:
ini
x_inside = [0.6]
y_inside = [-0.2]
else:
If the point is not inside the circle, run this block.
x_outside.append(x)
y_outside.append(y)
📌 Example:
python
x = 0.9
y = 0.9
distance = 0.9**2 + 0.9**2 = 0.81 + 0.81 = 1.62
This is outside, so:
python
x_outside.append(0.9)
y_outside.append(0.9)
pi_estimate = (inside_circle / NUM_POINTS) * 4
This line estimates the value of π using the Monte Carlo method.
inside_circle / NUM_POINTS = ratio of points inside the circle
Multiply by 4 because:
o The square area = 4
o The circle area = π
o So, π ≈ (points inside / total points) × 4
📌 Example:
python
inside_circle = 7854
NUM_POINTS = 10000
pi_estimate = (7854 / 10000) * 4 = 3.1416
print(f"Estimated value of π: {pi_estimate}")
This prints the estimated π value.
f"" is a formatted string, so {pi_estimate} gets replaced by its value.
📌 Example output:
nginx
Estimated value of π: 3.1416
[Link](figsize=(6,6))
[Link]() = create a new graph.
figsize=(6,6) = 6 inches wide and 6 inches tall.
[Link](x_inside, y_inside, color="blue", s=1, label="Inside Circle")
scatter() = draw dots.
x_inside, y_inside = coordinates of inside points.
color="blue" = blue dots.
s=1 = very small dots.
label = name to show in the legend.
[Link](x_outside, y_outside, color="red", s=1, label="Outside Circle")
Same thing, but now drawing red dots for outside points.
[Link]("X-axis") and [Link]("Y-axis")
Add labels to x and y axes.
[Link]("Monte Carlo Simulation for π Estimation")
Adds a title to the graph.
[Link]()
Shows the color legend (blue for inside, red for outside).
[Link]()
Opens a window and displays the graph with all the points.
2. 📦 import random
Brings in Python’s built-in random module.
We’ll use this to generate random (x, y) coordinates.
📌 Example from your code:
python
CopyEdit
x, y = [Link](-1, 1), [Link](-1, 1)
📦 import numpy as np
numpy (short for Numerical Python) is a powerful math library.
as np = shortcut name so we can write [Link]() instead of [Link]().
In this specific code, numpy is not used (can be removed safely unless added
later).
📦 import [Link] as plt
[Link] is used for plotting graphs.
plt = short name for easier writing.
Used later in:
python
CopyEdit
[Link](...)
[Link]()
🔧 Function: estimate_pi(num_points)
def estimate_pi(num_points):
def = Define a function.
estimate_pi = Name of the function.
num_points = Parameter (how many random points to use).
This function runs the Monte Carlo simulation to estimate π.
inside_circle = 0
This keeps a count of how many points fall inside the circle.
It starts at 0.
for _ in range(num_points):
A loop that runs num_points times.
_ = We don’t care about the loop number, just repeating the task.
range(num_points) = Repeats the loop that many times.
📌 Example:
python
CopyEdit
if num_points = 3
→ loop runs 3 times
x, y = [Link](-1, 1), [Link](-1, 1)
Generate a random point (x, y) inside a square from -1 to 1 on both axes.
📌 Example run:
ini
CopyEdit
x = 0.5
y = -0.7
This gives us the point (0.5, -0.7).
if x**2 + y**2 <= 1:
This checks if the point is inside the unit circle.
x**2 + y**2 is the distance squared from the origin.
📌 Example:
python
CopyEdit
x = 0.5 → x**2 = 0.25
y = 0.5 → y**2 = 0.25
0.25 + 0.25 = 0.5 → inside the circle (since 0.5 <= 1)
inside_circle += 1
Adds 1 to the counter if the point is inside the circle.
pi_estimate = (inside_circle / num_points) * 4
Monte Carlo formula:
π≈(Points Inside CircleTotal Points)×4\pi \approx \left(\frac{\text{Points Inside Circle}}{\
text{Total Points}}\right) \times 4π≈(Total PointsPoints Inside Circle)×4
📌 Example:
python
CopyEdit
inside_circle = 7850
num_points = 10000
→ pi_estimate = (7850 / 10000) × 4 = 3.14
return pi_estimate
The function returns the estimated value of π to use later.
📏 Function: compute_errors(pi_estimate, pi_actual=3.14159)
def compute_errors(pi_estimate, pi_actual=3.14159):
A function to calculate:
o Absolute Error
o Relative Error
pi_estimate: The calculated value from estimate_pi.
pi_actual = 3.14159: This is the known value of π.
absolute_error = abs(pi_estimate - pi_actual)
abs() = absolute value (always positive).
Subtract estimated π from actual π.
📌 Example:
python
CopyEdit
pi_estimate = 3.12
→ absolute_error = abs(3.12 - 3.14159) = 0.02159
relative_error = (absolute_error / pi_actual) * 100
Converts the error to a percentage.
📌 Example:
python
CopyEdit
absolute_error = 0.02159
relative_error = (0.02159 / 3.14159) × 100 ≈ 0.6868%
return absolute_error, relative_error
Returns both errors so we can use or print them later.
📊 Sample Sizes and Output Formatting
sample_sizes = [1000, 10000, 100000, 1000000]
These are the different sizes of simulations we will run.
More points = more accurate π.
results = []
An empty list to store all the results (π estimate and errors).
print(f"{'Num Points':<15}{'Estimated π':<15}{'Absolute Error':<20}
{'Relative Error (%)'}")
Prints headers (column titles) in aligned format.
📌 Output looks like:
scss
CopyEdit
Num Points Estimated π Absolute Error Relative Error (%)
print("="*65)
Prints a line of 65 equal signs to divide the table.
📌 Output:
diff
CopyEdit
=====================================================
============
🔁 Loop through Each Sample Size
python
CopyEdit
for N in sample_sizes:
For each value (e.g., 1000, 10000, etc.), run the simulation and error checking.
pi_estimate = estimate_pi(N)
Call the first function to estimate π using N random points.
abs_error, rel_error = compute_errors(pi_estimate)
Calculate absolute and relative error for the current π estimate.
[Link]((N, pi_estimate, abs_error, rel_error))
Save all results in the list for later graphing.
print(f"{N:<15}{pi_estimate:<15.6f}{abs_error:<20.6f}{rel_error:.6f}%")
Print each row of the table with:
o Points used
o π estimate
o Absolute error
o Relative error %
📌 Example output:
matlab
CopyEdit
10000 3.141600 0.000010 0.000318%
📈 Plotting the Error Graph
num_points = [r[0] for r in results]
Creates a list of all N values (number of points).
abs_errors = [r[2] for r in results]
Creates a list of all absolute errors.
[Link](figsize=(8, 5))
Create a plot with width 8 inches and height 5 inches.
[Link](num_points, abs_errors, ...)
Draws a line plot of how error changes with more points.
📌 Each dot shows:
X = number of points
Y = absolute error
[Link]("log")
Use logarithmic scale on x-axis.
This makes it easier to see how error drops quickly as point count increases.
Labels and Display:
python
CopyEdit
[Link]("Number of Points (log scale)")
[Link]("Absolute Error")
[Link]("Error Convergence in Monte Carlo π Estimation")
[Link]()
[Link]()
[Link]()
Adds axis labels, a title, a legend, a grid, and finally shows the graph.
✅ Final Output Example
Console output:
matlab
CopyEdit
Num Points Estimated π Absolute Error Relative Error (%)
=====================================================
============
1000 3.148000 0.006410 0.204000%
10000 3.139200 0.002390 0.076000%
100000 3.141700 0.000110 0.003500%
1000000 3.141590 0.000000 0.000002%
Graph:
Shows that as the number of points increases, the error becomes smaller.
3. ✅ import random
import → This word brings an external tool/module into your program.
random → A Python module that helps make random numbers.
📌 Example in code:
Used in: [Link](-1, 1)
This gives you a random number between -1 and 1.
✅ import numpy as np
import → Brings the numpy module into your program.
numpy → A powerful module for math (especially arrays and math functions).
as np → This lets you use np instead of writing numpy every time (shortcut).
📌 Note: In your current code, np is not actually used. It can be removed safely if unused.
✅ import [Link] as plt
matplotlib → A big module for drawing graphs.
pyplot → A part of matplotlib used for drawing plots easily.
as plt → Shortcut: now we can write [Link]() instead of [Link]().
📌 Example in code:
[Link](...) draws the error line.
✅ def estimate_pi(num_points):
def → Used to define or make a function.
estimate_pi → The name of the function. It means “calculate or guess the value of
π”.
(num_points) → The input to the function. You decide how many points to use.
📌 Example:
estimate_pi(10000) means the function will generate 10,000 points.
✅ inside_circle = 0
This makes a variable named inside_circle.
Starts at 0. It will count how many random points are inside a circle.
✅ for _ in range(num_points):
for → A loop. It repeats something.
_ → A temporary name; we don’t use this value, so _ is a placeholder.
range(num_points) → Repeat the loop num_points times.
📌 Example:
If num_points = 10000, the loop runs 10,000 times.
✅ x, y = [Link](-1, 1), [Link](-1, 1)
x, y → Coordinates for a point on a graph.
[Link](-1, 1) → Gives a random number from -1 to 1.
📌 Example Output:
One run may give: x = 0.4, y = -0.8
✅ if x**2 + y**2 <= 1:
x**2 → Means “x squared” or x × x
y**2 → Means “y squared”
x**2 + y**2 → This checks how far the point is from the center (0,0).
<= 1 → If it is inside the circle (distance is 1 or less), it is a valid point.
📌 Example:
If x = 0.3, y = 0.4,
Then x² + y² = 0.09 + 0.16 = 0.25 → which is <= 1 → inside the circle
✅ inside_circle += 1
Add 1 to the count of how many points are inside the circle.
✅ pi_estimate = (inside_circle / num_points) * 4
inside_circle / num_points → Finds the percentage of points inside the circle.
× 4 → Multiply by 4 to estimate the value of π (based on area ratio: circle vs
square).
📌 Example:
If 7850 of 10,000 points are inside:
(7850 / 10000) * 4 = 3.14
✅ return pi_estimate
Gives back the estimated π value from the function.
✅ def compute_errors(pi_estimate, pi_actual=3.14159):
Makes a function to calculate errors.
pi_estimate → The value we guessed.
pi_actual = 3.14159 → The real π value (default if none is given).
✅ absolute_error = abs(pi_estimate - pi_actual)
abs(...) → Absolute value (no negative signs).
This finds the difference between estimated and real π.
📌 Example:
If pi_estimate = 3.13,
abs(3.13 - 3.14159) = 0.01159
✅ relative_error = (absolute_error / pi_actual) * 100
Finds how big the error is in percentage.
📌 Example:
If absolute_error = 0.01,
Then relative_error = (0.01 / 3.14159) * 100 ≈ 0.318%
✅ sample_sizes = [1000, 5000, 10000, 50000, 100000, 500000, 1000000]
A list of how many random points you will try.
Used to test accuracy: More points = better estimate of π
✅ results = []
Empty list where we will store the results for each sample size.
✅ for N in sample_sizes:
For each number of points (N), repeat the steps.
✅ pi_estimate = estimate_pi(N)
Call the function to estimate π with N points.
✅ abs_error, rel_error = compute_errors(pi_estimate)
Get both absolute and relative errors.
✅ [Link]((N, pi_estimate, abs_error, rel_error))
Save the data for later plotting.
✅ print(f"...{:<15}...")
This is formatted printing.
:<15 means make the space 15 characters wide and align left.
This is used to make table-style printing neat and readable.
📌 Example Print Output:
markdown
CopyEdit
Num Points Estimated π Absolute Error Relative Error (%)
=====================================================
============
1000 3.148000 0.006410 0.204000%
✅ Plotting Code with matplotlib
🔸 [Link](figsize=(10, 5))
Makes a blank graph area.
Size = 10 inches wide, 5 inches tall.
🔸 [Link](1, 2, 1)
Tells Python: “Draw 2 plots in 1 row, and this is plot 1”.
🔸 [Link](...)
Draws the line graph.
marker='o' → Draws circles on each data point.
color='b' → Blue line.
label="Absolute Error" → Label for the legend.
🔸 [Link]("log")
Makes x-axis a logarithmic scale (not linear).
Useful for big numbers like 10,000 to 1,000,000.
🔸 [Link]("Number of Points (log scale)")
Adds label to x-axis.
🔸 [Link]("Absolute Error")
Adds label to y-axis.
🔸 [Link]("Absolute Error Convergence")
Adds title to the first graph.
🔸 [Link]()
Shows the label (e.g., “Absolute Error”) on the graph.
🔸 [Link]()
Adds grid lines to help read the graph.
🔸 plt.tight_layout()
Makes sure graphs don’t overlap or look messy.
🔸 [Link]()
Displays the full graph on screen.