gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
nanoflann.hpp
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  * Copyright 2011-2016 Jose Luis Blanco (joseluisblancoc@gmail.com).
7  * All rights reserved.
8  *
9  * THE BSD LICENSE
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  *
15  * 1. Redistributions of source code must retain the above copyright
16  * notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  * notice, this list of conditions and the following disclaimer in the
19  * documentation and/or other materials provided with the distribution.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *************************************************************************/
32 
46 #ifndef NANOFLANN_HPP_
47 #define NANOFLANN_HPP_
48 
49 #include <vector>
50 #include <cassert>
51 #include <algorithm>
52 #include <stdexcept>
53 #include <cstdio> // for fwrite()
54 #include <cmath> // for abs()
55 #include <cstdlib> // for abs()
56 #include <limits>
57 
58 // Avoid conflicting declaration of min/max macros in windows headers
59 #if !defined(NOMINMAX) && (defined(_WIN32) || defined(_WIN32_) || defined(WIN32) || defined(_WIN64))
60 # define NOMINMAX
61 # ifdef max
62 # undef max
63 # undef min
64 # endif
65 #endif
66 
67 namespace nanoflann
68 {
73  #define NANOFLANN_VERSION 0x123
74 
77  template <typename DistanceType, typename IndexType = size_t, typename CountType = size_t>
79  {
80  IndexType * indices;
81  DistanceType* dists;
82  CountType capacity;
83  CountType count;
84 
85  public:
86  inline KNNResultSet(CountType capacity_) : indices(0), dists(0), capacity(capacity_), count(0)
87  {
88  }
89 
90  inline void init(IndexType* indices_, DistanceType* dists_)
91  {
92  indices = indices_;
93  dists = dists_;
94  count = 0;
95  if (capacity)
96  dists[capacity-1] = (std::numeric_limits<DistanceType>::max)();
97  }
98 
99  inline CountType size() const
100  {
101  return count;
102  }
103 
104  inline bool full() const
105  {
106  return count == capacity;
107  }
108 
109 
114  inline bool addPoint(DistanceType dist, IndexType index)
115  {
116  CountType i;
117  for (i=count; i>0; --i) {
118 #ifdef NANOFLANN_FIRST_MATCH // If defined and two points have the same distance, the one with the lowest-index will be returned first.
119  if ( (dists[i-1]>dist) || ((dist==dists[i-1])&&(indices[i-1]>index)) ) {
120 #else
121  if (dists[i-1]>dist) {
122 #endif
123  if (i<capacity) {
124  dists[i] = dists[i-1];
125  indices[i] = indices[i-1];
126  }
127  }
128  else break;
129  }
130  if (i<capacity) {
131  dists[i] = dist;
132  indices[i] = index;
133  }
134  if (count<capacity) count++;
135 
136  // tell caller that the search shall continue
137  return true;
138  }
139 
140  inline DistanceType worstDist() const
141  {
142  return dists[capacity-1];
143  }
144  };
145 
148  {
150  template <typename PairType>
151  inline bool operator()(const PairType &p1, const PairType &p2) const {
152  return p1.second < p2.second;
153  }
154  };
155 
159  template <typename DistanceType, typename IndexType = size_t>
161  {
162  public:
163  const DistanceType radius;
164 
165  std::vector<std::pair<IndexType,DistanceType> >& m_indices_dists;
166 
167  inline RadiusResultSet(DistanceType radius_, std::vector<std::pair<IndexType,DistanceType> >& indices_dists) : radius(radius_), m_indices_dists(indices_dists)
168  {
169  init();
170  }
171 
172  inline ~RadiusResultSet() { }
173 
174  inline void init() { clear(); }
175  inline void clear() { m_indices_dists.clear(); }
176 
177  inline size_t size() const { return m_indices_dists.size(); }
178 
179  inline bool full() const { return true; }
180 
185  inline bool addPoint(DistanceType dist, IndexType index)
186  {
187  if (dist<radius)
188  m_indices_dists.push_back(std::make_pair(index,dist));
189  return true;
190  }
191 
192  inline DistanceType worstDist() const { return radius; }
193 
198  std::pair<IndexType,DistanceType> worst_item() const
199  {
200  if (m_indices_dists.empty()) throw std::runtime_error("Cannot invoke RadiusResultSet::worst_item() on an empty list of results.");
201  typedef typename std::vector<std::pair<IndexType,DistanceType> >::const_iterator DistIt;
202  DistIt it = std::max_element(m_indices_dists.begin(), m_indices_dists.end(), IndexDist_Sorter());
203  return *it;
204  }
205  };
206 
207 
213  template<typename T>
214  void save_value(FILE* stream, const T& value, size_t count = 1)
215  {
216  fwrite(&value, sizeof(value),count, stream);
217  }
218 
219  template<typename T>
220  void save_value(FILE* stream, const std::vector<T>& value)
221  {
222  size_t size = value.size();
223  fwrite(&size, sizeof(size_t), 1, stream);
224  fwrite(&value[0], sizeof(T), size, stream);
225  }
226 
227  template<typename T>
228  void load_value(FILE* stream, T& value, size_t count = 1)
229  {
230  size_t read_cnt = fread(&value, sizeof(value), count, stream);
231  if (read_cnt != count) {
232  throw std::runtime_error("Cannot read from file");
233  }
234  }
235 
236 
237  template<typename T>
238  void load_value(FILE* stream, std::vector<T>& value)
239  {
240  size_t size;
241  size_t read_cnt = fread(&size, sizeof(size_t), 1, stream);
242  if (read_cnt!=1) {
243  throw std::runtime_error("Cannot read from file");
244  }
245  value.resize(size);
246  read_cnt = fread(&value[0], sizeof(T), size, stream);
247  if (read_cnt!=size) {
248  throw std::runtime_error("Cannot read from file");
249  }
250  }
262  template<class T, class DataSource, typename _DistanceType = T>
263  struct L1_Adaptor
264  {
265  typedef T ElementType;
266  typedef _DistanceType DistanceType;
267 
268  const DataSource &data_source;
269 
270  L1_Adaptor(const DataSource &_data_source) : data_source(_data_source) { }
271 
272  inline DistanceType operator()(const T* a, const size_t b_idx, size_t size, DistanceType worst_dist = -1) const
273  {
274  DistanceType result = DistanceType();
275  const T* last = a + size;
276  const T* lastgroup = last - 3;
277  size_t d = 0;
278 
279  /* Process 4 items with each loop for efficiency. */
280  while (a < lastgroup) {
281  const DistanceType diff0 = std::abs(a[0] - data_source.kdtree_get_pt(b_idx,d++));
282  const DistanceType diff1 = std::abs(a[1] - data_source.kdtree_get_pt(b_idx,d++));
283  const DistanceType diff2 = std::abs(a[2] - data_source.kdtree_get_pt(b_idx,d++));
284  const DistanceType diff3 = std::abs(a[3] - data_source.kdtree_get_pt(b_idx,d++));
285  result += diff0 + diff1 + diff2 + diff3;
286  a += 4;
287  if ((worst_dist>0)&&(result>worst_dist)) {
288  return result;
289  }
290  }
291  /* Process last 0-3 components. Not needed for standard vector lengths. */
292  while (a < last) {
293  result += std::abs( *a++ - data_source.kdtree_get_pt(b_idx,d++) );
294  }
295  return result;
296  }
297 
298  template <typename U, typename V>
299  inline DistanceType accum_dist(const U a, const V b, int ) const
300  {
301  return std::abs(a-b);
302  }
303  };
304 
310  template<class T, class DataSource, typename _DistanceType = T>
311  struct L2_Adaptor
312  {
313  typedef T ElementType;
314  typedef _DistanceType DistanceType;
315 
316  const DataSource &data_source;
317 
318  L2_Adaptor(const DataSource &_data_source) : data_source(_data_source) { }
319 
320  inline DistanceType operator()(const T* a, const size_t b_idx, size_t size, DistanceType worst_dist = -1) const
321  {
322  DistanceType result = DistanceType();
323  const T* last = a + size;
324  const T* lastgroup = last - 3;
325  size_t d = 0;
326 
327  /* Process 4 items with each loop for efficiency. */
328  while (a < lastgroup) {
329  const DistanceType diff0 = a[0] - data_source.kdtree_get_pt(b_idx,d++);
330  const DistanceType diff1 = a[1] - data_source.kdtree_get_pt(b_idx,d++);
331  const DistanceType diff2 = a[2] - data_source.kdtree_get_pt(b_idx,d++);
332  const DistanceType diff3 = a[3] - data_source.kdtree_get_pt(b_idx,d++);
333  result += diff0 * diff0 + diff1 * diff1 + diff2 * diff2 + diff3 * diff3;
334  a += 4;
335  if ((worst_dist>0)&&(result>worst_dist)) {
336  return result;
337  }
338  }
339  /* Process last 0-3 components. Not needed for standard vector lengths. */
340  while (a < last) {
341  const DistanceType diff0 = *a++ - data_source.kdtree_get_pt(b_idx,d++);
342  result += diff0 * diff0;
343  }
344  return result;
345  }
346 
347  template <typename U, typename V>
348  inline DistanceType accum_dist(const U a, const V b, int ) const
349  {
350  return (a-b)*(a-b);
351  }
352  };
353 
359  template<class T, class DataSource, typename _DistanceType = T>
361  {
362  typedef T ElementType;
363  typedef _DistanceType DistanceType;
364 
365  const DataSource &data_source;
366 
367  L2_Simple_Adaptor(const DataSource &_data_source) : data_source(_data_source) { }
368 
369  inline DistanceType operator()(const T* a, const size_t b_idx, size_t size) const {
370  return data_source.kdtree_distance(a,b_idx,size);
371  }
372 
373  template <typename U, typename V>
374  inline DistanceType accum_dist(const U a, const V b, int ) const
375  {
376  return (a-b)*(a-b);
377  }
378  };
379 
381  struct metric_L1 {
382  template<class T, class DataSource>
383  struct traits {
385  };
386  };
388  struct metric_L2 {
389  template<class T, class DataSource>
390  struct traits {
392  };
393  };
396  template<class T, class DataSource>
397  struct traits {
399  };
400  };
401 
409  {
410  KDTreeSingleIndexAdaptorParams(size_t _leaf_max_size = 10) :
411  leaf_max_size(_leaf_max_size)
412  {}
413 
415  };
416 
419  {
421  SearchParams(int checks_IGNORED_ = 32, float eps_ = 0, bool sorted_ = true ) :
422  checks(checks_IGNORED_), eps(eps_), sorted(sorted_) {}
423 
424  int checks;
425  float eps;
426  bool sorted;
427  };
441  template <typename T>
442  inline T* allocate(size_t count = 1)
443  {
444  T* mem = static_cast<T*>( ::malloc(sizeof(T)*count));
445  return mem;
446  }
447 
448 
464  const size_t WORDSIZE=16;
465  const size_t BLOCKSIZE=8192;
466 
468  {
469  /* We maintain memory alignment to word boundaries by requiring that all
470  allocations be in multiples of the machine wordsize. */
471  /* Size of machine word in bytes. Must be power of 2. */
472  /* Minimum number of bytes requested at a time from the system. Must be multiple of WORDSIZE. */
473 
474 
475  size_t remaining; /* Number of bytes left in current block of storage. */
476  void* base; /* Pointer to base of current block of storage. */
477  void* loc; /* Current location in block to next allocate memory. */
478 
480  {
481  remaining = 0;
482  base = NULL;
483  usedMemory = 0;
484  wastedMemory = 0;
485  }
486 
487  public:
488  size_t usedMemory;
489  size_t wastedMemory;
490 
495  internal_init();
496  }
497 
502  free_all();
503  }
504 
506  void free_all()
507  {
508  while (base != NULL) {
509  void *prev = *(static_cast<void**>( base)); /* Get pointer to prev block. */
510  ::free(base);
511  base = prev;
512  }
513  internal_init();
514  }
515 
520  void* malloc(const size_t req_size)
521  {
522  /* Round size up to a multiple of wordsize. The following expression
523  only works for WORDSIZE that is a power of 2, by masking last bits of
524  incremented size to zero.
525  */
526  const size_t size = (req_size + (WORDSIZE - 1)) & ~(WORDSIZE - 1);
527 
528  /* Check whether a new block must be allocated. Note that the first word
529  of a block is reserved for a pointer to the previous block.
530  */
531  if (size > remaining) {
532 
533  wastedMemory += remaining;
534 
535  /* Allocate new storage. */
536  const size_t blocksize = (size + sizeof(void*) + (WORDSIZE-1) > BLOCKSIZE) ?
537  size + sizeof(void*) + (WORDSIZE-1) : BLOCKSIZE;
538 
539  // use the standard C malloc to allocate memory
540  void* m = ::malloc(blocksize);
541  if (!m) {
542  fprintf(stderr,"Failed to allocate memory.\n");
543  return NULL;
544  }
545 
546  /* Fill first word of new block with pointer to previous block. */
547  static_cast<void**>(m)[0] = base;
548  base = m;
549 
550  size_t shift = 0;
551  //int size_t = (WORDSIZE - ( (((size_t)m) + sizeof(void*)) & (WORDSIZE-1))) & (WORDSIZE-1);
552 
553  remaining = blocksize - sizeof(void*) - shift;
554  loc = (static_cast<char*>(m) + sizeof(void*) + shift);
555  }
556  void* rloc = loc;
557  loc = static_cast<char*>(loc) + size;
558  remaining -= size;
559 
560  usedMemory += size;
561 
562  return rloc;
563  }
564 
572  template <typename T>
573  T* allocate(const size_t count = 1)
574  {
575  T* mem = static_cast<T*>(this->malloc(sizeof(T)*count));
576  return mem;
577  }
578 
579  };
585  // ---------------- CArray -------------------------
611  template <typename T, std::size_t N>
612  class CArray {
613  public:
614  T elems[N]; // fixed-size array of elements of type T
615 
616  public:
617  // type definitions
618  typedef T value_type;
619  typedef T* iterator;
620  typedef const T* const_iterator;
621  typedef T& reference;
622  typedef const T& const_reference;
623  typedef std::size_t size_type;
624  typedef std::ptrdiff_t difference_type;
625 
626  // iterator support
627  inline iterator begin() { return elems; }
628  inline const_iterator begin() const { return elems; }
629  inline iterator end() { return elems+N; }
630  inline const_iterator end() const { return elems+N; }
631 
632  // reverse iterator support
633 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
634  typedef std::reverse_iterator<iterator> reverse_iterator;
635  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
636 #elif defined(_MSC_VER) && (_MSC_VER == 1300) && defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB == 310)
637  // workaround for broken reverse_iterator in VC7
638  typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, iterator,
640  typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, const_iterator,
642 #else
643  // workaround for broken reverse_iterator implementations
644  typedef std::reverse_iterator<iterator,T> reverse_iterator;
645  typedef std::reverse_iterator<const_iterator,T> const_reverse_iterator;
646 #endif
647 
650  reverse_iterator rend() { return reverse_iterator(begin()); }
652  // operator[]
653  inline reference operator[](size_type i) { return elems[i]; }
654  inline const_reference operator[](size_type i) const { return elems[i]; }
655  // at() with range check
656  reference at(size_type i) { rangecheck(i); return elems[i]; }
657  const_reference at(size_type i) const { rangecheck(i); return elems[i]; }
658  // front() and back()
659  reference front() { return elems[0]; }
660  const_reference front() const { return elems[0]; }
661  reference back() { return elems[N-1]; }
662  const_reference back() const { return elems[N-1]; }
663  // size is constant
664  static inline size_type size() { return N; }
665  static bool empty() { return false; }
666  static size_type max_size() { return N; }
667  enum { static_size = N };
669  inline void resize(const size_t nElements) { if (nElements!=N) throw std::logic_error("Try to change the size of a CArray."); }
670  // swap (note: linear complexity in N, constant for given instantiation)
671  void swap (CArray<T,N>& y) { std::swap_ranges(begin(),end(),y.begin()); }
672  // direct access to data (read-only)
673  const T* data() const { return elems; }
674  // use array as C array (direct read/write access to data)
675  T* data() { return elems; }
676  // assignment with type conversion
677  template <typename T2> CArray<T,N>& operator= (const CArray<T2,N>& rhs) {
678  std::copy(rhs.begin(),rhs.end(), begin());
679  return *this;
680  }
681  // assign one value to all elements
682  inline void assign (const T& value) { for (size_t i=0;i<N;i++) elems[i]=value; }
683  // assign (compatible with std::vector's one) (by JLBC for MRPT)
684  void assign (const size_t n, const T& value) { assert(N==n); for (size_t i=0;i<N;i++) elems[i]=value; }
685  private:
686  // check range (may be private because it is static)
687  static void rangecheck (size_type i) { if (i >= size()) { throw std::out_of_range("CArray<>: index out of range"); } }
688  }; // end of CArray
689 
693  template <int DIM, typename T>
695  {
697  };
699  template <typename T>
701  typedef std::vector<T> container_t;
702  };
744  template <typename Distance, class DatasetAdaptor,int DIM = -1, typename IndexType = size_t>
746  {
747  private:
750  public:
751  typedef typename Distance::ElementType ElementType;
752  typedef typename Distance::DistanceType DistanceType;
753  protected:
754 
758  std::vector<IndexType> vind;
759 
761 
762 
766  const DatasetAdaptor &dataset;
767 
769 
770  size_t m_size;
772  int dim;
773 
774 
775  /*--------------------- Internal Data Structures --------------------------*/
776  struct Node
777  {
779  union {
780  struct leaf
781  {
782  IndexType left, right;
783  } lr;
784  struct nonleaf
785  {
786  int divfeat;
787  DistanceType divlow, divhigh;
788  } sub;
789  } node_type;
790  Node* child1, * child2;
791  };
792  typedef Node* NodePtr;
793 
794 
795  struct Interval
796  {
798  };
799 
802 
805 
809 
818 
819  public:
820 
821  Distance distance;
822 
836  KDTreeSingleIndexAdaptor(const int dimensionality, const DatasetAdaptor& inputData, const KDTreeSingleIndexAdaptorParams& params = KDTreeSingleIndexAdaptorParams() ) :
837  dataset(inputData), index_params(params), root_node(NULL), distance(inputData)
838  {
839  m_size = dataset.kdtree_get_point_count();
840  m_size_at_index_build = m_size;
841  dim = dimensionality;
842  if (DIM>0) dim=DIM;
843  m_leaf_max_size = params.leaf_max_size;
844 
845  // Create a permutable array of indices to the input vectors.
846  init_vind();
847  }
848 
851 
853  void freeIndex()
854  {
855  pool.free_all();
856  root_node=NULL;
857  m_size_at_index_build = 0;
858  }
859 
863  void buildIndex()
864  {
865  init_vind();
866  freeIndex();
867  m_size_at_index_build = m_size;
868  if(m_size == 0) return;
869  computeBoundingBox(root_bbox);
870  root_node = divideTree(0, m_size, root_bbox ); // construct the tree
871  }
872 
874  size_t size() const { return m_size; }
875 
877  size_t veclen() const {
878  return static_cast<size_t>(DIM>0 ? DIM : dim);
879  }
880 
885  size_t usedMemory() const
886  {
887  return pool.usedMemory+pool.wastedMemory+dataset.kdtree_get_point_count()*sizeof(IndexType); // pool memory and vind array memory
888  }
889 
905  template <typename RESULTSET>
906  bool findNeighbors(RESULTSET& result, const ElementType* vec, const SearchParams& searchParams) const
907  {
908  assert(vec);
909  if (size() == 0)
910  return false;
911  if (!root_node)
912  throw std::runtime_error("[nanoflann] findNeighbors() called before building the index.");
913  float epsError = 1+searchParams.eps;
914 
915  distance_vector_t dists; // fixed or variable-sized container (depending on DIM)
916  dists.assign((DIM>0 ? DIM : dim) ,0); // Fill it with zeros.
917  DistanceType distsq = computeInitialDistances(vec, dists);
918  searchLevel(result, vec, root_node, distsq, dists, epsError); // "count_leaf" parameter removed since was neither used nor returned to the user.
919  return result.full();
920  }
921 
930  size_t knnSearch(const ElementType *query_point, const size_t num_closest, IndexType *out_indices, DistanceType *out_distances_sq, const int /* nChecks_IGNORED */ = 10) const
931  {
933  resultSet.init(out_indices, out_distances_sq);
934  this->findNeighbors(resultSet, query_point, nanoflann::SearchParams());
935  return resultSet.size();
936  }
937 
950  size_t radiusSearch(const ElementType *query_point,const DistanceType &radius, std::vector<std::pair<IndexType,DistanceType> >& IndicesDists, const SearchParams& searchParams) const
951  {
952  RadiusResultSet<DistanceType,IndexType> resultSet(radius,IndicesDists);
953  const size_t nFound = radiusSearchCustomCallback(query_point,resultSet,searchParams);
954  if (searchParams.sorted)
955  std::sort(IndicesDists.begin(),IndicesDists.end(), IndexDist_Sorter() );
956  return nFound;
957  }
958 
964  template <class SEARCH_CALLBACK>
965  size_t radiusSearchCustomCallback(const ElementType *query_point,SEARCH_CALLBACK &resultSet, const SearchParams& searchParams = SearchParams() ) const
966  {
967  this->findNeighbors(resultSet, query_point, searchParams);
968  return resultSet.size();
969  }
970 
973  private:
975  void init_vind()
976  {
977  // Create a permutable array of indices to the input vectors.
978  m_size = dataset.kdtree_get_point_count();
979  if (vind.size()!=m_size) vind.resize(m_size);
980  for (size_t i = 0; i < m_size; i++) vind[i] = i;
981  }
982 
984  inline ElementType dataset_get(size_t idx, int component) const {
985  return dataset.kdtree_get_pt(idx,component);
986  }
987 
988 
989  void save_tree(FILE* stream, NodePtr tree)
990  {
991  save_value(stream, *tree);
992  if (tree->child1!=NULL) {
993  save_tree(stream, tree->child1);
994  }
995  if (tree->child2!=NULL) {
996  save_tree(stream, tree->child2);
997  }
998  }
999 
1000 
1001  void load_tree(FILE* stream, NodePtr& tree)
1002  {
1003  tree = pool.allocate<Node>();
1004  load_value(stream, *tree);
1005  if (tree->child1!=NULL) {
1006  load_tree(stream, tree->child1);
1007  }
1008  if (tree->child2!=NULL) {
1009  load_tree(stream, tree->child2);
1010  }
1011  }
1012 
1013 
1015  {
1016  bbox.resize((DIM>0 ? DIM : dim));
1017  if (dataset.kdtree_get_bbox(bbox))
1018  {
1019  // Done! It was implemented in derived class
1020  }
1021  else
1022  {
1023  const size_t N = dataset.kdtree_get_point_count();
1024  if (!N) throw std::runtime_error("[nanoflann] computeBoundingBox() called but no data points found.");
1025  for (int i=0; i<(DIM>0 ? DIM : dim); ++i) {
1026  bbox[i].low =
1027  bbox[i].high = dataset_get(0,i);
1028  }
1029  for (size_t k=1; k<N; ++k) {
1030  for (int i=0; i<(DIM>0 ? DIM : dim); ++i) {
1031  if (dataset_get(k,i)<bbox[i].low) bbox[i].low = dataset_get(k,i);
1032  if (dataset_get(k,i)>bbox[i].high) bbox[i].high = dataset_get(k,i);
1033  }
1034  }
1035  }
1036  }
1037 
1038 
1046  NodePtr divideTree(const IndexType left, const IndexType right, BoundingBox& bbox)
1047  {
1048  NodePtr node = pool.allocate<Node>(); // allocate memory
1049 
1050  /* If too few exemplars remain, then make this a leaf node. */
1051  if ( (right-left) <= static_cast<IndexType>(m_leaf_max_size) ) {
1052  node->child1 = node->child2 = NULL; /* Mark as leaf node. */
1053  node->node_type.lr.left = left;
1054  node->node_type.lr.right = right;
1055 
1056  // compute bounding-box of leaf points
1057  for (int i=0; i<(DIM>0 ? DIM : dim); ++i) {
1058  bbox[i].low = dataset_get(vind[left],i);
1059  bbox[i].high = dataset_get(vind[left],i);
1060  }
1061  for (IndexType k=left+1; k<right; ++k) {
1062  for (int i=0; i<(DIM>0 ? DIM : dim); ++i) {
1063  if (bbox[i].low>dataset_get(vind[k],i)) bbox[i].low=dataset_get(vind[k],i);
1064  if (bbox[i].high<dataset_get(vind[k],i)) bbox[i].high=dataset_get(vind[k],i);
1065  }
1066  }
1067  }
1068  else {
1069  IndexType idx;
1070  int cutfeat;
1071  DistanceType cutval;
1072  middleSplit_(&vind[0]+left, right-left, idx, cutfeat, cutval, bbox);
1073 
1074  node->node_type.sub.divfeat = cutfeat;
1075 
1076  BoundingBox left_bbox(bbox);
1077  left_bbox[cutfeat].high = cutval;
1078  node->child1 = divideTree(left, left+idx, left_bbox);
1079 
1080  BoundingBox right_bbox(bbox);
1081  right_bbox[cutfeat].low = cutval;
1082  node->child2 = divideTree(left+idx, right, right_bbox);
1083 
1084  node->node_type.sub.divlow = left_bbox[cutfeat].high;
1085  node->node_type.sub.divhigh = right_bbox[cutfeat].low;
1086 
1087  for (int i=0; i<(DIM>0 ? DIM : dim); ++i) {
1088  bbox[i].low = std::min(left_bbox[i].low, right_bbox[i].low);
1089  bbox[i].high = std::max(left_bbox[i].high, right_bbox[i].high);
1090  }
1091  }
1092 
1093  return node;
1094  }
1095 
1096 
1097  void computeMinMax(IndexType* ind, IndexType count, int element, ElementType& min_elem, ElementType& max_elem)
1098  {
1099  min_elem = dataset_get(ind[0],element);
1100  max_elem = dataset_get(ind[0],element);
1101  for (IndexType i=1; i<count; ++i) {
1102  ElementType val = dataset_get(ind[i],element);
1103  if (val<min_elem) min_elem = val;
1104  if (val>max_elem) max_elem = val;
1105  }
1106  }
1107 
1108  void middleSplit_(IndexType* ind, IndexType count, IndexType& index, int& cutfeat, DistanceType& cutval, const BoundingBox& bbox)
1109  {
1110  const DistanceType EPS=static_cast<DistanceType>(0.00001);
1111  ElementType max_span = bbox[0].high-bbox[0].low;
1112  for (int i=1; i<(DIM>0 ? DIM : dim); ++i) {
1113  ElementType span = bbox[i].high-bbox[i].low;
1114  if (span>max_span) {
1115  max_span = span;
1116  }
1117  }
1118  ElementType max_spread = -1;
1119  cutfeat = 0;
1120  for (int i=0; i<(DIM>0 ? DIM : dim); ++i) {
1121  ElementType span = bbox[i].high-bbox[i].low;
1122  if (span>(1-EPS)*max_span) {
1123  ElementType min_elem, max_elem;
1124  computeMinMax(ind, count, i, min_elem, max_elem);
1125  ElementType spread = max_elem-min_elem;;
1126  if (spread>max_spread) {
1127  cutfeat = i;
1128  max_spread = spread;
1129  }
1130  }
1131  }
1132  // split in the middle
1133  DistanceType split_val = (bbox[cutfeat].low+bbox[cutfeat].high)/2;
1134  ElementType min_elem, max_elem;
1135  computeMinMax(ind, count, cutfeat, min_elem, max_elem);
1136 
1137  if (split_val<min_elem) cutval = min_elem;
1138  else if (split_val>max_elem) cutval = max_elem;
1139  else cutval = split_val;
1140 
1141  IndexType lim1, lim2;
1142  planeSplit(ind, count, cutfeat, cutval, lim1, lim2);
1143 
1144  if (lim1>count/2) index = lim1;
1145  else if (lim2<count/2) index = lim2;
1146  else index = count/2;
1147  }
1148 
1149 
1159  void planeSplit(IndexType* ind, const IndexType count, int cutfeat, DistanceType &cutval, IndexType& lim1, IndexType& lim2)
1160  {
1161  /* Move vector indices for left subtree to front of list. */
1162  IndexType left = 0;
1163  IndexType right = count-1;
1164  for (;; ) {
1165  while (left<=right && dataset_get(ind[left],cutfeat)<cutval) ++left;
1166  while (right && left<=right && dataset_get(ind[right],cutfeat)>=cutval) --right;
1167  if (left>right || !right) break; // "!right" was added to support unsigned Index types
1168  std::swap(ind[left], ind[right]);
1169  ++left;
1170  --right;
1171  }
1172  /* If either list is empty, it means that all remaining features
1173  * are identical. Split in the middle to maintain a balanced tree.
1174  */
1175  lim1 = left;
1176  right = count-1;
1177  for (;; ) {
1178  while (left<=right && dataset_get(ind[left],cutfeat)<=cutval) ++left;
1179  while (right && left<=right && dataset_get(ind[right],cutfeat)>cutval) --right;
1180  if (left>right || !right) break; // "!right" was added to support unsigned Index types
1181  std::swap(ind[left], ind[right]);
1182  ++left;
1183  --right;
1184  }
1185  lim2 = left;
1186  }
1187 
1189  {
1190  assert(vec);
1191  DistanceType distsq = DistanceType();
1192 
1193  for (int i = 0; i < (DIM>0 ? DIM : dim); ++i) {
1194  if (vec[i] < root_bbox[i].low) {
1195  dists[i] = distance.accum_dist(vec[i], root_bbox[i].low, i);
1196  distsq += dists[i];
1197  }
1198  if (vec[i] > root_bbox[i].high) {
1199  dists[i] = distance.accum_dist(vec[i], root_bbox[i].high, i);
1200  distsq += dists[i];
1201  }
1202  }
1203 
1204  return distsq;
1205  }
1206 
1212  template <class RESULTSET>
1213  bool searchLevel(RESULTSET& result_set, const ElementType* vec, const NodePtr node, DistanceType mindistsq,
1214  distance_vector_t& dists, const float epsError) const
1215  {
1216  /* If this is a leaf node, then do check and return. */
1217  if ((node->child1 == NULL)&&(node->child2 == NULL)) {
1218  //count_leaf += (node->lr.right-node->lr.left); // Removed since was neither used nor returned to the user.
1219  DistanceType worst_dist = result_set.worstDist();
1220  for (IndexType i=node->node_type.lr.left; i<node->node_type.lr.right; ++i) {
1221  const IndexType index = vind[i];// reorder... : i;
1222  DistanceType dist = distance(vec, index, (DIM>0 ? DIM : dim));
1223  if (dist<worst_dist) {
1224  if(!result_set.addPoint(dist,vind[i])) {
1225  // the resultset doesn't want to receive any more points, we're done searching!
1226  return false;
1227  }
1228  }
1229  }
1230  return true;
1231  }
1232 
1233  /* Which child branch should be taken first? */
1234  int idx = node->node_type.sub.divfeat;
1235  ElementType val = vec[idx];
1236  DistanceType diff1 = val - node->node_type.sub.divlow;
1237  DistanceType diff2 = val - node->node_type.sub.divhigh;
1238 
1239  NodePtr bestChild;
1240  NodePtr otherChild;
1241  DistanceType cut_dist;
1242  if ((diff1+diff2)<0) {
1243  bestChild = node->child1;
1244  otherChild = node->child2;
1245  cut_dist = distance.accum_dist(val, node->node_type.sub.divhigh, idx);
1246  }
1247  else {
1248  bestChild = node->child2;
1249  otherChild = node->child1;
1250  cut_dist = distance.accum_dist( val, node->node_type.sub.divlow, idx);
1251  }
1252 
1253  /* Call recursively to search next level down. */
1254  if(!searchLevel(result_set, vec, bestChild, mindistsq, dists, epsError)) {
1255  // the resultset doesn't want to receive any more points, we're done searching!
1256  return false;
1257  }
1258 
1259  DistanceType dst = dists[idx];
1260  mindistsq = mindistsq + cut_dist - dst;
1261  dists[idx] = cut_dist;
1262  if (mindistsq*epsError<=result_set.worstDist()) {
1263  if(!searchLevel(result_set, vec, otherChild, mindistsq, dists, epsError)) {
1264  // the resultset doesn't want to receive any more points, we're done searching!
1265  return false;
1266  }
1267  }
1268  dists[idx] = dst;
1269  return true;
1270  }
1271 
1272  public:
1277  void saveIndex(FILE* stream)
1278  {
1279  save_value(stream, m_size);
1280  save_value(stream, dim);
1281  save_value(stream, root_bbox);
1282  save_value(stream, m_leaf_max_size);
1283  save_value(stream, vind);
1284  save_tree(stream, root_node);
1285  }
1286 
1291  void loadIndex(FILE* stream)
1292  {
1293  load_value(stream, m_size);
1294  load_value(stream, dim);
1295  load_value(stream, root_bbox);
1296  load_value(stream, m_leaf_max_size);
1297  load_value(stream, vind);
1298  load_tree(stream, root_node);
1299  }
1300 
1301  }; // class KDTree
1302 
1303 
1322  template <class MatrixType, int DIM = -1, class Distance = nanoflann::metric_L2>
1324  {
1326  typedef typename MatrixType::Scalar num_t;
1327  typedef typename MatrixType::Index IndexType;
1328  typedef typename Distance::template traits<num_t,self_t>::distance_t metric_t;
1330 
1332 
1334  KDTreeEigenMatrixAdaptor(const int dimensionality, const MatrixType &mat, const int leaf_max_size = 10) : m_data_matrix(mat)
1335  {
1336  const IndexType dims = mat.cols();
1337  if (dims!=dimensionality) throw std::runtime_error("Error: 'dimensionality' must match column count in data matrix");
1338  if (DIM>0 && static_cast<int>(dims)!=DIM)
1339  throw std::runtime_error("Data set dimensionality does not match the 'DIM' template argument");
1340  index = new index_t( dims, *this /* adaptor */, nanoflann::KDTreeSingleIndexAdaptorParams(leaf_max_size ) );
1341  index->buildIndex();
1342  }
1343  private:
1346  public:
1347 
1349  delete index;
1350  }
1351 
1352  const MatrixType &m_data_matrix;
1353 
1359  inline void query(const num_t *query_point, const size_t num_closest, IndexType *out_indices, num_t *out_distances_sq, const int /* nChecks_IGNORED */ = 10) const
1360  {
1361  nanoflann::KNNResultSet<num_t,IndexType> resultSet(num_closest);
1362  resultSet.init(out_indices, out_distances_sq);
1363  index->findNeighbors(resultSet, query_point, nanoflann::SearchParams());
1364  }
1365 
1369  const self_t & derived() const {
1370  return *this;
1371  }
1373  return *this;
1374  }
1375 
1376  // Must return the number of data points
1377  inline size_t kdtree_get_point_count() const {
1378  return m_data_matrix.rows();
1379  }
1380 
1381  // Returns the L2 distance between the vector "p1[0:size-1]" and the data point with index "idx_p2" stored in the class:
1382  inline num_t kdtree_distance(const num_t *p1, const IndexType idx_p2,IndexType size) const
1383  {
1384  num_t s=0;
1385  for (IndexType i=0; i<size; i++) {
1386  const num_t d= p1[i]-m_data_matrix.coeff(idx_p2,i);
1387  s+=d*d;
1388  }
1389  return s;
1390  }
1391 
1392  // Returns the dim'th component of the idx'th point in the class:
1393  inline num_t kdtree_get_pt(const IndexType idx, int dim) const {
1394  return m_data_matrix.coeff(idx,IndexType(dim));
1395  }
1396 
1397  // Optional bounding-box computation: return false to default to a standard bbox computation loop.
1398  // Return true if the BBOX was already computed by the class and returned in "bb" so it can be avoided to redo it again.
1399  // Look at bb.size() to find out the expected dimensionality (e.g. 2 or 3 for point clouds)
1400  template <class BBOX>
1401  bool kdtree_get_bbox(BBOX& /*bb*/) const {
1402  return false;
1403  }
1404 
1407  }; // end of KDTreeEigenMatrixAdaptor // end of grouping
1411 } // end of NS
1412 
1413 
1414 #endif /* NANOFLANN_HPP_ */
nanoflann::KDTreeSingleIndexAdaptor::dim
int dim
Dimensionality of each data point.
Definition: nanoflann.hpp:772
nanoflann::KDTreeSingleIndexAdaptor::findNeighbors
bool findNeighbors(RESULTSET &result, const ElementType *vec, const SearchParams &searchParams) const
Definition: nanoflann.hpp:906
nanoflann::KDTreeEigenMatrixAdaptor
Definition: nanoflann.hpp:1324
nanoflann::KDTreeSingleIndexAdaptor::Node::child2
Node * child2
Child nodes (both=NULL mean its a leaf node)
Definition: nanoflann.hpp:790
nanoflann::KDTreeSingleIndexAdaptorParams::leaf_max_size
size_t leaf_max_size
Definition: nanoflann.hpp:414
nanoflann::CArray::end
const_iterator end() const
Definition: nanoflann.hpp:630
nanoflann::RadiusResultSet::radius
const DistanceType radius
Definition: nanoflann.hpp:163
nanoflann::KDTreeEigenMatrixAdaptor::kdtree_distance
num_t kdtree_distance(const num_t *p1, const IndexType idx_p2, IndexType size) const
Definition: nanoflann.hpp:1382
nanoflann::L2_Simple_Adaptor::L2_Simple_Adaptor
L2_Simple_Adaptor(const DataSource &_data_source)
Definition: nanoflann.hpp:367
nanoflann::KNNResultSet::worstDist
DistanceType worstDist() const
Definition: nanoflann.hpp:140
nanoflann::KDTreeSingleIndexAdaptor::KDTreeSingleIndexAdaptor
KDTreeSingleIndexAdaptor(const KDTreeSingleIndexAdaptor< Distance, DatasetAdaptor, DIM, IndexType > &)
nanoflann::CArray::at
reference at(size_type i)
Definition: nanoflann.hpp:656
nanoflann::CArray::operator[]
const_reference operator[](size_type i) const
Definition: nanoflann.hpp:654
nanoflann::KDTreeSingleIndexAdaptor::knnSearch
size_t knnSearch(const ElementType *query_point, const size_t num_closest, IndexType *out_indices, DistanceType *out_distances_sq, const int=10) const
Definition: nanoflann.hpp:930
nanoflann::RadiusResultSet::addPoint
bool addPoint(DistanceType dist, IndexType index)
Definition: nanoflann.hpp:185
nanoflann::CArray::value_type
T value_type
Definition: nanoflann.hpp:618
nanoflann::KDTreeSingleIndexAdaptor::middleSplit_
void middleSplit_(IndexType *ind, IndexType count, IndexType &index, int &cutfeat, DistanceType &cutval, const BoundingBox &bbox)
Definition: nanoflann.hpp:1108
nanoflann::KDTreeEigenMatrixAdaptor::~KDTreeEigenMatrixAdaptor
~KDTreeEigenMatrixAdaptor()
Definition: nanoflann.hpp:1348
nanoflann::KDTreeSingleIndexAdaptor::veclen
size_t veclen() const
Definition: nanoflann.hpp:877
nanoflann::RadiusResultSet::worst_item
std::pair< IndexType, DistanceType > worst_item() const
Definition: nanoflann.hpp:198
std::swap
void swap(picojson::value &x, picojson::value &y)
Definition: picojson.h:1136
nanoflann::KNNResultSet::count
CountType count
Definition: nanoflann.hpp:83
nanoflann::KNNResultSet::KNNResultSet
KNNResultSet(CountType capacity_)
Definition: nanoflann.hpp:86
distance
double distance(MVertex *v1, MVertex *v2)
Definition: MVertex.h:245
nanoflann::CArray::reverse_iterator
std::reverse_iterator< iterator > reverse_iterator
Definition: nanoflann.hpp:634
nanoflann::IndexDist_Sorter
Definition: nanoflann.hpp:148
nanoflann::RadiusResultSet::~RadiusResultSet
~RadiusResultSet()
Definition: nanoflann.hpp:172
nanoflann::KDTreeEigenMatrixAdaptor::KDTreeEigenMatrixAdaptor
KDTreeEigenMatrixAdaptor(const int dimensionality, const MatrixType &mat, const int leaf_max_size=10)
The kd-tree index for the user to call its methods as usual with any other FLANN index.
Definition: nanoflann.hpp:1334
nanoflann::KDTreeSingleIndexAdaptor::searchLevel
bool searchLevel(RESULTSET &result_set, const ElementType *vec, const NodePtr node, DistanceType mindistsq, distance_vector_t &dists, const float epsError) const
Definition: nanoflann.hpp:1213
nanoflann::PooledAllocator::~PooledAllocator
~PooledAllocator()
Definition: nanoflann.hpp:501
nanoflann::PooledAllocator::PooledAllocator
PooledAllocator()
Definition: nanoflann.hpp:494
nanoflann::load_value
void load_value(FILE *stream, T &value, size_t count=1)
Definition: nanoflann.hpp:228
nanoflann::CArray::operator[]
reference operator[](size_type i)
Definition: nanoflann.hpp:653
nanoflann::KDTreeSingleIndexAdaptor::usedMemory
size_t usedMemory() const
Definition: nanoflann.hpp:885
nanoflann::KDTreeSingleIndexAdaptor::load_tree
void load_tree(FILE *stream, NodePtr &tree)
Definition: nanoflann.hpp:1001
nanoflann::CArray::resize
void resize(const size_t nElements)
Definition: nanoflann.hpp:669
nanoflann::L1_Adaptor::ElementType
T ElementType
Definition: nanoflann.hpp:265
nanoflann::KNNResultSet::full
bool full() const
Definition: nanoflann.hpp:104
nanoflann::KDTreeSingleIndexAdaptor::init_vind
void init_vind()
Definition: nanoflann.hpp:975
nanoflann::PooledAllocator::usedMemory
size_t usedMemory
Definition: nanoflann.hpp:488
nanoflann::PooledAllocator::wastedMemory
size_t wastedMemory
Definition: nanoflann.hpp:489
nanoflann::PooledAllocator::base
void * base
Definition: nanoflann.hpp:476
nanoflann::L2_Adaptor::operator()
DistanceType operator()(const T *a, const size_t b_idx, size_t size, DistanceType worst_dist=-1) const
Definition: nanoflann.hpp:320
nanoflann::L2_Adaptor::data_source
const DataSource & data_source
Definition: nanoflann.hpp:316
nanoflann::KDTreeSingleIndexAdaptor::Node::right
IndexType right
Indices of points in leaf node.
Definition: nanoflann.hpp:782
nanoflann::KNNResultSet::capacity
CountType capacity
Definition: nanoflann.hpp:82
nanoflann::KDTreeSingleIndexAdaptor::divideTree
NodePtr divideTree(const IndexType left, const IndexType right, BoundingBox &bbox)
Definition: nanoflann.hpp:1046
nanoflann::metric_L2_Simple::traits
Definition: nanoflann.hpp:397
nanoflann::CArray::begin
iterator begin()
Definition: nanoflann.hpp:627
nanoflann::RadiusResultSet::size
size_t size() const
Definition: nanoflann.hpp:177
nanoflann::L1_Adaptor::data_source
const DataSource & data_source
Definition: nanoflann.hpp:268
nanoflann::KDTreeEigenMatrixAdaptor::kdtree_get_pt
num_t kdtree_get_pt(const IndexType idx, int dim) const
Definition: nanoflann.hpp:1393
nanoflann
Definition: nanoflann.hpp:68
nanoflann::SearchParams::eps
float eps
search for eps-approximate neighbours (default: 0)
Definition: nanoflann.hpp:425
nanoflann::KDTreeEigenMatrixAdaptor::kdtree_get_bbox
bool kdtree_get_bbox(BBOX &) const
Definition: nanoflann.hpp:1401
nanoflann::L2_Adaptor::ElementType
T ElementType
Definition: nanoflann.hpp:313
nanoflann::CArray::begin
const_iterator begin() const
Definition: nanoflann.hpp:628
nanoflann::KDTreeSingleIndexAdaptor::m_size_at_index_build
size_t m_size_at_index_build
Number of points in the dataset when the index was built.
Definition: nanoflann.hpp:771
nanoflann::PooledAllocator::internal_init
void internal_init()
Definition: nanoflann.hpp:479
nanoflann::CArray::size_type
std::size_t size_type
Definition: nanoflann.hpp:623
nanoflann::KDTreeEigenMatrixAdaptor::derived
self_t & derived()
Definition: nanoflann.hpp:1372
nanoflann::allocate
T * allocate(size_t count=1)
Definition: nanoflann.hpp:442
nanoflann::KDTreeSingleIndexAdaptor::saveIndex
void saveIndex(FILE *stream)
Definition: nanoflann.hpp:1277
nanoflann::KDTreeEigenMatrixAdaptor::metric_t
Distance::template traits< num_t, self_t >::distance_t metric_t
Definition: nanoflann.hpp:1328
nanoflann::CArray::front
const_reference front() const
Definition: nanoflann.hpp:660
nanoflann::CArray::reference
T & reference
Definition: nanoflann.hpp:621
nanoflann::KDTreeEigenMatrixAdaptor::KDTreeEigenMatrixAdaptor
KDTreeEigenMatrixAdaptor(const self_t &)
nanoflann::metric_L2::traits
Definition: nanoflann.hpp:390
nanoflann::L1_Adaptor::L1_Adaptor
L1_Adaptor(const DataSource &_data_source)
Definition: nanoflann.hpp:270
nanoflann::KDTreeSingleIndexAdaptorParams::KDTreeSingleIndexAdaptorParams
KDTreeSingleIndexAdaptorParams(size_t _leaf_max_size=10)
Definition: nanoflann.hpp:410
nanoflann::KDTreeSingleIndexAdaptor::dataset_get
ElementType dataset_get(size_t idx, int component) const
Helper accessor to the dataset points:
Definition: nanoflann.hpp:984
nanoflann::L1_Adaptor::accum_dist
DistanceType accum_dist(const U a, const V b, int) const
Definition: nanoflann.hpp:299
nanoflann::KDTreeSingleIndexAdaptor::Node::lr
struct nanoflann::KDTreeSingleIndexAdaptor::Node::@31::leaf lr
nanoflann::RadiusResultSet::clear
void clear()
Definition: nanoflann.hpp:175
nanoflann::KDTreeSingleIndexAdaptor::buildIndex
void buildIndex()
Definition: nanoflann.hpp:863
nanoflann::L2_Simple_Adaptor
Definition: nanoflann.hpp:361
nanoflann::KDTreeSingleIndexAdaptor::root_bbox
BoundingBox root_bbox
Definition: nanoflann.hpp:808
nanoflann::KDTreeSingleIndexAdaptor::distance_vector_t
array_or_vector_selector< DIM, DistanceType >::container_t distance_vector_t
Definition: nanoflann.hpp:804
nanoflann::SearchParams::sorted
bool sorted
only for radius search, require neighbours sorted by distance (default: true)
Definition: nanoflann.hpp:426
nanoflann::L1_Adaptor::DistanceType
_DistanceType DistanceType
Definition: nanoflann.hpp:266
nanoflann::PooledAllocator::loc
void * loc
Definition: nanoflann.hpp:477
nanoflann::RadiusResultSet::RadiusResultSet
RadiusResultSet(DistanceType radius_, std::vector< std::pair< IndexType, DistanceType > > &indices_dists)
Definition: nanoflann.hpp:167
nanoflann::metric_L2_Simple::traits::distance_t
L2_Simple_Adaptor< T, DataSource > distance_t
Definition: nanoflann.hpp:398
nanoflann::L2_Adaptor
Definition: nanoflann.hpp:312
nanoflann::CArray::iterator
T * iterator
Definition: nanoflann.hpp:619
nanoflann::KDTreeSingleIndexAdaptor::size
size_t size() const
Definition: nanoflann.hpp:874
nanoflann::PooledAllocator::allocate
T * allocate(const size_t count=1)
Definition: nanoflann.hpp:573
nanoflann::PooledAllocator::remaining
size_t remaining
Definition: nanoflann.hpp:475
nanoflann::metric_L1::traits::distance_t
L1_Adaptor< T, DataSource > distance_t
Definition: nanoflann.hpp:384
nanoflann::SearchParams
Definition: nanoflann.hpp:419
nanoflann::CArray::rangecheck
static void rangecheck(size_type i)
Definition: nanoflann.hpp:687
nanoflann::KDTreeEigenMatrixAdaptor::m_data_matrix
const MatrixType & m_data_matrix
Definition: nanoflann.hpp:1352
nanoflann::KNNResultSet::addPoint
bool addPoint(DistanceType dist, IndexType index)
Definition: nanoflann.hpp:114
nanoflann::CArray::at
const_reference at(size_type i) const
Definition: nanoflann.hpp:657
nanoflann::KDTreeSingleIndexAdaptor::distance
Distance distance
Definition: nanoflann.hpp:821
nanoflann::IndexDist_Sorter::operator()
bool operator()(const PairType &p1, const PairType &p2) const
Definition: nanoflann.hpp:151
nanoflann::BLOCKSIZE
const size_t BLOCKSIZE
Definition: nanoflann.hpp:465
nanoflann::CArray::size
static size_type size()
Definition: nanoflann.hpp:664
nanoflann::PooledAllocator::malloc
void * malloc(const size_t req_size)
Definition: nanoflann.hpp:520
nanoflann::CArray::back
const_reference back() const
Definition: nanoflann.hpp:662
nanoflann::KDTreeSingleIndexAdaptor::KDTreeSingleIndexAdaptor
KDTreeSingleIndexAdaptor(const int dimensionality, const DatasetAdaptor &inputData, const KDTreeSingleIndexAdaptorParams &params=KDTreeSingleIndexAdaptorParams())
Definition: nanoflann.hpp:836
nanoflann::KNNResultSet::dists
DistanceType * dists
Definition: nanoflann.hpp:81
nanoflann::metric_L2
Definition: nanoflann.hpp:388
nanoflann::KDTreeEigenMatrixAdaptor::num_t
MatrixType::Scalar num_t
Definition: nanoflann.hpp:1326
nanoflann::KDTreeSingleIndexAdaptor::save_tree
void save_tree(FILE *stream, NodePtr tree)
Definition: nanoflann.hpp:989
nanoflann::RadiusResultSet
Definition: nanoflann.hpp:161
nanoflann::CArray::const_reverse_iterator
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: nanoflann.hpp:635
nanoflann::KNNResultSet::init
void init(IndexType *indices_, DistanceType *dists_)
Definition: nanoflann.hpp:90
nanoflann::KDTreeSingleIndexAdaptor::computeMinMax
void computeMinMax(IndexType *ind, IndexType count, int element, ElementType &min_elem, ElementType &max_elem)
Definition: nanoflann.hpp:1097
nanoflann::CArray::const_reference
const T & const_reference
Definition: nanoflann.hpp:622
nanoflann::L2_Simple_Adaptor::data_source
const DataSource & data_source
Definition: nanoflann.hpp:365
nanoflann::KDTreeSingleIndexAdaptor::radiusSearchCustomCallback
size_t radiusSearchCustomCallback(const ElementType *query_point, SEARCH_CALLBACK &resultSet, const SearchParams &searchParams=SearchParams()) const
Definition: nanoflann.hpp:965
nanoflann::metric_L2::traits::distance_t
L2_Adaptor< T, DataSource > distance_t
Definition: nanoflann.hpp:391
nanoflann::KNNResultSet::indices
IndexType * indices
Definition: nanoflann.hpp:80
nanoflann::KDTreeSingleIndexAdaptor::vind
std::vector< IndexType > vind
Definition: nanoflann.hpp:758
nanoflann::L2_Simple_Adaptor::accum_dist
DistanceType accum_dist(const U a, const V b, int) const
Definition: nanoflann.hpp:374
nanoflann::L2_Simple_Adaptor::DistanceType
_DistanceType DistanceType
Definition: nanoflann.hpp:363
nanoflann::KDTreeEigenMatrixAdaptor::query
void query(const num_t *query_point, const size_t num_closest, IndexType *out_indices, num_t *out_distances_sq, const int=10) const
Definition: nanoflann.hpp:1359
nanoflann::L2_Adaptor::DistanceType
_DistanceType DistanceType
Definition: nanoflann.hpp:314
nanoflann::RadiusResultSet::worstDist
DistanceType worstDist() const
Definition: nanoflann.hpp:192
nanoflann::KDTreeSingleIndexAdaptor::loadIndex
void loadIndex(FILE *stream)
Definition: nanoflann.hpp:1291
nanoflann::KDTreeEigenMatrixAdaptor::index_t
KDTreeSingleIndexAdaptor< metric_t, self_t, DIM, IndexType > index_t
Definition: nanoflann.hpp:1329
nanoflann::KDTreeEigenMatrixAdaptor::index
index_t * index
Definition: nanoflann.hpp:1331
nanoflann::KDTreeEigenMatrixAdaptor::IndexType
MatrixType::Index IndexType
Definition: nanoflann.hpp:1327
nanoflann::RadiusResultSet::m_indices_dists
std::vector< std::pair< IndexType, DistanceType > > & m_indices_dists
Definition: nanoflann.hpp:165
element
Definition: shapeFunctions.h:12
nanoflann::KDTreeSingleIndexAdaptor::root_node
NodePtr root_node
Definition: nanoflann.hpp:807
nanoflann::PooledAllocator
Definition: nanoflann.hpp:468
nanoflann::CArray::assign
void assign(const T &value)
Definition: nanoflann.hpp:682
nanoflann::KDTreeEigenMatrixAdaptor::derived
const self_t & derived() const
Definition: nanoflann.hpp:1369
nanoflann::KDTreeSingleIndexAdaptor::Node::divlow
DistanceType divlow
Definition: nanoflann.hpp:787
nanoflann::KDTreeSingleIndexAdaptorParams
Definition: nanoflann.hpp:409
nanoflann::KDTreeSingleIndexAdaptor::Node::sub
struct nanoflann::KDTreeSingleIndexAdaptor::Node::@31::nonleaf sub
nanoflann::RadiusResultSet::init
void init()
Definition: nanoflann.hpp:174
nanoflann::KDTreeSingleIndexAdaptor::m_leaf_max_size
size_t m_leaf_max_size
Definition: nanoflann.hpp:760
nanoflann::KDTreeSingleIndexAdaptor::index_params
const KDTreeSingleIndexAdaptorParams index_params
Definition: nanoflann.hpp:768
nanoflann::CArray::data
T * data()
Definition: nanoflann.hpp:675
nanoflann::CArray
Definition: nanoflann.hpp:612
nanoflann::metric_L1
Definition: nanoflann.hpp:381
nanoflann::CArray::rend
const_reverse_iterator rend() const
Definition: nanoflann.hpp:651
nanoflann::CArray::empty
static bool empty()
Definition: nanoflann.hpp:665
nanoflann::L2_Adaptor::L2_Adaptor
L2_Adaptor(const DataSource &_data_source)
Definition: nanoflann.hpp:318
nanoflann::metric_L1::traits
Definition: nanoflann.hpp:383
nanoflann::SearchParams::checks
int checks
Ignored parameter (Kept for compatibility with the FLANN interface).
Definition: nanoflann.hpp:424
nanoflann::CArray::back
reference back()
Definition: nanoflann.hpp:661
nanoflann::CArray::swap
void swap(CArray< T, N > &y)
Definition: nanoflann.hpp:671
nanoflann::KDTreeSingleIndexAdaptor::radiusSearch
size_t radiusSearch(const ElementType *query_point, const DistanceType &radius, std::vector< std::pair< IndexType, DistanceType > > &IndicesDists, const SearchParams &searchParams) const
Definition: nanoflann.hpp:950
picojson::copy
void copy(const std::string &s, Iter oi)
Definition: picojson.h:510
nanoflann::KDTreeSingleIndexAdaptor::Node::node_type
union nanoflann::KDTreeSingleIndexAdaptor::Node::@31 node_type
nanoflann::L1_Adaptor::operator()
DistanceType operator()(const T *a, const size_t b_idx, size_t size, DistanceType worst_dist=-1) const
Definition: nanoflann.hpp:272
nanoflann::KDTreeSingleIndexAdaptor::m_size
size_t m_size
Number of current points in the dataset.
Definition: nanoflann.hpp:770
nanoflann::KDTreeSingleIndexAdaptor::~KDTreeSingleIndexAdaptor
~KDTreeSingleIndexAdaptor()
Definition: nanoflann.hpp:850
nanoflann::CArray::rbegin
const_reverse_iterator rbegin() const
Definition: nanoflann.hpp:649
nanoflann::CArray::assign
void assign(const size_t n, const T &value)
Definition: nanoflann.hpp:684
nanoflann::KDTreeSingleIndexAdaptor::dataset
const DatasetAdaptor & dataset
The source of our data.
Definition: nanoflann.hpp:766
nanoflann::KNNResultSet
Definition: nanoflann.hpp:79
nanoflann::KDTreeEigenMatrixAdaptor::self_t
KDTreeEigenMatrixAdaptor< MatrixType, DIM, Distance > self_t
Definition: nanoflann.hpp:1325
ElementType
Definition: ElementType.h:11
nanoflann::array_or_vector_selector<-1, T >::container_t
std::vector< T > container_t
Definition: nanoflann.hpp:701
nanoflann::KDTreeSingleIndexAdaptor::Node::divfeat
int divfeat
Dimension used for subdivision.
Definition: nanoflann.hpp:786
nanoflann::CArray::data
const T * data() const
Definition: nanoflann.hpp:673
nanoflann::metric_L2_Simple
Definition: nanoflann.hpp:395
nanoflann::L1_Adaptor
Definition: nanoflann.hpp:264
nanoflann::L2_Adaptor::accum_dist
DistanceType accum_dist(const U a, const V b, int) const
Definition: nanoflann.hpp:348
nanoflann::array_or_vector_selector
Definition: nanoflann.hpp:695
nanoflann::CArray::const_iterator
const T * const_iterator
Definition: nanoflann.hpp:620
nanoflann::L2_Simple_Adaptor::ElementType
T ElementType
Definition: nanoflann.hpp:362
nanoflann::L2_Simple_Adaptor::operator()
DistanceType operator()(const T *a, const size_t b_idx, size_t size) const
Definition: nanoflann.hpp:369
nanoflann::KDTreeSingleIndexAdaptor::Node::child1
Node * child1
Definition: nanoflann.hpp:790
nanoflann::SearchParams::SearchParams
SearchParams(int checks_IGNORED_=32, float eps_=0, bool sorted_=true)
Definition: nanoflann.hpp:421
nanoflann::KDTreeSingleIndexAdaptor
Definition: nanoflann.hpp:746
nanoflann::KDTreeSingleIndexAdaptor::freeIndex
void freeIndex()
Definition: nanoflann.hpp:853
nanoflann::KDTreeSingleIndexAdaptor::ElementType
Distance::ElementType ElementType
Definition: nanoflann.hpp:751
nanoflann::KDTreeSingleIndexAdaptor::Interval
Definition: nanoflann.hpp:796
nanoflann::KDTreeSingleIndexAdaptor::NodePtr
Node * NodePtr
Definition: nanoflann.hpp:792
nanoflann::KDTreeSingleIndexAdaptor::Node
Definition: nanoflann.hpp:777
nanoflann::RadiusResultSet::full
bool full() const
Definition: nanoflann.hpp:179
nanoflann::KDTreeSingleIndexAdaptor::BoundingBox
array_or_vector_selector< DIM, Interval >::container_t BoundingBox
Definition: nanoflann.hpp:801
nanoflann::array_or_vector_selector::container_t
CArray< T, DIM > container_t
Definition: nanoflann.hpp:696
nanoflann::CArray::rbegin
reverse_iterator rbegin()
Definition: nanoflann.hpp:648
nanoflann::save_value
void save_value(FILE *stream, const T &value, size_t count=1)
Definition: nanoflann.hpp:214
nanoflann::KDTreeSingleIndexAdaptor::DistanceType
Distance::DistanceType DistanceType
Definition: nanoflann.hpp:752
nanoflann::KDTreeSingleIndexAdaptor::Interval::low
ElementType low
Definition: nanoflann.hpp:797
nanoflann::PooledAllocator::free_all
void free_all()
Definition: nanoflann.hpp:506
nanoflann::KDTreeSingleIndexAdaptor::pool
PooledAllocator pool
Definition: nanoflann.hpp:817
nanoflann::KNNResultSet::size
CountType size() const
Definition: nanoflann.hpp:99
nanoflann::KDTreeSingleIndexAdaptor::computeInitialDistances
DistanceType computeInitialDistances(const ElementType *vec, distance_vector_t &dists) const
Definition: nanoflann.hpp:1188
nanoflann::KDTreeSingleIndexAdaptor::computeBoundingBox
void computeBoundingBox(BoundingBox &bbox)
Definition: nanoflann.hpp:1014
nanoflann::KDTreeSingleIndexAdaptor::planeSplit
void planeSplit(IndexType *ind, const IndexType count, int cutfeat, DistanceType &cutval, IndexType &lim1, IndexType &lim2)
Definition: nanoflann.hpp:1159
nanoflann::CArray::end
iterator end()
Definition: nanoflann.hpp:629
nanoflann::WORDSIZE
const size_t WORDSIZE
Definition: nanoflann.hpp:464
nanoflann::CArray::rend
reverse_iterator rend()
Definition: nanoflann.hpp:650
nanoflann::KDTreeEigenMatrixAdaptor::kdtree_get_point_count
size_t kdtree_get_point_count() const
Definition: nanoflann.hpp:1377
nanoflann::CArray::max_size
static size_type max_size()
Definition: nanoflann.hpp:666
nanoflann::CArray::front
reference front()
Definition: nanoflann.hpp:659
nanoflann::CArray::difference_type
std::ptrdiff_t difference_type
Definition: nanoflann.hpp:624