commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From er...@apache.org
Subject svn commit: r1154416 - in /commons/proper/math/trunk/src: main/java/org/apache/commons/math/util/MathUtils.java test/java/org/apache/commons/math/util/MathUtilsTest.java
Date Sat, 06 Aug 2011 00:13:49 GMT
Author: erans
Date: Sat Aug  6 00:13:49 2011
New Revision: 1154416

URL: http://svn.apache.org/viewvc?rev=1154416&view=rev
Log:
Array version of "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=1154416&r1=1154415&r2=1154416&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 Sat
Aug  6 00:13:49 2011
@@ -2608,4 +2608,64 @@ public final class MathUtils {
 
     }
 
+    /**
+     * Compute a linear combination accurately.
+     * This method computes the sum of the products
+     * <code>a<sub>i</sub> b<sub>i</sub></code> to high
accuracy.
+     * It does so by using specific multiplication and addition algorithms to
+     * preserve accuracy and reduce cancellation effects.
+     * <br/>
+     * It is based on the 2005 paper
+     * <a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.2.1547">
+     * Accurate Sum and Dot Product</a> by Takeshi Ogita, Siegfried M. Rump,
+     * and Shin'ichi Oishi published in SIAM J. Sci. Comput.
+     *
+     * @param a Factors.
+     * @param b Factors.
+     * @return <code>&Sigma;<sub>i</sub> a<sub>i</sub>
b<sub>i</sub></code>.
+     */
+    public static double linearCombination(final double[] a, final double[] b) {
+        final int len = a.length;
+        if (len != b.length) {
+            throw new DimensionMismatchException(len, b.length);
+        }
+
+        final double[] prodHigh = new double[len];
+        double prodLowSum = 0;
+
+        for (int i = 0; i < len; i++) {
+            final double ai = a[i];
+            final double ca = SPLIT_FACTOR * ai;
+            final double aHigh = ca - (ca - ai);
+            final double aLow = ai - aHigh;
+
+            final double bi = b[i];
+            final double cb = SPLIT_FACTOR * bi;
+            final double bHigh = cb - (cb - bi);
+            final double bLow = bi - bHigh;
+            prodHigh[i] = ai * bi;
+            final double prodLow = aLow * bLow - (((prodHigh[i] -
+                                                    aHigh * bHigh) -
+                                                   aLow * bHigh) -
+                                                  aHigh * bLow);
+            prodLowSum += prodLow;
+        }
+
+        final int lenMinusOne = len - 1;
+        final double[] sHigh = new double[lenMinusOne];
+
+        sHigh[0] = prodHigh[0] + prodHigh[1];
+        double sPrime = sHigh[0] - prodHigh[1];
+        double sLowSum = (prodHigh[1] - (sHigh[0] - sPrime)) + (prodHigh[0] - sPrime);
+
+        for (int i = 1; i < lenMinusOne; i++) {
+            final int prev = i - 1;
+            final int next = i + 1;
+            sHigh[i] = sHigh[prev] + prodHigh[next];
+            sPrime = sHigh[i] - prodHigh[next];
+            sLowSum += (prodHigh[next] - (sHigh[i] - sPrime)) + (sHigh[prev] - sPrime);
+        }
+
+        return sHigh[lenMinusOne - 1] + (prodLowSum + sLowSum);
+    }
 }

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=1154416&r1=1154415&r2=1154416&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
Sat Aug  6 00:13:49 2011
@@ -1841,4 +1841,25 @@ public final class MathUtilsTest {
             // Expected.
         }
     }
+
+    @Test
+    public void testLinearCombination1() {
+        final double[] a = new double[] {
+            -1321008684645961.0 / 268435456.0,
+            -5774608829631843.0 / 268435456.0,
+            -7645843051051357.0 / 8589934592.0
+        };
+        final double[] b = new double[] {
+            -5712344449280879.0 / 2097152.0,
+            -4550117129121957.0 / 2097152.0,
+            8846951984510141.0 / 131072.0
+        };
+
+        final double abSumInline = MathUtils.linearCombination(a[0], b[0],
+                                                               a[1], b[1],
+                                                               a[2], b[2]);
+        final double abSumArray = MathUtils.linearCombination(a, b);
+
+        Assert.assertEquals(abSumInline, abSumArray, 0);
+    }
 }



Mime
View raw message