View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.rng.examples.quadrature;
18  
19  import org.apache.commons.rng.simple.RandomSource;
20  
21  /**
22   * Computation of \( \pi \) using Monte-Carlo integration.
23   *
24   * The computation estimates the value by computing the probability that
25   * a point \( p = (x, y) \) will lie in the circle of radius \( r = 1 \)
26   * inscribed in the square of side \( r = 1 \).
27   * The probability could be computed by \[ area_{circle} / area_{square} \],
28   * where \( area_{circle} = \pi * r^2 \) and \( area_{square} = 4 r^2 \).
29   * Hence, the probability is \( \frac{\pi}{4} \).
30   *
31   * The Monte Carlo simulation will produce \( N \) points.
32   * Defining \( N_c \) as the number of point that satisfy \( x^2 + y^2 \le 1 \),
33   * we will have \( \frac{N_c}{N} \approx \frac{\pi}{4} \).
34   */
35  public class ComputePi extends MonteCarloIntegration {
36      /** Domain dimension. */
37      private static final int DIMENSION = 2;
38  
39      /**
40       * @param source RNG algorithm.
41       */
42      public ComputePi(RandomSource source) {
43          super(source, DIMENSION);
44      }
45  
46      /**
47       * Program entry point.
48       *
49       * @param args Arguments.
50       * The order is as follows:
51       * <ol>
52       *  <li>
53       *   Number of random 2-dimensional points to generate.
54       *  </li>
55       *  <li>
56       *   {@link RandomSource Random source identifier}.
57       *  </li>
58       * </ol>
59       */
60      public static void main(String[] args) {
61          if (args.length != 2) {
62              throw new IllegalStateException("Missing arguments");
63          }
64  
65          final long numPoints = Long.parseLong(args[0]);
66          final RandomSource randomSource = RandomSource.valueOf(args[1]);
67  
68          final ComputePi piApp = new ComputePi(randomSource);
69          final double piMC = piApp.compute(numPoints);
70  
71          //CHECKSTYLE: stop all
72          System.out.println("After generating " + (DIMENSION * numPoints) +
73                             " random numbers, the error on 𝛑 is " + Math.abs(piMC - Math.PI));
74          //CHECKSTYLE: resume all
75      }
76  
77      /**
78       * @param numPoints Number of random points to generate.
79       * @return the approximate value of pi.
80       */
81      public double compute(long numPoints) {
82          return 4 * integrate(numPoints);
83      }
84  
85      /** {@inheritDoc} */
86      @Override
87      protected boolean isInside(double ... rand) {
88          final double r2 = rand[0] * rand[0] + rand[1] * rand[1];
89          return r2 <= 1;
90      }
91  }