[JAVA] Accuracy of pi calculation by Monte Carlo method

Introduction

The Monte Carlo method is a method of repeating trials using random numbers. It is well known that there is a way to find the pi in this way ... but I suddenly thought. ** Is it really more accurate than the straightforward method? ** ... So let's actually experiment.

How to find by Monte Carlo method

Imagine a 1 * 1 square, and put a quarter of a circle with a radius of 1 in it. Use ** random numbers to get a lot of ** points in this square. Let * N * be the number of points placed. If * N * is large enough, you can score evenly. Of these points, if the points contained in the circle are counted as * A *, the area of the square is 1 and the area of the 1/4 circle is * π / 4 *.

Monte.java


import java.util.Random;

public class Monte {
    public static void main(String[] args) {
        for (int i = 0; i < 3 ; i++) {
            monte();
        }
    }
    public static void monte() {
        Random r = new Random(System.currentTimeMillis());
        int cnt = 0;
        final int n = 400000000; //Number of trials
        double x,y;
        for (int i = 0; i < n; i++) {
            x = r.nextDouble();
            y = r.nextDouble();
            //Is this point in the circle?(Is the distance from the origin to the point 1 or less?)
            if(x * x + y * y <= 1){
               cnt++; 
            }
        }
        System.out.println((double)cnt / (double)n * 4D);
    }
}

How to find a rival horse

Imagine a 1 * 1 square, and put a quarter of a circle with a radius of 1 in it. Make a lot of ** evenly spaced ** points from end to end in this square. Let * N * be the number of points placed. If * N * is large enough, you can score evenly. (Around one side, points with only the square root of * N * will appear.) Of these points, if the points contained in the circle are counted as * A *, the area of the square is 1 and the area of the 1/4 circle is * π / 4 *.

Grid.java


public class Grid {
    public static void main(String[] args) {
        int cnt = 0;
        final int ns = 20000; //Square root of number of trials
        for (double x = 0; x < ns; x++) {
            for (double y = 0; y < ns; y++) {
                if(x / (double)(ns - 1) * x / (double)(ns - 1) +
                    y / (double)(ns - 1) * y / (double)(ns - 1) <= 1D){
                    cnt++; 
                }
            }
        }
        System.out.println((double)cnt / ((double)ns * (double)ns) * 4D);
    }
}

result

Results of the Monte Carlo method

100 10000 1000000 100000000 400000000(reference)
First time 3.16 3.1396 3.139172 3.14166432 3.14149576
Second time 3.2 3.1472 3.1426 3.14173924 3.1414574
third time 3.08 3.1436 3.142624 3.14167628 3.1415464
result(Median) 3.16 3.1436 3.1426 3.14167628 3.14149576

Overall result

100(10^2) 10000(100^2) 1000000(1000^2) 100000000(10000^2) 400000000(reference)(20000^2)
Monte Carlo method 3.16 3.1436 3.1426 3.14167628 3.14149576
Competitive horse(grid) 2.92 3.1156 3.139156 3.141361 3.14147708
Ideal value 3.1415926535 3.1415926535 3.1415926535 3.1415926535 3.1415926535
Error rate(Monte)[%] 0.568 0.064 0.032 0.003 -0.003
Error rate(grid)[%] -7.054 -0.827 -0.078 -0.007 -0.004

Summary

(In my environment, the computer became heavy from around 100000000.) As long as the number of trials is small, it can be said that the Monte Carlo method is more accurate. However, the increase in accuracy has begun to decline from around 100000000, and can this be said to be a mountain of seki with pseudo-random numbers?

in conclusion

** Sometimes a random attack is better than a total attack! ** ** It depends on the accuracy of the pseudo-random numbers used, but using random numbers is also fun. However, there are limits, so if you want to find it completely accurately, there are other methods.

Recommended Posts

Accuracy of pi calculation by Monte Carlo method
Finding pi with the Monte Carlo method? (Ruby)
Numerical calculation of variable coefficient second-order linear homogeneous differential equation by Euler method
[Java] Dynamic method call by reflection of enum (enum)