31 #ifndef RTABMAP_FLANN_NNINDEX_H
32 #define RTABMAP_FLANN_NNINDEX_H
46 #define KNN_HEAP_THRESHOLD 250
54 virtual size_t veclen()
const = 0;
56 virtual size_t size()
const = 0;
72 template <
typename Distance>
73 class NNIndex :
public IndexBase
103 if (
other.data_ptr_) {
154 throw FLANNException(
"Functionality not supported by this index");
190 if (index!=
size_t(-1)) {
201 inline size_t size()
const
219 inline size_t veclen()
const
235 template<
typename Archive>
240 if (Archive::is_saving::value) {
249 if (Archive::is_loading::value) {
250 if (strncmp(
header.h.signature,
257 throw FLANNException(
"Datatype of saved index is different than of the one to be created.");
261 throw FLANNException(
"Saved index type is different then the current index type.");
272 if (Archive::is_saving::value) {
278 if (Archive::is_loading::value) {
293 throw FLANNException(
"Saved index does not contain the dataset and no dataset was provided.");
319 const SearchParams& params)
const
325 assert(dists.
cols >= knn);
337 #pragma omp parallel num_threads(params.cores)
339 KNNResultSet2<DistanceType> resultSet(knn);
340 #pragma omp for schedule(static) reduction(+:count)
341 for (
int i = 0;
i < (
int)queries.
rows; i++) {
344 size_t n =
std::min(resultSet.size(), knn);
345 resultSet.copy(indices[i], dists[i], n,
params.sorted);
352 #pragma omp parallel num_threads(params.cores)
354 KNNSimpleResultSet<DistanceType> resultSet(knn);
355 #pragma omp for schedule(static) reduction(+:count)
356 for (
int i = 0;
i < (
int)queries.
rows; i++) {
359 size_t n =
std::min(resultSet.size(), knn);
360 resultSet.copy(indices[i], dists[i], n,
params.sorted);
406 std::vector< std::vector<size_t> >& indices,
407 std::vector<std::vector<DistanceType> >& dists,
409 const SearchParams& params)
const
425 #pragma omp parallel num_threads(params.cores)
427 KNNResultSet2<DistanceType> resultSet(knn);
428 #pragma omp for schedule(static) reduction(+:count)
429 for (
int i = 0;
i < (
int)queries.
rows; i++) {
432 size_t n =
std::min(resultSet.size(), knn);
444 #pragma omp parallel num_threads(params.cores)
446 KNNSimpleResultSet<DistanceType> resultSet(knn);
447 #pragma omp for schedule(static) reduction(+:count)
448 for (
int i = 0;
i < (
int)queries.
rows; i++) {
451 size_t n =
std::min(resultSet.size(), knn);
455 resultSet.copy(&indices[i][0], &dists[i][0], n,
params.sorted);
477 std::vector< std::vector<int> >& indices,
478 std::vector<std::vector<DistanceType> >& dists,
480 const SearchParams& params)
const
482 std::vector<std::vector<size_t> > indices_;
485 indices.resize(indices_.size());
486 for (
size_t i=0;
i<indices_.size();++
i) {
487 indices[
i].assign(indices_[i].begin(), indices_[i].
end());
510 int max_neighbors =
params.max_neighbors;
511 if (max_neighbors<0) max_neighbors = num_neighbors;
512 else max_neighbors =
std::min(max_neighbors,(
int)num_neighbors);
514 if (max_neighbors==0) {
515 #pragma omp parallel num_threads(params.cores)
518 #pragma omp for schedule(static) reduction(+:count)
530 #pragma omp parallel num_threads(params.cores)
533 #pragma omp for schedule(static) reduction(+:count)
537 size_t n = resultSet.
size();
539 if (
n>num_neighbors)
n = num_neighbors;
544 if (
n<dists.
cols) dists[
i][
n] = std::numeric_limits<DistanceType>::infinity();
551 #pragma omp parallel num_threads(params.cores)
554 #pragma omp for schedule(static) reduction(+:count)
555 for (
int i = 0;
i < (
int)queries.
rows; i++) {
558 size_t n = resultSet.size();
560 if ((
int)n>max_neighbors)
n = max_neighbors;
561 resultSet.copy(indices[i], dists[i], n,
params.sorted);
565 if (n<dists.
cols) dists[
i][
n] = std::numeric_limits<DistanceType>::infinity();
588 const SearchParams& params)
const
598 delete[] indices_.ptr();
612 std::vector< std::vector<size_t> >& indices,
613 std::vector<std::vector<DistanceType> >& dists,
620 if (
params.max_neighbors==0) {
621 #pragma omp parallel num_threads(params.cores)
624 #pragma omp for schedule(static) reduction(+:count)
636 if (
params.max_neighbors<0) {
638 #pragma omp parallel num_threads(params.cores)
641 #pragma omp for schedule(static) reduction(+:count)
645 size_t n = resultSet.
size();
658 #pragma omp parallel num_threads(params.cores)
660 KNNRadiusResultSet<DistanceType> resultSet(radius,
params.max_neighbors);
661 #pragma omp for schedule(static) reduction(+:count)
662 for (
int i = 0;
i < (
int)queries.
rows; i++) {
665 size_t n = resultSet.size();
671 resultSet.copy(&indices[i][0], &dists[i][0], n,
params.sorted);
691 std::vector< std::vector<int> >& indices,
692 std::vector<std::vector<DistanceType> >& dists,
694 const SearchParams& params)
const
696 std::vector<std::vector<size_t> > indices_;
699 indices.resize(indices_.size());
700 for (
size_t i=0;
i<indices_.size();++
i) {
701 indices[
i].assign(indices_[i].begin(), indices_[i].
end());
707 virtual void findNeighbors(ResultSet<DistanceType>& result,
const ElementType* vec,
const SearchParams& searchParams)
const = 0;
717 if (
ids_.size()==0) {
720 size_t point_index =
size_t(-1);
721 if (
id <
ids_.size() &&
ids_[
id]==
id) {
730 size_t mid = (start+
end)/2;
735 else if (
ids_[mid]<
id) {
778 ids_.resize(new_size);
781 for (
size_t i=
size_;
i<new_size;++
i) {
806 ids_.resize(last_idx);
881 std::vector<size_t>
ids_;
886 std::vector<ElementType*>
points_;
897 #define USING_BASECLASS_SYMBOLS \
898 using NNIndex<Distance>::distance_;\
899 using NNIndex<Distance>::size_;\
900 using NNIndex<Distance>::size_at_build_;\
901 using NNIndex<Distance>::veclen_;\
902 using NNIndex<Distance>::index_params_;\
903 using NNIndex<Distance>::removed_points_;\
904 using NNIndex<Distance>::ids_;\
905 using NNIndex<Distance>::removed_;\
906 using NNIndex<Distance>::points_;\
907 using NNIndex<Distance>::extendDataset;\
908 using NNIndex<Distance>::setDataset;\
909 using NNIndex<Distance>::cleanRemovedPoints;\
910 using NNIndex<Distance>::indices_to_ids;
917 #endif //FLANN_NNINDEX_H