Monte Carlo simulation in Scala

Wed 01 January 2014

Monte Carlo simulations can be described as algorithms that use repeated experiments and resulting probabilities of results to compute answers to problems that cannot be described in closed form. For example, they are used heavily in financial simulations to gauge downside risk exposure since market movements and returns are not deterministic. I was reacquainting myself with these simulations on Wikipedia recently and found the canonical example of using these simulations to calculate the value of Pi to be quite intuitive. Having taken the Coursera class on Functional Programming in Scala recently, I thought it would be neat to implement the experiment in the language.

The crux of the experiment is that we can use the fact that the ratio of the area of a square and a quarter circle incribed within is 4/Pi to calculate the value of Pi empirically. This is done by repeated experiments where a uniformly random set of points is generated in each turn and then the points that fall within the circle are counted. The ratio of the total number of points generated and those that fall within the circle will then be close to 4/Pi. Over multiple runs, we should then converge on the real value of 4/Pi from which we can then dervice the value of Pi. The image below conveys the idea well:

Monte Carlo - Value of Pi

Let's see an implementation of this in Scala:

First, we define a function that generates a set of random coordinates within a unit square ([0,1],[0,1]) and returns whether that point falls within the quarter circle or outside it.

def getPoint(): Int = {
  if (scala.math.sqrt(scala.math.pow(Random.nextDouble,2) + scala.math.pow(Random.nextDouble,2)) <= 1) 1 else 0
}

Next, we define a function that calls the function defined above np number of times and returns the ratio of number of times the point fell within the circle to the total number of points generated (np).

def getRatio(np: Int): Double = {
  (List.fill(np)(getPoint).sum * 1.0) / np
}

Last, we call the function defined above a large number of times, take the average of the ratios returned and multiply the result by 4 to obtain the value of Pi.

var pi = (List.fill(arguments(0))(getRatio(arguments(1))).sum / arguments(0)) * 4.0

And we're done! With 10,000 experiments with 10,000 random points generated in each run, here's what I get:

Approximation of Pi: 3.1418077199999566

Not bad! You can find the complete source for this example on Github.