github.com/weaviate/weaviate@v1.24.6/adapters/repos/db/vector/compressionhelpers/binary_quantization.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 compressionhelpers 13 14 import ( 15 "errors" 16 "math" 17 "math/bits" 18 19 "github.com/weaviate/weaviate/adapters/repos/db/vector/hnsw/distancer" 20 ) 21 22 type BinaryQuantizer struct { 23 distancer distancer.Provider 24 } 25 26 func NewBinaryQuantizer(distancer distancer.Provider) BinaryQuantizer { 27 return BinaryQuantizer{ 28 distancer: distancer, 29 } 30 } 31 32 func (bq BinaryQuantizer) Encode(vec []float32) []uint64 { 33 total := len(vec) / 64 34 if len(vec)%64 != 0 { 35 total++ 36 } 37 code := make([]uint64, total) 38 for j := 0; j < len(vec); j++ { 39 if vec[j] < 0 { 40 segment := j / 64 41 code[segment] += uint64(math.Pow(2, float64(j%64))) 42 } 43 } 44 return code 45 } 46 47 func (bq BinaryQuantizer) DistanceBetweenCompressedVectors(x, y []uint64) (float32, error) { 48 if len(x) != len(y) { 49 return 0, errors.New("BinaryQuantizer.DistanceBetweenCompressedVectors: Both vectors should have the same len") 50 } 51 total := float32(0) 52 for segment := range x { 53 total += float32(bits.OnesCount64(x[segment] ^ y[segment])) 54 } 55 return total, nil 56 }