Monte-Carlo integration as a usage example.

Project: http://git-wip-us.apache.org/repos/asf/commons-rng/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-rng/commit/a9092d38
Tree: http://git-wip-us.apache.org/repos/asf/commons-rng/tree/a9092d38
Diff: http://git-wip-us.apache.org/repos/asf/commons-rng/diff/a9092d38

Branch: refs/heads/master
Commit: a9092d38d9d00e44cf178a8f164fa693705e87b7
Parents: 6ee7951
Author: Gilles <er...@apache.org>
Authored: Fri Aug 12 18:03:18 2016 +0200
Committer: Gilles <er...@apache.org>
Committed: Fri Aug 12 18:03:18 2016 +0200

----------------------------------------------------------------------
 .../apache/commons/rng/userguide/ComputePi.java | 91 ++++++++++++++++++++
 .../rng/userguide/MonteCarloIntegration.java    | 90 +++++++++++++++++++
 2 files changed, 181 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/commons-rng/blob/a9092d38/src/userguide/java/org/apache/commons/rng/userguide/ComputePi.java
----------------------------------------------------------------------
diff --git a/src/userguide/java/org/apache/commons/rng/userguide/ComputePi.java 
b/src/userguide/java/org/apache/commons/rng/userguide/ComputePi.java
new file mode 100644
index 0000000..5ab4c8a
--- /dev/null
+++ b/src/userguide/java/org/apache/commons/rng/userguide/ComputePi.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.rng.userguide;
+
+import org.apache.commons.rng.UniformRandomProvider;
+import org.apache.commons.rng.RandomSource;
+
+/**
+ * Computation of \( \pi \) using Monte-Carlo integration.
+ *
+ * The computation estimates the value by computing the probability that
+ * a point \( p = (x, y) \) will lie in the circle of radius \( r = 1 \)
+ * inscribed in the square of side \( r = 1 \).
+ * The probability could be computed by \[ area_{circle} / area_{square} \],
+ * where \( area_{circle} = \pi * r^2 \) and \( area_{square} = 4 r^2 \).
+ * Hence, the probability is \( \frac{\pi}{4} \).
+ *
+ * The Monte Carlo simulation will produce \( N \) points.
+ * Defining \( N_c \) as the number of point that satisfy \( x^2 + y^2 <= 1 \),
+ * we will have \( \frac{N_c}{N} \approx \frac{\pi}{4} \).
+ */
+public class ComputePi extends MonteCarloIntegration {
+    /** Domain dimension. */
+    private static final int DIMENSION = 2;
+
+    /**
+     * Simulation constructor.
+     *
+     * @param source RNG algorithm.
+     */
+    public ComputePi(RandomSource source) {
+        super(source, DIMENSION);
+    }
+
+    /**
+     * Arguments:
+     * <ul>
+     *  <li>
+     *   Error on the approximation: computation will stop when the
+     *   absolute difference between successive approximations is lower
+     *   than the given value.
+     *  </li>
+     *  <li>
+     *   {@link RandomSource Random source identifier}.
+     *  </li>
+     * </ul>
+     */
+    public static void main(String[] args) {
+        if (args.length != 2) {
+            throw new IllegalStateException("Missing arguments");
+        }
+
+        final long numPoints = Long.valueOf(args[0]);
+        final RandomSource randomSource = RandomSource.valueOf(args[1]);
+
+        final ComputePi piApp = new ComputePi(randomSource);
+        final double piMC = piApp.compute(numPoints);
+
+        System.out.println("After generating " + (DIMENSION * numPoints) +
+                           " random numbers, the error on 𝛑 is " + 
Math.abs(piMC - Math.PI));
+    }
+
+    /**
+     * @param n Number of random points to generate.
+     * @return the approximate value of pi.
+     */
+    public double compute(long numPoints) {
+        return 4 * integrate(numPoints);
+    }
+    
+    /** {@inheritDoc} */
+    @Override
+    protected boolean isInside(double ... rand) {
+        final double r2 = rand[0] * rand[0] + rand[1] * rand[1];
+        return r2 <= 1;
+    }
+}

http://git-wip-us.apache.org/repos/asf/commons-rng/blob/a9092d38/src/userguide/java/org/apache/commons/rng/userguide/MonteCarloIntegration.java
----------------------------------------------------------------------
diff --git 
a/src/userguide/java/org/apache/commons/rng/userguide/MonteCarloIntegration.java
 
b/src/userguide/java/org/apache/commons/rng/userguide/MonteCarloIntegration.java
new file mode 100644
index 0000000..e7e17a8
--- /dev/null
+++ 
b/src/userguide/java/org/apache/commons/rng/userguide/MonteCarloIntegration.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.rng.userguide;
+
+import org.apache.commons.rng.UniformRandomProvider;
+import org.apache.commons.rng.RandomSource;
+
+/**
+ * <a href="https://en.wikipedia.org/wiki/Monte_Carlo_integration";>Monte-Carlo 
method</a>
+ * for approximating an integral on a n-dimensional unit cube.
+ */
+public abstract class MonteCarloIntegration {
+    /** RNG. */
+    private final UniformRandomProvider rng;
+    /** Integration domain dimension. */
+    private final int dimension;
+
+    /**
+     * Simulation constructor.
+     *
+     * @param source RNG algorithm.
+     * @param dimension Integration domain dimension.
+     */
+    public MonteCarloIntegration(RandomSource source,
+                                 int dimension) {
+        this.rng = RandomSource.create(source);
+        this.dimension = dimension;
+    }
+
+    /**
+     * Run the Monte-Carlo integration.
+     *
+     * @param n Number of random points to generate.
+     * @return the integral.
+     */
+    public double integrate(long n) {
+        double result = 0;
+        long inside = 0;
+        long total = 0;
+        while (total < n) {
+            if (isInside(generateU01())) {
+                ++inside;
+            }
+
+            ++total;
+            result = inside / (double) total;
+        }
+
+        return result;
+    }
+    
+    /**
+     * Indicates whether the given points is inside the region whose
+     * integral is computed.
+     *
+     * @param point Point whose coordinates are random numbers uniformly
+     * distributed in the unit interval.
+     * @return {@code true} if the {@code point} is inside. 
+     */
+    protected abstract boolean isInside(double ... point);
+
+    /**
+     * @return a value from a random sequence uniformly distributed
+     * in the {@code [0, 1)} interval.
+     */
+    private double[] generateU01() {
+        final double[] rand = new double[dimension];
+
+        for (int i = 0; i < dimension; i++) {
+            rand[i] = rng.nextDouble();
+        }
+
+        return rand;
+    }
+}

Reply via email to