# Approximating Pi, Monte Carlo integration

I wrote some code that uses Monte Carlo Integration to Approximate pi in Java and Akka. The tl;dr explanation is you can imagine throwing darts at a square with a circle inscribed inside of it. You know the area formulas for a square and a circle so you can use the ratio of darts that landed in the circle vs those that landed in the square to reconstruct pi.

# Config.java

package populate;

/**
* Global class used to change world parameters.
* At the moment, you can only change the number of actors
* in the world.
*/
public class Config {
public static int ACTOR_COUNT = 20;
}


# Dart.java

package populate;

import akka.actor.UntypedActor;
import java.util.ArrayList;

public class Dart extends UntypedActor {

// Location of darts thrown.
private ArrayList<Point> darts;

/**
* Throws a bunch of "darts" at a square.
* @param size  The number of darts thrown.
*/
private void throwDarts(int size) {
for (int i = 0; i < size; i++) {
}
}

/**
* Use Monte Carlo integration to approximate pi.
* (see: https://www.wikiwand.com/en/Monte_Carlo_integration)
*/
private float approximatePi() {
int total = 0; // Keep track of total points thrown.
int inside = 0; // Keep track of points inside the circle.
for (Point d : darts) {
if (d.x * d.x + d.y * d.y <= 1) {
inside += 1;
}
total += 1;
}
return 4 * ((float) inside) / total;
}

@Override
if (msg != null) {
this.throwDarts(50);
getSender().tell(approximatePi(), getSelf());
} else {
getContext().stop(getSelf());
unhandled(msg);
}
}

@Override
public void preStart() {
darts = new ArrayList<Point>();
}
}


# Main.java

package populate;

public class Main {

public static void main(String[] args) {
akka.Main.main(new String[] { World.class.getName() });
}

}


# Point.java

package populate;

public class Point {
public double x;
public double y;

public Point(double x, double y) {
this.x = x;
this.y = y;
}

static public Point genRandPoint() {
return new Point(
.current()
.nextDouble(-1, 1),
.current()
.nextDouble(-1, 1)
);
}
}


# World.java

package populate;

import akka.actor.Props;
import akka.actor.UntypedActor;
import akka.actor.ActorRef;

/**
* This class is responsible for creating the "dart-throwing" actors.
* It is also responsible for averaging the results of the Dart actors.
*/
public class World extends UntypedActor {

// Sum of the Dart Actor results.
private static double sum = 0.0;
// Keep track of actors still going.
private static Integer actorsLeft = Config.ACTOR_COUNT;

/**
* Calculate the "average of the averages".
* Each Dart actor approximates pi. This function takes those results
* and averages them to get a *hopefully* better approximation of pi.
*/
if (msg != null) {
sum += (Float) msg;
actorsLeft--;
if (actorsLeft <= 0) {
System.out.println(sum / (double) Config.ACTOR_COUNT);
getContext().stop(getSelf());
}
} else {
unhandled(msg);
}
}

/**
* Initializes a number of darts and tells the Dart actors
* and tells them to start computing.
*/
@Override
public void preStart() {
for (int i = 0; i < Config.ACTOR_COUNT; i++) {
final ActorRef dart = getContext()
.actorOf(
Props.create(Dart.class),
"dart" + Integer.toString(i));
// The choice of "0" is used, but anything non-null would
// work. (If it were null, the Dart actor would die before
// it did any work.
dart.tell(0, getSelf());
}
}
}


The full repo can be found here and can be run with gradle run.

I don't feel very confident with my understanding of Akka...

• Small thing not worth an answer: Don't write a config class: you already have a config file from akka, you can use that instead and access it "for free" through akka utilities May 3, 2017 at 13:33

## Naming

The Dart class does not define darts. It holds a Collection of Points called darts. It is a Quiver. I would rename Point as Dart however, and it could extends Java's Point class.

World encompasses a lot of things. Maybe a more precise name would be better? How about DartThrowingCompetition?

## Using Streams

Streams are compact, and high-performance. If you're throwing a lot of darts, they're worth a look.

For example:

private void throwDarts(int size) {
for (int i = 0; i < size; i++) {
}
}


Can become:

private void throwDarts(int size) {
darts = IntStream.range(0, size).mapToObj(num -> Point::genRandPoint).collect(Collectors.toList());
}


The next bit may be Off-Topic, I got carried away in my thought process :)

But I would even keep darts a Stream to perform the rest of the computations. This is so concise that I compiled it in a single method in the following PiEvaluator class:

public class PiEvaluator {

/**
* Throws a bunch of "darts" at a square.
* @param size  The number of darts thrown.
* @return the approximation of PI
*/
private double evaluatePi(int nbDarts) {
long hitCount = IntStream.range(1, nbDarts)
.mapToObj(num -> TestStream.throwOneDart())
.filter(hit -> hit==true)
.count();
return 4 * (double) hitCount / nbDarts;
}

/**
* Throws one dart at random. If the dart hits the target, return true.
* @return true if the dart lands on target
*/
public boolean throwOneDart(){
Point dart = Point.genRandPoint();
return dart.x * dart.x + dart.y * dart.y <= 1;
}
}


However I'm afraid I didn't use the akka framework at all (I'm not familiar with it) so this might be off-topic. Knowing Streams are lazy, and will wait for the last meaningful call to do the work, I'm not even sure it's akka-able.