This is an automated email from the ASF dual-hosted git repository.
zhangzp pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/flink-ml.git
The following commit(s) were added to refs/heads/master by this push:
new aab8250 [FLINK-29843] Avoid negative euclidean distance square
aab8250 is described below
commit aab82502ee4947efdab5bd8f522552091e83d821
Author: yunfengzhou-hub <[email protected]>
AuthorDate: Wed Nov 2 15:06:41 2022 +0800
[FLINK-29843] Avoid negative euclidean distance square
This closes #170.
---
.../flink/ml/common/distance/EuclideanDistanceMeasure.java | 9 ++++++++-
.../org/apache/flink/ml/common/distance/DistanceMeasureTest.java | 7 +++++++
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git
a/flink-ml-core/src/main/java/org/apache/flink/ml/common/distance/EuclideanDistanceMeasure.java
b/flink-ml-core/src/main/java/org/apache/flink/ml/common/distance/EuclideanDistanceMeasure.java
index 8ef341a..1fad959 100644
---
a/flink-ml-core/src/main/java/org/apache/flink/ml/common/distance/EuclideanDistanceMeasure.java
+++
b/flink-ml-core/src/main/java/org/apache/flink/ml/common/distance/EuclideanDistanceMeasure.java
@@ -39,7 +39,14 @@ public class EuclideanDistanceMeasure implements
DistanceMeasure {
}
private double distanceSquare(VectorWithNorm v1, VectorWithNorm v2) {
- return v1.l2Norm * v1.l2Norm + v2.l2Norm * v2.l2Norm - 2.0 *
BLAS.dot(v1.vector, v2.vector);
+ // Computing the distance square between two vectors that are close
enough might result in
+ // a negative value, due to the loss of data accuracy. A Math.max
helps to guarantee that
+ // a non-negative value is returned.
+ return Math.max(
+ 0.0,
+ v1.l2Norm * v1.l2Norm
+ + v2.l2Norm * v2.l2Norm
+ - 2.0 * BLAS.dot(v1.vector, v2.vector));
}
@Override
diff --git
a/flink-ml-core/src/test/java/org/apache/flink/ml/common/distance/DistanceMeasureTest.java
b/flink-ml-core/src/test/java/org/apache/flink/ml/common/distance/DistanceMeasureTest.java
index 7370f2b..2067c7f 100644
---
a/flink-ml-core/src/test/java/org/apache/flink/ml/common/distance/DistanceMeasureTest.java
+++
b/flink-ml-core/src/test/java/org/apache/flink/ml/common/distance/DistanceMeasureTest.java
@@ -54,6 +54,13 @@ public class DistanceMeasureTest {
assertEquals(1, distanceMeasure.findClosest(CENTROIDS,
VECTOR_WITH_NORM_B));
}
+ @Test
+ public void testEuclideanOfIdenticalVectors() {
+ VectorWithNorm vector = new VectorWithNorm(Vectors.dense(3.0, 3.0));
+ DistanceMeasure distanceMeasure =
EuclideanDistanceMeasure.getInstance();
+ assertEquals(0, distanceMeasure.distance(vector, vector));
+ }
+
@Test
public void testManhattan() {
DistanceMeasure distanceMeasure =
ManhattanDistanceMeasure.getInstance();