Skip to the lesson
FixTheRobot Explore Robotics / Probability for Robotics / M1 Introduction to Probability in Robotics / M1-T3

Probability for Robotics · Theory · M1

M1-T3 — Simulating Randomness: Sampling and Monte Carlo

When you cannot calculate a probability, run the experiment ten thousand times and count. Then say how wrong the count can be.

  • Lesson 3 of 3
  • Beginner
  • Module 1: Introduction to Probability in Robotics
  • Theory
  • About 14 minutes to read

The probability that a robot docks, clears a doorway or loses track of its position rarely has a formula. But a robot model with random noise can be run in simulation as often as you like. This lesson shows how to turn many simulated runs into a probability, why the answer gets better only with the square root of the effort, and how a seed makes a random experiment repeatable. The same idea, a distribution represented by samples, later becomes the particle filter.

Learning objectives

After this lesson, you should be able to:

  • Explain what a pseudo-random number generator and a seed are, and why a simulation must be reproducible.
  • Estimate a probability by Monte Carlo simulation and state the estimate with its standard error.
  • Derive the standard error sqrt(p(1 − p)/n) of an estimated probability.
  • Compute how many runs are needed for a required accuracy, and recognise what more runs cannot fix.

The intuition

The previous lesson read a probability off a table of 200 real runs. Real runs are slow. If we have a model of the robot (the command, plus noise of a known size), a computer can produce a run in microseconds, and the recipe for any probability becomes:

  1. Simulate the experiment once, drawing every noisy quantity at random.
  2. Record whether the event of interest happened.
  3. Repeat nn times and report the fraction of runs in which it happened.

This is a Monte Carlo method: computing by random sampling. It works for events of any shape and for models of any complexity, which is why it is everywhere in robotics. Its one weakness is visible in the figure: the answer is itself random.

Running Monte Carlo estimates converging to the exact probabilityThree wandering curves show the estimated docking probability after ten to ten thousand simulated runs, each from a different seed. A shaded funnel around the exact value 0.944 shows the range that holds 95 percent of estimates. The funnel is wide at ten runs and narrow at ten thousand, and it narrows by a factor of ten for every hundredfold increase in the number of runs.0.840.880.920.961number of simulated runs n (logarithmic scale)estimate of P(dock)10100100010000 exact 0.944 shaded: 95% of estimates fall here (±1.96 standard errors)
Three simulations of the same docking experiment with different seeds. Each curve is the fraction of runs that docked so far. All converge to the exact probability, but slowly: the funnel narrows tenfold for a hundredfold increase in runs.

With 10 runs the three estimates disagree wildly. With 10 000 they agree to within about half a percentage point. Two facts explain the picture, and the derivation below proves both:

  • The estimate converges to the truth. This is the law of large numbers, and it is what gives the frequency reading of probability its meaning.
  • It converges slowly. The typical error shrinks like 1/n1/\sqrt{n}: four times the runs for half the error.

Random numbers from a deterministic machine

A computer has no dice. A pseudo-random number generator is an ordinary function that turns an internal number, its state, into a new state and an output between 0 and 1, in a way so scrambled that the outputs pass statistical tests for randomness. The starting state is the seed. The same seed always yields the same sequence; a different seed yields an unrelated one.

That determinism is a feature. A simulated failure that you cannot reproduce cannot be debugged. With a seed, “run 4 812 hit the wall” is a test case you can replay under a debugger, hand to a colleague, and keep as a regression test after the fix.

Fix the seed to make an experiment repeatable. Change the seed to see how much of your result was luck. A conclusion that holds for one seed only is not a conclusion.

Definitions

Sample
One value drawn from a distribution: one simulated heading error, one simulated end point.
Seed
The number that initializes a generator. Rng(42) always produces the same stream.
Indicator IiI_i
A variable that is 1 if the event happened in run ii and 0 if not. Counting successes is adding indicators.
Estimator p^\hat{p}
The rule that turns data into an estimate. Here p^=k/n\hat{p} = k/n, the fraction of the nn runs in which the event happened. Because the runs are random, p^\hat{p} is random too.
Standard error
The standard deviation of an estimator: the typical distance between the estimate and the true value over repetitions of the whole experiment.
Bias
A systematic difference between what the estimator converges to and the quantity you wanted. More runs do not reduce it.
Monte Carlo estimate of a probability
p^  =  1n∑i=1nIi  =  kn\hat{p} \;=\; \frac{1}{n}\sum_{i=1}^{n} I_i \;=\; \frac{k}{n}
kk is the number of runs in which the event happened. The hat marks a quantity estimated from data.
Standard error and 95% interval
se(p^)=p (1−p)np^±1.96 se   holds the true p in about 95% of experiments\mathrm{se}(\hat{p}) = \sqrt{\frac{p\,(1-p)}{n}} \qquad\qquad \hat{p} \pm 1.96\,\mathrm{se} \;\text{ holds the true } p \text{ in about 95\% of experiments}
In practice pp is unknown and p^\hat{p} is used in its place. For p^\hat{p} near 0 or 1, or small nn, use the Wilson interval (wilson_interval in robotprob), which never leaves [0,1][0, 1].

Derivation: why the error shrinks like 1/√n

The derivation uses two summaries of a random quantity that M4-T1: Expectation and Variance treats in full. For now, two facts are enough. The expectation E[X]\mathbb{E}[X] is the long-run average of XX. The variance Var(X)\mathrm{Var}(X) is the long-run average of the squared distance of XX from its expectation; its square root is the standard deviation, the typical size of a deviation.

  1. E[Ii]=1⋅p+0⋅(1−p)=p\mathbb{E}[I_i] = 1 \cdot p + 0 \cdot (1-p) = p

    An indicator is 1 with probability pp and 0 otherwise, so its long-run average is pp.

  2. Var(Ii)=(1−p)2 p+(0−p)2 (1−p)=p (1−p)\mathrm{Var}(I_i) = (1-p)^2\,p + (0-p)^2\,(1-p) = p\,(1-p)

    Squared distance from the mean, weighted by probability, then simplified. It is largest at p=0.5p = 0.5 (the outcome is least predictable) and zero at p=0p = 0 or 1.

  3. E[p^]=1n∑i=1nE[Ii]=p\mathbb{E}[\hat{p}] = \frac{1}{n}\sum_{i=1}^{n}\mathbb{E}[I_i] = p

    The expectation of a sum is the sum of the expectations (linearity). So the estimator is unbiased: on average it is exactly right.

  4. Var ⁣(∑i=1nIi)=∑i=1nVar(Ii)=n p (1−p)\mathrm{Var}\!\left(\sum_{i=1}^{n} I_i\right) = \sum_{i=1}^{n}\mathrm{Var}(I_i) = n\,p\,(1-p)

    For independent runs, variances add. This is where the requirement enters that each run uses fresh random numbers and does not influence another.

  5. Var(p^)=1n2 n p (1−p)=p (1−p)n\mathrm{Var}(\hat{p}) = \frac{1}{n^{2}}\, n\,p\,(1-p) = \frac{p\,(1-p)}{n}

    Multiplying a quantity by a constant cc multiplies its variance by c2c^{2}; here c=1/nc = 1/n.

  6. se(p^)=Var(p^)=p (1−p)n\mathrm{se}(\hat{p}) = \sqrt{\mathrm{Var}(\hat{p})} = \sqrt{\frac{p\,(1-p)}{n}}

    The standard error is the standard deviation of the estimator.

Steps 3 and 6 together are the law of large numbers for this case: the estimator is centred on pp and its spread goes to zero as nn grows, so it converges to pp.

How many runs?

To make the 95% interval no wider than ±h\pm h, set 1.96 se=h1.96\,\mathrm{se} = h and solve for nn:

Runs needed for a half-width h
n  =  1.962  p (1−p)h2n \;=\; \frac{1.96^{2}\; p\,(1-p)}{h^{2}}
The accuracy enters squared. Before any run is made, use a guess for pp; the cautious choice is p=0.5p = 0.5, which maximizes p(1−p)p(1-p).

Monte Carlo error falls as 1/√n: to gain one more decimal digit of accuracy you need one hundred times as many runs.

A worked example

Rover turns towards a dock 2.00 m away and drives. Its heading error is Gaussian with standard deviation 1.5°. To keep the example exact, ignore the distance noise: the sideways error at the dock is then y=2sin⁡θy = 2\sin\theta, and Rover docks when ∣y∣≤0.10|y| \le 0.10 m. What is the probability of docking?

  1. Exact answer, for comparison. ∣2sin⁡θ∣≤0.10|2\sin\theta| \le 0.10 means ∣θ∣≤arcsin⁡(0.05)=2.866∘|\theta| \le \arcsin(0.05) = 2.866^{\circ}, which is 2.866/1.5=1.9112.866/1.5 = 1.911 standard deviations. The area of a Gaussian within ±1.911 standard deviations is 0.9440. (Most real problems have no such formula; this one was chosen so that the simulation can be checked.)
  2. Simulate. Draw θ\theta from the generator, compute yy, count the run if ∣y∣≤0.10|y| \le 0.10.
  3. Report with a standard error. With 100 runs: 95 docked, p^=0.95\hat{p} = 0.95, se=0.95×0.05/100=0.022\mathrm{se} = \sqrt{0.95 \times 0.05 / 100} = 0.022. The honest statement is “0.95 ± 0.04”: compatible with a true value anywhere from 0.91 to 0.99.
  4. Increase n. With 10 000 runs: p^=0.9447\hat{p} = 0.9447, se=0.0023\mathrm{se} = 0.0023, and the actual error is 0.0007.
  5. Check the standard error itself. Repeat the whole experiment with 200 different seeds and measure the spread of the 200 estimates. For 100, 400 and 1600 runs it is 0.0234, 0.0117 and 0.0057: each fourfold increase in runs halves it, and each value matches p(1−p)/n\sqrt{p(1-p)/n}.
  6. Plan. To know the docking probability within ±0.01: n=1.962×0.944×0.056/0.012≈2030n = 1.96^{2} \times 0.944 \times 0.056 / 0.01^{2} \approx 2030 runs (the program, which keeps every digit of the exact probability, prints 2033).
import math
from robotprob import Rng, gaussian_cdf

D, sigma_theta, edge = 2.0, math.radians(1.5), 0.10
exact = 2 * gaussian_cdf(math.asin(edge / D), 0.0, sigma_theta) - 1

rng = Rng(42)                                   # the seed makes this experiment repeatable
for n in (100, 1000, 10000):
    k = 0
    for _ in range(n):
        theta = rng.gauss(0.0, sigma_theta)     # one simulated run
        if abs(D * math.sin(theta)) <= edge:
            k += 1
    p = k / n
    se = math.sqrt(p * (1 - p) / n)
    print(n, 'runs: p =', round(p, 4), ' standard error =', round(se, 4), ' actual error =', round(p - exact, 4))
print('exact probability =', round(exact, 4))
print('runs for +-0.01    =', math.ceil(1.96 ** 2 * exact * (1 - exact) / 0.01 ** 2))
100 runs: p = 0.95  standard error = 0.0218  actual error = 0.006
1000 runs: p = 0.926  standard error = 0.0083  actual error = -0.018
10000 runs: p = 0.9447  standard error = 0.0023  actual error = 0.0007
exact probability = 0.944
runs for +-0.01    = 2033
The 1000-run estimate is 2.2 standard errors low. That is unusual but not suspicious: about one experiment in twenty lands more than two standard errors from the truth. It is the reason to report an interval and not a bare number.

The second program repeats the experiment under 200 seeds to measure the spread of the estimate directly.

import math
from robotprob import Rng, std

D, sigma_theta, edge, exact = 2.0, math.radians(1.5), 0.10, 0.9440
for n in (100, 400, 1600):
    estimates = []
    for seed in range(1, 201):
        rng = Rng(seed)
        k = sum(1 for _ in range(n) if abs(D * math.sin(rng.gauss(0.0, sigma_theta))) <= edge)
        estimates.append(k / n)
    print(n, 'runs: spread of 200 estimates =', round(std(estimates, 0), 4), ' formula =', round(math.sqrt(exact * (1 - exact) / n), 4))
100 runs: spread of 200 estimates = 0.0234  formula = 0.023
400 runs: spread of 200 estimates = 0.0117  formula = 0.0115
1600 runs: spread of 200 estimates = 0.0057  formula = 0.0057

In robotics

Particle filters are Monte Carlo inside the robot

A particle filter represents the belief about the robot's pose by a set of samples, typically a few hundred to a few thousand, instead of a formula. Everything derived here applies to it: its estimates carry a 1/n1/\sqrt{n} error, more particles cost more computation for slowly improving accuracy, and its random choices should be seeded so that a failure can be replayed. Module 9 builds it; M9-T1: Monte Carlo Belief and Importance Sampling starts from this lesson.

Evaluating a robot in simulation

“The planner succeeded in 47 of 50 simulated trials” is a Monte Carlo estimate of a success probability: p^=0.94\hat{p} = 0.94 with a standard error of 0.034. It cannot distinguish a 90% planner from a 97% one. The Robot Learning course treats this in Evaluating a Policy: held-out scenarios, intervals and paired comparisons.

Rare failures need many runs

For a small probability pp, the relative error of the estimate is se/p≈1/n p\mathrm{se}/p \approx 1/\sqrt{n\,p}. To know a failure probability of 1 in 10 000 to within 10% takes about 100/p=106100/p = 10^{6} runs, and zero failures in 1000 runs only shows that the probability is probably below about 0.3%. This is why safety cases cannot rest on plain simulation counts alone.

Randomized algorithms

Sampling-based planners (PRM and RRT) and robust estimators (RANSAC) draw random samples by design. Their results vary from run to run, so they are compared over many seeds, and their random generators are seeded in tests.

Ground truth for approximations

When a filter approximates how uncertainty passes through a nonlinear function, the reference answer is a large Monte Carlo run. The tests of this course's library do exactly that: the unscented transform of module 8 is accepted because it matches 400 000 samples where plain linearization does not.

Common misconceptions

“A computer’s random numbers are random.”

They are a fixed sequence determined by the seed. Good generators are statistically indistinguishable from randomness for simulation purposes, but two simulations with the same seed are the same simulation, and two parallel workers that forget to use different seeds produce identical “independent” runs.

“More runs fix any inaccuracy.”

More runs reduce the sampling error only. If the model’s heading noise is 1.5° and the real robot’s is 2.5°, a million runs give a very precise answer to the wrong question. That is bias, and only better modelling or real data reduce it.

“A thousand runs is always plenty.”

It depends on the probability and on the accuracy needed. A thousand runs pin a probability near 0.5 to about ±3 percentage points. They say almost nothing about an event with probability 0.001, which is expected to occur once.

“Fixing the seed is cheating.”

Fixing the seed makes a result reproducible, which is necessary for debugging and testing. What would be cheating is trying seeds until one gives the result you hoped for and reporting only that one. Report results over several seeds, chosen before you look.

Key takeaways

  1. Monte Carlo estimates a probability as the fraction of simulated runs in which the event happens. It needs only a model you can sample from.
  2. A seeded generator makes a random experiment exactly repeatable. Keep the seed of every failure.
  3. The estimate is unbiased and its standard error is sqrt(p(1 − p)/n). Always report it, or a 95% interval of about ±2 standard errors.
  4. Error falls as 1/√n: half the error costs four times the runs. The runs needed for a half-width h are 1.96² p(1 − p)/h².
  5. Sampling error and model error are different. Runs reduce the first; only a better model or real data reduce the second.

References and further reading

Each source is marked free or paid. Free to read does not mean free to reuse: the course resources page lists every source with its licence.

Knowledge check

Three questions. Write an answer, then reveal the explanation. Your answers stay in your browser.

Question 1

A colleague reports that a new localization algorithm succeeded in 96 of 100 simulated runs and the old one in 92 of 100, and concludes the new one is better. Using the standard error, say whether the data support that.

Explanation

For the new algorithm se = sqrt(0.96 × 0.04 / 100) = 0.020; for the old one sqrt(0.92 × 0.08 / 100) = 0.027. The difference is 0.04 and its standard error is sqrt(0.020² + 0.027²) = 0.034, so the difference is about 1.2 standard errors: well within what chance alone produces. The data do not show that the new algorithm is better. To resolve a 4-point difference near 0.94 needs roughly 1.96² × 2 × 0.94 × 0.06 / 0.02² ≈ 1100 runs each for a ±2-point interval on the difference, or a paired comparison on the same scenarios.

Question 2

A simulation crashes the robot into a wall on roughly one run in 500, but only when run on the overnight server, and nobody can reproduce it. What one change to how the simulation handles random numbers would have made the bug straightforward to find?

Explanation

Seed every run explicitly and log the seed with the result (for example seed = run index, or a seed drawn once and printed). Then the failing run can be re-executed exactly, on any machine, as many times as needed, and the seed becomes a permanent regression test. The crash is deterministic given the seed; it only looked unreproducible because the seed came from the clock and was thrown away.

Question 3

After 100 000 simulated runs your docking probability is 0.9442 ± 0.0007, but the real robot docks only about 85% of the time over 300 trials. Is the simulation’s small standard error a reason to trust it over the real trials? What is the standard error of the real figure, and what does the disagreement mean?

Explanation

No. The standard error of 0.0007 measures only how precisely the simulation has computed the docking probability of the model. The real trials give 0.85 with se = sqrt(0.85 × 0.15 / 300) = 0.021, so the truth for the real robot is roughly 0.81 to 0.89. The gap of 0.094 is more than four of those standard errors: it is bias, not sampling noise. The model is wrong (for example the real heading noise is larger, or the distance noise that the model ignores matters), and no number of extra simulated runs will close the gap.

What’s next

Module 1 has given you the vocabulary, the rules and an experimental method. Module 2 turns to the objects those rules act on: random variables and their distributions.

Practice this lesson

Noisy Robot Motion Simulator

The same command gives a different end position every run. Simulate noisy motion, measure the spread, and predict how often the robot stops inside the docking zone.

Next lesson

M2-T1 — Discrete Random Variables and Probability Mass Functions

Define a random variable, write its probability mass function and use the Bernoulli, binomial and categorical distributions.

Nothing below is required to finish this lesson.

Other courses on this site treat neighbouring topics from their own angle: