Skip to content

Commit ac5bb48

Browse files
author
Joseph Smith
committed
Fix cosine similarity to handle division by zero
1 parent a7115e2 commit ac5bb48

2 files changed

Lines changed: 15 additions & 1 deletion

File tree

common-lib/src/main/scala/com/gu/mediaservice/lib/VectorUtils.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ object VectorUtils {
1010
}
1111

1212
def cosineSimilarity(vectorOne: List[Double], vectorTwo: List[Double]): Double = {
13-
dotProduct(vectorOne, vectorTwo) / (magnitude(vectorOne) * magnitude(vectorTwo))
13+
val magnitudeProduct = magnitude(vectorOne) * magnitude(vectorTwo)
14+
if (magnitudeProduct == 0.0) 0.0
15+
else dotProduct(vectorOne, vectorTwo) / magnitudeProduct
1416
}
1517
}

common-lib/src/test/scala/com/gu/mediaservice/lib/VectorUtilsTest.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,16 @@ class VectorUtilsTest extends AnyFunSpec with Matchers {
4040
it ("should return a cosine similarity of -1 for opposite vectors") {
4141
VectorUtils.cosineSimilarity(List(1.0, 2.0, 3.0), List(-1.0, -2.0, -3.0)) shouldBe -1.0 +- 1e-9
4242
}
43+
44+
it ("should return a cosine similarity of 0 when the first vector has zero magnitude") {
45+
VectorUtils.cosineSimilarity(List(0.0, 0.0, 0.0), List(1.0, 2.0, 3.0)) shouldBe 0.0 +- 1e-9
46+
}
47+
48+
it ("should return a cosine similarity of 0 when the second vector has zero magnitude") {
49+
VectorUtils.cosineSimilarity(List(1.0, 2.0, 3.0), List(0.0, 0.0, 0.0)) shouldBe 0.0 +- 1e-9
50+
}
51+
52+
it ("should return a cosine similarity of 0 when both vectors have zero magnitude") {
53+
VectorUtils.cosineSimilarity(List(0.0, 0.0, 0.0), List(0.0, 0.0, 0.0)) shouldBe 0.0 +- 1e-9
54+
}
4355
}

0 commit comments

Comments
 (0)