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 dd0df6178ea9cbc6f8ca4cdf60513fce52ecf991
Author: Alex Herbert <aherb...@apache.org>
AuthorDate: Fri Jul 9 16:11:44 2021 +0100

    Update to avoid infinite samples from the tail
---
 .../distribution/ZigguratSamplerPerformance.java   | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 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 dbaf9d0..7a2f8af 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
@@ -236,6 +236,11 @@ public class ZigguratSamplerPerformance {
         private static final double[] W;
         /** Auxiliary table. */
         private static final double[] F;
+        /**
+         * The multiplier to convert the least significant 53-bits of a {@code 
long} to a {@code double}.
+         * Taken from org.apache.commons.rng.core.util.NumberFactory.
+         */
+        private static final double DOUBLE_MULTIPLIER = 0x1.0p-53d;
 
         /** Underlying source of randomness. */
         private final UniformRandomProvider rng;
@@ -312,8 +317,9 @@ public class ZigguratSamplerPerformance {
                 double y;
                 double x;
                 do {
-                    y = -Math.log(rng.nextDouble());
-                    x = -Math.log(rng.nextDouble()) * ONE_OVER_R;
+                    // Avoid infinity by creating a non-zero double.
+                    y = -Math.log(makeNonZeroDouble(rng.nextLong()));
+                    x = -Math.log(makeNonZeroDouble(rng.nextLong())) * 
ONE_OVER_R;
                 } while (y + y < x * x);
 
                 final double out = R + x;
@@ -331,6 +337,18 @@ public class ZigguratSamplerPerformance {
         }
 
         /**
+         * Creates a {@code double} in the interval {@code (0, 1]} from a 
{@code long} value.
+         *
+         * @param v Number.
+         * @return a {@code double} value in the interval {@code (0, 1]}.
+         */
+        private static double makeNonZeroDouble(long v) {
+            // This matches the method in 
o.a.c.rng.core.util.NumberFactory.makeDouble(long)
+            // but shifts the range from [0, 1) to (0, 1].
+            return ((v >>> 11) + 1L) * DOUBLE_MULTIPLIER;
+        }
+
+        /**
          * Compute the Gaussian probability density function {@code f(x) = 
e^-0.5x^2}.
          *
          * @param x Argument.

Reply via email to