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  }