62 short_inner_prod (T
const* query,
63 typename NearestNeighbor<T>::Result* result,
64 T
const* elements,
int num_elements,
int dimensions)
66#if ENABLE_SSE2_NN_SEARCH && defined(__SSE2__)
68 int const dim_8 = dimensions / 8;
69 __m128i
const* descr_ptr =
reinterpret_cast<__m128i const*
>(elements);
70 for (
int descr_iter = 0; descr_iter < num_elements; ++descr_iter)
73 __m128i
const* query_ptr =
reinterpret_cast<__m128i const*
>(query);
74 __m128i reg_result = _mm_set1_epi16(0);
75 for (
int i = 0; i < dim_8; ++i, ++query_ptr, ++descr_ptr)
77 __m128i reg_query = _mm_load_si128(query_ptr);
78 __m128i reg_subject = _mm_load_si128(descr_ptr);
79 reg_result = _mm_add_epi16(reg_result,
80 _mm_mullo_epi16(reg_query, reg_subject));
82 T
const* tmp =
reinterpret_cast<T const*
>(®_result);
83 int inner_product = tmp[0] + tmp[1] + tmp[2] + tmp[3]
84 + tmp[4] + tmp[5] + tmp[6] + tmp[7];
87 if (inner_product >= result->dist_2nd_best)
89 if (inner_product >= result->dist_1st_best)
91 result->index_2nd_best = result->index_1st_best;
92 result->dist_2nd_best = result->dist_1st_best;
93 result->index_1st_best = descr_iter;
94 result->dist_1st_best = inner_product;
98 result->index_2nd_best = descr_iter;
99 result->dist_2nd_best = inner_product;
104 T
const* descr_ptr = elements;
105 for (
int i = 0; i < num_elements; ++i)
107 int inner_product = 0;
108 for (
int i = 0; i < dimensions; ++i, ++descr_ptr)
109 inner_product += query[i] * *descr_ptr;
112 if (inner_product >= result->dist_2nd_best)
114 if (inner_product >= result->dist_1st_best)
116 result->index_2nd_best = result->index_1st_best;
117 result->dist_2nd_best = result->dist_1st_best;
118 result->index_1st_best = i;
119 result->dist_1st_best = inner_product;
123 result->index_2nd_best = i;
124 result->dist_2nd_best = inner_product;
141 float_inner_prod (
float const* query,
142 NearestNeighbor<float>::Result* result,
143 float const* elements,
int num_elements,
int dimensions)
145#if ENABLE_SSE3_NN_SEARCH && defined(__SSE3__)
154 __m128
const* descr_ptr =
reinterpret_cast<__m128 const*
>(elements);
155 int const dim_4 = dimensions / 4;
156 for (
int descr_iter = 0; descr_iter < num_elements; ++descr_iter)
159 __m128
const* query_ptr =
reinterpret_cast<__m128 const*
>(query);
160 __m128 sum = _mm_setzero_ps();
161 for (
int i = 0; i < dim_4; ++i, ++query_ptr, ++descr_ptr)
162 sum = _mm_add_ps(sum, _mm_mul_ps(*query_ptr, *descr_ptr));
163 sum = _mm_hadd_ps(sum, sum);
164 sum = _mm_hadd_ps(sum, sum);
167 float inner_product = _mm_cvtss_f32(sum);
168 if (inner_product >= result->dist_2nd_best)
170 if (inner_product >= result->dist_1st_best)
172 result->index_2nd_best = result->index_1st_best;
173 result->dist_2nd_best = result->dist_1st_best;
174 result->index_1st_best = descr_iter;
175 result->dist_1st_best = inner_product;
179 result->index_2nd_best = descr_iter;
180 result->dist_2nd_best = inner_product;
185 float const* descr_ptr = elements;
186 for (
int i = 0; i < num_elements; ++i)
188 float inner_product = 0.0f;
189 for (
int j = 0; j < dimensions; ++j, ++descr_ptr)
190 inner_product += query[j] * *descr_ptr;
193 if (inner_product >= result->dist_2nd_best)
195 if (inner_product >= result->dist_1st_best)
197 result->index_2nd_best = result->index_1st_best;
198 result->dist_2nd_best = result->dist_1st_best;
199 result->index_1st_best = i;
200 result->dist_1st_best = inner_product;
204 result->index_2nd_best = i;
205 result->dist_2nd_best = inner_product;
225 short_inner_prod<short>(query, result, this->elements,
226 this->num_elements, this->dimensions);
251 short_inner_prod<unsigned short>(query, result, this->elements,
252 this->num_elements, this->dimensions);
281 float_inner_prod(query, result, this->elements,
282 this->num_elements, this->dimensions);
Nearest (and second nearest) neighbor search for normalized vectors.
#define SFM_NAMESPACE_END
#define SFM_NAMESPACE_BEGIN
Unlike the naming suggests, these are square distances.