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 22add40d908f3ae8f71d96e472b726c2e4e6ccf9 Author: Alex Herbert <aherb...@apache.org> AuthorDate: Thu Aug 1 00:40:12 2019 +0100 Add edge case for sampler pair rejection. --- .../MarsagliaNormalisedGaussianSamplerTest.java | 44 ++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/commons-rng-sampling/src/test/java/org/apache/commons/rng/sampling/distribution/MarsagliaNormalisedGaussianSamplerTest.java b/commons-rng-sampling/src/test/java/org/apache/commons/rng/sampling/distribution/MarsagliaNormalisedGaussianSamplerTest.java index 0d1ab3f..287cf41 100644 --- a/commons-rng-sampling/src/test/java/org/apache/commons/rng/sampling/distribution/MarsagliaNormalisedGaussianSamplerTest.java +++ b/commons-rng-sampling/src/test/java/org/apache/commons/rng/sampling/distribution/MarsagliaNormalisedGaussianSamplerTest.java @@ -17,8 +17,10 @@ package org.apache.commons.rng.sampling.distribution; import org.apache.commons.rng.UniformRandomProvider; +import org.apache.commons.rng.core.source32.IntProvider; import org.apache.commons.rng.sampling.RandomAssert; import org.apache.commons.rng.simple.RandomSource; +import org.junit.Assert; import org.junit.Test; /** @@ -37,4 +39,46 @@ public class MarsagliaNormalisedGaussianSamplerTest { final SharedStateContinuousSampler sampler2 = sampler1.withUniformRandomProvider(rng2); RandomAssert.assertProduceSameSequence(sampler1, sampler2); } + + /** + * Test the edge case where the pair of samples are rejected. This occurs when the distance + * of the pair is outside the unit circle or lies on the origin. + */ + @Test + public void testSamplePairIsRejected() { + final double value = 0.25; + final UniformRandomProvider rng = new IntProvider() { + private int i; + + @Override + public int next() { + // Not used + return 0; + } + + @Override + public double nextDouble() { + i++; + if (i <= 2) { + // First two samples are one. + // This is outside the unit circle. + return 1.0; + } + if (i <= 4) { + // Next two samples are 0.5. + // The pair lies at the origin. + return 0.5; + } + return value; + } + }; + + final MarsagliaNormalizedGaussianSampler sampler = new MarsagliaNormalizedGaussianSampler(rng); + + // Compute as per the algorithm + final double x = 2 * value - 1; + final double r2 = x * x + x * x; + final double expected = x * Math.sqrt(-2 * Math.log(r2) / r2); + Assert.assertEquals(expected, sampler.sample(), 0); + } }