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 /** Expected number of arguments. */ 37 private static final int EXPECTED_ARGUMENTS = 2; 38 /** Domain dimension. */ 39 private static final int DIMENSION = 2; 40 41 /** 42 * @param source RNG algorithm. 43 */ 44 public ComputePi(RandomSource source) { 45 super(source, DIMENSION); 46 } 47 48 /** 49 * Program entry point. 50 * 51 * @param args Arguments. 52 * The order is as follows: 53 * <ol> 54 * <li> 55 * Number of random 2-dimensional points to generate. 56 * </li> 57 * <li> 58 * {@link RandomSource Random source identifier}. 59 * </li> 60 * </ol> 61 */ 62 public static void main(String[] args) { 63 if (args.length != EXPECTED_ARGUMENTS) { 64 throw new IllegalStateException("Missing arguments"); 65 } 66 67 final long numPoints = Long.parseLong(args[0]); 68 final RandomSource randomSource = RandomSource.valueOf(args[1]); 69 70 final ComputePi piApp = new ComputePi(randomSource); 71 final double piMC = piApp.compute(numPoints); 72 73 //CHECKSTYLE: stop all 74 System.out.println("After generating " + (DIMENSION * numPoints) + 75 " random numbers, the error on 𝛑 is " + Math.abs(piMC - Math.PI)); 76 //CHECKSTYLE: resume all 77 } 78 79 /** 80 * @param numPoints Number of random points to generate. 81 * @return the approximate value of pi. 82 */ 83 public double compute(long numPoints) { 84 return 4 * integrate(numPoints); 85 } 86 87 /** {@inheritDoc} */ 88 @Override 89 protected boolean isInside(double... rand) { 90 final double r2 = rand[0] * rand[0] + rand[1] * rand[1]; 91 return r2 <= 1; 92 } 93 }