Author: luc
Date: Mon Aug 15 20:31:49 2011
New Revision: 1157994

URL: http://svn.apache.org/viewvc?rev=1157994&view=rev
Log:
Fixed handling of Infinite and NaN coefficients in linearCombination

Modified:
    
commons/proper/math/trunk/src/main/java/org/apache/commons/math/util/MathUtils.java
    
commons/proper/math/trunk/src/test/java/org/apache/commons/math/util/MathUtilsTest.java

Modified: 
commons/proper/math/trunk/src/main/java/org/apache/commons/math/util/MathUtils.java
URL: 
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/util/MathUtils.java?rev=1157994&r1=1157993&r2=1157994&view=diff
==============================================================================
--- 
commons/proper/math/trunk/src/main/java/org/apache/commons/math/util/MathUtils.java
 (original)
+++ 
commons/proper/math/trunk/src/main/java/org/apache/commons/math/util/MathUtils.java
 Mon Aug 15 20:31:49 2011
@@ -2402,7 +2402,15 @@ public final class MathUtils {
 
         // final rounding, s12 may have suffered many cancellations, we try
         // to recover some bits from the extra words we have saved up to now
-        return s12High + (prod1Low + prod2Low + s12Low);
+        double result = s12High + (prod1Low + prod2Low + s12Low);
+
+        if (Double.isNaN(result)) {
+            // either we have split infinite numbers or some coefficients were 
NaNs,
+            // just rely on the naive implementation and let IEEE754 handle 
this
+            result = a1 * b1 + a2 * b2;
+        }
+
+        return result;
 
     }
 
@@ -2492,7 +2500,15 @@ public final class MathUtils {
 
         // final rounding, s123 may have suffered many cancellations, we try
         // to recover some bits from the extra words we have saved up to now
-        return s123High + (prod1Low + prod2Low + prod3Low + s12Low + s123Low);
+        double result = s123High + (prod1Low + prod2Low + prod3Low + s12Low + 
s123Low);
+
+        if (Double.isNaN(result)) {
+            // either we have split infinite numbers or some coefficients were 
NaNs,
+            // just rely on the naive implementation and let IEEE754 handle 
this
+            result = a1 * b1 + a2 * b2 + a3 * b3;
+        }
+
+        return result;
 
     }
 
@@ -2604,7 +2620,15 @@ public final class MathUtils {
 
         // final rounding, s1234 may have suffered many cancellations, we try
         // to recover some bits from the extra words we have saved up to now
-        return s1234High + (prod1Low + prod2Low + prod3Low + prod4Low + s12Low 
+ s123Low + s1234Low);
+        double result = s1234High + (prod1Low + prod2Low + prod3Low + prod4Low 
+ s12Low + s123Low + s1234Low);
+
+        if (Double.isNaN(result)) {
+            // either we have split infinite numbers or some coefficients were 
NaNs,
+            // just rely on the naive implementation and let IEEE754 handle 
this
+            result = a1 * b1 + a2 * b2 + a3 * b3 + a4 * b4;
+        }
+
+        return result;
 
     }
 
@@ -2667,6 +2691,19 @@ public final class MathUtils {
             sHighPrev = sHighCur;
         }
 
-        return sHighPrev + (prodLowSum + sLowSum);
+        double result = sHighPrev + (prodLowSum + sLowSum);
+
+        if (Double.isNaN(result)) {
+            // either we have split infinite numbers or some coefficients were 
NaNs,
+            // just rely on the naive implementation and let IEEE754 handle 
this
+            result = 0;
+            for (int i = 0; i < len; ++i) {
+                result += a[i] * b[i];
+            }
+        }
+
+        return result;
+
     }
+
 }

Modified: 
commons/proper/math/trunk/src/test/java/org/apache/commons/math/util/MathUtilsTest.java
URL: 
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/util/MathUtilsTest.java?rev=1157994&r1=1157993&r2=1157994&view=diff
==============================================================================
--- 
commons/proper/math/trunk/src/test/java/org/apache/commons/math/util/MathUtilsTest.java
 (original)
+++ 
commons/proper/math/trunk/src/test/java/org/apache/commons/math/util/MathUtilsTest.java
 Mon Aug 15 20:31:49 2011
@@ -1885,4 +1885,158 @@ public final class MathUtilsTest {
             Assert.assertEquals(sInline, sArray, 0);
         }
     }
+
+    @Test
+    public void testLinearCombinationInfinite() {
+        final double[][] a = new double[][] {
+            { 1, 2, 3, 4},
+            { 1, Double.POSITIVE_INFINITY, 3, 4},
+            { 1, 2, Double.POSITIVE_INFINITY, 4},
+            { 1, Double.POSITIVE_INFINITY, 3, Double.NEGATIVE_INFINITY},
+            { 1, 2, 3, 4},
+            { 1, 2, 3, 4},
+            { 1, 2, 3, 4},
+            { 1, 2, 3, 4}
+        };
+        final double[][] b = new double[][] {
+            { 1, -2, 3, 4},
+            { 1, -2, 3, 4},
+            { 1, -2, 3, 4},
+            { 1, -2, 3, 4},
+            { 1, Double.POSITIVE_INFINITY, 3, 4},
+            { 1, -2, Double.POSITIVE_INFINITY, 4},
+            { 1, Double.POSITIVE_INFINITY, 3, Double.NEGATIVE_INFINITY},
+            { Double.NaN, -2, 3, 4}
+        };
+
+        Assert.assertEquals(-3,
+                            MathUtils.linearCombination(a[0][0], b[0][0],
+                                                        a[0][1], b[0][1]),
+                            1.0e-10);
+        Assert.assertEquals(6,
+                            MathUtils.linearCombination(a[0][0], b[0][0],
+                                                        a[0][1], b[0][1],
+                                                        a[0][2], b[0][2]),
+                            1.0e-10);
+        Assert.assertEquals(22,
+                            MathUtils.linearCombination(a[0][0], b[0][0],
+                                                        a[0][1], b[0][1],
+                                                        a[0][2], b[0][2],
+                                                        a[0][3], b[0][3]),
+                            1.0e-10);
+        Assert.assertEquals(22, MathUtils.linearCombination(a[0], b[0]), 
1.0e-10);
+
+        Assert.assertEquals(Double.NEGATIVE_INFINITY,
+                            MathUtils.linearCombination(a[1][0], b[1][0],
+                                                        a[1][1], b[1][1]),
+                            1.0e-10);
+        Assert.assertEquals(Double.NEGATIVE_INFINITY,
+                            MathUtils.linearCombination(a[1][0], b[1][0],
+                                                        a[1][1], b[1][1],
+                                                        a[1][2], b[1][2]),
+                            1.0e-10);
+        Assert.assertEquals(Double.NEGATIVE_INFINITY,
+                            MathUtils.linearCombination(a[1][0], b[1][0],
+                                                        a[1][1], b[1][1],
+                                                        a[1][2], b[1][2],
+                                                        a[1][3], b[1][3]),
+                            1.0e-10);
+        Assert.assertEquals(Double.NEGATIVE_INFINITY, 
MathUtils.linearCombination(a[1], b[1]), 1.0e-10);
+
+        Assert.assertEquals(-3,
+                            MathUtils.linearCombination(a[2][0], b[2][0],
+                                                        a[2][1], b[2][1]),
+                            1.0e-10);
+        Assert.assertEquals(Double.POSITIVE_INFINITY,
+                            MathUtils.linearCombination(a[2][0], b[2][0],
+                                                        a[2][1], b[2][1],
+                                                        a[2][2], b[2][2]),
+                            1.0e-10);
+        Assert.assertEquals(Double.POSITIVE_INFINITY,
+                            MathUtils.linearCombination(a[2][0], b[2][0],
+                                                        a[2][1], b[2][1],
+                                                        a[2][2], b[2][2],
+                                                        a[2][3], b[2][3]),
+                            1.0e-10);
+        Assert.assertEquals(Double.POSITIVE_INFINITY, 
MathUtils.linearCombination(a[2], b[2]), 1.0e-10);
+
+        Assert.assertEquals(Double.NEGATIVE_INFINITY,
+                            MathUtils.linearCombination(a[3][0], b[3][0],
+                                                        a[3][1], b[3][1]),
+                            1.0e-10);
+        Assert.assertEquals(Double.NEGATIVE_INFINITY,
+                            MathUtils.linearCombination(a[3][0], b[3][0],
+                                                        a[3][1], b[3][1],
+                                                        a[3][2], b[3][2]),
+                            1.0e-10);
+        Assert.assertEquals(Double.NEGATIVE_INFINITY,
+                            MathUtils.linearCombination(a[3][0], b[3][0],
+                                                        a[3][1], b[3][1],
+                                                        a[3][2], b[3][2],
+                                                        a[3][3], b[3][3]),
+                            1.0e-10);
+        Assert.assertEquals(Double.NEGATIVE_INFINITY, 
MathUtils.linearCombination(a[3], b[3]), 1.0e-10);
+
+        Assert.assertEquals(Double.POSITIVE_INFINITY,
+                            MathUtils.linearCombination(a[4][0], b[4][0],
+                                                        a[4][1], b[4][1]),
+                            1.0e-10);
+        Assert.assertEquals(Double.POSITIVE_INFINITY,
+                            MathUtils.linearCombination(a[4][0], b[4][0],
+                                                        a[4][1], b[4][1],
+                                                        a[4][2], b[4][2]),
+                            1.0e-10);
+        Assert.assertEquals(Double.POSITIVE_INFINITY,
+                            MathUtils.linearCombination(a[4][0], b[4][0],
+                                                        a[4][1], b[4][1],
+                                                        a[4][2], b[4][2],
+                                                        a[4][3], b[4][3]),
+                            1.0e-10);
+        Assert.assertEquals(Double.POSITIVE_INFINITY, 
MathUtils.linearCombination(a[4], b[4]), 1.0e-10);
+
+        Assert.assertEquals(-3,
+                            MathUtils.linearCombination(a[5][0], b[5][0],
+                                                        a[5][1], b[5][1]),
+                            1.0e-10);
+        Assert.assertEquals(Double.POSITIVE_INFINITY,
+                            MathUtils.linearCombination(a[5][0], b[5][0],
+                                                        a[5][1], b[5][1],
+                                                        a[5][2], b[5][2]),
+                            1.0e-10);
+        Assert.assertEquals(Double.POSITIVE_INFINITY,
+                            MathUtils.linearCombination(a[5][0], b[5][0],
+                                                        a[5][1], b[5][1],
+                                                        a[5][2], b[5][2],
+                                                        a[5][3], b[5][3]),
+                            1.0e-10);
+        Assert.assertEquals(Double.POSITIVE_INFINITY, 
MathUtils.linearCombination(a[5], b[5]), 1.0e-10);
+
+        Assert.assertEquals(Double.POSITIVE_INFINITY,
+                            MathUtils.linearCombination(a[6][0], b[6][0],
+                                                        a[6][1], b[6][1]),
+                            1.0e-10);
+        Assert.assertEquals(Double.POSITIVE_INFINITY,
+                            MathUtils.linearCombination(a[6][0], b[6][0],
+                                                        a[6][1], b[6][1],
+                                                        a[6][2], b[6][2]),
+                            1.0e-10);
+        Assert.assertTrue(Double.isNaN(MathUtils.linearCombination(a[6][0], 
b[6][0],
+                                                                   a[6][1], 
b[6][1],
+                                                                   a[6][2], 
b[6][2],
+                                                                   a[6][3], 
b[6][3])));
+        Assert.assertTrue(Double.isNaN(MathUtils.linearCombination(a[6], 
b[6])));
+
+        Assert.assertTrue(Double.isNaN(MathUtils.linearCombination(a[7][0], 
b[7][0],
+                                                        a[7][1], b[7][1])));
+        Assert.assertTrue(Double.isNaN(MathUtils.linearCombination(a[7][0], 
b[7][0],
+                                                        a[7][1], b[7][1],
+                                                        a[7][2], b[7][2])));
+        Assert.assertTrue(Double.isNaN(MathUtils.linearCombination(a[7][0], 
b[7][0],
+                                                                   a[7][1], 
b[7][1],
+                                                                   a[7][2], 
b[7][2],
+                                                                   a[7][3], 
b[7][3])));
+        Assert.assertTrue(Double.isNaN(MathUtils.linearCombination(a[7], 
b[7])));
+
+    }
+
 }


Reply via email to