Monte Carlo simulations are often used model the probability of different outcomes. They work by generating random values, passing them into a model, and then averaging the results.

The simplest Monte Carlo simulation, and a great way to start, is by using the technique to estimate the value of Pi.

I first did this back in University, albeit using C rather than Rust.

The equation for a circle, centred around the origin is:

$$ x^2 + y^2 = R^2$$

If we put that circle inside a square, and constrain it so that the maximum R is 1, then

$$ x^2 + y^2 = 1 $$

and the area of that square will be $$4r^2$$

More generally,

$$ CircleArea / SquareArea = \Pi r^2 / 4r^2 $$

$$ CircleArea / SquareArea = \Pi / 4 $$

$$ \Pi = 4 (CircleArea / SquareArea) $$

So, to estimate Pi we can generate random values for `x`

and `y`

, between 0 and 1.

Every point will fall inside the square, but only some will fall inside the circle. If we keep a tally of how many points we generate, and work out a ratio of ones that fall inside the circle we can then get an estimate of Pi.

For a more visual description, checkout this YouTube short video (1min).

## Time for Rust

Using the `rand`

crate, we can simply generate random values, and work out if the point lies within our circle.

```
use rand::Rng;
fn main() {
let mut rng = rand::thread_rng();
let total_points = 1_000_000;
let mut points_inside_circle = 0;
for _ in 0..total_points {
let x: f64 = rng.gen();
let y: f64 = rng.gen();
if x * x + y * y <= 1.0 {
points_inside_circle += 1;
}
}
let pi_estimate = 4.0 * (points_inside_circle as f64) / (total_points as f64);
println!("Estimated Pi = {}", pi_estimate);
}
```

If you keep in mind that we're aiming at `3.14159265`

, the simulation quickly reaches two, three and four decimal points correctly.

Past that point, calculating Pi using this method becomes computationally expensive!

Number of Points | Pi Estimate |
---|---|

1M | 3.14256 |

10M | 3.14155 |

100M | 3.14156 |

1B | 3.14158 |

10B | 3.14159 |