Author: celestin
Date: Mon Jun 11 05:52:16 2012
New Revision: 1348721

URL: http://svn.apache.org/viewvc?rev=1348721&view=rev
Log:
MATH-803:
  - modified OpenMapRealVector.ebeMultiply() and ebeDivide() to handle
special cases  0d * NaN, 0d * Infinity, 0d / 0d and 0d / NaN.
  - added implementation of isNaN() and isInfinite() to
SparseRealVectorTest.SparseRealVectorTestImpl in order to allow for testing
of OpenMapRealVector.ebeMultiply() and ebeDivide() with mixed types.

Modified:
    
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/OpenMapRealVector.java
    
commons/proper/math/trunk/src/test/java/org/apache/commons/math3/linear/SparseRealVectorTest.java

Modified: 
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/OpenMapRealVector.java
URL: 
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/OpenMapRealVector.java?rev=1348721&r1=1348720&r2=1348721&view=diff
==============================================================================
--- 
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/OpenMapRealVector.java
 (original)
+++ 
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/OpenMapRealVector.java
 Mon Jun 11 05:52:16 2012
@@ -341,10 +341,14 @@ public class OpenMapRealVector extends S
     public OpenMapRealVector ebeDivide(RealVector v) {
         checkVectorDimensions(v.getDimension());
         OpenMapRealVector res = new OpenMapRealVector(this);
-        Iterator iter = entries.iterator();
-        while (iter.hasNext()) {
-            iter.advance();
-            res.setEntry(iter.key(), iter.value() / v.getEntry(iter.key()));
+        /*
+         * MATH-803: it is not sufficient to loop through non zero entries of
+         * this only. Indeed, if this[i] = 0d and v[i] = 0d, then
+         * this[i] / v[i] = NaN, and not 0d.
+         */
+        final int n = getDimension();
+        for (int i = 0; i < n; i++) {
+            res.setEntry(i, this.getEntry(i) / v.getEntry(i));
         }
         return res;
     }
@@ -359,6 +363,25 @@ public class OpenMapRealVector extends S
             iter.advance();
             res.setEntry(iter.key(), iter.value() * v.getEntry(iter.key()));
         }
+        /*
+         * MATH-803: the above loop assumes that 0d * x  = 0d for any double x,
+         * which allows to consider only the non-zero entries of this. However,
+         * this fails if this[i] == 0d and (v[i] = NaN or v[i] = Infinity).
+         *
+         * These special cases are handled below.
+         */
+        if (v.isNaN() || v.isInfinite()) {
+            final int n = getDimension();
+            for (int i = 0; i < n; i++) {
+                final double y = v.getEntry(i);
+                if (Double.isNaN(y)) {
+                    res.setEntry(i, Double.NaN);
+                } else if (Double.isInfinite(y)) {
+                    final double x = this.getEntry(i);
+                    res.setEntry(i, x * y);
+                }
+            }
+        }
         return res;
     }
 

Modified: 
commons/proper/math/trunk/src/test/java/org/apache/commons/math3/linear/SparseRealVectorTest.java
URL: 
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/linear/SparseRealVectorTest.java?rev=1348721&r1=1348720&r2=1348721&view=diff
==============================================================================
--- 
commons/proper/math/trunk/src/test/java/org/apache/commons/math3/linear/SparseRealVectorTest.java
 (original)
+++ 
commons/proper/math/trunk/src/test/java/org/apache/commons/math3/linear/SparseRealVectorTest.java
 Mon Jun 11 05:52:16 2012
@@ -237,14 +237,25 @@ public class SparseRealVectorTest extend
 
         @Override
         public boolean isNaN() {
-            throw unsupported();
+            boolean isNaN = false;
+            for (int i = 0; i < data.length; i++) {
+                isNaN |= Double.isNaN(data[i]);
+            }
+            return isNaN;
         }
 
         @Override
         public boolean isInfinite() {
-            throw unsupported();
+            boolean isInfinite = false;
+            for (int i = 0; i < data.length; i++) {
+                final double x = data[i];
+                if (Double.isNaN(x)) {
+                    return false;
+                }
+                isInfinite |= Double.isInfinite(x);
+            }
+            return isInfinite;
         }
-
     }
 
     @Override


Reply via email to