github.com/weaviate/weaviate@v1.24.6/usecases/vectorizer/distance.go (about) 1 // _ _ 2 // __ _____ __ ___ ___ __ _| |_ ___ 3 // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \ 4 // \ V V / __/ (_| |\ V /| | (_| | || __/ 5 // \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___| 6 // 7 // Copyright © 2016 - 2024 Weaviate B.V. All rights reserved. 8 // 9 // CONTACT: hello@weaviate.io 10 // 11 12 package vectorizer 13 14 import ( 15 "fmt" 16 "math" 17 ) 18 19 // NormalizedDistance between two arbitrary vectors, errors if dimensions don't 20 // match, will return results between 0 (no distance) and 1 (maximum distance) 21 func NormalizedDistance(a, b []float32) (float32, error) { 22 sim, err := cosineSim(a, b) 23 if err != nil { 24 return 1, fmt.Errorf("normalized distance: %v", err) 25 } 26 27 return (1 - sim) / 2, nil 28 } 29 30 func cosineSim(a, b []float32) (float32, error) { 31 if len(a) != len(b) { 32 return 0, fmt.Errorf("vectors have different dimensions") 33 } 34 35 var ( 36 sumProduct float64 37 sumASquare float64 38 sumBSquare float64 39 ) 40 41 for i := range a { 42 sumProduct += float64(a[i] * b[i]) 43 sumASquare += float64(a[i] * a[i]) 44 sumBSquare += float64(b[i] * b[i]) 45 } 46 47 return float32(sumProduct / (math.Sqrt(sumASquare * sumBSquare))), nil 48 }