xc
kdtree.hpp
Go to the documentation of this file.
1 
46 #ifndef INCLUDE_KDTREE_KDTREE_HPP
47 #define INCLUDE_KDTREE_KDTREE_HPP
48 
49 
50 //
51 // This number is guarenteed to change with every release.
52 //
53 // KDTREE_VERSION % 100 is the patch level
54 // KDTREE_VERSION / 100 % 1000 is the minor version
55 // KDTREE_VERSION / 100000 is the major version
56 #define KDTREE_VERSION 700
57 //
58 // KDTREE_LIB_VERSION must be defined to be the same as KDTREE_VERSION
59 // but as a *string* in the form "x_y[_z]" where x is the major version
60 // number, y is the minor version number, and z is the patch level if not 0.
61 #define KDTREE_LIB_VERSION "0_7_0"
62 
63 
64 #include <vector>
65 
66 #ifdef KDTREE_CHECK_PERFORMANCE_COUNTERS
67 # include <map>
68 #endif
69 #include <algorithm>
70 
71 #ifdef KDTREE_DEFINE_OSTREAM_OPERATORS
72 # include <ostream>
73 # include <stack>
74 #endif
75 
76 #include <cmath>
77 #include <cstddef>
78 #include <cassert>
79 
80 #include "function.hpp"
81 #include "allocator.hpp"
82 #include "iterator.hpp"
83 #include "node.hpp"
84 #include "region.hpp"
85 
86 namespace kd_tree
87 {
88 
89 #ifdef KDTREE_CHECK_PERFORMANCE
90  unsigned long long num_dist_calcs = 0;
91 #endif
92 
93  template <size_t const __K, typename _Val,
94  typename _Acc = _Bracket_accessor<_Val>,
95  typename _Dist = squared_difference<typename _Acc::result_type,
96  typename _Acc::result_type>,
97  typename _Cmp = std::less<typename _Acc::result_type>,
98  typename _Alloc = std::allocator<_Node<_Val> > >
99  class KDTree : protected _Alloc_base<_Val, _Alloc>
100  {
101  protected:
103  typedef typename _Base::allocator_type allocator_type;
104 
105  typedef _Node_base* _Base_ptr;
106  typedef _Node_base const* _Base_const_ptr;
107  typedef _Node<_Val>* _Link_type;
108  typedef _Node<_Val> const* _Link_const_type;
109 
111 
112  public:
114  _Region_;
115  typedef _Val value_type;
116  typedef value_type* pointer;
117  typedef value_type const* const_pointer;
118  typedef value_type& reference;
119  typedef value_type const& const_reference;
120  typedef typename _Acc::result_type subvalue_type;
121  typedef typename _Dist::distance_type distance_type;
122  typedef size_t size_type;
123  typedef ptrdiff_t difference_type;
124 
125  KDTree(_Acc const& __acc = _Acc(), _Dist const& __dist = _Dist(),
126  _Cmp const& __cmp = _Cmp(), const allocator_type& __a = allocator_type())
127  : _Base(__a), _M_header(),
128  _M_count(0), _M_acc(__acc), _M_cmp(__cmp), _M_dist(__dist)
129  {
130  _M_empty_initialise();
131  }
132 
133  KDTree(const KDTree& __x)
134  : _Base(__x.get_allocator()), _M_header(), _M_count(0),
135  _M_acc(__x._M_acc), _M_cmp(__x._M_cmp), _M_dist(__x._M_dist)
136  {
137  _M_empty_initialise();
138  // this is slow:
139  // this->insert(begin(), __x.begin(), __x.end());
140  // this->optimise();
141 
142  // this is much faster, as it skips a lot of useless work
143  // do the optimisation before inserting
144  // Needs to be stored in a vector first as _M_optimise()
145  // sorts the data in the passed iterators directly.
146  std::vector<value_type> temp;
147  temp.reserve(__x.size());
148  std::copy(__x.begin(),__x.end(),std::back_inserter(temp));
149  _M_optimise(temp.begin(), temp.end(), 0);
150  }
151 
152  template<typename _InputIterator>
153  KDTree(_InputIterator __first, _InputIterator __last,
154  _Acc const& acc = _Acc(), _Dist const& __dist = _Dist(),
155  _Cmp const& __cmp = _Cmp(), const allocator_type& __a = allocator_type())
156  : _Base(__a), _M_header(), _M_count(0),
157  _M_acc(acc), _M_cmp(__cmp), _M_dist(__dist)
158  {
159  _M_empty_initialise();
160  // this is slow:
161  // this->insert(begin(), __first, __last);
162  // this->optimise();
163 
164  // this is much faster, as it skips a lot of useless work
165  // do the optimisation before inserting
166  // Needs to be stored in a vector first as _M_optimise()
167  // sorts the data in the passed iterators directly.
168  std::vector<value_type> temp;
169  temp.reserve(std::distance(__first,__last));
170  std::copy(__first,__last,std::back_inserter(temp));
171  _M_optimise(temp.begin(), temp.end(), 0);
172 
173  // NOTE: this will BREAK users that are passing in
174  // read-once data via the iterator...
175  // We increment __first all the way to __last once within
176  // the distance() call, and again within the copy() call.
177  //
178  // This should end up using some funky C++ concepts or
179  // type traits to check that the iterators can be used in this way...
180  }
181 
182 
183  // this will CLEAR the tree and fill it with the contents
184  // of 'writable_vector'. it will use the passed vector directly,
185  // and will basically resort the vector many times over while
186  // optimising the tree.
187  //
188  // Paul: I use this when I have already built up a vector of data
189  // that I want to add, and I don't mind if its contents get shuffled
190  // by the kdtree optimise routine.
191  void efficient_replace_and_optimise( std::vector<value_type> & writable_vector )
192  {
193  this->clear();
194  _M_optimise(writable_vector.begin(), writable_vector.end(), 0);
195  }
196 
197 
198 
199  KDTree&
200  operator=(const KDTree& __x)
201  {
202  if (this != &__x)
203  {
204  _M_acc = __x._M_acc;
205  _M_dist = __x._M_dist;
206  _M_cmp = __x._M_cmp;
207  // this is slow:
208  // this->insert(begin(), __x.begin(), __x.end());
209  // this->optimise();
210 
211  // this is much faster, as it skips a lot of useless work
212  // do the optimisation before inserting
213  // Needs to be stored in a vector first as _M_optimise()
214  // sorts the data in the passed iterators directly.
215  std::vector<value_type> temp;
216  temp.reserve(__x.size());
217  std::copy(__x.begin(),__x.end(),std::back_inserter(temp));
218  efficient_replace_and_optimise(temp);
219  }
220  return *this;
221  }
222 
223  ~KDTree()
224  {
225  this->clear();
226  }
227 
228  allocator_type
229  get_allocator() const
230  {
231  return _Base::get_allocator();
232  }
233 
234  size_type
235  size() const
236  {
237  return _M_count;
238  }
239 
240  size_type
241  max_size() const
242  {
243  return size_type(-1);
244  }
245 
246  bool
247  empty() const
248  {
249  return this->size() == 0;
250  }
251 
252  void
253  clear()
254  {
255  _M_erase_subtree(_M_get_root());
256  _M_set_leftmost(&_M_header);
257  _M_set_rightmost(&_M_header);
258  _M_set_root(NULL);
259  _M_count = 0;
260  }
261 
267  _Cmp
268  value_comp() const
269  { return _M_cmp; }
270 
276  _Acc
277  value_acc() const
278  { return _M_acc; }
279 
286  const _Dist&
288  { return _M_dist; }
289 
290  _Dist&
292  { return _M_dist; }
293 
294  // typedef _Iterator<_Val, reference, pointer> iterator;
296  // No mutable iterator at this stage
297  typedef const_iterator iterator;
298  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
299  typedef std::reverse_iterator<iterator> reverse_iterator;
300 
301  // Note: the static_cast in end() is invalid (_M_header is not convertable to a _Link_type), but
302  // thats ok as it just means undefined behaviour if the user dereferences the end() iterator.
303 
304  const_iterator begin() const { return const_iterator(_M_get_leftmost()); }
305  const_iterator end() const { return const_iterator(static_cast<_Link_const_type>(&_M_header)); }
306  const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
307  const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
308 
309  iterator
310  insert(iterator /* ignored */, const_reference __V)
311  {
312  return this->insert(__V);
313  }
314 
315  iterator
316  insert(const_reference __V)
317  {
318  if (!_M_get_root())
319  {
320  _Link_type __n = _M_new_node(__V, &_M_header);
321  ++_M_count;
322  _M_set_root(__n);
323  _M_set_leftmost(__n);
324  _M_set_rightmost(__n);
325  return iterator(__n);
326  }
327  return _M_insert(_M_get_root(), __V, 0);
328  }
329 
330  template <class _InputIterator>
331  void insert(_InputIterator __first, _InputIterator __last) {
332  for (; __first != __last; ++__first)
333  this->insert(*__first);
334  }
335 
336  void
337  insert(iterator __pos, size_type __n, const value_type& __x)
338  {
339  for (; __n > 0; --__n)
340  this->insert(__pos, __x);
341  }
342 
343  template<typename _InputIterator>
344  void
345  insert(iterator __pos, _InputIterator __first, _InputIterator __last) {
346  for (; __first != __last; ++__first)
347  this->insert(__pos, *__first);
348  }
349 
350  // Note: this uses the find() to location the item you want to erase.
351  // find() compares by equivalence of location ONLY. See the comments
352  // above find_exact() for why you may not want this.
353  //
354  // If you want to erase ANY item that has the same location as __V,
355  // then use this function.
356  //
357  // If you want to erase a PARTICULAR item, and not any other item
358  // that might happen to have the same location, then you should use
359  // erase_exact().
360  void
361  erase(const_reference __V) {
362  const_iterator b = this->find(__V);
363  this->erase(b);
364  }
365 
366  void
367  erase_exact(const_reference __V) {
368  this->erase(this->find_exact(__V));
369  }
370 
371  // note: kept as const because its easier to const-cast it away
372  void
373  erase(const_iterator const& __IT)
374  {
375  assert(__IT != this->end());
376  _Link_const_type target = __IT.get_raw_node();
377  _Link_const_type n = target;
378  size_type level = 0;
379  while ((n = _S_parent(n)) != &_M_header)
380  ++level;
381  _M_erase( const_cast<_Link_type>(target), level );
382  _M_delete_node( const_cast<_Link_type>(target) );
383  --_M_count;
384  }
385 
386 /* this does not work since erasure changes sort order
387  void
388  erase(const_iterator __A, const_iterator const& __B)
389  {
390  if (0 && __A == this->begin() && __B == this->end())
391  {
392  this->clear();
393  }
394  else
395  {
396  while (__A != __B)
397  this->erase(__A++);
398  }
399  }
400 */
401 
402  // compares via equivalence
403  // so if you are looking for any item with the same location,
404  // according to the standard accessor comparisions,
405  // then this is the function for you.
406  template <class SearchVal>
407  const_iterator
408  find(SearchVal const& __V) const
409  {
410  if (!_M_get_root()) return this->end();
411  return _M_find(_M_get_root(), __V, 0);
412  }
413 
414  // compares via equality
415  // if you are looking for a particular item in the tree,
416  // and (for example) it has an ID that is checked via an == comparison
417  // eg
418  // struct Item
419  // {
420  // size_type unique_id;
421  // bool operator==(Item const& a, Item const& b) { return a.unique_id == b.unique_id; }
422  // Location location;
423  // };
424  // Two items may be equivalent in location. find() would return
425  // either one of them. But no two items have the same ID, so
426  // find_exact() would always return the item with the same location AND id.
427  //
428  template <class SearchVal>
429  const_iterator
430  find_exact(SearchVal const& __V) const
431  {
432  if (!_M_get_root()) return this->end();
433  return _M_find_exact(_M_get_root(), __V, 0);
434  }
435 
436  size_type
437  count_within_range(const_reference __V, subvalue_type const __R) const
438  {
439  if (!_M_get_root()) return 0;
440  _Region_ __region(__V, __R, _M_acc, _M_cmp);
441  return this->count_within_range(__region);
442  }
443 
444  size_type
445  count_within_range(_Region_ const& __REGION) const
446  {
447  if (!_M_get_root()) return 0;
448 
449  _Region_ __bounds(__REGION);
450  return _M_count_within_range(_M_get_root(),
451  __REGION, __bounds, 0);
452  }
453 
454  template <typename SearchVal, class Visitor>
455  Visitor
456  visit_within_range(SearchVal const& V, subvalue_type const R, Visitor visitor) const
457  {
458  if (!_M_get_root()) return visitor;
459  _Region_ region(V, R, _M_acc, _M_cmp);
460  return this->visit_within_range(region, visitor);
461  }
462 
463  template <class Visitor>
464  Visitor
465  visit_within_range(_Region_ const& REGION, Visitor visitor) const
466  {
467  if (_M_get_root())
468  {
469  _Region_ bounds(REGION);
470  return _M_visit_within_range(visitor, _M_get_root(), REGION, bounds, 0);
471  }
472  return visitor;
473  }
474 
475  const_iterator
476  find_within_range_iterative(const_reference __a, const_reference __b)
477  {
478  return const_iterator(begin());
479  }
480 
481  template <typename SearchVal, typename _OutputIterator>
482  _OutputIterator
483  find_within_range(SearchVal const& val, subvalue_type const range,
484  _OutputIterator out) const
485  {
486  if (!_M_get_root()) return out;
487  _Region_ region(val, range, _M_acc, _M_cmp);
488  return this->find_within_range(region, out);
489  }
490 
491  template <typename _OutputIterator>
492  _OutputIterator
493  find_within_range(_Region_ const& region,
494  _OutputIterator out) const
495  {
496  if (_M_get_root())
497  {
498  _Region_ bounds(region);
499  out = _M_find_within_range(out, _M_get_root(),
500  region, bounds, 0);
501  }
502  return out;
503  }
504 
505  template <class SearchVal>
506  std::pair<const_iterator, distance_type>
507  find_nearest (SearchVal const& __val) const
508  {
509  if (_M_get_root())
510  {
511  std::pair<const _Node<_Val>*,
512  std::pair<size_type, typename _Acc::result_type> >
513  best = _S_node_nearest (__K, 0, __val,
514  _M_get_root(), &_M_header, _M_get_root(),
516  (__K, _M_dist, _M_acc, _M_get_root()->_M_value, __val)),
517  _M_cmp, _M_acc, _M_dist,
519  return std::pair<const_iterator, distance_type>
520  (best.first, best.second.second);
521  }
522  return std::pair<const_iterator, distance_type>(end(), 0);
523  }
524 
525  template <class SearchVal>
526  std::pair<const_iterator, distance_type>
527  find_nearest (SearchVal const& __val, distance_type __max) const
528  {
529  if (_M_get_root())
530  {
531  bool root_is_candidate = false;
532  const _Node<_Val>* node = _M_get_root();
533  { // scope to ensure we don't use 'root_dist' anywhere else
534  distance_type root_dist = sqrt(_S_accumulate_node_distance
535  (__K, _M_dist, _M_acc, _M_get_root()->_M_value, __val));
536  if (root_dist <= __max)
537  {
538  root_is_candidate = true;
539  __max = root_dist;
540  }
541  }
542  std::pair<const _Node<_Val>*,
543  std::pair<size_type, typename _Acc::result_type> >
544  best = _S_node_nearest (__K, 0, __val, _M_get_root(), &_M_header,
545  node, __max, _M_cmp, _M_acc, _M_dist,
547  // make sure we didn't just get stuck with the root node...
548  if (root_is_candidate || best.first != _M_get_root())
549  return std::pair<const_iterator, distance_type>
550  (best.first, best.second.second);
551  }
552  return std::pair<const_iterator, distance_type>(end(), __max);
553  }
554 
555  template <class SearchVal, class _Predicate>
556  std::pair<const_iterator, distance_type>
557  find_nearest_if (SearchVal const& __val, distance_type __max,
558  _Predicate __p) const
559  {
560  if (_M_get_root())
561  {
562  bool root_is_candidate = false;
563  const _Node<_Val>* node = _M_get_root();
564  if (__p(_M_get_root()->_M_value))
565  {
566  { // scope to ensure we don't use root_dist anywhere else
567  distance_type root_dist = sqrt(_S_accumulate_node_distance
568  (__K, _M_dist, _M_acc, _M_get_root()->_M_value, __val));
569  if (root_dist <= __max)
570  {
571  root_is_candidate = true;
572  root_dist = __max;
573  }
574  }
575  }
576  std::pair<const _Node<_Val>*,
577  std::pair<size_type, typename _Acc::result_type> >
578  best = _S_node_nearest (__K, 0, __val, _M_get_root(), &_M_header,
579  node, __max, _M_cmp, _M_acc, _M_dist, __p);
580  // make sure we didn't just get stuck with the root node...
581  if (root_is_candidate || best.first != _M_get_root())
582  return std::pair<const_iterator, distance_type>
583  (best.first, best.second.second);
584  }
585  return std::pair<const_iterator, distance_type>(end(), __max);
586  }
587 
588  void
589  optimise()
590  {
591  std::vector<value_type> __v(this->begin(),this->end());
592  this->clear();
593  _M_optimise(__v.begin(), __v.end(), 0);
594  }
595 
596  void
597  optimize()
598  { // cater for people who cannot spell :)
599  this->optimise();
600  }
601 
602  void check_tree()
603  {
604  _M_check_node(_M_get_root(),0);
605  }
606 
607  protected:
608 
609  void _M_check_children( _Link_const_type child, _Link_const_type parent, size_type const level, bool to_the_left )
610  {
611  assert(parent);
612  if (child)
613  {
614  _Node_compare_ compare(level % __K, _M_acc, _M_cmp);
615  // REMEMBER! its a <= relationship for BOTH branches
616  // for left-case (true), child<=node --> !(node<child)
617  // for right-case (false), node<=child --> !(child<node)
618  assert(!to_the_left || !compare(parent->_M_value,child->_M_value)); // check the left
619  assert(to_the_left || !compare(child->_M_value,parent->_M_value)); // check the right
620  // and recurse down the tree, checking everything
621  _M_check_children(_S_left(child),parent,level,to_the_left);
622  _M_check_children(_S_right(child),parent,level,to_the_left);
623  }
624  }
625 
626  void _M_check_node( _Link_const_type node, size_type const level )
627  {
628  if (node)
629  {
630  // (comparing on this level)
631  // everything to the left of this node must be smaller than this
632  _M_check_children( _S_left(node), node, level, true );
633  // everything to the right of this node must be larger than this
634  _M_check_children( _S_right(node), node, level, false );
635 
636  _M_check_node( _S_left(node), level+1 );
637  _M_check_node( _S_right(node), level+1 );
638  }
639  }
640 
641  void _M_empty_initialise()
642  {
643  _M_set_leftmost(&_M_header);
644  _M_set_rightmost(&_M_header);
645  _M_header._M_parent = NULL;
646  _M_set_root(NULL);
647  }
648 
649  iterator
650  _M_insert_left(_Link_type __N, const_reference __V)
651  {
652  _S_set_left(__N, _M_new_node(__V)); ++_M_count;
653  _S_set_parent( _S_left(__N), __N );
654  if (__N == _M_get_leftmost())
655  _M_set_leftmost( _S_left(__N) );
656  return iterator(_S_left(__N));
657  }
658 
659  iterator
660  _M_insert_right(_Link_type __N, const_reference __V)
661  {
662  _S_set_right(__N, _M_new_node(__V)); ++_M_count;
663  _S_set_parent( _S_right(__N), __N );
664  if (__N == _M_get_rightmost())
665  _M_set_rightmost( _S_right(__N) );
666  return iterator(_S_right(__N));
667  }
668 
669  iterator
670  _M_insert(_Link_type __N, const_reference __V,
671  size_type const __L)
672  {
673  if (_Node_compare_(__L % __K, _M_acc, _M_cmp)(__V, __N->_M_value))
674  {
675  if (!_S_left(__N))
676  return _M_insert_left(__N, __V);
677  return _M_insert(_S_left(__N), __V, __L+1);
678  }
679  else
680  {
681  if (!_S_right(__N) || __N == _M_get_rightmost())
682  return _M_insert_right(__N, __V);
683  return _M_insert(_S_right(__N), __V, __L+1);
684  }
685  }
686 
687  _Link_type
688  _M_erase(_Link_type dead_dad, size_type const level)
689  {
690  // find a new step_dad, he will become a drop-in replacement.
691  _Link_type step_dad = _M_get_erase_replacement(dead_dad, level);
692 
693  // tell dead_dad's parent that his new child is step_dad
694  if (dead_dad == _M_get_root())
695  _M_set_root(step_dad);
696  else if (_S_left(_S_parent(dead_dad)) == dead_dad)
697  _S_set_left(_S_parent(dead_dad), step_dad);
698  else
699  _S_set_right(_S_parent(dead_dad), step_dad);
700 
701  // deal with the left and right edges of the tree...
702  // if the dead_dad was at the edge, then substitude...
703  // but if there IS no new dead, then left_most is the dead_dad's parent
704  if (dead_dad == _M_get_leftmost())
705  _M_set_leftmost( (step_dad ? step_dad : _S_parent(dead_dad)) );
706  if (dead_dad == _M_get_rightmost())
707  _M_set_rightmost( (step_dad ? step_dad : _S_parent(dead_dad)) );
708 
709  if (step_dad)
710  {
711  // step_dad gets dead_dad's parent
712  _S_set_parent(step_dad, _S_parent(dead_dad));
713 
714  // first tell the children that step_dad is their new dad
715  if (_S_left(dead_dad))
716  _S_set_parent(_S_left(dead_dad), step_dad);
717  if (_S_right(dead_dad))
718  _S_set_parent(_S_right(dead_dad), step_dad);
719 
720  // step_dad gets dead_dad's children
721  _S_set_left(step_dad, _S_left(dead_dad));
722  _S_set_right(step_dad, _S_right(dead_dad));
723  }
724 
725  return step_dad;
726  }
727 
728 
729 
730  _Link_type
731  _M_get_erase_replacement(_Link_type node, size_type const level)
732  {
733  // if 'node' is null, then we can't do any better
734  if (_S_is_leaf(node))
735  return NULL;
736 
737  std::pair<_Link_type,size_type> candidate;
738  // if there is nothing to the left, find a candidate on the right tree
739  if (!_S_left(node))
740  candidate = _M_get_j_min( std::pair<_Link_type,size_type>(_S_right(node),level), level+1);
741  // ditto for the right
742  else if ((!_S_right(node)))
743  candidate = _M_get_j_max( std::pair<_Link_type,size_type>(_S_left(node),level), level+1);
744  // we have both children ...
745  else
746  {
747  // we need to do a little more work in order to find a good candidate
748  // this is actually a technique used to choose a node from either the
749  // left or right branch RANDOMLY, so that the tree has a greater change of
750  // staying balanced.
751  // If this were a true binary tree, we would always hunt down the right branch.
752  // See top for notes.
753  _Node_compare_ compare(level % __K, _M_acc, _M_cmp);
754  // compare the children based on this level's criteria...
755  // (this gives virtually random results)
756  if (compare(_S_right(node)->_M_value, _S_left(node)->_M_value))
757  // the right is smaller, get our replacement from the SMALLEST on the right
758  candidate = _M_get_j_min(std::pair<_Link_type,size_type>(_S_right(node),level), level+1);
759  else
760  candidate = _M_get_j_max( std::pair<_Link_type,size_type>(_S_left(node),level), level+1);
761  }
762 
763  // we have a candidate replacement by now.
764  // remove it from the tree, but don't delete it.
765  // it must be disconnected before it can be reconnected.
766  _Link_type parent = _S_parent(candidate.first);
767  if (_S_left(parent) == candidate.first)
768  _S_set_left(parent, _M_erase(candidate.first, candidate.second));
769  else
770  _S_set_right(parent, _M_erase(candidate.first, candidate.second));
771 
772  return candidate.first;
773  }
774 
775 
776 
777  std::pair<_Link_type,size_type>
778  _M_get_j_min( std::pair<_Link_type,size_type> const node, size_type const level)
779  {
780  typedef std::pair<_Link_type,size_type> Result;
781  if (_S_is_leaf(node.first))
782  return Result(node.first,level);
783 
784  _Node_compare_ compare(node.second % __K, _M_acc, _M_cmp);
785  Result candidate = node;
786  if (_S_left(node.first))
787  {
788  Result left = _M_get_j_min(Result(_S_left(node.first), node.second), level+1);
789  if (compare(left.first->_M_value, candidate.first->_M_value))
790  candidate = left;
791  }
792  if (_S_right(node.first))
793  {
794  Result right = _M_get_j_min( Result(_S_right(node.first),node.second), level+1);
795  if (compare(right.first->_M_value, candidate.first->_M_value))
796  candidate = right;
797  }
798  if (candidate.first == node.first)
799  return Result(candidate.first,level);
800 
801  return candidate;
802  }
803 
804 
805 
806  std::pair<_Link_type,size_type>
807  _M_get_j_max( std::pair<_Link_type,size_type> const node, size_type const level)
808  {
809  typedef std::pair<_Link_type,size_type> Result;
810 
811  if (_S_is_leaf(node.first))
812  return Result(node.first,level);
813 
814  _Node_compare_ compare(node.second % __K, _M_acc, _M_cmp);
815  Result candidate = node;
816  if (_S_left(node.first))
817  {
818  Result left = _M_get_j_max( Result(_S_left(node.first),node.second), level+1);
819  if (compare(candidate.first->_M_value, left.first->_M_value))
820  candidate = left;
821  }
822  if (_S_right(node.first))
823  {
824  Result right = _M_get_j_max(Result(_S_right(node.first),node.second), level+1);
825  if (compare(candidate.first->_M_value, right.first->_M_value))
826  candidate = right;
827  }
828 
829  if (candidate.first == node.first)
830  return Result(candidate.first,level);
831 
832  return candidate;
833  }
834 
835 
836  void
837  _M_erase_subtree(_Link_type __n)
838  {
839  while (__n)
840  {
841  _M_erase_subtree(_S_right(__n));
842  _Link_type __t = _S_left(__n);
843  _M_delete_node(__n);
844  __n = __t;
845  }
846  }
847 
848  const_iterator
849  _M_find(_Link_const_type node, const_reference value, size_type const level) const
850  {
851  // be aware! This is very different to normal binary searches, because of the <=
852  // relationship used. See top for notes.
853  // Basically we have to check ALL branches, as we may have an identical node
854  // in different branches.
855  const_iterator found = this->end();
856 
857  _Node_compare_ compare(level % __K, _M_acc, _M_cmp);
858  if (!compare(node->_M_value,value)) // note, this is a <= test
859  {
860  // this line is the only difference between _M_find_exact() and _M_find()
861  if (_M_matches_node(node, value, level))
862  return const_iterator(node); // return right away
863  if (_S_left(node))
864  found = _M_find(_S_left(node), value, level+1);
865  }
866  if ( _S_right(node) && found == this->end() && !compare(value,node->_M_value)) // note, this is a <= test
867  found = _M_find(_S_right(node), value, level+1);
868  return found;
869  }
870 
871  const_iterator
872  _M_find_exact(_Link_const_type node, const_reference value, size_type const level) const
873  {
874  // be aware! This is very different to normal binary searches, because of the <=
875  // relationship used. See top for notes.
876  // Basically we have to check ALL branches, as we may have an identical node
877  // in different branches.
878  const_iterator found = this->end();
879 
880  _Node_compare_ compare(level % __K, _M_acc, _M_cmp);
881  if (!compare(node->_M_value,value)) // note, this is a <= test
882  {
883  // this line is the only difference between _M_find_exact() and _M_find()
884  if (value == *const_iterator(node))
885  return const_iterator(node); // return right away
886  if (_S_left(node))
887  found = _M_find_exact(_S_left(node), value, level+1);
888  }
889 
890  // note: no else! items that are identical can be down both branches
891  if ( _S_right(node) && found == this->end() && !compare(value,node->_M_value)) // note, this is a <= test
892  found = _M_find_exact(_S_right(node), value, level+1);
893  return found;
894  }
895 
896  bool
897  _M_matches_node_in_d(_Link_const_type __N, const_reference __V,
898  size_type const __L) const
899  {
900  _Node_compare_ compare(__L % __K, _M_acc, _M_cmp);
901  return !(compare(__N->_M_value, __V) || compare(__V, __N->_M_value));
902  }
903 
904  bool
905  _M_matches_node_in_other_ds(_Link_const_type __N, const_reference __V,
906  size_type const __L = 0) const
907  {
908  size_type __i = __L;
909  while ((__i = (__i + 1) % __K) != __L % __K)
910  if (!_M_matches_node_in_d(__N, __V, __i)) return false;
911  return true;
912  }
913 
914  bool
915  _M_matches_node(_Link_const_type __N, const_reference __V,
916  size_type __L = 0) const
917  {
918  return _M_matches_node_in_d(__N, __V, __L)
919  && _M_matches_node_in_other_ds(__N, __V, __L);
920  }
921 
922  size_type
923  _M_count_within_range(_Link_const_type __N, _Region_ const& __REGION,
924  _Region_ const& __BOUNDS,
925  size_type const __L) const
926  {
927  size_type count = 0;
928  if (__REGION.encloses(_S_value(__N)))
929  {
930  ++count;
931  }
932  if (_S_left(__N))
933  {
934  _Region_ __bounds(__BOUNDS);
935  __bounds.set_high_bound(_S_value(__N), __L);
936  if (__REGION.intersects_with(__bounds))
937  count += _M_count_within_range(_S_left(__N),
938  __REGION, __bounds, __L+1);
939  }
940  if (_S_right(__N))
941  {
942  _Region_ __bounds(__BOUNDS);
943  __bounds.set_low_bound(_S_value(__N), __L);
944  if (__REGION.intersects_with(__bounds))
945  count += _M_count_within_range(_S_right(__N),
946  __REGION, __bounds, __L+1);
947  }
948 
949  return count;
950  }
951 
952 
953  template <class Visitor>
954  Visitor
955  _M_visit_within_range(Visitor visitor,
956  _Link_const_type N, _Region_ const& REGION,
957  _Region_ const& BOUNDS,
958  size_type const L) const
959  {
960  if (REGION.encloses(_S_value(N)))
961  {
962  visitor(_S_value(N));
963  }
964  if (_S_left(N))
965  {
966  _Region_ bounds(BOUNDS);
967  bounds.set_high_bound(_S_value(N), L);
968  if (REGION.intersects_with(bounds))
969  visitor = _M_visit_within_range(visitor, _S_left(N),
970  REGION, bounds, L+1);
971  }
972  if (_S_right(N))
973  {
974  _Region_ bounds(BOUNDS);
975  bounds.set_low_bound(_S_value(N), L);
976  if (REGION.intersects_with(bounds))
977  visitor = _M_visit_within_range(visitor, _S_right(N),
978  REGION, bounds, L+1);
979  }
980 
981  return visitor;
982  }
983 
984 
985 
986  template <typename _OutputIterator>
987  _OutputIterator
988  _M_find_within_range(_OutputIterator out,
989  _Link_const_type __N, _Region_ const& __REGION,
990  _Region_ const& __BOUNDS,
991  size_type const __L) const
992  {
993  if (__REGION.encloses(_S_value(__N)))
994  {
995  *out++ = _S_value(__N);
996  }
997  if (_S_left(__N))
998  {
999  _Region_ __bounds(__BOUNDS);
1000  __bounds.set_high_bound(_S_value(__N), __L);
1001  if (__REGION.intersects_with(__bounds))
1002  out = _M_find_within_range(out, _S_left(__N),
1003  __REGION, __bounds, __L+1);
1004  }
1005  if (_S_right(__N))
1006  {
1007  _Region_ __bounds(__BOUNDS);
1008  __bounds.set_low_bound(_S_value(__N), __L);
1009  if (__REGION.intersects_with(__bounds))
1010  out = _M_find_within_range(out, _S_right(__N),
1011  __REGION, __bounds, __L+1);
1012  }
1013 
1014  return out;
1015  }
1016 
1017 
1018  template <typename _Iter>
1019  void
1020  _M_optimise(_Iter const& __A, _Iter const& __B,
1021  size_type const __L)
1022  {
1023  if (__A == __B) return;
1024  _Node_compare_ compare(__L % __K, _M_acc, _M_cmp);
1025  _Iter __m = __A + (__B - __A) / 2;
1026  std::nth_element(__A, __m, __B, compare);
1027  this->insert(*__m);
1028  if (__m != __A) _M_optimise(__A, __m, __L+1);
1029  if (++__m != __B) _M_optimise(__m, __B, __L+1);
1030  }
1031 
1032  _Link_const_type
1033  _M_get_root() const
1034  {
1035  return const_cast<_Link_const_type>(_M_root);
1036  }
1037 
1038  _Link_type
1039  _M_get_root()
1040  {
1041  return _M_root;
1042  }
1043 
1044  void _M_set_root(_Link_type n)
1045  {
1046  _M_root = n;
1047  }
1048 
1049  _Link_const_type
1050  _M_get_leftmost() const
1051  {
1052  return static_cast<_Link_type>(_M_header._M_left);
1053  }
1054 
1055  void
1056  _M_set_leftmost( _Node_base * a )
1057  {
1058  _M_header._M_left = a;
1059  }
1060 
1061  _Link_const_type
1062  _M_get_rightmost() const
1063  {
1064  return static_cast<_Link_type>( _M_header._M_right );
1065  }
1066 
1067  void
1068  _M_set_rightmost( _Node_base * a )
1069  {
1070  _M_header._M_right = a;
1071  }
1072 
1073  static _Link_type
1074  _S_parent(_Base_ptr N)
1075  {
1076  return static_cast<_Link_type>( N->_M_parent );
1077  }
1078 
1079  static _Link_const_type
1080  _S_parent(_Base_const_ptr N)
1081  {
1082  return static_cast<_Link_const_type>( N->_M_parent );
1083  }
1084 
1085  static void
1086  _S_set_parent(_Base_ptr N, _Base_ptr p)
1087  {
1088  N->_M_parent = p;
1089  }
1090 
1091  static void
1092  _S_set_left(_Base_ptr N, _Base_ptr l)
1093  {
1094  N->_M_left = l;
1095  }
1096 
1097  static _Link_type
1098  _S_left(_Base_ptr N)
1099  {
1100  return static_cast<_Link_type>( N->_M_left );
1101  }
1102 
1103  static _Link_const_type
1104  _S_left(_Base_const_ptr N)
1105  {
1106  return static_cast<_Link_const_type>( N->_M_left );
1107  }
1108 
1109  static void
1110  _S_set_right(_Base_ptr N, _Base_ptr r)
1111  {
1112  N->_M_right = r;
1113  }
1114 
1115  static _Link_type
1116  _S_right(_Base_ptr N)
1117  {
1118  return static_cast<_Link_type>( N->_M_right );
1119  }
1120 
1121  static _Link_const_type
1122  _S_right(_Base_const_ptr N)
1123  {
1124  return static_cast<_Link_const_type>( N->_M_right );
1125  }
1126 
1127  static bool
1128  _S_is_leaf(_Base_const_ptr N)
1129  {
1130  return !_S_left(N) && !_S_right(N);
1131  }
1132 
1133  static const_reference
1134  _S_value(_Link_const_type N)
1135  {
1136  return N->_M_value;
1137  }
1138 
1139  static const_reference
1140  _S_value(_Base_const_ptr N)
1141  {
1142  return static_cast<_Link_const_type>(N)->_M_value;
1143  }
1144 
1145  static _Link_const_type
1146  _S_minimum(_Link_const_type __X)
1147  {
1148  return static_cast<_Link_const_type> ( _Node_base::_S_minimum(__X) );
1149  }
1150 
1151  static _Link_const_type
1152  _S_maximum(_Link_const_type __X)
1153  {
1154  return static_cast<_Link_const_type>( _Node_base::_S_maximum(__X) );
1155  }
1156 
1157 
1158  _Link_type
1159  _M_new_node(const_reference __V, // = value_type(),
1160  _Base_ptr const __PARENT = NULL,
1161  _Base_ptr const __LEFT = NULL,
1162  _Base_ptr const __RIGHT = NULL)
1163  {
1164  typename _Base::NoLeakAlloc noleak(this);
1165  _Link_type new_node = noleak.get();
1166  this->_M_construct_node(new_node, __V, __PARENT, __LEFT, __RIGHT);
1167  noleak.disconnect();
1168  return new_node;
1169  }
1170 
1171  /* WHAT was this for?
1172  _Link_type
1173  _M_clone_node(_Link_const_type __X)
1174  {
1175  _Link_type __ret = _M_allocate_node(__X->_M_value);
1176  // TODO
1177  return __ret;
1178  }
1179  */
1180 
1181  void _M_delete_node(_Link_type __p)
1182  {
1183  this->_M_destroy_node(__p);
1184  this->_M_deallocate_node(__p);
1185  }
1186 
1187  _Link_type _M_root;
1188  _Node_base _M_header;
1189  size_type _M_count;
1190  _Acc _M_acc;
1191  _Cmp _M_cmp;
1192  _Dist _M_dist;
1193 
1194 #ifdef KDTREE_DEFINE_OSTREAM_OPERATORS
1195  friend std::ostream&
1196  operator<<(std::ostream& o,
1198  {
1199  o << "meta node: " << tree._M_header << std::endl;
1200  o << "root node: " << tree._M_root << std::endl;
1201 
1202  if (tree.empty())
1203  return o << "[empty " << __K << "d-tree " << &tree << "]";
1204 
1205  o << "nodes total: " << tree.size() << std::endl;
1206  o << "dimensions: " << __K << std::endl;
1207 
1209  typedef typename _Tree::_Link_type _Link_type;
1210 
1211  std::stack<_Link_const_type> s;
1212  s.push(tree._M_get_root());
1213 
1214  while (!s.empty())
1215  {
1216  _Link_const_type n = s.top();
1217  s.pop();
1218  o << *n << std::endl;
1219  if (_Tree::_S_left(n)) s.push(_Tree::_S_left(n));
1220  if (_Tree::_S_right(n)) s.push(_Tree::_S_right(n));
1221  }
1222 
1223  return o;
1224  }
1225 #endif
1226 
1227  };
1228 
1229 
1230 } // namespace kd_tree
1231 
1232 #endif // include guard
1233 
1234 /* COPYRIGHT --
1235  *
1236  * This file is part of libkdtree++, a C++ template KD-Tree sorting container.
1237  * libkdtree++ is (c) 2004-2007 Martin F. Krafft <libkdtree@pobox.madduck.net>
1238  * and Sylvain Bougerel <sylvain.bougerel.devel@gmail.com> distributed under the
1239  * terms of the Artistic License 2.0. See the ./COPYING file in the source tree
1240  * root for more information.
1241  * Parts of this file are (c) 2004-2007 Paul Harris <paulharris@computer.org>.
1242  *
1243  * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
1244  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES
1245  * OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1246  */
_Cmp value_comp() const
Comparator for the values in the KDTree.
Definition: kdtree.hpp:268
std::pair< const _Node< _Val > *, std::pair< size_t, typename _Dist::distance_type > > _S_node_nearest(const size_t __k, size_t __dim, SearchVal const &__val, const _Node< _Val > *__node, const _Node_base *__end, const _Node< _Val > *__best, typename _Dist::distance_type __max, const _Cmp &__cmp, const _Acc &__acc, const _Dist &__dist, _Predicate __p)
Definition: node.hpp:199
Definition: iterator.hpp:17
const _Dist & value_distance() const
Distance calculator between 2 value&#39;s element.
Definition: kdtree.hpp:287
Defines the interface of the _Region class.
Definition: kdtree.hpp:99
Definition: node.hpp:95
Defines the various functors and interfaces used for KDTree.
Definition: region.hpp:19
Definition: node.hpp:49
_Dist::distance_type _S_accumulate_node_distance(const size_t __dim, const _Dist &__dist, const _Acc &__acc, const _ValA &__a, const _ValB &__b)
Definition: node.hpp:156
Definition: function.hpp:28
Defines the allocator interface as used by the KDTree class.
Definition: node.hpp:19
_Acc value_acc() const
Accessor to the value&#39;s elements.
Definition: kdtree.hpp:277
Definition: allocator.hpp:18
Defines interfaces for nodes as used by the KDTree class.
Definition: allocator.hpp:14
Defines interfaces for iterators as used by the KDTree class.