ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
nn_index.h
Go to the documentation of this file.
1 /***********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
5  * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
6  *
7  * THE BSD LICENSE
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in the
17  * documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  *************************************************************************/
30 
31 #ifndef FLANN_NNINDEX_H
32 #define FLANN_NNINDEX_H
33 
34 #include <vector>
35 
36 #include "FLANN/general.h"
37 #include "FLANN/util/matrix.h"
38 #include "FLANN/util/params.h"
39 #include "FLANN/util/result_set.h"
41 #include "FLANN/util/saving.h"
42 
43 namespace flann
44 {
45 
46 #define KNN_HEAP_THRESHOLD 250
47 
48 
49 class IndexBase
50 {
51 public:
52  virtual ~IndexBase() {};
53 
54  virtual size_t veclen() const = 0;
55 
56  virtual size_t size() const = 0;
57 
58  virtual flann_algorithm_t getType() const = 0;
59 
60  virtual int usedMemory() const = 0;
61 
62  virtual IndexParams getParameters() const = 0;
63 
64  virtual void loadIndex(FILE* stream) = 0;
65 
66  virtual void saveIndex(FILE* stream) = 0;
67 };
68 
72 template <typename Distance>
73 class NNIndex : public IndexBase
74 {
75 public:
76  typedef typename Distance::ElementType ElementType;
77  typedef typename Distance::ResultType DistanceType;
78 
81  {
82  }
83 
86  {
87  }
88 
89  NNIndex(const NNIndex& other) :
90  distance_(other.distance_),
91  last_id_(other.last_id_),
92  size_(other.size_),
94  veclen_(other.veclen_),
96  removed_(other.removed_),
99  ids_(other.ids_),
100  points_(other.points_),
101  data_ptr_(NULL)
102  {
103  if (other.data_ptr_) {
106  for (size_t i=0;i<size_;++i) {
107  points_[i] = data_ptr_ + i*veclen_;
108  }
109  }
110  }
111 
112  virtual ~NNIndex()
113  {
114  if (data_ptr_) {
115  delete[] data_ptr_;
116  }
117  }
118 
119 
120  virtual NNIndex* clone() const = 0;
121 
125  virtual void buildIndex()
126  {
127  freeIndex();
129 
130  // building index
131  buildIndexImpl();
132 
134 
135  }
136 
141  virtual void buildIndex(const Matrix<ElementType>& dataset)
142  {
143  setDataset(dataset);
144  this->buildIndex();
145  }
146 
152  virtual void addPoints(const Matrix<ElementType>& points, float rebuild_threshold = 2)
153  {
154  throw FLANNException("Functionality not supported by this index");
155  }
156 
161  virtual void removePoint(size_t id)
162  {
163  if (!removed_) {
164  ids_.resize(size_);
165  for (size_t i=0;i<size_;++i) {
166  ids_[i] = i;
167  }
170  last_id_ = size_;
171  removed_ = true;
172  }
173 
174  size_t point_index = id_to_index(id);
175  if (point_index!=size_t(-1) && !removed_points_.test(point_index)) {
176  removed_points_.set(point_index);
177  removed_count_++;
178  }
179  }
180 
181 
187  virtual ElementType* getPoint(size_t id)
188  {
189  size_t index = id_to_index(id);
190  if (index!=size_t(-1)) {
191  return points_[index];
192  }
193  else {
194  return NULL;
195  }
196  }
197 
201  inline size_t size() const
202  {
203  return size_ - removed_count_;
204  }
205 
209  inline size_t veclen() const
210  {
211  return veclen_;
212  }
213 
220  {
221  return index_params_;
222  }
223 
224 
225  template<typename Archive>
226  void serialize(Archive& ar)
227  {
228  IndexHeader header;
229 
230  if (Archive::is_saving::value) {
232  header.h.index_type = getType();
233  header.h.rows = size_;
234  header.h.cols = veclen_;
235  }
236  ar & header;
237 
238  // sanity checks
239  if (Archive::is_loading::value) {
240  if (strncmp(header.h.signature,
242  strlen(FLANN_SIGNATURE_) - strlen("v0.0")) != 0) {
243  throw FLANNException("Invalid index file, wrong signature");
244  }
245 
247  throw FLANNException("Datatype of saved index is different than of the one to be created.");
248  }
249 
250  if (header.h.index_type != getType()) {
251  throw FLANNException("Saved index type is different then the current index type.");
252  }
253  // TODO: check for distance type
254 
255  }
256 
257  ar & size_;
258  ar & veclen_;
259  ar & size_at_build_;
260 
261  bool save_dataset;
262  if (Archive::is_saving::value) {
263  save_dataset = get_param(index_params_,"save_dataset", false);
264  }
265  ar & save_dataset;
266 
267  if (save_dataset) {
268  if (Archive::is_loading::value) {
269  if (data_ptr_) {
270  delete[] data_ptr_;
271  }
273  points_.resize(size_);
274  for (size_t i=0;i<size_;++i) {
275  points_[i] = data_ptr_ + i*veclen_;
276  }
277  }
278  for (size_t i=0;i<size_;++i) {
280  }
281  } else {
282  if (points_.size()!=size_) {
283  throw FLANNException("Saved index does not contain the dataset and no dataset was provided.");
284  }
285  }
286 
287  ar & last_id_;
288  ar & ids_;
289  ar & removed_;
290  if (removed_) {
291  ar & removed_points_;
292  }
293  ar & removed_count_;
294  }
295 
296 
305  virtual int knnSearch(const Matrix<ElementType>& queries,
306  Matrix<size_t>& indices,
307  Matrix<DistanceType>& dists,
308  size_t knn,
309  const SearchParams& params) const
310  {
311  assert(queries.cols == veclen());
312  assert(indices.rows >= queries.rows);
313  assert(dists.rows >= queries.rows);
314  assert(indices.cols >= knn);
315  assert(dists.cols >= knn);
316  bool use_heap;
317 
318  if (params.use_heap==FLANN_Undefined) {
319  use_heap = (knn>KNN_HEAP_THRESHOLD)?true:false;
320  }
321  else {
322  use_heap = (params.use_heap==FLANN_True)?true:false;
323  }
324  int count = 0;
325 
326  if (use_heap) {
327 #pragma omp parallel num_threads(params.cores)
328  {
329  KNNResultSet2<DistanceType> resultSet(knn);
330 #pragma omp for schedule(dynamic) reduction(+:count)
331  for (int i = 0; i < (int)queries.rows; i++) {
332  resultSet.clear();
333  findNeighbors(resultSet, queries[i], params);
334  size_t n = std::min(resultSet.size(), knn);
335  resultSet.copy(indices[i], dists[i], n, params.sorted);
336  indices_to_ids(indices[i], indices[i], n);
337  count += n;
338  }
339  }
340  }
341  else {
342 #pragma omp parallel num_threads(params.cores)
343  {
344  KNNSimpleResultSet<DistanceType> resultSet(knn);
345 #pragma omp for schedule(dynamic) reduction(+:count)
346  for (int i = 0; i < (int)queries.rows; i++) {
347  resultSet.clear();
348  findNeighbors(resultSet, queries[i], params);
349  size_t n = std::min(resultSet.size(), knn);
350  resultSet.copy(indices[i], dists[i], n, params.sorted);
351  indices_to_ids(indices[i], indices[i], n);
352  count += n;
353  }
354  }
355  }
356  return count;
357  }
358 
368  int knnSearch(const Matrix<ElementType>& queries,
369  Matrix<int>& indices,
370  Matrix<DistanceType>& dists,
371  size_t knn,
372  const SearchParams& params) const
373  {
374  flann::Matrix<size_t> indices_(new size_t[indices.rows*indices.cols], indices.rows, indices.cols);
375  int result = knnSearch(queries, indices_, dists, knn, params);
376 
377  for (size_t i=0;i<indices.rows;++i) {
378  for (size_t j=0;j<indices.cols;++j) {
379  indices[i][j] = indices_[i][j];
380  }
381  }
382  delete[] indices_.ptr();
383  return result;
384  }
385 
386 
395  int knnSearch(const Matrix<ElementType>& queries,
396  std::vector< std::vector<size_t> >& indices,
397  std::vector<std::vector<DistanceType> >& dists,
398  size_t knn,
399  const SearchParams& params) const
400  {
401  assert(queries.cols == veclen());
402  bool use_heap;
403  if (params.use_heap==FLANN_Undefined) {
404  use_heap = (knn>KNN_HEAP_THRESHOLD)?true:false;
405  }
406  else {
407  use_heap = (params.use_heap==FLANN_True)?true:false;
408  }
409 
410  if (indices.size() < queries.rows ) indices.resize(queries.rows);
411  if (dists.size() < queries.rows ) dists.resize(queries.rows);
412 
413  int count = 0;
414  if (use_heap) {
415 #pragma omp parallel num_threads(params.cores)
416  {
417  KNNResultSet2<DistanceType> resultSet(knn);
418 #pragma omp for schedule(dynamic) reduction(+:count)
419  for (int i = 0; i < (int)queries.rows; i++) {
420  resultSet.clear();
421  findNeighbors(resultSet, queries[i], params);
422  size_t n = std::min(resultSet.size(), knn);
423  indices[i].resize(n);
424  dists[i].resize(n);
425  if (n>0) {
426  resultSet.copy(&indices[i][0], &dists[i][0], n, params.sorted);
427  indices_to_ids(&indices[i][0], &indices[i][0], n);
428  }
429  count += n;
430  }
431  }
432  }
433  else {
434 #pragma omp parallel num_threads(params.cores)
435  {
436  KNNSimpleResultSet<DistanceType> resultSet(knn);
437 #pragma omp for schedule(dynamic) reduction(+:count)
438  for (int i = 0; i < (int)queries.rows; i++) {
439  resultSet.clear();
440  findNeighbors(resultSet, queries[i], params);
441  size_t n = std::min(resultSet.size(), knn);
442  indices[i].resize(n);
443  dists[i].resize(n);
444  if (n>0) {
445  resultSet.copy(&indices[i][0], &dists[i][0], n, params.sorted);
446  indices_to_ids(&indices[i][0], &indices[i][0], n);
447  }
448  count += n;
449  }
450  }
451  }
452 
453  return count;
454  }
455 
456 
466  int knnSearch(const Matrix<ElementType>& queries,
467  std::vector< std::vector<int> >& indices,
468  std::vector<std::vector<DistanceType> >& dists,
469  size_t knn,
470  const SearchParams& params) const
471  {
472  std::vector<std::vector<size_t> > indices_;
473  int result = knnSearch(queries, indices_, dists, knn, params);
474 
475  indices.resize(indices_.size());
476  for (size_t i=0;i<indices_.size();++i) {
477  indices[i].assign(indices_[i].begin(), indices_[i].end());
478  }
479  return result;
480  }
481 
491  int radiusSearch(const Matrix<ElementType>& queries,
492  Matrix<size_t>& indices,
493  Matrix<DistanceType>& dists,
494  float radius,
495  const SearchParams& params) const
496  {
497  assert(queries.cols == veclen());
498  int count = 0;
499  size_t num_neighbors = std::min(indices.cols, dists.cols);
500  int max_neighbors = params.max_neighbors;
501  if (max_neighbors<0) max_neighbors = num_neighbors;
502  else max_neighbors = std::min(max_neighbors,(int)num_neighbors);
503 
504  if (max_neighbors==0) {
505 #pragma omp parallel num_threads(params.cores)
506  {
507  CountRadiusResultSet<DistanceType> resultSet(radius);
508 #pragma omp for schedule(dynamic) reduction(+:count)
509  for (int i = 0; i < (int)queries.rows; i++) {
510  resultSet.clear();
511  findNeighbors(resultSet, queries[i], params);
512  count += resultSet.size();
513  }
514  }
515  }
516  else {
517  // explicitly indicated to use unbounded radius result set
518  // and we know there'll be enough room for resulting indices and dists
519  if (params.max_neighbors<0 && (num_neighbors>=size())) {
520 #pragma omp parallel num_threads(params.cores)
521  {
522  RadiusResultSet<DistanceType> resultSet(radius);
523 #pragma omp for schedule(dynamic) reduction(+:count)
524  for (int i = 0; i < (int)queries.rows; i++) {
525  resultSet.clear();
526  findNeighbors(resultSet, queries[i], params);
527  size_t n = resultSet.size();
528  count += n;
529  if (n>num_neighbors) n = num_neighbors;
530  resultSet.copy(indices[i], dists[i], n, params.sorted);
531 
532  // mark the next element in the output buffers as unused
533  if (n<indices.cols) indices[i][n] = size_t(-1);
534  if (n<dists.cols) dists[i][n] = std::numeric_limits<DistanceType>::infinity();
535  indices_to_ids(indices[i], indices[i], n);
536  }
537  }
538  }
539  else {
540  // number of neighbors limited to max_neighbors
541 #pragma omp parallel num_threads(params.cores)
542  {
543  KNNRadiusResultSet<DistanceType> resultSet(radius, max_neighbors);
544 #pragma omp for schedule(dynamic) reduction(+:count)
545  for (int i = 0; i < (int)queries.rows; i++) {
546  resultSet.clear();
547  findNeighbors(resultSet, queries[i], params);
548  size_t n = resultSet.size();
549  count += n;
550  if ((int)n>max_neighbors) n = max_neighbors;
551  resultSet.copy(indices[i], dists[i], n, params.sorted);
552 
553  // mark the next element in the output buffers as unused
554  if (n<indices.cols) indices[i][n] = size_t(-1);
555  if (n<dists.cols) dists[i][n] = std::numeric_limits<DistanceType>::infinity();
556  indices_to_ids(indices[i], indices[i], n);
557  }
558  }
559  }
560  }
561  return count;
562  }
563 
564 
574  int radiusSearch(const Matrix<ElementType>& queries,
575  Matrix<int>& indices,
576  Matrix<DistanceType>& dists,
577  float radius,
578  const SearchParams& params) const
579  {
580  flann::Matrix<size_t> indices_(new size_t[indices.rows*indices.cols], indices.rows, indices.cols);
581  int result = radiusSearch(queries, indices_, dists, radius, params);
582 
583  for (size_t i=0;i<indices.rows;++i) {
584  for (size_t j=0;j<indices.cols;++j) {
585  indices[i][j] = indices_[i][j];
586  }
587  }
588  delete[] indices_.ptr();
589  return result;
590  }
591 
601  int radiusSearch(const Matrix<ElementType>& queries,
602  std::vector< std::vector<size_t> >& indices,
603  std::vector<std::vector<DistanceType> >& dists,
604  float radius,
605  const SearchParams& params) const
606  {
607  assert(queries.cols == veclen());
608  int count = 0;
609  // just count neighbors
610  if (params.max_neighbors==0) {
611 #pragma omp parallel num_threads(params.cores)
612  {
613  CountRadiusResultSet<DistanceType> resultSet(radius);
614 #pragma omp for schedule(dynamic) reduction(+:count)
615  for (int i = 0; i < (int)queries.rows; i++) {
616  resultSet.clear();
617  findNeighbors(resultSet, queries[i], params);
618  count += resultSet.size();
619  }
620  }
621  }
622  else {
623  if (indices.size() < queries.rows ) indices.resize(queries.rows);
624  if (dists.size() < queries.rows ) dists.resize(queries.rows);
625 
626  if (params.max_neighbors<0) {
627  // search for all neighbors
628 #pragma omp parallel num_threads(params.cores)
629  {
630  RadiusResultSet<DistanceType> resultSet(radius);
631 #pragma omp for schedule(dynamic) reduction(+:count)
632  for (int i = 0; i < (int)queries.rows; i++) {
633  resultSet.clear();
634  findNeighbors(resultSet, queries[i], params);
635  size_t n = resultSet.size();
636  count += n;
637  indices[i].resize(n);
638  dists[i].resize(n);
639  if (n > 0) {
640  resultSet.copy(&indices[i][0], &dists[i][0], n, params.sorted);
641  indices_to_ids(&indices[i][0], &indices[i][0], n);
642  }
643  }
644  }
645  }
646  else {
647  // number of neighbors limited to max_neighbors
648 #pragma omp parallel num_threads(params.cores)
649  {
650  KNNRadiusResultSet<DistanceType> resultSet(radius, params.max_neighbors);
651 #pragma omp for schedule(dynamic) reduction(+:count)
652  for (int i = 0; i < (int)queries.rows; i++) {
653  resultSet.clear();
654  findNeighbors(resultSet, queries[i], params);
655  size_t n = resultSet.size();
656  count += n;
657  if ((int)n>params.max_neighbors) n = params.max_neighbors;
658  indices[i].resize(n);
659  dists[i].resize(n);
660  if (n > 0) {
661  resultSet.copy(&indices[i][0], &dists[i][0], n, params.sorted);
662  indices_to_ids(&indices[i][0], &indices[i][0], n);
663  }
664  }
665  }
666  }
667  }
668  return count;
669  }
670 
680  int radiusSearch(const Matrix<ElementType>& queries,
681  std::vector< std::vector<int> >& indices,
682  std::vector<std::vector<DistanceType> >& dists,
683  float radius,
684  const SearchParams& params) const
685  {
686  std::vector<std::vector<size_t> > indices_;
687  int result = radiusSearch(queries, indices_, dists, radius, params);
688 
689  indices.resize(indices_.size());
690  for (size_t i=0;i<indices_.size();++i) {
691  indices[i].assign(indices_[i].begin(), indices_[i].end());
692  }
693  return result;
694  }
695 
696 
697  virtual void findNeighbors(ResultSet<DistanceType>& result, const ElementType* vec, const SearchParams& searchParams) const = 0;
698 
699 protected:
700 
701  virtual void freeIndex() = 0;
702 
703  virtual void buildIndexImpl() = 0;
704 
705  size_t id_to_index(size_t id)
706  {
707  if (ids_.size()==0) {
708  return id;
709  }
710  size_t point_index = size_t(-1);
711  if (id < ids_.size() && ids_[id]==id) {
712  return id;
713  }
714  else {
715  // binary search
716  size_t start = 0;
717  size_t end = ids_.size();
718 
719  while (start<end) {
720  size_t mid = (start+end)/2;
721  if (ids_[mid]==id) {
722  point_index = mid;
723  break;
724  }
725  else if (ids_[mid]<id) {
726  start = mid + 1;
727  }
728  else {
729  end = mid;
730  }
731  }
732  }
733  return point_index;
734  }
735 
736 
737  void indices_to_ids(const size_t* in, size_t* out, size_t size) const
738  {
739  if (removed_) {
740  for (size_t i=0;i<size;++i) {
741  out[i] = ids_[in[i]];
742  }
743  }
744  }
745 
746  void setDataset(const Matrix<ElementType>& dataset)
747  {
748  size_ = dataset.rows;
749  veclen_ = dataset.cols;
750  last_id_ = 0;
751 
752  ids_.clear();
754  removed_ = false;
755  removed_count_ = 0;
756 
757  points_.resize(size_);
758  for (size_t i=0;i<size_;++i) {
759  points_[i] = dataset[i];
760  }
761  }
762 
763  void extendDataset(const Matrix<ElementType>& new_points)
764  {
765  size_t new_size = size_ + new_points.rows;
766  if (removed_) {
767  removed_points_.resize(new_size);
768  ids_.resize(new_size);
769  }
770  points_.resize(new_size);
771  for (size_t i=size_;i<new_size;++i) {
772  points_[i] = new_points[i-size_];
773  if (removed_) {
774  ids_[i] = last_id_++;
776  }
777  }
778  size_ = new_size;
779  }
780 
781 
783  {
784  if (!removed_) return;
785 
786  size_t last_idx = 0;
787  for (size_t i=0;i<size_;++i) {
788  if (!removed_points_.test(i)) {
789  points_[last_idx] = points_[i];
790  ids_[last_idx] = ids_[i];
791  removed_points_.reset(last_idx);
792  ++last_idx;
793  }
794  }
795  points_.resize(last_idx);
796  ids_.resize(last_idx);
797  removed_points_.resize(last_idx);
798  size_ = last_idx;
799  removed_count_ = 0;
800  }
801 
802  void swap(NNIndex& other)
803  {
804  std::swap(distance_, other.distance_);
805  std::swap(last_id_, other.last_id_);
806  std::swap(size_, other.size_);
808  std::swap(veclen_, other.veclen_);
810  std::swap(removed_, other.removed_);
813  std::swap(ids_, other.ids_);
814  std::swap(points_, other.points_);
815  std::swap(data_ptr_, other.data_ptr_);
816  }
817 
818 protected:
819 
824 
825 
831  size_t last_id_;
832 
836  size_t size_;
837 
842 
846  size_t veclen_;
847 
852 
856  bool removed_;
857 
862 
867 
871  std::vector<size_t> ids_;
872 
876  std::vector<ElementType*> points_;
877 
882 
883 
884 };
885 
886 
887 #define USING_BASECLASS_SYMBOLS \
888  using NNIndex<Distance>::distance_;\
889  using NNIndex<Distance>::size_;\
890  using NNIndex<Distance>::size_at_build_;\
891  using NNIndex<Distance>::veclen_;\
892  using NNIndex<Distance>::index_params_;\
893  using NNIndex<Distance>::removed_points_;\
894  using NNIndex<Distance>::ids_;\
895  using NNIndex<Distance>::removed_;\
896  using NNIndex<Distance>::points_;\
897  using NNIndex<Distance>::extendDataset;\
898  using NNIndex<Distance>::setDataset;\
899  using NNIndex<Distance>::cleanRemovedPoints;\
900  using NNIndex<Distance>::indices_to_ids;
901 
902 
903 
904 }
905 
906 
907 #endif //FLANN_NNINDEX_H
int count
int points
double Distance(const Point3D< Real > &p1, const Point3D< Real > &p2)
cmdLineReadable * params[]
#define NULL
core::Tensor result
Definition: VtkUtils.cpp:76
bool copy
Definition: VtkUtils.cpp:74
void set(size_t index)
bool test(size_t index) const
void resize(size_t size)
virtual ~IndexBase()
Definition: nn_index.h:52
virtual size_t veclen() const =0
virtual int usedMemory() const =0
virtual IndexParams getParameters() const =0
virtual void saveIndex(FILE *stream)=0
virtual void loadIndex(FILE *stream)=0
virtual size_t size() const =0
virtual flann_algorithm_t getType() const =0
void copy(size_t *indices, DistanceType *dists, size_t num_elements, bool sorted=true)
Definition: result_set.h:612
void copy(size_t *indices, DistanceType *dists, size_t num_elements, bool sorted=true)
Definition: result_set.h:388
size_t size() const
Definition: result_set.h:335
void copy(size_t *indices, DistanceType *dists, size_t num_elements, bool sorted=true)
Definition: result_set.h:180
size_t cols
Definition: matrix.h:73
size_t rows
Definition: matrix.h:72
T * ptr() const
Definition: matrix.h:127
virtual void buildIndexImpl()=0
std::vector< size_t > ids_
Definition: nn_index.h:871
virtual int knnSearch(const Matrix< ElementType > &queries, Matrix< size_t > &indices, Matrix< DistanceType > &dists, size_t knn, const SearchParams &params) const
Perform k-nearest neighbor search.
Definition: nn_index.h:305
virtual void removePoint(size_t id)
Definition: nn_index.h:161
size_t veclen() const
Definition: nn_index.h:209
void indices_to_ids(const size_t *in, size_t *out, size_t size) const
Definition: nn_index.h:737
NNIndex(const NNIndex &other)
Definition: nn_index.h:89
std::vector< ElementType * > points_
Definition: nn_index.h:876
int radiusSearch(const Matrix< ElementType > &queries, Matrix< size_t > &indices, Matrix< DistanceType > &dists, float radius, const SearchParams &params) const
Perform radius search.
Definition: nn_index.h:491
int radiusSearch(const Matrix< ElementType > &queries, std::vector< std::vector< size_t > > &indices, std::vector< std::vector< DistanceType > > &dists, float radius, const SearchParams &params) const
Perform radius search.
Definition: nn_index.h:601
NNIndex(const IndexParams &params, Distance d)
Definition: nn_index.h:84
Distance::ElementType ElementType
Definition: nn_index.h:76
virtual void addPoints(const Matrix< ElementType > &points, float rebuild_threshold=2)
Incrementally add points to the index.
Definition: nn_index.h:152
size_t veclen_
Definition: nn_index.h:846
virtual void buildIndex(const Matrix< ElementType > &dataset)
Definition: nn_index.h:141
void serialize(Archive &ar)
Definition: nn_index.h:226
void swap(NNIndex &other)
Definition: nn_index.h:802
size_t removed_count_
Definition: nn_index.h:866
int radiusSearch(const Matrix< ElementType > &queries, Matrix< int > &indices, Matrix< DistanceType > &dists, float radius, const SearchParams &params) const
Definition: nn_index.h:574
int knnSearch(const Matrix< ElementType > &queries, std::vector< std::vector< size_t > > &indices, std::vector< std::vector< DistanceType > > &dists, size_t knn, const SearchParams &params) const
Perform k-nearest neighbor search.
Definition: nn_index.h:395
size_t last_id_
Definition: nn_index.h:831
Distance::ResultType DistanceType
Definition: nn_index.h:77
size_t size() const
Definition: nn_index.h:201
IndexParams getParameters() const
Definition: nn_index.h:219
DynamicBitset removed_points_
Definition: nn_index.h:861
NNIndex(Distance d)
Definition: nn_index.h:79
virtual ElementType * getPoint(size_t id)
Definition: nn_index.h:187
int radiusSearch(const Matrix< ElementType > &queries, std::vector< std::vector< int > > &indices, std::vector< std::vector< DistanceType > > &dists, float radius, const SearchParams &params) const
Definition: nn_index.h:680
size_t size_
Definition: nn_index.h:836
void cleanRemovedPoints()
Definition: nn_index.h:782
int knnSearch(const Matrix< ElementType > &queries, std::vector< std::vector< int > > &indices, std::vector< std::vector< DistanceType > > &dists, size_t knn, const SearchParams &params) const
Definition: nn_index.h:466
virtual void freeIndex()=0
ElementType * data_ptr_
Definition: nn_index.h:881
void setDataset(const Matrix< ElementType > &dataset)
Definition: nn_index.h:746
Distance distance_
Definition: nn_index.h:823
virtual ~NNIndex()
Definition: nn_index.h:112
virtual void buildIndex()
Definition: nn_index.h:125
int knnSearch(const Matrix< ElementType > &queries, Matrix< int > &indices, Matrix< DistanceType > &dists, size_t knn, const SearchParams &params) const
Definition: nn_index.h:368
void extendDataset(const Matrix< ElementType > &new_points)
Definition: nn_index.h:763
virtual void findNeighbors(ResultSet< DistanceType > &result, const ElementType *vec, const SearchParams &searchParams) const =0
IndexParams index_params_
Definition: nn_index.h:851
size_t id_to_index(size_t id)
Definition: nn_index.h:705
virtual NNIndex * clone() const =0
size_t size_at_build_
Definition: nn_index.h:841
size_t size() const
Definition: result_set.h:455
void copy(size_t *indices, DistanceType *dists, size_t num_elements, bool sorted=true)
Definition: result_set.h:490
__device__ __forceinline__ float infinity()
Definition: result_set.h:36
int min(int a, int b)
Definition: cutil_math.h:53
flann_algorithm_t
Definition: defines.h:80
const binary_object make_binary_object(void *t, size_t size)
T get_param(const IndexParams &params, std::string name, const T &default_value)
Definition: params.h:95
@ FLANN_True
Definition: params.h:56
@ FLANN_Undefined
Definition: params.h:57
std::map< std::string, any > IndexParams
Definition: params.h:51
void swap(cloudViewer::core::SmallVectorImpl< T > &LHS, cloudViewer::core::SmallVectorImpl< T > &RHS)
Implement std::swap in terms of SmallVector swap.
Definition: SmallVector.h:1370
#define KNN_HEAP_THRESHOLD
Definition: nn_index.h:46
#define FLANN_SIGNATURE_
Definition: saving.h:43
flann_algorithm_t index_type
Definition: serialization.h:19
flann_datatype_t data_type
Definition: serialization.h:18
IndexHeaderStruct h
Definition: saving.h:53