photoprism/pkg/vector/distance.go
Michael Mayer 03129c9129 Vector: Reorganize package into topic-based files #4669
Split the catch-all values.go into one file per concept, each mirrored
by its test: distance.go, norm.go, stats.go, product.go, centroid.go,
plus the mean methods folded into mean.go and Copy/Dim/Sum into
vector.go. Remove values.go, values_test.go, and values_more_test.go so
functionality and tests live where developers expect them.

Hoist the two 512-dimensional face embeddings shared by the distance,
norm, and cosine tests into fixtures_test.go, removing the previous
triplication, and decompose the monolithic TestVector into per-concept
tests. Close pre-existing coverage gaps in the integer converters and
the GeometricMean/HarmonicMean method wrappers, bringing the package to
100% statement coverage. Pure code movement; no behavior change.
2026-05-30 09:44:03 +00:00

82 lines
1.8 KiB
Go

package vector
import "math"
// EuclideanDist returns the Euclidean distance between the vectors,
func (v Vector) EuclideanDist(w Vector) float64 {
return EuclideanDist(v, w)
}
// CosineSimilarity returns the cosine similarity between two vectors,
// ranging from -1 (opposite) to 1 (identical).
func (v Vector) CosineSimilarity(w Vector) float64 {
return CosineSimilarity(v, w)
}
// CosineDist returns the cosine distance between two vectors (1 - cosine similarity).
func (v Vector) CosineDist(w Vector) float64 {
return CosineDist(v, w)
}
// EuclideanDist returns the Euclidean distance between multiple vectors.
func EuclideanDist(a, b Vector) float64 {
if a.Dim() != b.Dim() {
return NaN()
}
var (
s, t float64
)
for i := range a {
t = a[i] - b[i]
s += t * t
}
return math.Sqrt(s)
}
// CosineSimilarity returns the cosine similarity between two vectors, ranging
// from -1 (opposite) to 1 (identical). It returns NaN when the dimensions
// differ and 0 when either operand is a zero vector.
func CosineSimilarity(a, b Vector) float64 {
if a.Dim() != b.Dim() {
return NaN()
}
var sum, s1, s2 float64
for i := range a {
sum += a[i] * b[i]
s1 += a[i] * a[i]
s2 += b[i] * b[i]
}
if s1 == 0 || s2 == 0 {
return 0.0
}
return sum / (math.Sqrt(s1) * math.Sqrt(s2))
}
// CosineDist returns the cosine distance between two vectors, defined as
// 1 - CosineSimilarity. Identical vectors yield 0; it returns NaN when the
// dimensions differ.
func CosineDist(a, b Vector) float64 {
return 1.0 - CosineSimilarity(a, b)
}
// CosineDists returns the cosine distances between two sets of vectors.
func CosineDists(x, y Vectors) Vectors {
result := make(Vectors, len(x))
for i, a := range x {
result[i] = make([]float64, len(y))
for j, b := range y {
result[i][j] = CosineDist(a, b)
}
}
return result
}