More efficient implementation: Removed unnecessary arrays.

Added another test.


git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1154485 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Gilles Sadowski 2011-08-06 11:02:01 +00:00
parent 367fe7662e
commit a9c5cda5bd
2 changed files with 36 additions and 12 deletions

View File

@ -2651,21 +2651,22 @@ public final class MathUtils {
prodLowSum += prodLow;
}
final double prodHighCur = prodHigh[0];
double prodHighNext = prodHigh[1];
double sHighPrev = prodHighCur + prodHighNext;
double sPrime = sHighPrev - prodHighNext;
double sLowSum = (prodHighNext - (sHighPrev - sPrime)) + (prodHighCur - sPrime);
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);
prodHighNext = prodHigh[i + 1];
final double sHighCur = sHighPrev + prodHighNext;
sPrime = sHighCur - prodHighNext;
sLowSum += (prodHighNext - (sHighCur - sPrime)) + (sHighPrev - sPrime);
sHighPrev = sHighCur;
}
return sHigh[lenMinusOne - 1] + (prodLowSum + sLowSum);
return sHighPrev + (prodLowSum + sLowSum);
}
}

View File

@ -29,6 +29,7 @@ import org.apache.commons.math.exception.NotFiniteNumberException;
import org.apache.commons.math.exception.NullArgumentException;
import org.apache.commons.math.exception.util.LocalizedFormats;
import org.apache.commons.math.random.RandomDataImpl;
import org.apache.commons.math.random.Well1024a;
import org.junit.Assert;
import org.junit.Test;
@ -1862,4 +1863,26 @@ public final class MathUtilsTest {
Assert.assertEquals(abSumInline, abSumArray, 0);
}
@Test
public void testLinearCombination2() {
// we compare accurate versus naive dot product implementations
// on regular vectors (i.e. not extreme cases like in the previous test)
Well1024a random = new Well1024a(553267312521321234l);
for (int i = 0; i < 10000; ++i) {
final double ux = 1e17 * random.nextDouble();
final double uy = 1e17 * random.nextDouble();
final double uz = 1e17 * random.nextDouble();
final double vx = 1e17 * random.nextDouble();
final double vy = 1e17 * random.nextDouble();
final double vz = 1e17 * random.nextDouble();
final double sInline = MathUtils.linearCombination(ux, vx,
uy, vy,
uz, vz);
final double sArray = MathUtils.linearCombination(new double[] {ux, uy, uz},
new double[] {vx, vy, vz});
Assert.assertEquals(sInline, sArray, 0);
}
}
}