[MATH-1068] Avoid overflow in Kendalls correlation for large input arrays.

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1546840 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Thomas Neidhart 2013-12-01 19:17:22 +00:00
parent aff82362cf
commit b12610d35e
3 changed files with 17 additions and 3 deletions

View File

@ -51,6 +51,9 @@ If the output is not quite correct, check for invisible trailing spaces!
</properties> </properties>
<body> <body>
<release version="3.3" date="TBD" description="TBD"> <release version="3.3" date="TBD" description="TBD">
<action dev="tn" type="fix" issue="MATH-1068" due-to="Gal Lalouche">
Avoid overflow when calculating Kendall's correlation for large arrays.
</action>
<action dev="erans" type="fix" issue="MATH-1067" due-to="Florian Erhard"> <action dev="erans" type="fix" issue="MATH-1067" due-to="Florian Erhard">
Avoid infinite recursion in "Beta.regularizedBeta" (package "o.a.c.m.special"); Avoid infinite recursion in "Beta.regularizedBeta" (package "o.a.c.m.special");
</action> </action>

View File

@ -160,7 +160,7 @@ public class KendallsCorrelation {
} }
final int n = xArray.length; final int n = xArray.length;
final int numPairs = n * (n - 1) / 2; final long numPairs = n * (n - 1l) / 2l;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
Pair<Double, Double>[] pairs = new Pair[n]; Pair<Double, Double>[] pairs = new Pair[n];
@ -254,7 +254,8 @@ public class KendallsCorrelation {
} }
tiedYPairs += consecutiveYTies * (consecutiveYTies - 1) / 2; tiedYPairs += consecutiveYTies * (consecutiveYTies - 1) / 2;
int concordantMinusDiscordant = numPairs - tiedXPairs - tiedYPairs + tiedXYPairs - 2 * swaps; final long concordantMinusDiscordant = numPairs - tiedXPairs - tiedYPairs + tiedXYPairs - 2 * swaps;
return concordantMinusDiscordant / FastMath.sqrt((numPairs - tiedXPairs) * (numPairs - tiedYPairs)); final double nonTiedPairsMultiplied = (numPairs - tiedXPairs) * (double) (numPairs - tiedYPairs);
return concordantMinusDiscordant / FastMath.sqrt(nonTiedPairsMultiplied);
} }
} }

View File

@ -16,6 +16,8 @@
*/ */
package org.apache.commons.math3.stat.correlation; package org.apache.commons.math3.stat.correlation;
import java.util.Arrays;
import org.apache.commons.math3.TestUtils; import org.apache.commons.math3.TestUtils;
import org.apache.commons.math3.linear.BlockRealMatrix; import org.apache.commons.math3.linear.BlockRealMatrix;
import org.apache.commons.math3.linear.RealMatrix; import org.apache.commons.math3.linear.RealMatrix;
@ -248,4 +250,12 @@ public class KendallsCorrelationTest extends PearsonsCorrelationTest {
new BlockRealMatrix(expected)); new BlockRealMatrix(expected));
} }
@Test
public void testLargeArray() {
// test integer overflow detected in MATH-1068
double[] xArray = new double[100000];
Arrays.fill(xArray, 0, 2500, 1.0);
Assert.assertEquals(1.0, correlation.correlation(xArray, xArray), 1e-6);
}
} }