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);
+    }
 }

Reply via email to