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.