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
The following commit(s) were added to refs/heads/master by this push: new d5ea18a RNG-155: Update ZigguratNormalizedGaussianSampler to a table size of 256 d5ea18a is described below commit d5ea18a19209e53f783ef6ec79c17fc8e2a10a6f Author: Alex Herbert <aherb...@apache.org> AuthorDate: Sun Jul 11 08:24:19 2021 +0100 RNG-155: Update ZigguratNormalizedGaussianSampler to a table size of 256 Branch frequencies have been updated appropriately. --- .../distribution/ZigguratSamplerPerformance.java | 21 ++++++++++++--------- .../ZigguratNormalizedGaussianSampler.java | 16 ++++++++-------- src/changes/changes.xml | 3 +++ 3 files changed, 23 insertions(+), 17 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 45e56c1..d9e258e 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 @@ -204,9 +204,9 @@ public class ZigguratSamplerPerformance { final RandomSource randomSource = RandomSource.valueOf(randomSourceName); final UniformRandomProvider rng = randomSource.create(); if (GAUSSIAN_128.equals(type)) { - sampler = ZigguratNormalizedGaussianSampler.of(rng); + sampler = new ZigguratNormalizedGaussianSampler128(rng); } else if (GAUSSIAN_256.equals(type)) { - sampler = new ZigguratNormalizedGaussianSampler256(rng); + sampler = ZigguratNormalizedGaussianSampler.of(rng); } else if ("Exponential".equals(type)) { sampler = new ZigguratExponentialSampler(rng); } else if (MOD_GAUSSIAN.equals(type)) { @@ -274,9 +274,9 @@ public class ZigguratSamplerPerformance { final UniformRandomProvider rng = randomSource.create(); ContinuousSampler s = null; if (GAUSSIAN_128.equals(type)) { - s = ZigguratNormalizedGaussianSampler.of(rng); + s = new ZigguratNormalizedGaussianSampler128(rng); } else if (GAUSSIAN_256.equals(type)) { - s = new ZigguratNormalizedGaussianSampler256(rng); + s = ZigguratNormalizedGaussianSampler.of(rng); } else if (MOD_GAUSSIAN.equals(type)) { s = ZigguratSampler.NormalizedGaussian.of(rng); } else { @@ -455,13 +455,13 @@ public class ZigguratSamplerPerformance { * * <p>This is a copy of {@link ZigguratNormalizedGaussianSampler} using a table size of 256. */ - static class ZigguratNormalizedGaussianSampler256 implements ContinuousSampler { + static class ZigguratNormalizedGaussianSampler128 implements ContinuousSampler { /** Start of tail. */ - private static final double R = 3.6541528853610088; + private static final double R = 3.442619855899; /** Inverse of R. */ private static final double ONE_OVER_R = 1 / R; /** Index of last entry in the tables (which have a size that is a power of 2). */ - private static final int LAST = 255; + private static final int LAST = 127; /** Auxiliary table. */ private static final long[] K; /** Auxiliary table. */ @@ -480,7 +480,7 @@ public class ZigguratSamplerPerformance { static { // Filling the tables. // Rectangle area. - final double v = 0.00492867323399; + final double v = 9.91256303526217e-3; // Direction support uses the sign bit so the maximum magnitude from the long is 2^63 final double max = Math.pow(2, 63); final double oneOverMax = 1d / max; @@ -519,7 +519,7 @@ public class ZigguratSamplerPerformance { /** * @param rng Generator of uniformly distributed random numbers. */ - ZigguratNormalizedGaussianSampler256(UniformRandomProvider rng) { + ZigguratNormalizedGaussianSampler128(UniformRandomProvider rng) { this.rng = rng; } @@ -529,6 +529,7 @@ public class ZigguratSamplerPerformance { final long j = rng.nextLong(); final int i = ((int) j) & LAST; if (Math.abs(j) < K[i]) { + // This branch is called about 0.972101 times per sample. return j * W[i]; } return fix(j, i); @@ -561,6 +562,7 @@ public class ZigguratSamplerPerformance { // This branch is called about 0.027323 times per sample. final double x = hz * W[iz]; if (F[iz] + rng.nextDouble() * (F[iz - 1] - F[iz]) < pdf(x)) { + // This branch is called about 0.014961 times per sample. return x; } // Try again. @@ -712,6 +714,7 @@ public class ZigguratSamplerPerformance { return Math.exp(-x); } } + /** * Modified Ziggurat method for sampling from a Gaussian distribution with mean 0 and standard deviation 1. * diff --git a/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/ZigguratNormalizedGaussianSampler.java b/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/ZigguratNormalizedGaussianSampler.java index db3c8c6..a78fccc 100644 --- a/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/ZigguratNormalizedGaussianSampler.java +++ b/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/ZigguratNormalizedGaussianSampler.java @@ -40,11 +40,11 @@ import org.apache.commons.rng.UniformRandomProvider; public class ZigguratNormalizedGaussianSampler implements NormalizedGaussianSampler, SharedStateContinuousSampler { /** Start of tail. */ - private static final double R = 3.442619855899; + private static final double R = 3.6541528853610088; /** Inverse of R. */ private static final double ONE_OVER_R = 1 / R; /** Index of last entry in the tables (which have a size that is a power of 2). */ - private static final int LAST = 127; + private static final int LAST = 255; /** Auxiliary table. */ private static final long[] K; /** Auxiliary table. */ @@ -58,7 +58,7 @@ public class ZigguratNormalizedGaussianSampler static { // Filling the tables. // Rectangle area. - final double v = 9.91256303526217e-3; + final double v = 0.00492867323399; // Direction support uses the sign bit so the maximum magnitude from the long is 2^63 final double max = Math.pow(2, 63); final double oneOverMax = 1d / max; @@ -107,7 +107,7 @@ public class ZigguratNormalizedGaussianSampler final long j = rng.nextLong(); final int i = ((int) j) & LAST; if (Math.abs(j) < K[i]) { - // This branch is called about 0.972101 times per sample. + // This branch is called about 0.985086 times per sample. return j * W[i]; } return fix(j, i); @@ -130,7 +130,7 @@ public class ZigguratNormalizedGaussianSampler int iz) { if (iz == 0) { // Base strip. - // This branch is called about 5.7624515E-4 times per sample. + // This branch is called about 2.55224E-4 times per sample. double y; double x; do { @@ -150,14 +150,14 @@ public class ZigguratNormalizedGaussianSampler return hz > 0 ? out : -out; } // Wedge of other strips. - // This branch is called about 0.027323 times per sample. + // This branch is called about 0.0146584 times per sample. final double x = hz * W[iz]; if (F[iz] + rng.nextDouble() * (F[iz - 1] - F[iz]) < pdf(x)) { - // This branch is called about 0.014961 times per sample. + // This branch is called about 0.00797887 times per sample. return x; } // Try again. - // This branch is called about 0.012362 times per sample. + // This branch is called about 0.00667957 times per sample. return sample(); } diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 38970b7..91573f0 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -77,6 +77,9 @@ re-run tests that fail, and pass the build if they succeed within the allotted number of reruns (the test will be marked as 'flaky' in the report). "> + <action dev="aherbert" type="update" issue="155"> + "ZigguratNormalizedGaussianSampler": Update to a table size of 256. + </action> <action dev="aherbert" type="update" issue="152"> Update samplers to use ZigguratSampler.NormalizedGaussian for Gaussian deviates. </action>