What the simulation shows
The quarter circle of radius 1 has area π/4; the unit square around it has area 1. A point drawn uniformly from the square lands inside the quarter circle with probability exactly π/4. Counting hits over many points estimates that probability, and four times the estimate is an estimate of π.
Two things are worth watching in the lab:
- The estimate wanders, then settles. After 100 points it is often off by 0.1 or more. After 10,000 points it is usually within about 0.03. The convergence plot uses a logarithmic x-axis so the whole run is visible.
- The error follows a known envelope. The dashed band is π ± 2 standard errors for each sample size. For most seeds the running estimate stays inside it most of the time — that is what a standard error means, not a guarantee for any single run.
Press Play to add points in batches, or change the seed to see a different but equally valid run.
How the model works
Each trial draws two independent uniform numbers x, y on [0, 1) and records a hit when x² + y² ≤ 1. The number of hits H after n trials is binomial with success probability p = π/4.
Because H is binomial, the standard error of the estimate is
With p = π/4 ≈ 0.785 the constant is 4·√(0.785 · 0.215) ≈ 1.642. The error shrinks with the square root of the sample size: to gain one more correct decimal place you need about 100 times as many points. That 1/√n rate is the same for every plain Monte Carlo estimator, which is why this toy problem is the standard first example — see how accurate a Monte Carlo estimate is.
The lab reports the standard error computed from the observed hit fraction, the same formula a practitioner would use when the true answer is unknown.
Algorithm
- Set H = 0.
- Repeat n times: draw x, y ~ U[0, 1); if x² + y² ≤ 1, increment H.
- Return π̂ = 4H/n and SE = 4√(p̂(1 − p̂)/n) with p̂ = H/n.
There is no need to take a square root per point: comparing x² + y² with 1 is equivalent to comparing the distance with 1.
Example result
With the default 10,000 points and seed 42, 7,866 points landed inside the quarter circle, giving π̂ = 3.1464. The standard error at this sample size is about 0.0164, so an error of 0.0048 is an ordinary outcome.
| Points | 10,000 |
|---|---|
| Inside circle | 7,866 |
| Estimate of π | 3.1464 |
| Error |π̂ − π| | 0.0048 |
| Standard error | 0.0164 |
Implementation
The page runs simulation.js from the package below; the Python file is a line-by-line port with the same random-number generator, so a given seed produces the same result in both languages. The excerpts show the core of each.
// Draw n points uniformly in the unit square and count those with x² + y² ≤ 1.
// The quarter circle covers π/4 of the square, so π ≈ 4 · inside / n.
export function samplePoints(k, rng, onPoint) {
let inside = 0;
for (let i = 0; i < k; i++) {
const x = rng.uniform();
const y = rng.uniform();
const hit = x * x + y * y <= 1;
if (hit) inside++;
if (onPoint) onPoint(x, y, hit);
}
return inside;
}
export function summarize(n, inside) {
const p = inside / n;
const estimate = 4 * p;
return {
points: n,
inside,
estimate,
error: Math.abs(estimate - Math.PI),
std_error: 4 * Math.sqrt((p * (1 - p)) / n),
};
}def estimate_pi(n, rng):
"""Count uniform points in the unit square that land inside the quarter circle."""
inside = 0
for _ in range(n):
x = rng.uniform()
y = rng.uniform()
if x * x + y * y <= 1:
inside += 1
p = inside / n
return 4 * p, 4 * math.sqrt(p * (1 - p) / n)Run the full model from a terminal:
node simulation.js --n 10000 --seed 42
python simulation.py --n 10000 --seed 42Download the model
| File | Contents | Size |
|---|---|---|
README.md | How to run it, parameters, example result | 1.9 KB |
model.json | Parameters with ranges and defaults, outputs, the seed-42 example | 1.2 KB |
simulation.js | The model used on this page plus a command-line runner (Node 18+) | 6.3 KB |
simulation.py | Python 3.9+ port, standard library only | 5.2 KB |
example.csv | Result table from the example run | 5.2 KB |
LICENSE.txt | MIT License | 1.0 KB |
Assumptions & limitations
- Pseudo-random, not random. Points come from a seeded pseudo-random generator (xoshiro128**). It is far better than needed here, but a flawed generator can bias Monte Carlo results; see pseudo-random numbers and seeds.
- 32-bit resolution. Each coordinate has 2³² possible values. That granularity is invisible at the sample sizes in the lab.
- A teaching method, not a way to compute π. Series and iterative algorithms produce trillions of digits; this estimator gains one digit per 100× more work.
- The error band is approximate. It uses the normal approximation to the binomial, which is poor for very small n.
References
- Metropolis, N. & Ulam, S. (1949). The Monte Carlo Method. Journal of the American Statistical Association, 44(247), 335–341. doi.org/10.1080/01621459.1949.10483310
- Owen, A. B. (2013). Monte Carlo theory, methods and examples, chapter 2. Stanford University. artowen.su.domains/mc
- Blackman, D. & Vigna, S. xoshiro / xoroshiro generators and the PRNG shootout. prng.di.unimi.it