Search code examples
javamontecarlopi

Monte Carlo Simulation of Pi in simple java?


I am trying to do the famous Monte Carlo simulation to estimate pi for my Java course. Here is the Simulation:

 public class Darts
    {
    //"throwing" a dart
    public static boolean [] dartThrow(int r, int d){
        boolean [] booleanArray = new boolean[d];
        for(int i = 0; i < d; i++){
        double xCoord = Math.random() * 2;
        double yCoord = Math.random() * 2;
        if((Math.pow(xCoord,2) + Math.pow(yCoord,2)) <= r){
            booleanArray[i] = true;
        }
        else{
            booleanArray [i] = false;
        }
       }
       return booleanArray;
    }

    //calculating pi from throwing results
    public static double piEstimater(boolean [] h, int d){
        int trueCounter = 0;
        for(int i = 0; i < h.length; i++){
            if(h[i] == true){
                trueCounter++;
            }
        }
        return 4 * ((double)trueCounter / d);
    }

    //printing results
    public static void printer(double [] a){
        System.out.println("     Pi Estimation Tool    ");
        System.out.println("---------------------------");
        for(int i = 0; i < a.length; i++){
            System.out.print("Trial [" + i + "]: pi = ");
            System.out.printf("%6f\n", a[i]);
        }
    }

    public static void main(String[] args){
        //variables
        Scanner in = new Scanner(System.in);
        int radius = 1;
        int darts;
        int trials;

        System.out.println("Enter the number of darts to calculate for: ");
        darts = in.nextInt();
        System.out.println("Enter the number of trials to calculate for: ");
        trials = in.nextInt();

        double [] arrayOfEstimates = new double [trials];
        int i = 0;
        for(double a : arrayOfEstimates){
           boolean [] hitCounter = dartThrow(radius, darts);
           double piEstimate = piEstimater(hitCounter, darts);
           arrayOfEstimates[i] = piEstimate;
           i++;
        }

        printer(arrayOfEstimates);
    }
}

I have created code that executes correctly, except for that the results never go above ~ .8. I would like to just assume that this is happening because the random numbers are so low, but if it happens every time something HAS to be wrong, right? Please keep in mind that this code contains about all the Java techniques I know, so I would appreciate it if you kept from including anything more "advanced." Thanks!


Solution

  • The idea of the calculation of PI using the Monte Carlo method is to sample random points in a square, and count the fraction of them that fall within the area of a circle bound by that square. If enough points are uniformly sampled, the fraction would be close to the area of the circle divided by the area of the bounding square :

    fraction = PI*r^2/(2r)^2

    and therefore

    PI = fraction * 4.

    Now, since you are sampling only positive coordinates, if we assume that the circle is centered at the origin (0,0), we only sample points within the top-right quarter of the circle and its bounding square, but the equation remains the same.

    If your circle has radius r, you should sample coordinates between 0 and r.

    Therefore you should change this :

        double xCoord = Math.random() * 2;
        double yCoord = Math.random() * 2;
    

    To this :

        double xCoord = Math.random() * r;
        double yCoord = Math.random() * r;
    

    In addition the condition should be ((Math.pow(xCoord,2) + Math.pow(yCoord,2)) <= r*r).

    Of course, you can simplify it by eliminating r and assuming the radius is 1.

    In that case the condition would be ((Math.pow(xCoord,2) + Math.pow(yCoord,2)) <= 1) and the coordinates would be sampled between 0 and 1.