35 #ifndef RTABMAP_FLANN_LSH_INDEX_H_
36 #define RTABMAP_FLANN_LSH_INDEX_H_
59 LshIndexParams(
unsigned int table_number = 12,
unsigned int key_size = 20,
unsigned int multi_probe_level = 2)
63 (*this)[
"table_number"] = table_number;
65 (*this)[
"key_size"] = key_size;
67 (*this)[
"multi_probe_level"] = multi_probe_level;
77 template<
typename Distance>
78 class LshIndex :
public NNIndex<Distance>
149 size_t old_size =
size_;
159 for (
size_t i=old_size;
i<
size_;++
i) {
173 template<
typename Archive>
187 if (Archive::is_loading::value) {
234 assert(dists.
cols >= knn);
238 #pragma omp parallel num_threads(params.cores)
241 #pragma omp for schedule(static) reduction(+:count)
242 for (
int i = 0;
i < (
int)queries.
rows; i++) {
253 #pragma omp parallel num_threads(params.cores)
256 #pragma omp for schedule(static) reduction(+:count)
280 std::vector< std::vector<size_t> >& indices,
281 std::vector<std::vector<DistanceType> >& dists,
283 const SearchParams& params)
const
287 if (dists.size() < queries.
rows ) dists.resize(queries.
rows);
291 #pragma omp parallel num_threads(params.cores)
293 KNNUniqueResultSet<DistanceType> resultSet(knn);
294 #pragma omp for schedule(static) reduction(+:count)
295 for (
int i = 0;
i < (
int)queries.
rows; i++) {
298 size_t n =
std::min(resultSet.size(), knn);
302 resultSet.copy(&indices[i][0], &dists[i][0], n,
params.sorted);
310 #pragma omp parallel num_threads(params.cores)
313 #pragma omp for schedule(static) reduction(+:count)
354 std::vector<std::pair<size_t,ElementType*> > features;
355 features.reserve(
points_.size());
357 features.push_back(std::make_pair(i,
points_[i]));
378 struct SortScoreIndexPairOnSecond
382 return left.second < right.second;
393 std::vector<lsh::BucketKey>& xor_masks)
395 xor_masks.push_back(key);
396 if (level == 0)
return;
397 for (
int index = lowest_index - 1; index >= 0; --index) {
413 float& checked_average)
415 static std::vector<ScoreIndexPair> score_index_heap;
419 typename std::vector<lsh::LshTable<ElementType> >::const_iterator
table =
tables_.begin();
420 typename std::vector<lsh::LshTable<ElementType> >::const_iterator table_end =
tables_.end();
423 std::vector<lsh::BucketKey>::const_iterator xor_mask =
xor_masks_.begin();
424 std::vector<lsh::BucketKey>::const_iterator xor_mask_end =
xor_masks_.end();
425 for (; xor_mask != xor_mask_end; ++xor_mask) {
426 size_t sub_key =
key ^ (*xor_mask);
428 if (bucket == 0)
continue;
431 std::vector<lsh::FeatureIndex>::const_iterator training_index = bucket->begin();
432 std::vector<lsh::FeatureIndex>::const_iterator last_training_index = bucket->end();
436 for (; training_index < last_training_index; ++training_index) {
440 if (hamming_distance < worst_score) {
443 std::push_heap(score_index_heap.begin(), score_index_heap.end());
445 if (score_index_heap.size() > (
unsigned int)k_nn) {
447 std::pop_heap(score_index_heap.begin(), score_index_heap.end());
448 score_index_heap.pop_back();
450 worst_score = score_index_heap.front().first;
458 typename std::vector<lsh::LshTable<ElementType> >::const_iterator
table =
tables_.begin();
459 typename std::vector<lsh::LshTable<ElementType> >::const_iterator table_end =
tables_.end();
462 std::vector<lsh::BucketKey>::const_iterator xor_mask =
xor_masks_.begin();
463 std::vector<lsh::BucketKey>::const_iterator xor_mask_end =
xor_masks_.end();
464 for (; xor_mask != xor_mask_end; ++xor_mask) {
465 size_t sub_key =
key ^ (*xor_mask);
467 if (bucket == 0)
continue;
470 std::vector<lsh::FeatureIndex>::const_iterator training_index = bucket->begin();
471 std::vector<lsh::FeatureIndex>::const_iterator last_training_index = bucket->end();
475 for (; training_index < last_training_index; ++training_index) {
479 if (hamming_distance < radius) score_index_heap.push_back(
ScoreIndexPair(hamming_distance, training_index));
492 typename std::vector<lsh::LshTable<ElementType> >::const_iterator
table =
tables_.begin();
493 typename std::vector<lsh::LshTable<ElementType> >::const_iterator table_end =
tables_.end();
496 std::vector<lsh::BucketKey>::const_iterator xor_mask =
xor_masks_.begin();
497 std::vector<lsh::BucketKey>::const_iterator xor_mask_end =
xor_masks_.end();
498 for (; xor_mask != xor_mask_end; ++xor_mask) {
499 size_t sub_key =
key ^ (*xor_mask);
501 if (bucket == 0)
continue;
504 std::vector<lsh::FeatureIndex>::const_iterator training_index = bucket->begin();
505 std::vector<lsh::FeatureIndex>::const_iterator last_training_index = bucket->end();
509 for (; training_index < last_training_index; ++training_index) {
513 result.addPoint(hamming_distance, *training_index);
532 std::vector<lsh::LshTable<ElementType> >
tables_;
548 #endif //FLANN_LSH_INDEX_H_