diff --git a/faiss/MetricType.h b/faiss/MetricType.h index 8e889b1a03..7506a29713 100644 --- a/faiss/MetricType.h +++ b/faiss/MetricType.h @@ -25,6 +25,7 @@ enum MetricType { METRIC_L1, ///< L1 (aka cityblock) METRIC_Linf, ///< infinity distance METRIC_Lp, ///< L_p distance, p is given by a faiss::Index + METRIC_HAMMING, ///< Hamming distance for binary vectors /// metric_arg /// some additional metrics defined in scipy.spatial.distance diff --git a/faiss/utils/extra_distances-inl.h b/faiss/utils/extra_distances-inl.h index cf89c47629..fc267c44b5 100644 --- a/faiss/utils/extra_distances-inl.h +++ b/faiss/utils/extra_distances-inl.h @@ -13,6 +13,8 @@ #include #include #include +#include +#include namespace faiss { @@ -23,6 +25,7 @@ struct VectorDistance { static constexpr bool is_similarity = is_similarity_metric(mt); inline float operator()(const float* x, const float* y) const; + inline size_t operator()(const uint8_t* x, const uint8_t* y) const; // heap template to use for this type of metric using C = typename std::conditional< @@ -45,6 +48,17 @@ inline float VectorDistance::operator()( return fvec_inner_product(x, y, d); } +template<> +inline size_t VectorDistance::operator()( + const uint8_t* x, + const uint8_t* y) const { + int h = 0; + for (size_t i = 0; i < d; i++) { + h += (int)hamdis_tab_ham_bytes[x[i] ^ y[i]]; + } + return h; +} + template <> inline float VectorDistance::operator()( const float* x,