RNG-55: Check for zero norm.

Project: http://git-wip-us.apache.org/repos/asf/commons-rng/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-rng/commit/8539ccbe
Tree: http://git-wip-us.apache.org/repos/asf/commons-rng/tree/8539ccbe
Diff: http://git-wip-us.apache.org/repos/asf/commons-rng/diff/8539ccbe

Branch: refs/heads/master
Commit: 8539ccbeda3d390390cfc57185cfc6d2f6d0ebee
Parents: c54506b
Author: Gilles <er...@apache.org>
Authored: Thu Aug 16 14:44:56 2018 +0200
Committer: Gilles <er...@apache.org>
Committed: Thu Aug 16 14:44:56 2018 +0200

----------------------------------------------------------------------
 .../commons/rng/sampling/UnitSphereSampler.java   |  9 +++++++++
 .../rng/sampling/UnitSphereSamplerTest.java       | 18 ++++++++++++++++++
 src/changes/changes.xml                           |  3 +++
 3 files changed, 30 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/commons-rng/blob/8539ccbe/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/UnitSphereSampler.java
----------------------------------------------------------------------
diff --git 
a/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/UnitSphereSampler.java
 
b/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/UnitSphereSampler.java
index b289025..46dd474 100644
--- 
a/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/UnitSphereSampler.java
+++ 
b/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/UnitSphereSampler.java
@@ -59,6 +59,15 @@ public class UnitSphereSampler {
             normSq += comp * comp;
         }
 
+        if (normSq == 0) {
+            // Zero-norm vector is discarded.
+            // Using recursion as it is highly unlikely to generate more
+            // than a few such vectors. It also protects against infinite
+            // loop (in case a buggy generator is used), by eventually
+            // raising a "StackOverflowError".
+            return nextVector();
+        }
+
         final double f = 1 / Math.sqrt(normSq);
         for (int i = 0; i < dimension; i++) {
             v[i] *= f;

http://git-wip-us.apache.org/repos/asf/commons-rng/blob/8539ccbe/commons-rng-sampling/src/test/java/org/apache/commons/rng/sampling/UnitSphereSamplerTest.java
----------------------------------------------------------------------
diff --git 
a/commons-rng-sampling/src/test/java/org/apache/commons/rng/sampling/UnitSphereSamplerTest.java
 
b/commons-rng-sampling/src/test/java/org/apache/commons/rng/sampling/UnitSphereSamplerTest.java
index a66e4cd..2b7ff47 100644
--- 
a/commons-rng-sampling/src/test/java/org/apache/commons/rng/sampling/UnitSphereSamplerTest.java
+++ 
b/commons-rng-sampling/src/test/java/org/apache/commons/rng/sampling/UnitSphereSamplerTest.java
@@ -56,6 +56,24 @@ public class UnitSphereSamplerTest {
         }
     }
 
+    /** Cf. RNG-55. */
+    @Test(expected = StackOverflowError.class)
+    public void testBadProvider1() {
+        final UniformRandomProvider bad = new UniformRandomProvider() {
+                public long nextLong(long n) { return 0; }
+                public long nextLong() { return 0; }
+                public int nextInt(int n) { return 0; }
+                public int nextInt() { return 0; }
+                public float nextFloat() { return 0; }
+                public double nextDouble() { return 0;}
+                public void nextBytes(byte[] bytes, int start, int len) {}
+                public void nextBytes(byte[] bytes) {}
+                public boolean nextBoolean() { return false; }
+            };
+
+        new UnitSphereSampler(1, bad).nextVector();
+    }
+
     /**
      * @return the length (L2-norm) of given vector.
      */

http://git-wip-us.apache.org/repos/asf/commons-rng/blob/8539ccbe/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index f36c4e3..2bd1a44 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -67,6 +67,9 @@ Additional code is provided in the following module:
 It is however not part of the official API and no compatibility
 should be expected in subsequent releases.
 ">
+      <action dev="erans" type="fix" issue="RNG-55" due-to="Alex D. Herbert">
+        "UnitSphereSampler": Prevent returning NaN components.
+      </action>
     </release>
 
     <release version="1.1" date="2018-08-14" description="

Reply via email to