Fixed an overflow error in MathUtils.distance that was causing KMeansPlusPlusClusterer to fail with a NullPointerException when

component distances between points exceeded Integer.MAXVALUE.
JIRA: MATH-305
Reported by Erik van Ingen

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@885027 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Phil Steitz 2009-11-27 21:45:38 +00:00
parent 9e6576e7cd
commit ef9b639afc
3 changed files with 29 additions and 2 deletions

View File

@ -1621,9 +1621,9 @@ public final class MathUtils {
* @return the L<sub>2</sub> distance between the two points
*/
public static double distance(int[] p1, int[] p2) {
int sum = 0;
double sum = 0;
for (int i = 0; i < p1.length; i++) {
final int dp = p1[i] - p2[i];
final double dp = p1[i] - p2[i];
sum += dp * dp;
}
return Math.sqrt(sum);

View File

@ -39,6 +39,11 @@ The <action> type attribute can be add,update,fix,remove.
</properties>
<body>
<release version="2.1" date="TBD" description="TBD">
<action dev="psteitz" type="fix" issue="MATH-305" due-to="Erik van Ingen">
Fixed an overflow error in MathUtils.distance that was causing KMeansPlusPlusClusterer
to fail with a NullPointerException when component distances between points
exceeded Integer.MAXVALUE.
</action>
<action dev="psteitz" type="update" issue="MATH-315" due-to="Mikkel Meyer Andersen">
Added generationsEvolved property to GeneticAlgorithm to track the number of generations
evolved by the evolve() method before reaching the StoppingCondition.

View File

@ -93,5 +93,27 @@ public class KMeansPlusPlusClustererTest {
assertTrue(cluster3Found);
}
/**
* JIRA: MATH-305
*
* Two points, one cluster, one iteration
*/
@Test
public void testPerformClusterAnalysisDegenerate() {
KMeansPlusPlusClusterer<EuclideanIntegerPoint> transformer = new KMeansPlusPlusClusterer<EuclideanIntegerPoint>(
new Random(1746432956321l));
EuclideanIntegerPoint[] points = new EuclideanIntegerPoint[] {
new EuclideanIntegerPoint(new int[] { 1959, 325100 }),
new EuclideanIntegerPoint(new int[] { 1960, 373200 }), };
List<Cluster<EuclideanIntegerPoint>> clusters = transformer.cluster(Arrays.asList(points), 1, 1);
assertEquals(1, clusters.size());
assertEquals(2, (clusters.get(0).getPoints().size()));
EuclideanIntegerPoint pt1 = new EuclideanIntegerPoint(new int[] { 1959, 325100 });
EuclideanIntegerPoint pt2 = new EuclideanIntegerPoint(new int[] { 1960, 373200 });
assertTrue(clusters.get(0).getPoints().contains(pt1));
assertTrue(clusters.get(0).getPoints().contains(pt2));
}
}