You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ah...@apache.org on 2021/08/08 19:43:55 UTC

[commons-rng] branch master updated (f950e2c -> 848058f)

This is an automated email from the ASF dual-hosted git repository.

aherbert pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/commons-rng.git.


    from f950e2c  Update test for the change in the ZigguratSampler
     new ac44b79  Correctly exclude duplicate files from shaded jar
     new 2a6a5b2  RNG-159: Correct convex normal sampling
     new 4c734c8  Fix size 5 sampler
     new f205e3f  Precompute size minus 1
     new 6e933d7  Add link from example table to the example distribution plots
     new bc05537  fix
     new 848058f  RNG-159: Reinstate ignored test.

The 7 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 commons-rng-examples/examples-jmh/pom.xml          |   4 +-
 .../distribution/ZigguratSamplerPerformance.java   | 185 +++++++++++++++++----
 .../rng/sampling/distribution/ZigguratSampler.java |  16 +-
 .../sampling/distribution/ZigguratSamplerTest.java |  52 +++---
 src/site/apt/userguide/rng.apt                     |   2 +-
 5 files changed, 180 insertions(+), 79 deletions(-)

[commons-rng] 07/07: RNG-159: Reinstate ignored test.

Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-rng.git

commit 848058f213148206e94918d3fccc912f44b8852c
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Sun Aug 8 20:43:52 2021 +0100

    RNG-159: Reinstate ignored test.
    
    Merge common test code
---
 .../sampling/distribution/ZigguratSamplerTest.java | 50 ++++++++--------------
 1 file changed, 19 insertions(+), 31 deletions(-)

diff --git a/commons-rng-sampling/src/test/java/org/apache/commons/rng/sampling/distribution/ZigguratSamplerTest.java b/commons-rng-sampling/src/test/java/org/apache/commons/rng/sampling/distribution/ZigguratSamplerTest.java
index 6b65d91..3a862c2 100644
--- a/commons-rng-sampling/src/test/java/org/apache/commons/rng/sampling/distribution/ZigguratSamplerTest.java
+++ b/commons-rng-sampling/src/test/java/org/apache/commons/rng/sampling/distribution/ZigguratSamplerTest.java
@@ -17,7 +17,6 @@
 package org.apache.commons.rng.sampling.distribution;
 
 import org.junit.Assert;
-import org.junit.Ignore;
 import org.junit.Test;
 import java.util.Arrays;
 import org.apache.commons.math3.distribution.NormalDistribution;
@@ -90,34 +89,7 @@ public class ZigguratSamplerTest {
         for (int i = 0; i < bins; i++) {
             quantiles[i] = dist.inverseCumulativeProbability((i + 1.0) / bins);
         }
-
-        final int samples = 10000000;
-        final long[] observed = new long[bins];
-        final RestorableUniformRandomProvider rng = RandomSource.XO_SHI_RO_128_PP.create(0xabcdefL);
-        final ZigguratSampler.NormalizedGaussian sampler = ZigguratSampler.NormalizedGaussian.of(rng);
-        for (int i = 0; i < samples; i++) {
-            final double x = sampler.sample();
-            final int index = findIndex(quantiles, x);
-            observed[index]++;
-        }
-        final double[] expected = new double[bins];
-        Arrays.fill(expected, 1.0 / bins);
-
-        final ChiSquareTest chiSquareTest = new ChiSquareTest();
-        // Pass if we cannot reject null hypothesis that the distributions are the same.
-        double chi2 = chiSquareTest.chiSquareTest(expected, observed);
-        Assert.assertFalse("Chi-square p-value = " + chi2, chi2 < 0.001);
-
-        // Test around the mean
-        for (final double range : new double[] {0.5, 0.25, 0.1, 0.05}) {
-            final int min = findIndex(quantiles, -range);
-            final int max = findIndex(quantiles, range);
-            final long[] observed2 = Arrays.copyOfRange(observed, min, max + 1);
-            final double[] expected2 = Arrays.copyOfRange(expected, min, max + 1);
-            chi2 = chiSquareTest.chiSquareTest(expected2, observed2);
-            Assert.assertFalse(String.format("(%s <= x < %s) Chi-square p-value = %s",
-                    -range, range, chi2), chi2 < 0.001);
-        }
+        testGaussianSamples(quantiles);
     }
 
     /**
@@ -133,6 +105,18 @@ public class ZigguratSamplerTest {
         for (int i = 0; i < bins; i++) {
             values[i] = minx + (maxx - minx) * (i + 1.0) / bins;
         }
+        testGaussianSamples(values);
+    }
+
+    /**
+     * Test Gaussian samples using the provided bins. Values correspond to the bin
+     * upper limit. It is assumed the values span the mean, and ideally most of the
+     * normal distribution.
+     *
+     * @param values Bin upper limits
+     */
+    private static void testGaussianSamples(double[] values) {
+        final int bins = values.length;
 
         final int samples = 10000000;
         final long[] observed = new long[bins];
@@ -154,10 +138,13 @@ public class ZigguratSamplerTest {
             x0 = x1;
         }
 
+        final double significanceLevel = 0.001;
+
         final ChiSquareTest chiSquareTest = new ChiSquareTest();
         // Pass if we cannot reject null hypothesis that the distributions are the same.
         double chi2 = chiSquareTest.chiSquareTest(expected, observed);
-        Assert.assertFalse("Chi-square p-value = " + chi2, chi2 < 0.001);
+        Assert.assertFalse(String.format("(%s <= x < %s) Chi-square p-value = %s",
+                Double.NEGATIVE_INFINITY, values[bins - 1], chi2), chi2 < 0.001);
 
         // Test around the mean
         for (final double range : new double[] {0.5, 0.25, 0.1, 0.05}) {
@@ -167,7 +154,8 @@ public class ZigguratSamplerTest {
             final double[] expected2 = Arrays.copyOfRange(expected, min, max + 1);
             chi2 = chiSquareTest.chiSquareTest(expected2, observed2);
             Assert.assertFalse(String.format("(%s <= x < %s) Chi-square p-value = %s",
-                -range, range, chi2), chi2 < 0.001);
+                min == 0 ? Double.NEGATIVE_INFINITY : values[min - 1], values[max], chi2),
+                chi2 < significanceLevel);
         }
     }
 

[commons-rng] 02/07: RNG-159: Correct convex normal sampling

Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-rng.git

commit 2a6a5b2aaf8546fc14c29dd8dfb24ce23cc988ff
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Sun Aug 8 18:32:02 2021 +0100

    RNG-159: Correct convex normal sampling
    
    Benchmark simple overhangs.
---
 .../distribution/ZigguratSamplerPerformance.java   | 176 +++++++++++++++++----
 .../rng/sampling/distribution/ZigguratSampler.java |  16 +-
 2 files changed, 153 insertions(+), 39 deletions(-)

diff --git a/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/sampling/distribution/ZigguratSamplerPerformance.java b/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/sampling/distribution/ZigguratSamplerPerformance.java
index 9e9679c..6e3fa7a 100644
--- a/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/sampling/distribution/ZigguratSamplerPerformance.java
+++ b/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/sampling/distribution/ZigguratSamplerPerformance.java
@@ -185,7 +185,8 @@ public class ZigguratSamplerPerformance {
          * The sampler type.
          */
         @Param({GAUSSIAN_128, GAUSSIAN_256, "Exponential", MOD_GAUSSIAN, "ModExponential",
-                "ModGaussian2", "ModExponential2"})
+                "ModGaussian2", "ModGaussianSimpleOverhangs",
+                "ModExponential2", "ModExponentialSimpleOverhangs"})
         private String type;
 
         /** The sampler. */
@@ -215,8 +216,12 @@ public class ZigguratSamplerPerformance {
                 sampler = ZigguratSampler.Exponential.of(rng);
             } else if ("ModGaussian2".equals(type)) {
                 sampler = new ModifiedZigguratNormalizedGaussianSampler(rng);
+            } else if ("ModGaussianSimpleOverhangs".equals(type)) {
+                sampler = new ModifiedZigguratNormalizedGaussianSamplerSimpleOverhangs(rng);
             } else if ("ModExponential2".equals(type)) {
                 sampler = new ModifiedZigguratExponentialSampler(rng);
+            } else if ("ModExponentialSimpleOverhangs".equals(type)) {
+                sampler = new ModifiedZigguratExponentialSamplerSimpleOverhangs(rng);
             } else {
                 throwIllegalStateException(type);
             }
@@ -731,24 +736,24 @@ public class ZigguratSamplerPerformance {
      */
     static class ModifiedZigguratNormalizedGaussianSampler implements ContinuousSampler {
         /** Maximum i value for early exit. */
-        private static final int I_MAX = 253;
+        protected static final int I_MAX = 253;
         /** The point where the Gaussian switches from convex to concave. */
-        private static final int J_INFLECTION = 205;
+        protected static final int J_INFLECTION = 205;
         /** Mask to create an unsigned long from a signed long. */
-        private static final long MAX_INT64 = 0x7fffffffffffffffL;
+        protected static final long MAX_INT64 = 0x7fffffffffffffffL;
         /** Used for largest deviations of f(x) from y_i. This is negated on purpose. */
-        private static final long MAX_IE = -2269182951627975918L;
+        protected static final long MAX_IE = -2269182951627975918L;
         /** Used for largest deviations of f(x) from y_i. */
-        private static final long MIN_IE = 760463704284035181L;
+        protected static final long MIN_IE = 760463704284035181L;
         /** 2^63. */
-        private static final double TWO_POW_63 = 0x1.0p63;
+        protected static final double TWO_POW_63 = 0x1.0p63;
         /** Beginning of tail. */
-        private static final double X_0 = 3.6360066255;
+        protected static final double X_0 = 3.6360066255;
         /** 1/X_0. */
-        private static final double ONE_OVER_X_0 = 1d / X_0;
+        protected static final double ONE_OVER_X_0 = 1d / X_0;
 
         /** The alias map. An integer in [0, 255] stored as a byte to save space. */
-        private static final byte[] MAP = toBytes(
+        protected static final byte[] MAP = toBytes(
             new int[] {0, 0, 239, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253,
                 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253,
                 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253,
@@ -762,7 +767,7 @@ public class ZigguratSamplerPerformance {
                 250, 250, 249, 249, 249, 248, 248, 248, 247, 247, 247, 246, 246, 245, 244, 244, 243, 242, 240, 2, 2, 3,
                 3, 0, 0, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 1, 0, 0});
         /** The alias inverse PMF. */
-        private static final long[] IPMF = {9223372036854775807L, 1100243796532604147L, 7866600928978262881L,
+        protected static final long[] IPMF = {9223372036854775807L, 1100243796532604147L, 7866600928978262881L,
             6788754710654027089L, 9022865200181691852L, 6522434035205505475L, 4723064097359993915L,
             3360495653216419673L, 2289663232373874393L, 1423968905551925104L, 708364817827802907L, 106102487305606492L,
             -408333464665790208L, -853239722779020926L, -1242095211825517037L, -1585059631105792592L,
@@ -830,7 +835,7 @@ public class ZigguratSamplerPerformance {
          * The precomputed ziggurat lengths, denoted X_i in the main text. X_i = length of
          * ziggurat layer i.
          */
-        private static final double[] X = {3.94216628254e-19, 3.72049450041e-19, 3.58270244806e-19, 3.48074762365e-19,
+        protected static final double[] X = {3.94216628254e-19, 3.72049450041e-19, 3.58270244806e-19, 3.48074762365e-19,
             3.39901771719e-19, 3.33037783603e-19, 3.27094388176e-19, 3.21835771325e-19, 3.17107585418e-19,
             3.1280307407e-19, 3.08845206558e-19, 3.05176506241e-19, 3.01752902926e-19, 2.98539834407e-19,
             2.95509674628e-19, 2.92639979885e-19, 2.899122587e-19, 2.87311087802e-19, 2.84823463271e-19,
@@ -882,7 +887,7 @@ public class ZigguratSamplerPerformance {
             5.88598735756e-20, 5.66626751161e-20, 5.43018136309e-20, 5.17381717445e-20, 4.89150317224e-20,
             4.57447418908e-20, 4.20788025686e-20, 3.76259867224e-20, 3.16285898059e-20, 0.0};
         /** Overhang table. Y_i = f(X_i). */
-        private static final double[] Y = {1.45984107966e-22, 3.00666134279e-22, 4.61297288151e-22, 6.26633500492e-22,
+        protected static final double[] Y = {1.45984107966e-22, 3.00666134279e-22, 4.61297288151e-22, 6.26633500492e-22,
             7.95945247619e-22, 9.68746550217e-22, 1.14468770024e-21, 1.32350363044e-21, 1.50498576921e-21,
             1.68896530007e-21, 1.87530253827e-21, 2.06387984237e-21, 2.25459669136e-21, 2.44736615188e-21,
             2.64211227278e-21, 2.83876811879e-21, 3.03727425675e-21, 3.23757757e-21, 3.43963031579e-21,
@@ -935,9 +940,9 @@ public class ZigguratSamplerPerformance {
             9.91869058575e-20, 1.00554562713e-19, 1.02084073773e-19, 1.03903609932e-19, 1.08420217249e-19};
 
         /** Underlying source of randomness. */
-        private final UniformRandomProvider rng;
+        protected final UniformRandomProvider rng;
         /** Exponential sampler used for the long tail. */
-        private final ContinuousSampler exponential;
+        protected final ContinuousSampler exponential;
 
         /**
          * @param rng Generator of uniformly distributed random numbers.
@@ -982,17 +987,18 @@ public class ZigguratSamplerPerformance {
                 for (;;) {
                     x = fastPrngSampleX(j, u1);
                     final long uDiff = randomInt63() - u1;
-                    if (uDiff > MIN_IE) {
+                    if (uDiff >= 0) {
+                        // Lower-left triangle
                         break;
                     }
-                    if (uDiff < MAX_IE) {
-                        continue;
-                    }
-                    // Long.MIN_VALUE is used as an unsigned int with value 2^63:
-                    // uy = Long.MIN_VALUE - (ux + uDiff)
-                    if (fastPrngSampleY(j, Long.MIN_VALUE - (u1 + uDiff)) < Math.exp(-0.5 * x * x)) {
+                    if (uDiff >= MAX_IE &&
+                        // Within maximum distance of f(x) from the triangle hypotenuse.
+                        // Long.MIN_VALUE is used as an unsigned int with value 2^63:
+                        // uy = Long.MIN_VALUE - (ux + uDiff)
+                        fastPrngSampleY(j, Long.MIN_VALUE - (u1 + uDiff)) < Math.exp(-0.5 * x * x)) {
                         break;
                     }
+                    // uDiff < MAX_IE (upper-right triangle) or rejected as above the curve
                     u1 = randomInt63();
                 }
             } else if (j == 0) {
@@ -1043,7 +1049,7 @@ public class ZigguratSamplerPerformance {
          *
          * @return the alias
          */
-        private int normSampleA() {
+        protected int normSampleA() {
             final long x = rng.nextLong();
             // j <- I(0, 256)
             final int j = ((int) x) & 0xff;
@@ -1055,7 +1061,7 @@ public class ZigguratSamplerPerformance {
          *
          * @return the long
          */
-        private long randomInt63() {
+        protected long randomInt63() {
             return rng.nextLong() & MAX_INT64;
         }
 
@@ -1067,7 +1073,7 @@ public class ZigguratSamplerPerformance {
          * @param ux ux
          * @return the sample
          */
-        private static double fastPrngSampleX(int j, long ux) {
+        protected static double fastPrngSampleX(int j, long ux) {
             return X[j] * TWO_POW_63 + (X[j - 1] - X[j]) * ux;
         }
 
@@ -1079,7 +1085,7 @@ public class ZigguratSamplerPerformance {
          * @param uy uy
          * @return the sample
          */
-        private static double fastPrngSampleY(int i, long uy) {
+        protected static double fastPrngSampleY(int i, long uy) {
             return Y[i - 1] * TWO_POW_63 + (Y[i] - Y[i - 1]) * uy;
         }
 
@@ -1099,6 +1105,77 @@ public class ZigguratSamplerPerformance {
     }
 
     /**
+     * Modified Ziggurat method for sampling from a Gaussian distribution with mean 0 and standard deviation 1.
+     *
+     * <p>Uses the algorithm from:
+     *
+     * <blockquote>
+     * McFarland, C.D. (2016)<br>
+     * "A modified ziggurat algorithm for generating exponentially and normally distributed pseudorandom numbers".<br>
+     * <i>Journal of Statistical Computation and Simulation</i> <b>86</b>, 1281-1294.
+     * </blockquote>
+     *
+     * <p>This implementation uses simple overhangs and does not exploit the precomputed
+     * distances of the concave and convex overhangs.
+     *
+     * @see <a href="https://www.tandfonline.com/doi/abs/10.1080/00949655.2015.1060234">
+     * McFarland (2016) JSCS 86, 1281-1294</a>
+     */
+    static class ModifiedZigguratNormalizedGaussianSamplerSimpleOverhangs
+        extends ModifiedZigguratNormalizedGaussianSampler {
+
+        /**
+         * @param rng Generator of uniformly distributed random numbers.
+         */
+        ModifiedZigguratNormalizedGaussianSamplerSimpleOverhangs(UniformRandomProvider rng) {
+            super(rng);
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public double sample() {
+            final long xx = rng.nextLong();
+            // Float multiplication squashes these last 8 bits, so they can be used to sample i
+            final int i = ((int) xx) & 0xff;
+
+            if (i < I_MAX) {
+                // Early exit.
+                // Branch frequency: 0.988280
+                return X[i] * xx;
+            }
+
+            // Recycle bits then advance RNG:
+            // u1 = RANDOM_INT63();
+            long u1 = xx & MAX_INT64;
+            // Another squashed, recyclable bit
+            // double sign_bit = u1 & 0x100 ? 1. : -1.
+            // Use 2 - 1 or 0 - 1
+            final double signBit = ((u1 >>> 7) & 0x2) - 1.0;
+            final int j = normSampleA();
+
+            // Simple overhangs
+            double x;
+            if (j == 0) {
+                // Tail
+                do {
+                    x = ONE_OVER_X_0 * exponential.sample();
+                } while (exponential.sample() < 0.5 * x * x);
+                x += X_0;
+            } else {
+                // Rejection sampling
+                for (;;) {
+                    x = fastPrngSampleX(j, u1);
+                    if (fastPrngSampleY(j, randomInt63()) < Math.exp(-0.5 * x * x)) {
+                        break;
+                    }
+                    u1 = randomInt63();
+                }
+            }
+            return signBit * x;
+        }
+    }
+
+    /**
      * Modified Ziggurat method for sampling from an exponential distribution.
      *
      * <p>Uses the algorithm from:
@@ -1308,7 +1385,7 @@ public class ZigguratSamplerPerformance {
             8.98023880577e-20, 9.24624714212e-20, 9.5919641345e-20, 1.08420217249e-19};
 
         /** Underlying source of randomness. */
-        private final UniformRandomProvider rng;
+        protected final UniformRandomProvider rng;
 
         /**
          * @param rng Generator of uniformly distributed random numbers.
@@ -1344,7 +1421,7 @@ public class ZigguratSamplerPerformance {
          *
          * @return the alias
          */
-        private int expSampleA() {
+        protected int expSampleA() {
             final long x = rng.nextLong();
             // j <- I(0, 256)
             final int j = ((int) x) & 0xff;
@@ -1357,7 +1434,7 @@ public class ZigguratSamplerPerformance {
          * @param j Index j (must be {@code > 0})
          * @return the sample
          */
-        private double expOverhang(int j) {
+        protected double expOverhang(int j) {
             // To sample a unit right-triangle:
             // U_x <- min(U_1, U_2)
             // distance <- | U_1 - U_2 |
@@ -1394,7 +1471,7 @@ public class ZigguratSamplerPerformance {
          *
          * @return the long
          */
-        private long randomInt63() {
+        protected long randomInt63() {
             return rng.nextLong() & MAX_INT64;
         }
 
@@ -1406,7 +1483,7 @@ public class ZigguratSamplerPerformance {
          * @param ux ux
          * @return the sample
          */
-        private static double fastPrngSampleX(int j, long ux) {
+        protected static double fastPrngSampleX(int j, long ux) {
             return X_I[j] * TWO_POW_63 + (X_I[j - 1] - X_I[j]) * ux;
         }
 
@@ -1418,7 +1495,7 @@ public class ZigguratSamplerPerformance {
          * @param uy uy
          * @return the sample
          */
-        private static double fastPrngSampleY(int i, long uy) {
+        static double fastPrngSampleY(int i, long uy) {
             return Y[i - 1] * TWO_POW_63 + (Y[i] - Y[i - 1]) * uy;
         }
 
@@ -1438,6 +1515,41 @@ public class ZigguratSamplerPerformance {
     }
 
     /**
+     * Modified Ziggurat method for sampling from an exponential distribution.
+     *
+     * <p>Uses the algorithm from:
+     *
+     * <blockquote>
+     * McFarland, C.D. (2016)<br>
+     * "A modified ziggurat algorithm for generating exponentially and normally distributed pseudorandom numbers".<br>
+     * <i>Journal of Statistical Computation and Simulation</i> <b>86</b>, 1281-1294.
+     * </blockquote>
+     *
+     * <p>This implementation uses simple overhangs and does not exploit the precomputed
+     * distances of the convex overhang.
+     *
+     * @see <a href="https://www.tandfonline.com/doi/abs/10.1080/00949655.2015.1060234">
+     * McFarland (2016) JSCS 86, 1281-1294</a>
+     */
+    static class ModifiedZigguratExponentialSamplerSimpleOverhangs
+        extends ModifiedZigguratExponentialSampler {
+
+        /**
+         * @param rng Generator of uniformly distributed random numbers.
+         */
+        ModifiedZigguratExponentialSamplerSimpleOverhangs(UniformRandomProvider rng) {
+            super(rng);
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        protected double expOverhang(int j) {
+            final double x = fastPrngSampleX(j, randomInt63());
+            return fastPrngSampleY(j, randomInt63()) <= Math.exp(-x) ? x : expOverhang(j);
+        }
+    }
+
+    /**
      * Throw an illegal state exception for the unknown parameter.
      *
      * @param parameter Parameter name
diff --git a/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/ZigguratSampler.java b/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/ZigguratSampler.java
index 82c0ec7..bdd3495 100644
--- a/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/ZigguratSampler.java
+++ b/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/ZigguratSampler.java
@@ -703,17 +703,18 @@ public abstract class ZigguratSampler implements SharedStateContinuousSampler {
                 for (;;) {
                     x = fastPrngSampleX(X, j, u1);
                     final long uDiff = randomInt63() - u1;
-                    if (uDiff > MIN_IE) {
+                    if (uDiff >= 0) {
+                        // Lower-left triangle
                         break;
                     }
-                    if (uDiff < MAX_IE) {
-                        continue;
-                    }
-                    // Long.MIN_VALUE is used as an unsigned int with value 2^63:
-                    // uy = Long.MIN_VALUE - (ux + uDiff)
-                    if (fastPrngSampleY(Y, j, Long.MIN_VALUE - (u1 + uDiff)) < Math.exp(-0.5 * x * x)) {
+                    if (uDiff >= MAX_IE &&
+                        // Within maximum distance of f(x) from the triangle hypotenuse.
+                        // Long.MIN_VALUE is used as an unsigned int with value 2^63:
+                        // uy = Long.MIN_VALUE - (ux + uDiff)
+                        fastPrngSampleY(Y, j, Long.MIN_VALUE - (u1 + uDiff)) < Math.exp(-0.5 * x * x)) {
                         break;
                     }
+                    // uDiff < MAX_IE (upper-right triangle) or rejected as above the curve
                     u1 = randomInt63();
                 }
             } else if (j == 0) {
@@ -734,6 +735,7 @@ public abstract class ZigguratSampler implements SharedStateContinuousSampler {
                     // U_y <- 1 - (U_x + distance)
                     long uDiff = randomInt63() - u1;
                     if (uDiff < 0) {
+                        // Upper-right triangle. Reflect in hypotenuse.
                         uDiff = -uDiff;
                         u1 -= uDiff;
                     }

[commons-rng] 01/07: Correctly exclude duplicate files from shaded jar

Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-rng.git

commit ac44b790244cc15278a5dc7e15cdf91a65334f9c
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Sun Aug 8 08:48:49 2021 +0100

    Correctly exclude duplicate files from shaded jar
---
 commons-rng-examples/examples-jmh/pom.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/commons-rng-examples/examples-jmh/pom.xml b/commons-rng-examples/examples-jmh/pom.xml
index 472ed84..72dc032 100644
--- a/commons-rng-examples/examples-jmh/pom.xml
+++ b/commons-rng-examples/examples-jmh/pom.xml
@@ -156,8 +156,8 @@
                         <exclude>META-INF/*.SF</exclude>
                         <exclude>META-INF/*.DSA</exclude>
                         <exclude>META-INF/*.RSA</exclude>
-                        <exclude>META-INF/LICENSE</exclude>
-                        <exclude>META-INF/THIRD-PARTY</exclude>
+                        <exclude>LICENSE</exclude>
+                        <exclude>THIRD-PARTY</exclude>
                         <exclude>META-INF/LICENSE.txt</exclude>
                         <exclude>META-INF/MANIFEST.MF</exclude>
                         <exclude>META-INF/NOTICE.txt</exclude>

[commons-rng] 05/07: Add link from example table to the example distribution plots

Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-rng.git

commit 6e933d760bce408da724cc439a832eae6ce0d82f
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Sun Aug 8 19:43:43 2021 +0100

    Add link from example table to the example distribution plots
---
 src/site/apt/userguide/rng.apt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/site/apt/userguide/rng.apt b/src/site/apt/userguide/rng.apt
index 371070e..6023481 100644
--- a/src/site/apt/userguide/rng.apt
+++ b/src/site/apt/userguide/rng.apt
@@ -982,7 +982,7 @@ double[] coordinate = sampler.sample();
 *----------*---------------+
 | Stress | Application for calling external tools that perform stringent uniformity tests (requires Java 8+). This application is used to generate results in the {{{a5._Quality}Quality}} section. |
 *----------*---------------+
-| Sampling | Application producing output from distribution samplers to create an approximate probability density function (PDF). |
+| Sampling | Application producing output from distribution samplers to create an approximate probability density function (PDF) as shown {{{./dist_density_approx.html}here}}. |
 *----------*---------------+
 | Quadrature | Application for computing numerical quadrature by Monte-Carlo (random) integration. |
 *----------*---------------+

[commons-rng] 04/07: Precompute size minus 1

Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-rng.git

commit f205e3fe054872a637f793a96bdcc481851372f8
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Sun Aug 8 19:25:16 2021 +0100

    Precompute size minus 1
---
 .../jmh/sampling/distribution/ZigguratSamplerPerformance.java     | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/sampling/distribution/ZigguratSamplerPerformance.java b/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/sampling/distribution/ZigguratSamplerPerformance.java
index 2bea436..3fc9e1c 100644
--- a/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/sampling/distribution/ZigguratSamplerPerformance.java
+++ b/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/sampling/distribution/ZigguratSamplerPerformance.java
@@ -429,8 +429,8 @@ public class ZigguratSamplerPerformance {
          * Create N samples from the sampler.
          */
         static class SizeNSampler extends SizeSampler {
-            /** The number of samples. */
-            private final int size;
+            /** The number of samples minus 1. */
+            private final int sizeM1;
 
             /**
              * @param delegate the sampler to create the samples
@@ -441,12 +441,12 @@ public class ZigguratSamplerPerformance {
                 if (size < 1) {
                     throw new IllegalArgumentException("Size must be above zero: " + size);
                 }
-                this.size = size;
+                this.sizeM1 = size - 1;
             }
 
             @Override
             public double sample() {
-                for (int i = size - 1; i != 0; i--) {
+                for (int i = sizeM1; i != 0; i--) {
                     delegate.sample();
                 }
                 return delegate.sample();

[commons-rng] 06/07: fix

Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-rng.git

commit bc0553785fdf1fdfb5b45f139adabb6552d33a3d
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Sun Aug 8 20:27:31 2021 +0100

    fix
---
 .../apache/commons/rng/sampling/distribution/ZigguratSamplerTest.java   | 2 --
 1 file changed, 2 deletions(-)

diff --git a/commons-rng-sampling/src/test/java/org/apache/commons/rng/sampling/distribution/ZigguratSamplerTest.java b/commons-rng-sampling/src/test/java/org/apache/commons/rng/sampling/distribution/ZigguratSamplerTest.java
index 2b881f2..6b65d91 100644
--- a/commons-rng-sampling/src/test/java/org/apache/commons/rng/sampling/distribution/ZigguratSamplerTest.java
+++ b/commons-rng-sampling/src/test/java/org/apache/commons/rng/sampling/distribution/ZigguratSamplerTest.java
@@ -82,7 +82,6 @@ public class ZigguratSamplerTest {
      * Test Gaussian samples using a large number of bins based on uniformly spaced quantiles.
      * Added for RNG-159.
      */
-    @Ignore("See RNG-159")
     @Test
     public void testGaussianSamplesWithQuantiles() {
         final int bins = 2000;
@@ -125,7 +124,6 @@ public class ZigguratSamplerTest {
      * Test Gaussian samples using a large number of bins uniformly spaced in a range.
      * Added for RNG-159.
      */
-    @Ignore("See RNG-159")
     @Test
     public void testGaussianSamplesWithUniformValues() {
         final int bins = 2000;

[commons-rng] 03/07: Fix size 5 sampler

Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-rng.git

commit 4c734c863ff74910089ba96a3096bbe116bd7beb
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Sun Aug 8 19:23:34 2021 +0100

    Fix size 5 sampler
---
 .../examples/jmh/sampling/distribution/ZigguratSamplerPerformance.java   | 1 +
 1 file changed, 1 insertion(+)

diff --git a/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/sampling/distribution/ZigguratSamplerPerformance.java b/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/sampling/distribution/ZigguratSamplerPerformance.java
index 6e3fa7a..2bea436 100644
--- a/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/sampling/distribution/ZigguratSamplerPerformance.java
+++ b/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/sampling/distribution/ZigguratSamplerPerformance.java
@@ -420,6 +420,7 @@ public class ZigguratSamplerPerformance {
                 delegate.sample();
                 delegate.sample();
                 delegate.sample();
+                delegate.sample();
                 return delegate.sample();
             }
         }