HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Approximating Pi, Monte Carlo integration

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
monteintegrationapproximatingcarlo

Problem

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 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 ();
    }
}


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;

import java.util.concurrent.ThreadLocalRandom;

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(
                ThreadLocalRandom
                .current()
                .nextDouble(-1, 1),
                ThreadLocalRandom
                .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 Untyped

Solution

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++) {
        darts.add(Point.genRandPoint());
    }
}


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.

Code Snippets

private void throwDarts(int size) {
    for (int i = 0; i < size; i++) {
        darts.add(Point.genRandPoint());
    }
}
private void throwDarts(int size) {
    darts = IntStream.range(0, size).mapToObj(num -> Point::genRandPoint).collect(Collectors.toList());
}
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;
    }
}

Context

StackExchange Code Review Q#145717, answer score: 3

Revisions (0)

No revisions yet.