knncolle_hnsw
knncolle bindings for HNSW
Loading...
Searching...
No Matches
distances.hpp
Go to the documentation of this file.
1#ifndef KNNCOLLE_HNSW_DISTANCES_HPP
2#define KNNCOLLE_HNSW_DISTANCES_HPP
3
4#include <cmath>
5#include <functional>
6#include <cstddef>
7
13namespace knncolle_hnsw {
14
20template<typename HnswData_ = float>
25 std::function<hnswlib::SpaceInterface<HnswData_>*(std::size_t)> create;
26
31 std::function<HnswData_(HnswData_)> normalize;
32};
33
39template<typename HnswData_ = float>
40class ManhattanDistance : public hnswlib::SpaceInterface<HnswData_> {
41private:
42 std::size_t my_data_size;
43 std::size_t my_dim;
44
45public:
49 ManhattanDistance(std::size_t dim) : my_data_size(dim * sizeof(HnswData_)), my_dim(dim) {}
50
54public:
55 std::size_t get_data_size() {
56 return my_data_size;
57 }
58
59 hnswlib::DISTFUNC<HnswData_> get_dist_func() {
60 return L1;
61 }
62
63 void * get_dist_func_param() {
64 return &my_dim;
65 }
66
67private:
68 static HnswData_ L1(const void *pVect1v, const void *pVect2v, const void *qty_ptr) {
69 const HnswData_* pVect1 = static_cast<const HnswData_*>(pVect1v);
70 const HnswData_* pVect2 = static_cast<const HnswData_*>(pVect2v);
71 std::size_t qty = *((size_t *) qty_ptr);
72 HnswData_ res = 0;
73 for (; qty > 0; --qty, ++pVect1, ++pVect2) {
74 res += std::abs(*pVect1 - *pVect2);
75 }
76 return res;
77 }
81};
82
88template<typename HnswData_ = float>
89class SquaredEuclideanDistance : public hnswlib::SpaceInterface<HnswData_> {
90private:
91 std::size_t my_data_size;
92 std::size_t my_dim;
93
94public:
98 SquaredEuclideanDistance(std::size_t dim) : my_data_size(dim * sizeof(HnswData_)), my_dim(dim) {}
99
103public:
104 std::size_t get_data_size() {
105 return my_data_size;
106 }
107
108 hnswlib::DISTFUNC<HnswData_> get_dist_func() {
109 return L2;
110 }
111
112 void * get_dist_func_param() {
113 return &my_dim;
114 }
115
116private:
117 static HnswData_ L2(const void *pVect1v, const void *pVect2v, const void *qty_ptr) {
118 const HnswData_* pVect1 = static_cast<const HnswData_*>(pVect1v);
119 const HnswData_* pVect2 = static_cast<const HnswData_*>(pVect2v);
120 std::size_t qty = *((size_t *) qty_ptr);
121 HnswData_ res = 0;
122 for (; qty > 0; --qty, ++pVect1, ++pVect2) {
123 auto delta = *pVect1 - *pVect2;
124 res += delta * delta;
125 }
126 return res;
127 }
131};
132
138template<typename HnswData_ = float>
141 output.create = [](std::size_t dim) -> hnswlib::SpaceInterface<HnswData_>* {
142 if constexpr(std::is_same<HnswData_, float>::value) {
143 return static_cast<hnswlib::SpaceInterface<HnswData_>*>(new hnswlib::L2Space(dim));
144 } else {
145 return static_cast<hnswlib::SpaceInterface<HnswData_>*>(new SquaredEuclideanDistance<HnswData_>(dim));
146 }
147 };
148 output.normalize = [](HnswData_ x) -> HnswData_ {
149 return std::sqrt(x);
150 };
151 return output;
152}
153
158template<typename HnswData_ = float>
161 output.create = [](std::size_t dim) -> hnswlib::SpaceInterface<HnswData_>* {
162 return static_cast<hnswlib::SpaceInterface<HnswData_>*>(new knncolle_hnsw::ManhattanDistance<HnswData_>(dim));
163 };
164 return output;
165}
166
167}
168
169#endif
Manhattan distance.
Definition distances.hpp:40
ManhattanDistance(std::size_t dim)
Definition distances.hpp:49
Squared Euclidean distance.
Definition distances.hpp:89
SquaredEuclideanDistance(std::size_t dim)
Definition distances.hpp:98
knncolle bindings for HNSW search.
Definition distances.hpp:13
DistanceConfig< HnswData_ > makeManhattanDistanceConfig()
Definition distances.hpp:159
DistanceConfig< HnswData_ > makeEuclideanDistanceConfig()
Definition distances.hpp:139
Distance configuration for the HNSW index.
Definition distances.hpp:21
std::function< HnswData_(HnswData_)> normalize
Definition distances.hpp:31
std::function< hnswlib::SpaceInterface< HnswData_ > *(std::size_t)> create
Definition distances.hpp:25