Geophysical Inversion and Modelling Library v1.5.4
Loading...
Searching...
No Matches
kdtree.hpp
Go to the documentation of this file.
1
45
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
86namespace KDTree
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:
102 typedef _Alloc_base<_Val, _Alloc> _Base;
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
110 typedef _Node_compare<_Val, _Acc, _Cmp> _Node_compare_;
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 std::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
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&
291 value_distance()
292 { return _M_dist; }
293
294 // typedef _Iterator<_Val, reference, pointer> iterator;
295 typedef _Iterator<_Val, const_reference, const_pointer> const_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,
514 0,
515 __val,
516 _M_get_root(),
517 &_M_header,
518 _M_get_root(),
520 _M_dist,
521 _M_acc,
522 _M_get_root()->_M_value,
523 __val)
524 ),
525 _M_cmp,
526 _M_acc,
527 _M_dist,
529 return std::pair<const_iterator, distance_type>
530 (best.first, best.second.second);
531 }
532 return std::pair<const_iterator, distance_type>(end(), 0);
533 }
534
535 template <class SearchVal>
536 std::pair<const_iterator, distance_type>
537 find_nearest (SearchVal const& __val, distance_type __max) const
538 {
539 if (_M_get_root())
540 {
541 bool root_is_candidate = false;
542 const _Node<_Val>* node = _M_get_root();
543 { // scope to ensure we don't use 'root_dist' anywhere else
544 distance_type root_dist = sqrt(_S_accumulate_node_distance
545 (__K, _M_dist, _M_acc, _M_get_root()->_M_value, __val));
546 if (root_dist <= __max)
547 {
548 root_is_candidate = true;
549 __max = root_dist;
550 }
551 }
552 std::pair<const _Node<_Val>*,
553 std::pair<size_type, typename _Acc::result_type> >
554 best = _S_node_nearest (__K, 0, __val, _M_get_root(), &_M_header,
555 node, __max, _M_cmp, _M_acc, _M_dist,
557 // make sure we didn't just get stuck with the root node...
558 if (root_is_candidate || best.first != _M_get_root())
559 return std::pair<const_iterator, distance_type>
560 (best.first, best.second.second);
561 }
562 return std::pair<const_iterator, distance_type>(end(), __max);
563 }
564
565 template <class SearchVal, class _Predicate>
566 std::pair<const_iterator, distance_type>
567 find_nearest_if (SearchVal const& __val, distance_type __max,
568 _Predicate __p) const
569 {
570 if (_M_get_root())
571 {
572 bool root_is_candidate = false;
573 const _Node<_Val>* node = _M_get_root();
574 if (__p(_M_get_root()->_M_value))
575 {
576 { // scope to ensure we don't use root_dist anywhere else
577 distance_type root_dist = sqrt(_S_accumulate_node_distance
578 (__K, _M_dist, _M_acc, _M_get_root()->_M_value, __val));
579 if (root_dist <= __max)
580 {
581 root_is_candidate = true;
582 root_dist = __max;
583 }
584 }
585 }
586 std::pair<const _Node<_Val>*,
587 std::pair<size_type, typename _Acc::result_type> >
588 best = _S_node_nearest (__K, 0, __val, _M_get_root(), &_M_header,
589 node, __max, _M_cmp, _M_acc, _M_dist, __p);
590 // make sure we didn't just get stuck with the root node...
591 if (root_is_candidate || best.first != _M_get_root())
592 return std::pair<const_iterator, distance_type>
593 (best.first, best.second.second);
594 }
595 return std::pair<const_iterator, distance_type>(end(), __max);
596 }
597
598 void
599 optimise()
600 {
601 std::vector<value_type> __v(this->begin(),this->end());
602 this->clear();
603 _M_optimise(__v.begin(), __v.end(), 0);
604 }
605
606 void
607 optimize()
608 { // cater for people who cannot spell :)
609 this->optimise();
610 }
611
612 void check_tree()
613 {
614 _M_check_node(_M_get_root(),0);
615 }
616
617 protected:
618
619 void _M_check_children( _Link_const_type child, _Link_const_type parent, size_type const level, bool to_the_left )
620 {
621 assert(parent);
622 if (child)
623 {
624 _Node_compare_ compare(level % __K, _M_acc, _M_cmp);
625 // REMEMBER! its a <= relationship for BOTH branches
626 // for left-case (true), child<=node --> !(node<child)
627 // for right-case (false), node<=child --> !(child<node)
628 assert(!to_the_left || !compare(parent->_M_value,child->_M_value)); // check the left
629 assert(to_the_left || !compare(child->_M_value,parent->_M_value)); // check the right
630 // and recurse down the tree, checking everything
631 _M_check_children(_S_left(child),parent,level,to_the_left);
632 _M_check_children(_S_right(child),parent,level,to_the_left);
633 }
634 }
635
636 void _M_check_node( _Link_const_type node, size_type const level )
637 {
638 if (node)
639 {
640 // (comparing on this level)
641 // everything to the left of this node must be smaller than this
642 _M_check_children( _S_left(node), node, level, true );
643 // everything to the right of this node must be larger than this
644 _M_check_children( _S_right(node), node, level, false );
645
646 _M_check_node( _S_left(node), level+1 );
647 _M_check_node( _S_right(node), level+1 );
648 }
649 }
650
651 void _M_empty_initialise()
652 {
653 _M_set_leftmost(&_M_header);
654 _M_set_rightmost(&_M_header);
655 _M_header._M_parent = NULL;
656 _M_set_root(NULL);
657 }
658
659 iterator
660 _M_insert_left(_Link_type __N, const_reference __V)
661 {
662 _S_set_left(__N, _M_new_node(__V)); ++_M_count;
663 _S_set_parent( _S_left(__N), __N );
664 if (__N == _M_get_leftmost())
665 _M_set_leftmost( _S_left(__N) );
666 return iterator(_S_left(__N));
667 }
668
669 iterator
670 _M_insert_right(_Link_type __N, const_reference __V)
671 {
672 _S_set_right(__N, _M_new_node(__V)); ++_M_count;
673 _S_set_parent( _S_right(__N), __N );
674 if (__N == _M_get_rightmost())
675 _M_set_rightmost( _S_right(__N) );
676 return iterator(_S_right(__N));
677 }
678
679 iterator
680 _M_insert(_Link_type __N, const_reference __V,
681 size_type const __L)
682 {
683 if (_Node_compare_(__L % __K, _M_acc, _M_cmp)(__V, __N->_M_value))
684 {
685 if (!_S_left(__N))
686 return _M_insert_left(__N, __V);
687 return _M_insert(_S_left(__N), __V, __L+1);
688 }
689 else
690 {
691 if (!_S_right(__N) || __N == _M_get_rightmost())
692 return _M_insert_right(__N, __V);
693 return _M_insert(_S_right(__N), __V, __L+1);
694 }
695 }
696
697 _Link_type
698 _M_erase(_Link_type dead_dad, size_type const level)
699 {
700 // find a new step_dad, he will become a drop-in replacement.
701 _Link_type step_dad = _M_get_erase_replacement(dead_dad, level);
702
703 // tell dead_dad's parent that his new child is step_dad
704 if (dead_dad == _M_get_root())
705 _M_set_root(step_dad);
706 else if (_S_left(_S_parent(dead_dad)) == dead_dad)
707 _S_set_left(_S_parent(dead_dad), step_dad);
708 else
709 _S_set_right(_S_parent(dead_dad), step_dad);
710
711 // deal with the left and right edges of the tree...
712 // if the dead_dad was at the edge, then substitude...
713 // but if there IS no new dead, then left_most is the dead_dad's parent
714 if (dead_dad == _M_get_leftmost())
715 _M_set_leftmost( (step_dad ? step_dad : _S_parent(dead_dad)) );
716 if (dead_dad == _M_get_rightmost())
717 _M_set_rightmost( (step_dad ? step_dad : _S_parent(dead_dad)) );
718
719 if (step_dad)
720 {
721 // step_dad gets dead_dad's parent
722 _S_set_parent(step_dad, _S_parent(dead_dad));
723
724 // first tell the children that step_dad is their new dad
725 if (_S_left(dead_dad))
726 _S_set_parent(_S_left(dead_dad), step_dad);
727 if (_S_right(dead_dad))
728 _S_set_parent(_S_right(dead_dad), step_dad);
729
730 // step_dad gets dead_dad's children
731 _S_set_left(step_dad, _S_left(dead_dad));
732 _S_set_right(step_dad, _S_right(dead_dad));
733 }
734
735 return step_dad;
736 }
737
738
739
740 _Link_type
741 _M_get_erase_replacement(_Link_type node, size_type const level)
742 {
743 // if 'node' is null, then we can't do any better
744 if (_S_is_leaf(node))
745 return NULL;
746
747 std::pair<_Link_type,size_type> candidate;
748 // if there is nothing to the left, find a candidate on the right tree
749 if (!_S_left(node))
750 candidate = _M_get_j_min( std::pair<_Link_type,size_type>(_S_right(node),level), level+1);
751 // ditto for the right
752 else if ((!_S_right(node)))
753 candidate = _M_get_j_max( std::pair<_Link_type,size_type>(_S_left(node),level), level+1);
754 // we have both children ...
755 else
756 {
757 // we need to do a little more work in order to find a good candidate
758 // this is actually a technique used to choose a node from either the
759 // left or right branch RANDOMLY, so that the tree has a greater change of
760 // staying balanced.
761 // If this were a true binary tree, we would always hunt down the right branch.
762 // See top for notes.
763 _Node_compare_ compare(level % __K, _M_acc, _M_cmp);
764 // compare the children based on this level's criteria...
765 // (this gives virtually random results)
766 if (compare(_S_right(node)->_M_value, _S_left(node)->_M_value))
767 // the right is smaller, get our replacement from the SMALLEST on the right
768 candidate = _M_get_j_min(std::pair<_Link_type,size_type>(_S_right(node),level), level+1);
769 else
770 candidate = _M_get_j_max( std::pair<_Link_type,size_type>(_S_left(node),level), level+1);
771 }
772
773 // we have a candidate replacement by now.
774 // remove it from the tree, but don't delete it.
775 // it must be disconnected before it can be reconnected.
776 _Link_type parent = _S_parent(candidate.first);
777 if (_S_left(parent) == candidate.first)
778 _S_set_left(parent, _M_erase(candidate.first, candidate.second));
779 else
780 _S_set_right(parent, _M_erase(candidate.first, candidate.second));
781
782 return candidate.first;
783 }
784
785
786
787 std::pair<_Link_type,size_type>
788 _M_get_j_min( std::pair<_Link_type,size_type> const node, size_type const level)
789 {
790 typedef std::pair<_Link_type,size_type> Result;
791 if (_S_is_leaf(node.first))
792 return Result(node.first,level);
793
794 _Node_compare_ compare(node.second % __K, _M_acc, _M_cmp);
795 Result candidate = node;
796 if (_S_left(node.first))
797 {
798 Result left = _M_get_j_min(Result(_S_left(node.first), node.second), level+1);
799 if (compare(left.first->_M_value, candidate.first->_M_value))
800 candidate = left;
801 }
802 if (_S_right(node.first))
803 {
804 Result right = _M_get_j_min( Result(_S_right(node.first),node.second), level+1);
805 if (compare(right.first->_M_value, candidate.first->_M_value))
806 candidate = right;
807 }
808 if (candidate.first == node.first)
809 return Result(candidate.first,level);
810
811 return candidate;
812 }
813
814
815
816 std::pair<_Link_type,size_type>
817 _M_get_j_max( std::pair<_Link_type,size_type> const node, size_type const level)
818 {
819 typedef std::pair<_Link_type,size_type> Result;
820
821 if (_S_is_leaf(node.first))
822 return Result(node.first,level);
823
824 _Node_compare_ compare(node.second % __K, _M_acc, _M_cmp);
825 Result candidate = node;
826 if (_S_left(node.first))
827 {
828 Result left = _M_get_j_max( Result(_S_left(node.first),node.second), level+1);
829 if (compare(candidate.first->_M_value, left.first->_M_value))
830 candidate = left;
831 }
832 if (_S_right(node.first))
833 {
834 Result right = _M_get_j_max(Result(_S_right(node.first),node.second), level+1);
835 if (compare(candidate.first->_M_value, right.first->_M_value))
836 candidate = right;
837 }
838
839 if (candidate.first == node.first)
840 return Result(candidate.first,level);
841
842 return candidate;
843 }
844
845
846 void
847 _M_erase_subtree(_Link_type __n)
848 {
849 while (__n)
850 {
851 _M_erase_subtree(_S_right(__n));
852 _Link_type __t = _S_left(__n);
853 _M_delete_node(__n);
854 __n = __t;
855 }
856 }
857
858 const_iterator
859 _M_find(_Link_const_type node, const_reference value, size_type const level) const
860 {
861 // be aware! This is very different to normal binary searches, because of the <=
862 // relationship used. See top for notes.
863 // Basically we have to check ALL branches, as we may have an identical node
864 // in different branches.
865 const_iterator found = this->end();
866
867 _Node_compare_ compare(level % __K, _M_acc, _M_cmp);
868 if (!compare(node->_M_value,value)) // note, this is a <= test
869 {
870 // this line is the only difference between _M_find_exact() and _M_find()
871 if (_M_matches_node(node, value, level))
872 return const_iterator(node); // return right away
873 if (_S_left(node))
874 found = _M_find(_S_left(node), value, level+1);
875 }
876 if ( _S_right(node) && found == this->end() && !compare(value,node->_M_value)) // note, this is a <= test
877 found = _M_find(_S_right(node), value, level+1);
878 return found;
879 }
880
881 const_iterator
882 _M_find_exact(_Link_const_type node, const_reference value, size_type const level) const
883 {
884 // be aware! This is very different to normal binary searches, because of the <=
885 // relationship used. See top for notes.
886 // Basically we have to check ALL branches, as we may have an identical node
887 // in different branches.
888 const_iterator found = this->end();
889
890 _Node_compare_ compare(level % __K, _M_acc, _M_cmp);
891 if (!compare(node->_M_value,value)) // note, this is a <= test
892 {
893 // this line is the only difference between _M_find_exact() and _M_find()
894 if (value == *const_iterator(node))
895 return const_iterator(node); // return right away
896 if (_S_left(node))
897 found = _M_find_exact(_S_left(node), value, level+1);
898 }
899
900 // note: no else! items that are identical can be down both branches
901 if ( _S_right(node) && found == this->end() && !compare(value,node->_M_value)) // note, this is a <= test
902 found = _M_find_exact(_S_right(node), value, level+1);
903 return found;
904 }
905
906 bool
907 _M_matches_node_in_d(_Link_const_type __N, const_reference __V,
908 size_type const __L) const
909 {
910 _Node_compare_ compare(__L % __K, _M_acc, _M_cmp);
911 return !(compare(__N->_M_value, __V) || compare(__V, __N->_M_value));
912 }
913
914 bool
915 _M_matches_node_in_other_ds(_Link_const_type __N, const_reference __V,
916 size_type const __L = 0) const
917 {
918 size_type __i = __L;
919 while ((__i = (__i + 1) % __K) != __L % __K)
920 if (!_M_matches_node_in_d(__N, __V, __i)) return false;
921 return true;
922 }
923
924 bool
925 _M_matches_node(_Link_const_type __N, const_reference __V,
926 size_type __L = 0) const
927 {
928 return _M_matches_node_in_d(__N, __V, __L)
929 && _M_matches_node_in_other_ds(__N, __V, __L);
930 }
931
932 size_type
933 _M_count_within_range(_Link_const_type __N, _Region_ const& __REGION,
934 _Region_ const& __BOUNDS,
935 size_type const __L) const
936 {
937 size_type count = 0;
938 if (__REGION.encloses(_S_value(__N)))
939 {
940 ++count;
941 }
942 if (_S_left(__N))
943 {
944 _Region_ __bounds(__BOUNDS);
945 __bounds.set_high_bound(_S_value(__N), __L);
946 if (__REGION.intersects_with(__bounds))
947 count += _M_count_within_range(_S_left(__N),
948 __REGION, __bounds, __L+1);
949 }
950 if (_S_right(__N))
951 {
952 _Region_ __bounds(__BOUNDS);
953 __bounds.set_low_bound(_S_value(__N), __L);
954 if (__REGION.intersects_with(__bounds))
955 count += _M_count_within_range(_S_right(__N),
956 __REGION, __bounds, __L+1);
957 }
958
959 return count;
960 }
961
962
963 template <class Visitor>
964 Visitor
965 _M_visit_within_range(Visitor visitor,
966 _Link_const_type N, _Region_ const& REGION,
967 _Region_ const& BOUNDS,
968 size_type const L) const
969 {
970 if (REGION.encloses(_S_value(N)))
971 {
972 visitor(_S_value(N));
973 }
974 if (_S_left(N))
975 {
976 _Region_ bounds(BOUNDS);
977 bounds.set_high_bound(_S_value(N), L);
978 if (REGION.intersects_with(bounds))
979 visitor = _M_visit_within_range(visitor, _S_left(N),
980 REGION, bounds, L+1);
981 }
982 if (_S_right(N))
983 {
984 _Region_ bounds(BOUNDS);
985 bounds.set_low_bound(_S_value(N), L);
986 if (REGION.intersects_with(bounds))
987 visitor = _M_visit_within_range(visitor, _S_right(N),
988 REGION, bounds, L+1);
989 }
990
991 return visitor;
992 }
993
994
995
996 template <typename _OutputIterator>
997 _OutputIterator
998 _M_find_within_range(_OutputIterator out,
999 _Link_const_type __N, _Region_ const& __REGION,
1000 _Region_ const& __BOUNDS,
1001 size_type const __L) const
1002 {
1003 if (__REGION.encloses(_S_value(__N)))
1004 {
1005 *out++ = _S_value(__N);
1006 }
1007 if (_S_left(__N))
1008 {
1009 _Region_ __bounds(__BOUNDS);
1010 __bounds.set_high_bound(_S_value(__N), __L);
1011 if (__REGION.intersects_with(__bounds))
1012 out = _M_find_within_range(out, _S_left(__N),
1013 __REGION, __bounds, __L+1);
1014 }
1015 if (_S_right(__N))
1016 {
1017 _Region_ __bounds(__BOUNDS);
1018 __bounds.set_low_bound(_S_value(__N), __L);
1019 if (__REGION.intersects_with(__bounds))
1020 out = _M_find_within_range(out, _S_right(__N),
1021 __REGION, __bounds, __L+1);
1022 }
1023
1024 return out;
1025 }
1026
1027
1028 template <typename _Iter>
1029 void
1030 _M_optimise(_Iter const& __A, _Iter const& __B,
1031 size_type const __L)
1032 {
1033 if (__A == __B) return;
1034 _Node_compare_ compare(__L % __K, _M_acc, _M_cmp);
1035 _Iter __m = __A + (__B - __A) / 2;
1036 std::nth_element(__A, __m, __B, compare);
1037 this->insert(*__m);
1038 if (__m != __A) _M_optimise(__A, __m, __L+1);
1039 if (++__m != __B) _M_optimise(__m, __B, __L+1);
1040 }
1041
1042 _Link_const_type
1043 _M_get_root() const
1044 {
1045 return const_cast<_Link_const_type>(_M_root);
1046 }
1047
1048 _Link_type
1049 _M_get_root()
1050 {
1051 return _M_root;
1052 }
1053
1054 void _M_set_root(_Link_type n)
1055 {
1056 _M_root = n;
1057 }
1058
1059 _Link_const_type
1060 _M_get_leftmost() const
1061 {
1062 return static_cast<_Link_type>(_M_header._M_left);
1063 }
1064
1065 void
1066 _M_set_leftmost( _Node_base * a )
1067 {
1068 _M_header._M_left = a;
1069 }
1070
1071 _Link_const_type
1072 _M_get_rightmost() const
1073 {
1074 return static_cast<_Link_type>( _M_header._M_right );
1075 }
1076
1077 void
1078 _M_set_rightmost( _Node_base * a )
1079 {
1080 _M_header._M_right = a;
1081 }
1082
1083 static _Link_type
1084 _S_parent(_Base_ptr N)
1085 {
1086 return static_cast<_Link_type>( N->_M_parent );
1087 }
1088
1089 static _Link_const_type
1090 _S_parent(_Base_const_ptr N)
1091 {
1092 return static_cast<_Link_const_type>( N->_M_parent );
1093 }
1094
1095 static void
1096 _S_set_parent(_Base_ptr N, _Base_ptr p)
1097 {
1098 N->_M_parent = p;
1099 }
1100
1101 static void
1102 _S_set_left(_Base_ptr N, _Base_ptr l)
1103 {
1104 N->_M_left = l;
1105 }
1106
1107 static _Link_type
1108 _S_left(_Base_ptr N)
1109 {
1110 return static_cast<_Link_type>( N->_M_left );
1111 }
1112
1113 static _Link_const_type
1114 _S_left(_Base_const_ptr N)
1115 {
1116 return static_cast<_Link_const_type>( N->_M_left );
1117 }
1118
1119 static void
1120 _S_set_right(_Base_ptr N, _Base_ptr r)
1121 {
1122 N->_M_right = r;
1123 }
1124
1125 static _Link_type
1126 _S_right(_Base_ptr N)
1127 {
1128 return static_cast<_Link_type>( N->_M_right );
1129 }
1130
1131 static _Link_const_type
1132 _S_right(_Base_const_ptr N)
1133 {
1134 return static_cast<_Link_const_type>( N->_M_right );
1135 }
1136
1137 static bool
1138 _S_is_leaf(_Base_const_ptr N)
1139 {
1140 return !_S_left(N) && !_S_right(N);
1141 }
1142
1143 static const_reference
1144 _S_value(_Link_const_type N)
1145 {
1146 return N->_M_value;
1147 }
1148
1149 static const_reference
1150 _S_value(_Base_const_ptr N)
1151 {
1152 return static_cast<_Link_const_type>(N)->_M_value;
1153 }
1154
1155 static _Link_const_type
1156 _S_minimum(_Link_const_type __X)
1157 {
1158 return static_cast<_Link_const_type> ( _Node_base::_S_minimum(__X) );
1159 }
1160
1161 static _Link_const_type
1162 _S_maximum(_Link_const_type __X)
1163 {
1164 return static_cast<_Link_const_type>( _Node_base::_S_maximum(__X) );
1165 }
1166
1167
1168 _Link_type
1169 _M_new_node(const_reference __V, // = value_type(),
1170 _Base_ptr const __PARENT = NULL,
1171 _Base_ptr const __LEFT = NULL,
1172 _Base_ptr const __RIGHT = NULL)
1173 {
1174 typename _Base::NoLeakAlloc noleak(this);
1175 _Link_type new_node = noleak.get();
1176 this->_M_construct_node(new_node, __V, __PARENT, __LEFT, __RIGHT);
1177 noleak.disconnect();
1178 return new_node;
1179 }
1180
1181 /* WHAT was this for?
1182 _Link_type
1183 _M_clone_node(_Link_const_type __X)
1184 {
1185 _Link_type __ret = _M_allocate_node(__X->_M_value);
1186 // TODO
1187 return __ret;
1188 }
1189 */
1190
1191 void
1192 _M_delete_node(_Link_type __p)
1193 {
1194 this->_M_destroy_node(__p);
1195 this->_M_deallocate_node(__p);
1196 }
1197
1198 _Link_type _M_root;
1199 _Node_base _M_header;
1200 size_type _M_count;
1201 _Acc _M_acc;
1202 _Cmp _M_cmp;
1203 _Dist _M_dist;
1204
1205#ifdef KDTREE_DEFINE_OSTREAM_OPERATORS
1206 friend std::ostream&
1207 operator<<(std::ostream& o,
1209 {
1210 o << "meta node: " << tree._M_header << std::endl;
1211 o << "root node: " << tree._M_root << std::endl;
1212
1213 if (tree.empty())
1214 return o << "[empty " << __K << "d-tree " << &tree << "]";
1215
1216 o << "nodes total: " << tree.size() << std::endl;
1217 o << "dimensions: " << __K << std::endl;
1218
1220 //typedef typename _Tree::_Link_type _Link_type;
1221
1222 std::stack<_Link_const_type> s;
1223 s.push(tree._M_get_root());
1224
1225 while (!s.empty())
1226 {
1227 _Link_const_type n = s.top();
1228 s.pop();
1229 o << *n << std::endl;
1230 if (_Tree::_S_left(n)) s.push(_Tree::_S_left(n));
1231 if (_Tree::_S_right(n)) s.push(_Tree::_S_right(n));
1232 }
1233
1234 return o;
1235 }
1236#endif
1237
1238 };
1239
1240
1241} // namespace KDTree
1242
1243#endif // include guard
1244
1245/* COPYRIGHT --
1246 *
1247 * This file is part of libkdtree++, a C++ template KD-Tree sorting container.
1248 * libkdtree++ is (c) 2004-2007 Martin F. Krafft <libkdtree@pobox.madduck.net>
1249 * and Sylvain Bougerel <sylvain.bougerel.devel@gmail.com> distributed under the
1250 * terms of the Artistic License 2.0. See the ./COPYING file in the source tree
1251 * root for more information.
1252 * Parts of this file are (c) 2004-2007 Paul Harris <paulharris@computer.org>.
1253 *
1254 * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
1255 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES
1256 * OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1257 */
Definition kdtree.hpp:100
const _Dist & value_distance() const
Distance calculator between 2 value's element.
Definition kdtree.hpp:287
_Acc value_acc() const
Accessor to the value's elements.
Definition kdtree.hpp:277
_Cmp value_comp() const
Comparator for the values in the KDTree.
Definition kdtree.hpp:268
Definition node.hpp:96
IndexArray find(const BVector &v)
Definition vector.h:1346
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
_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:17
Definition node.hpp:20
Definition node.hpp:50
Definition region.hpp:20
Definition function.hpp:29
Definition function.hpp:35