Skip to main content
Glama
orneryd

M.I.M.I.R - Multi-agent Intelligent Memory & Insight Repository

by orneryd
similarity.go5.52 kB
// Package vector provides vector math operations for NornicDB. // // This package consolidates all vector similarity and distance calculations // used throughout the codebase. Use these functions instead of implementing // your own to ensure consistency and correctness. // // Main Functions: // - CosineSimilarity: Standard similarity for float32 vectors (most common) // - CosineSimilarityFloat64: High-precision similarity for float64 vectors // - CosineSimilarityGPU: GPU-optimized similarity (returns float32) // - DotProduct: Dot product for float32 vectors // - EuclideanSimilarity: Distance-based similarity // - Normalize: Returns normalized copy of vector // - NormalizeInPlace: Normalizes vector in-place (modifies input) package vector import "math" // CosineSimilarity calculates cosine similarity between two float32 vectors. // Returns value in range [-1, 1] where 1 = identical, 0 = orthogonal, -1 = opposite. // // This is the STANDARD implementation for all non-GPU code. // Uses float64 accumulation for high precision, even with float32 inputs. // // Example: // // a := []float32{1.0, 2.0, 3.0} // b := []float32{4.0, 5.0, 6.0} // sim := CosineSimilarity(a, b) // Returns 0.9746318461970762 func CosineSimilarity(a, b []float32) float64 { if len(a) != len(b) || len(a) == 0 { return 0 } var dotProd, normA, normB float64 for i := range a { dotProd += float64(a[i] * b[i]) normA += float64(a[i] * a[i]) normB += float64(b[i] * b[i]) } if normA == 0 || normB == 0 { return 0 } return dotProd / (math.Sqrt(normA) * math.Sqrt(normB)) } // CosineSimilarityFloat64 calculates cosine similarity between two float64 vectors. // Returns value in range [-1, 1] where 1 = identical, 0 = orthogonal, -1 = opposite. // // Use this when working with float64 vectors directly. // // Example: // // a := []float64{1.0, 2.0, 3.0} // b := []float64{4.0, 5.0, 6.0} // sim := CosineSimilarityFloat64(a, b) // Returns 0.9746318461970762 func CosineSimilarityFloat64(a, b []float64) float64 { if len(a) != len(b) || len(a) == 0 { return 0 } var dotProduct, normA, normB float64 for i := range a { dotProduct += a[i] * b[i] normA += a[i] * a[i] normB += b[i] * b[i] } if normA == 0 || normB == 0 { return 0 } return dotProduct / (math.Sqrt(normA) * math.Sqrt(normB)) } // CosineSimilarityGPU calculates cosine similarity optimized for GPU operations. // Returns float32 for GPU compatibility. // // Uses float32 throughout for maximum GPU performance. // Slightly less accurate than CosineSimilarity() due to float32 accumulation. // // Use this ONLY for GPU-accelerated batch operations. func CosineSimilarityGPU(a, b []float32) float32 { if len(a) != len(b) || len(a) == 0 { return 0 } var dot, normA, normB float32 for i := range a { dot += a[i] * b[i] normA += a[i] * a[i] normB += b[i] * b[i] } if normA == 0 || normB == 0 { return 0 } return dot / (float32(math.Sqrt(float64(normA))) * float32(math.Sqrt(float64(normB)))) } // DotProduct calculates the dot product of two float32 vectors. // Returns float64 for precision. // // For normalized vectors, dot product equals cosine similarity. // // Example: // // a := []float32{1.0, 2.0, 3.0} // b := []float32{4.0, 5.0, 6.0} // dot := DotProduct(a, b) // Returns 32.0 func DotProduct(a, b []float32) float64 { if len(a) != len(b) { return 0 } var sum float64 for i := range a { sum += float64(a[i] * b[i]) } return sum } // EuclideanSimilarity calculates similarity based on Euclidean distance. // Returns value in range [0, 1] where 1 = identical, 0 = very different. // // Formula: 1 / (1 + distance) // // Example: // // a := []float32{1.0, 2.0, 3.0} // b := []float32{4.0, 5.0, 6.0} // sim := EuclideanSimilarity(a, b) // Returns ~0.161 func EuclideanSimilarity(a, b []float32) float64 { if len(a) != len(b) || len(a) == 0 { return 0 } var sum float64 for i := range a { diff := float64(a[i] - b[i]) sum += diff * diff } return 1.0 / (1.0 + math.Sqrt(sum)) } // EuclideanSimilarityFloat64 calculates similarity for float64 vectors. func EuclideanSimilarityFloat64(a, b []float64) float64 { if len(a) != len(b) || len(a) == 0 { return 0 } var sum float64 for i := range a { diff := a[i] - b[i] sum += diff * diff } return 1.0 / (1.0 + math.Sqrt(sum)) } // Normalize returns a normalized copy of the vector. // The input vector is not modified (immutable operation). // // Example: // // original := []float32{3.0, 4.0} // normalized := Normalize(original) // Returns [0.6, 0.8] // // original is unchanged func Normalize(vec []float32) []float32 { var sumSquares float64 for _, v := range vec { sumSquares += float64(v * v) } if sumSquares == 0 { result := make([]float32, len(vec)) return result } norm := math.Sqrt(sumSquares) normalized := make([]float32, len(vec)) for i, v := range vec { normalized[i] = float32(float64(v) / norm) } return normalized } // NormalizeInPlace normalizes a vector in-place (modifies the input). // After normalization, the vector has unit length (magnitude = 1). // // WARNING: Modifies the input slice. Use Normalize() to preserve original. // // Example: // // v := []float32{3.0, 4.0} // NormalizeInPlace(v) // v is now [0.6, 0.8] func NormalizeInPlace(v []float32) { var sumSquares float64 for _, x := range v { sumSquares += float64(x) * float64(x) } if sumSquares == 0 { return } norm := float32(1.0 / math.Sqrt(sumSquares)) for i := range v { v[i] *= norm } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/orneryd/Mimir'

If you have feedback or need assistance with the MCP directory API, please join our Discord server