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();

Reply via email to