Monte Carlo Pi Simulation in plain 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 created code that runs correctly, except the results never exceed ~ .8. I would just like to assume that this is because the random numbers are so low, but if it happens every time something must be wrong, right? Please keep in mind that this code contains all the Java methods I know, so I would appreciate it if you didn't include anything more "advanced". Thank!
source to share
The idea behind calculating PI using the Monte Carlo method is to sample random points in a square and count the proportion that falls within the area of the circle connected by that square. If enough points are evenly sampled, the fraction will 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 only selecting positive coordinates, if we assume that the circle is centered at the origin (0,0)
, we only select the points in the upper right quarter of the circle and its bounding square, but the equation remains the same.
If your circle has radius r, you must choose coordinates between 0 and r.
Therefore, you have to change this:
double xCoord = Math.random() * 2;
double yCoord = Math.random() * 2;
For this:
double xCoord = Math.random() * r;
double yCoord = Math.random() * r;
Also, the condition must be ((Math.pow(xCoord,2) + Math.pow(yCoord,2)) <= r*r)
.
You can of course simplify it by eliminating r and assuming the radius is 1.
In this case, the condition will be met ((Math.pow(xCoord,2) + Math.pow(yCoord,2)) <= 1)
, and the coordinates will be selected between 0 and 1.
source to share