OpenMS
KDTree.h
Go to the documentation of this file.
1 // Copyright (c) 2002-present, OpenMS Inc. -- EKU Tuebingen, ETH Zurich, and FU Berlin
2 // SPDX-License-Identifier: BSD-3-Clause
3 //
4 // --------------------------------------------------------------------------
5 // $Maintainer: Johannes Veit $
6 // $Authors: Johannes Veit $
7 // --------------------------------------------------------------------------
8 
9 /* Note: This file contains a concatenation of the 6 header files comprising
10  * libkdtree++ (node.hpp, function.hpp, allocator.hpp, iterator.hpp,
11  * region.hpp, kdtree.hpp).
12  *
13  * Johannes Veit (2016)
14  */
15 
16 /* COPYRIGHT --
17  *
18  * This file is part of libkdtree++, a C++ template KD-Tree sorting container.
19  * libkdtree++ is (c) 2004-2007 Martin F. Krafft <libkdtree@pobox.madduck.net>
20  * and Sylvain Bougerel <sylvain.bougerel.devel@gmail.com> distributed under the
21  * terms of the Artistic License 2.0. See the ./COPYING file in the source tree
22  * root for more information.
23  *
24  * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
25  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES
26  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27  */
28 
35 #ifndef OPENMS_DATASTRUCTURES_KDTREE_H
36 #define OPENMS_DATASTRUCTURES_KDTREE_H
37 
38 #ifdef KDTREE_DEFINE_OSTREAM_OPERATORS
39 # include <ostream>
40 #endif
41 
42 #include <cstddef>
43 #include <cmath>
44 #include <memory>
45 
46 namespace KDTree
47 {
48 struct _Node_base
49 {
51  typedef _Node_base const* _Base_const_ptr;
52 
56 
57  _Node_base(_Base_ptr const __PARENT = nullptr,
58  _Base_ptr const __LEFT = nullptr,
59  _Base_ptr const __RIGHT = nullptr)
60  : _M_parent(__PARENT), _M_left(__LEFT), _M_right(__RIGHT) {}
61 
62  static _Base_ptr
64  {
65  while (__x->_M_left) __x = __x->_M_left;
66  return __x;
67  }
68 
69  static _Base_ptr
71  {
72  while (__x->_M_right) __x = __x->_M_right;
73  return __x;
74  }
75 };
76 
77 template <typename _Val>
78 struct _Node : public _Node_base
79 {
81  typedef _Node* _Link_type;
82 
83  _Val _M_value;
84 
85  _Node(_Val const& __VALUE = _Val(),
86  _Base_ptr const __PARENT = nullptr,
87  _Base_ptr const __LEFT = nullptr,
88  _Base_ptr const __RIGHT = nullptr)
89  : _Node_base(__PARENT, __LEFT, __RIGHT), _M_value(__VALUE) {}
90 
91 #ifdef KDTREE_DEFINE_OSTREAM_OPERATORS
92 
93  template <typename Char, typename Traits>
94  friend
95  std::basic_ostream<Char, Traits>&
96  operator<<(typename std::basic_ostream<Char, Traits>& out,
97  _Node_base const& node)
98  {
99  out << &node;
100  out << " parent: " << node._M_parent;
101  out << "; left: " << node._M_left;
102  out << "; right: " << node._M_right;
103  return out;
104  }
105 
106  template <typename Char, typename Traits>
107  friend
108  std::basic_ostream<Char, Traits>&
109  operator<<(typename std::basic_ostream<Char, Traits>& out,
110  _Node<_Val> const& node)
111  {
112  out << &node;
113  out << ' ' << node._M_value;
114  out << "; parent: " << node._M_parent;
115  out << "; left: " << node._M_left;
116  out << "; right: " << node._M_right;
117  return out;
118  }
119 
120 #endif
121 };
122 
123 template <typename _Val, typename _Acc, typename _Cmp>
125 {
126 public:
127  _Node_compare(size_t const __DIM, _Acc const& acc, _Cmp const& cmp)
128  : _M_DIM(__DIM), _M_acc(acc), _M_cmp(cmp) {}
129 
130  bool
131  operator()(_Val const& __A, _Val const& __B) const
132  {
133  return _M_cmp(_M_acc(__A, _M_DIM), _M_acc(__B, _M_DIM));
134  }
135 
136 private:
137  size_t _M_DIM; // don't make this const so that an assignment operator can be auto-generated
138  _Acc _M_acc;
139  _Cmp _M_cmp;
140 };
141 
148 template <typename _ValA, typename _ValB, typename _Cmp,
149  typename _Acc>
150 inline
151 bool
152 _S_node_compare (const size_t __dim,
153  const _Cmp& __cmp, const _Acc& __acc,
154  const _ValA& __a, const _ValB& __b)
155 {
156  return __cmp(__acc(__a, __dim), __acc(__b, __dim));
157 }
158 
164 template <typename _ValA, typename _ValB, typename _Dist,
165  typename _Acc>
166 inline
167 typename _Dist::distance_type
168 _S_node_distance (const size_t __dim,
169  const _Dist& __dist, const _Acc& __acc,
170  const _ValA& __a, const _ValB& __b)
171 {
172  return __dist(__acc(__a, __dim), __acc(__b, __dim));
173 }
174 
181 template <typename _ValA, typename _ValB, typename _Dist,
182  typename _Acc>
183 inline
184 typename _Dist::distance_type
185 _S_accumulate_node_distance (const size_t __dim,
186  const _Dist& __dist, const _Acc& __acc,
187  const _ValA& __a, const _ValB& __b)
188 {
189  typename _Dist::distance_type d = 0;
190  for (size_t i=0; i<__dim; ++i)
191  d += __dist(__acc(__a, i), __acc(__b, i));
192  return d;
193 }
194 
200 template <typename _Val, typename _Cmp, typename _Acc, typename NodeType>
201 inline
202 const NodeType*
203 _S_node_descend (const size_t __dim,
204  const _Cmp& __cmp, const _Acc& __acc,
205  const _Val& __val, const NodeType* __node)
206 {
207  if (_S_node_compare(__dim, __cmp, __acc, __val, __node->_M_value))
208  return static_cast<const NodeType *>(__node->_M_left);
209  return static_cast<const NodeType *>(__node->_M_right);
210 }
211 
220 template <class SearchVal,
221  typename NodeType, typename _Cmp,
222  typename _Acc, typename _Dist,
223  typename _Predicate>
224 inline
225 std::pair<const NodeType*,
226 std::pair<size_t, typename _Dist::distance_type> >
227 _S_node_nearest (const size_t __k, size_t __dim, SearchVal const& __val,
228  const NodeType* __node, const _Node_base* __end,
229  const NodeType* __best, typename _Dist::distance_type __max,
230  const _Cmp& __cmp, const _Acc& __acc, const _Dist& __dist,
231  _Predicate __p)
232 {
233  typedef const NodeType* NodePtr;
234  NodePtr pcur = __node;
235  NodePtr cur = _S_node_descend(__dim % __k, __cmp, __acc, __val, __node);
236  size_t cur_dim = __dim+1;
237  // find the smallest __max distance in direct descent
238  while (cur)
239  {
240  if (__p(cur->_M_value))
241  {
242  typename _Dist::distance_type d = 0;
243  for (size_t i=0; i != __k; ++i)
244  d += _S_node_distance(i, __dist, __acc, __val, cur->_M_value);
245  d = std::sqrt(d);
246  if (d <= __max)
247  // ("bad candidate notes")
248  // Changed: removed this test: || ( d == __max && cur < __best ))
249  // Can't do this optimisation without checking that the current 'best' is not the root AND is not a valid candidate...
250  // This is because find_nearest() etc will call this function with the best set to _M_root EVEN IF _M_root is not a valid answer (eg too far away or doesn't pass the predicate test)
251  {
252  __best = cur;
253  __max = d;
254  __dim = cur_dim;
255  }
256  }
257  pcur = cur;
258  cur = _S_node_descend(cur_dim % __k, __cmp, __acc, __val, cur);
259  ++cur_dim;
260  }
261  // Swap cur to prev, only prev is a valid node.
262  cur = pcur;
263  --cur_dim;
264  pcur = NULL;
265  // Probe all node's children not visited yet (siblings of the visited nodes).
266  NodePtr probe = cur;
267  NodePtr pprobe = probe;
268  NodePtr near_node;
269  NodePtr far_node;
270  size_t probe_dim = cur_dim;
271  if (_S_node_compare(probe_dim % __k, __cmp, __acc, __val, probe->_M_value))
272  near_node = static_cast<NodePtr>(probe->_M_right);
273  else
274  near_node = static_cast<NodePtr>(probe->_M_left);
275  if (near_node
276  // only visit node's children if node's plane intersect hypersphere
277  && (std::sqrt(_S_node_distance(probe_dim % __k, __dist, __acc, __val, probe->_M_value)) <= __max))
278  {
279  probe = near_node;
280  ++probe_dim;
281  }
282  while (cur != __end)
283  {
284  while (probe != cur)
285  {
286  if (_S_node_compare(probe_dim % __k, __cmp, __acc, __val, probe->_M_value))
287  {
288  near_node = static_cast<NodePtr>(probe->_M_left);
289  far_node = static_cast<NodePtr>(probe->_M_right);
290  }
291  else
292  {
293  near_node = static_cast<NodePtr>(probe->_M_right);
294  far_node = static_cast<NodePtr>(probe->_M_left);
295  }
296  if (pprobe == probe->_M_parent) // going downward ...
297  {
298  if (__p(probe->_M_value))
299  {
300  typename _Dist::distance_type d = 0;
301  for (size_t i=0; i < __k; ++i)
302  d += _S_node_distance(i, __dist, __acc, __val, probe->_M_value);
303  d = std::sqrt(d);
304  if (d <= __max) // CHANGED, see the above notes ("bad candidate notes")
305  {
306  __best = probe;
307  __max = d;
308  __dim = probe_dim;
309  }
310  }
311  pprobe = probe;
312  if (near_node)
313  {
314  probe = near_node;
315  ++probe_dim;
316  }
317  else if (far_node &&
318  // only visit node's children if node's plane intersect hypersphere
319  std::sqrt(_S_node_distance(probe_dim % __k, __dist, __acc, __val, probe->_M_value)) <= __max)
320  {
321  probe = far_node;
322  ++probe_dim;
323  }
324  else
325  {
326  probe = static_cast<NodePtr>(probe->_M_parent);
327  --probe_dim;
328  }
329  }
330  else // ... and going upward.
331  {
332  if (pprobe == near_node && far_node
333  // only visit node's children if node's plane intersect hypersphere
334  && std::sqrt(_S_node_distance(probe_dim % __k, __dist, __acc, __val, probe->_M_value)) <= __max)
335  {
336  pprobe = probe;
337  probe = far_node;
338  ++probe_dim;
339  }
340  else
341  {
342  pprobe = probe;
343  probe = static_cast<NodePtr>(probe->_M_parent);
344  --probe_dim;
345  }
346  }
347  }
348  pcur = cur;
349  cur = static_cast<NodePtr>(cur->_M_parent);
350  --cur_dim;
351  pprobe = cur;
352  probe = cur;
353  probe_dim = cur_dim;
354  if (cur != __end)
355  {
356  if (pcur == cur->_M_left)
357  near_node = static_cast<NodePtr>(cur->_M_right);
358  else
359  near_node = static_cast<NodePtr>(cur->_M_left);
360  if (near_node
361  // only visit node's children if node's plane intersect hypersphere
362  && (std::sqrt(_S_node_distance(cur_dim % __k, __dist, __acc, __val, cur->_M_value)) <= __max))
363  {
364  probe = near_node;
365  ++probe_dim;
366  }
367  }
368  }
369  return std::pair<NodePtr,
370  std::pair<size_t, typename _Dist::distance_type> >
371  (__best, std::pair<size_t, typename _Dist::distance_type>
372  (__dim, __max));
373 }
374 
375 
376 } // namespace KDTree
377 
378 #endif // include guard
379 
380 /* COPYRIGHT --
381  *
382  * This file is part of libkdtree++, a C++ template KD-Tree sorting container.
383  * libkdtree++ is (c) 2004-2007 Martin F. Krafft <libkdtree@pobox.madduck.net>
384  * and Sylvain Bougerel <sylvain.bougerel.devel@gmail.com> distributed under the
385  * terms of the Artistic License 2.0. See the ./COPYING file in the source tree
386  * root for more information.
387  *
388  * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
389  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES
390  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
391  */
399 #ifndef INCLUDE_KDTREE_ACCESSOR_HPP
400 #define INCLUDE_KDTREE_ACCESSOR_HPP
401 
402 #include <cstddef>
403 
404 namespace KDTree
405 {
406 template <typename _Val>
408 {
409  typedef typename _Val::value_type result_type;
410 
412  operator()(_Val const& V, size_t const N) const
413  {
414  return V[N];
415  }
416 };
417 
418 template <typename _Tp>
420 {
421  bool operator() (const _Tp& ) const { return true; }
422 };
423 
424 template <typename _Tp, typename _Dist>
426 {
427  typedef _Dist distance_type;
428 
430  operator() (const _Tp& __a, const _Tp& __b) const
431  {
432  distance_type d=__a - __b;
433  return d*d;
434  }
435 };
436 
437 template <typename _Tp, typename _Dist>
439 {
440  typedef _Dist distance_type;
441 
443  : _M_count(0)
444  { }
445 
446  void reset ()
447  { _M_count = 0; }
448 
449  long&
450  count () const
451  { return _M_count; }
452 
454  operator() (const _Tp& __a, const _Tp& __b) const
455  {
456  distance_type d=__a - __b;
457  ++_M_count;
458  return d*d;
459  }
460 
461 private:
462  mutable long _M_count;
463 };
464 
465 } // namespace KDTree
466 
467 #endif // include guard
468 
469 /* COPYRIGHT --
470  *
471  * This file is part of libkdtree++, a C++ template KD-Tree sorting container.
472  * libkdtree++ is (c) 2004-2007 Martin F. Krafft <libkdtree@pobox.madduck.net>
473  * and Sylvain Bougerel <sylvain.bougerel.devel@gmail.com> distributed under the
474  * terms of the Artistic License 2.0. See the ./COPYING file in the source tree
475  * root for more information.
476  *
477  * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
478  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES
479  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
480  */
487 #ifndef INCLUDE_KDTREE_ALLOCATOR_HPP
488 #define INCLUDE_KDTREE_ALLOCATOR_HPP
489 
490 #include <cstddef>
491 
492 namespace KDTree
493 {
494 
495 template <typename _Tp, typename _Alloc>
497 {
498 public:
500  typedef typename _Node_::_Base_ptr _Base_ptr;
501  typedef _Alloc allocator_type;
502 
504  : _M_node_allocator(__A) {}
505 
508  {
509  return _M_node_allocator;
510  }
511 
512 
514  {
517 
518  public:
520 
521  _Node_ * get() { return new_node; }
522  void disconnect() { new_node = nullptr; }
523 
525  };
526 
527 
528 protected:
530 
531  _Node_*
533  {
534  return _M_node_allocator.allocate(1);
535  }
536 
537  void
539  {
540  return _M_node_allocator.deallocate(__P, 1);
541  }
542 
543  void
544  _M_construct_node(_Node_* __p, _Tp const __V = _Tp(),
545  _Base_ptr const __PARENT = NULL,
546  _Base_ptr const __LEFT = NULL,
547  _Base_ptr const __RIGHT = NULL)
548  {
549  new (__p) _Node_(__V, __PARENT, __LEFT, __RIGHT);
550  }
551 
552  void
554  {
555  std::allocator_traits<allocator_type>::destroy(_M_node_allocator, __p);
556  }
557 };
558 
559 } // namespace KDTree
560 
561 #endif // include guard
562 
563 /* COPYRIGHT --
564  *
565  * This file is part of libkdtree++, a C++ template KD-Tree sorting container.
566  * libkdtree++ is (c) 2004-2007 Martin F. Krafft <libkdtree@pobox.madduck.net>
567  * and Sylvain Bougerel <sylvain.bougerel.devel@gmail.com> distributed under the
568  * terms of the Artistic License 2.0. See the ./COPYING file in the source tree
569  * root for more information.
570  *
571  * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
572  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES
573  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
574  */
581 #ifndef INCLUDE_KDTREE_ITERATOR_HPP
582 #define INCLUDE_KDTREE_ITERATOR_HPP
583 
584 #include <iterator>
585 
586 namespace KDTree
587 {
588 template <typename _Val, typename _Ref, typename _Ptr>
589 class _Iterator;
590 
591 template<typename _Val, typename _Ref, typename _Ptr>
592 inline bool
593 operator==(_Iterator<_Val, _Ref, _Ptr> const&,
594  _Iterator<_Val, _Ref, _Ptr> const&);
595 
596 template<typename _Val>
597 inline bool
598 operator==(_Iterator<_Val, const _Val&, const _Val*> const&,
599  _Iterator<_Val, _Val&, _Val*> const&);
600 
601 template<typename _Val>
602 inline bool
603 operator==(_Iterator<_Val, _Val&, _Val*> const&,
604  _Iterator<_Val, const _Val&, const _Val*> const&);
605 
606 template<typename _Val, typename _Ref, typename _Ptr>
607 inline bool
608 operator!=(_Iterator<_Val, _Ref, _Ptr> const&,
609  _Iterator<_Val, _Ref, _Ptr> const&);
610 
611 template<typename _Val>
612 inline bool
613 operator!=(_Iterator<_Val, const _Val&, const _Val*> const&,
614  _Iterator<_Val, _Val&, _Val*> const&);
615 
616 template<typename _Val>
617 inline bool
618 operator!=(_Iterator<_Val, _Val&, _Val*> const&,
619  _Iterator<_Val, const _Val&, const _Val*> const&);
620 
622 {
623 protected:
626 
627  inline _Base_iterator(_Base_const_ptr const __N = nullptr)
628  : _M_node(__N) {}
629  inline _Base_iterator(_Base_iterator const& __THAT)
630  : _M_node(__THAT._M_node) {}
631 
632  inline void
634  {
635  if (_M_node->_M_right)
636  {
637  _M_node = _M_node->_M_right;
638  while (_M_node->_M_left) _M_node = _M_node->_M_left;
639  }
640  else
641  {
642  _Base_const_ptr __p = _M_node->_M_parent;
643  while (__p && _M_node == __p->_M_right)
644  {
645  _M_node = __p;
646  __p = _M_node->_M_parent;
647  }
648  if (__p) // (__p) provide undetermined behavior on end()++ rather
649  // than a segfault, similar to standard iterator.
650  _M_node = __p;
651  }
652  }
653 
654  inline void
656  {
657  if (!_M_node->_M_parent) // clearly identify the header node
658  {
659  _M_node = _M_node->_M_right;
660  }
661  else if (_M_node->_M_left)
662  {
663  _Base_const_ptr x = _M_node->_M_left;
664  while (x->_M_right) x = x->_M_right;
665  _M_node = x;
666  }
667  else
668  {
669  _Base_const_ptr __p = _M_node->_M_parent;
670  while (__p && _M_node == __p->_M_left) // see below
671  {
672  _M_node = __p;
673  __p = _M_node->_M_parent;
674  }
675  if (__p) // (__p) provide undetermined behavior on rend()++ rather
676  // than a segfault, similar to standard iterator.
677  _M_node = __p;
678  }
679  }
680 
681  template <size_t const __K, typename _Val, typename _Acc,
682  typename _Dist, typename _Cmp, typename _Alloc>
683  friend class KDTree;
684 };
685 
686 template <typename _Val, typename _Ref, typename _Ptr>
687 class _Iterator : protected _Base_iterator
688 {
689 public:
690  typedef _Val value_type;
691  typedef _Ref reference;
692  typedef _Ptr pointer;
697  typedef std::bidirectional_iterator_tag iterator_category;
698  typedef ptrdiff_t difference_type;
699 
700  inline _Iterator()
701  : _Base_iterator() {}
702  inline _Iterator(_Link_const_type const __N)
703  : _Base_iterator(__N) {}
704  inline _Iterator(iterator const& __THAT)
705  : _Base_iterator(__THAT) {}
706 
708  {
709  return _Link_const_type(_M_node);
710  }
711 
712  reference
713  operator*() const
714  {
715  return _Link_const_type(_M_node)->_M_value;
716  }
717 
718  pointer
719  operator->() const
720  {
721  return &(operator*());
722  }
723 
724  _Self
726  {
727  _M_increment();
728  return *this;
729  }
730 
731  _Self
733  {
734  _Self ret = *this;
735  _M_increment();
736  return ret;
737  }
738 
739  _Self&
741  {
742  _M_decrement();
743  return *this;
744  }
745 
746  _Self
748  {
749  _Self ret = *this;
750  _M_decrement();
751  return ret;
752  }
753 
754  friend bool
755  operator== <>(_Iterator<_Val, _Ref, _Ptr> const&,
757 
758  friend bool
759  operator== <>(_Iterator<_Val, const _Val&, const _Val*> const&,
761 
762  friend bool
763  operator== <>(_Iterator<_Val, _Val&, _Val*> const&,
765 
766  friend bool
767  operator!= <>(_Iterator<_Val, _Ref, _Ptr> const&,
769 
770  friend bool
771  operator!= <>(_Iterator<_Val, const _Val&, const _Val*> const&,
773 
774  friend bool
775  operator!= <>(_Iterator<_Val, _Val&, _Val*> const&,
777 };
778 
779 template<typename _Val, typename _Ref, typename _Ptr>
780 bool
782  _Iterator<_Val, _Ref, _Ptr> const& __Y)
783 { return __X._M_node == __Y._M_node; }
784 
785 template<typename _Val>
786 bool
789 { return __X._M_node == __Y._M_node; }
790 
791 template<typename _Val>
792 bool
795 { return __X._M_node == __Y._M_node; }
796 
797 template<typename _Val, typename _Ref, typename _Ptr>
798 bool
800  _Iterator<_Val, _Ref, _Ptr> const& __Y)
801 { return __X._M_node != __Y._M_node; }
802 
803 template<typename _Val>
804 bool
807 { return __X._M_node != __Y._M_node; }
808 
809 template<typename _Val>
810 bool
813 { return __X._M_node != __Y._M_node; }
814 
815 } // namespace KDTree
816 
817 #endif // include guard
818 
819 /* COPYRIGHT --
820  *
821  * This file is part of libkdtree++, a C++ template KD-Tree sorting container.
822  * libkdtree++ is (c) 2004-2007 Martin F. Krafft <libkdtree@pobox.madduck.net>
823  * and Sylvain Bougerel <sylvain.bougerel.devel@gmail.com> distributed under the
824  * terms of the Artistic License 2.0. See the ./COPYING file in the source tree
825  * root for more information.
826  *
827  * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
828  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES
829  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
830  */
837 #ifndef INCLUDE_KDTREE_REGION_HPP
838 #define INCLUDE_KDTREE_REGION_HPP
839 
840 #include <cstddef>
841 
842 namespace KDTree
843 {
844 
845 template <size_t const __K, typename _Val, typename _SubVal,
846  typename _Acc, typename _Cmp>
847 struct _Region
848 {
849  typedef _Val value_type;
850  typedef _SubVal subvalue_type;
851 
852  // special typedef for checking against a fuzzy point (for find_nearest)
853  // Note the region (first) component is not supposed to have an area, its
854  // bounds should all be set to a specific point.
855  typedef std::pair<_Region,_SubVal> _CenterPt;
856 
857  _Region(_Acc const& __acc=_Acc(), const _Cmp& __cmp=_Cmp())
858  : _M_acc(__acc), _M_cmp(__cmp) {}
859 
860  template <typename Val>
861  _Region(Val const& __V,
862  _Acc const& __acc=_Acc(), const _Cmp& __cmp=_Cmp())
863  : _M_acc(__acc), _M_cmp(__cmp)
864  {
865  for (size_t __i = 0; __i != __K; ++__i)
866  {
867  _M_low_bounds[__i] = _M_high_bounds[__i] = _M_acc(__V,__i);
868  }
869  }
870 
871  template <typename Val>
872  _Region(Val const& __V, subvalue_type const& __R,
873  _Acc const& __acc=_Acc(), const _Cmp& __cmp=_Cmp())
874  : _M_acc(__acc), _M_cmp(__cmp)
875  {
876  for (size_t __i = 0; __i != __K; ++__i)
877  {
878  _M_low_bounds[__i] = _M_acc(__V,__i) - __R;
879  _M_high_bounds[__i] = _M_acc(__V,__i) + __R;
880  }
881  }
882 
883  bool
884  intersects_with(_CenterPt const& __THAT) const
885  {
886  for (size_t __i = 0; __i != __K; ++__i)
887  {
888  // does it fall outside the bounds?
889  // ! low-tolerance <= x <= high+tolerance
890  // ! (low-tol <= x and x <= high+tol)
891  // !low-tol<=x or !x<=high+tol
892  // low-tol>x or x>high+tol
893  // x<low-tol or high+tol<x
894  if (_M_cmp(__THAT.first._M_low_bounds[__i], _M_low_bounds[__i] - __THAT.second)
895  || _M_cmp(_M_high_bounds[__i] + __THAT.second, __THAT.first._M_low_bounds[__i]))
896  return false;
897  }
898  return true;
899  }
900 
901  bool
902  intersects_with(_Region const& __THAT) const
903  {
904  for (size_t __i = 0; __i != __K; ++__i)
905  {
906  if (_M_cmp(__THAT._M_high_bounds[__i], _M_low_bounds[__i])
907  || _M_cmp(_M_high_bounds[__i], __THAT._M_low_bounds[__i]))
908  return false;
909  }
910  return true;
911  }
912 
913  bool
914  encloses(value_type const& __V) const
915  {
916  for (size_t __i = 0; __i != __K; ++__i)
917  {
918  if (_M_cmp(_M_acc(__V, __i), _M_low_bounds[__i])
919  || _M_cmp(_M_high_bounds[__i], _M_acc(__V, __i)))
920  return false;
921  }
922  return true;
923  }
924 
925  _Region&
926  set_high_bound(value_type const& __V, size_t const __L)
927  {
928  _M_high_bounds[__L % __K] = _M_acc(__V, __L % __K);
929  return *this;
930  }
931 
932  _Region&
933  set_low_bound(value_type const& __V, size_t const __L)
934  {
935  _M_low_bounds[__L % __K] = _M_acc(__V, __L % __K);
936  return *this;
937  }
938 
940  _Acc _M_acc;
941  _Cmp _M_cmp;
942 };
943 
944 } // namespace KDTree
945 
946 #endif // include guard
947 
948 /* COPYRIGHT --
949  *
950  * This file is part of libkdtree++, a C++ template KD-Tree sorting container.
951  * libkdtree++ is (c) 2004-2007 Martin F. Krafft <libkdtree@pobox.madduck.net>
952  * and Sylvain Bougerel <sylvain.bougerel.devel@gmail.com> distributed under the
953  * terms of the Artistic License 2.0. See the ./COPYING file in the source tree
954  * root for more information.
955  *
956  * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
957  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES
958  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
959  */
1005 #ifndef INCLUDE_KDTREE_KDTREE_HPP
1006 #define INCLUDE_KDTREE_KDTREE_HPP
1007 
1008 
1009 //
1010 // This number is guaranteed to change with every release.
1011 //
1012 // KDTREE_VERSION % 100 is the patch level
1013 // KDTREE_VERSION / 100 % 1000 is the minor version
1014 // KDTREE_VERSION / 100000 is the major version
1015 #define KDTREE_VERSION 701
1016 //
1017 // KDTREE_LIB_VERSION must be defined to be the same as KDTREE_VERSION
1018 // but as a *string* in the form "x_y[_z]" where x is the major version
1019 // number, y is the minor version number, and z is the patch level if not 0.
1020 #define KDTREE_LIB_VERSION "0_7_1"
1021 
1022 
1023 #include <vector>
1024 
1025 #ifdef KDTREE_CHECK_PERFORMANCE_COUNTERS
1026 # include <map>
1027 #endif
1028 #include <algorithm>
1029 #include <functional>
1030 
1031 #ifdef KDTREE_DEFINE_OSTREAM_OPERATORS
1032 # include <ostream>
1033 # include <stack>
1034 #endif
1035 
1036 #include <cmath>
1037 #include <cstddef>
1038 #include <cassert>
1039 
1040 namespace KDTree
1041 {
1042 
1043 #ifdef KDTREE_CHECK_PERFORMANCE
1044 unsigned long long num_dist_calcs = 0;
1045 #endif
1046 
1047 template <size_t const __K, typename _Val,
1048  typename _Acc = _Bracket_accessor<_Val>,
1049  typename _Dist = squared_difference<typename _Acc::result_type,
1050  typename _Acc::result_type>,
1051  typename _Cmp = std::less<typename _Acc::result_type>,
1052  typename _Alloc = std::allocator<_Node<_Val> > >
1053 class KDTree : protected _Alloc_base<_Val, _Alloc>
1054 {
1055 protected:
1058 
1060  typedef _Node_base const* _Base_const_ptr;
1063 
1065 
1066 public:
1068  typedef _Val value_type;
1070  typedef value_type const* const_pointer;
1072  typedef value_type const& const_reference;
1073  typedef typename _Acc::result_type subvalue_type;
1074  typedef typename _Dist::distance_type distance_type;
1075  typedef size_t size_type;
1076  typedef ptrdiff_t difference_type;
1077 
1078  KDTree(_Acc const& __acc = _Acc(), _Dist const& __dist = _Dist(),
1079  _Cmp const& __cmp = _Cmp(), const allocator_type& __a = allocator_type())
1080  : _Base(__a), _M_header(),
1081  _M_count(0), _M_acc(__acc), _M_cmp(__cmp), _M_dist(__dist)
1082  {
1083  _M_empty_initialise();
1084  }
1085 
1086  KDTree(const KDTree& __x)
1087  : _Base(__x.get_allocator()), _M_header(), _M_count(0),
1088  _M_acc(__x._M_acc), _M_cmp(__x._M_cmp), _M_dist(__x._M_dist)
1089  {
1090  _M_empty_initialise();
1091  // this is slow:
1092  // this->insert(begin(), __x.begin(), __x.end());
1093  // this->optimise();
1094 
1095  // this is much faster, as it skips a lot of useless work
1096  // do the optimisation before inserting
1097  // Needs to be stored in a vector first as _M_optimise()
1098  // sorts the data in the passed iterators directly.
1099  std::vector<value_type> temp;
1100  temp.reserve(__x.size());
1101  std::copy(__x.begin(),__x.end(),std::back_inserter(temp));
1102  _M_optimise(temp.begin(), temp.end(), 0);
1103  }
1104 
1105  template<typename _InputIterator>
1106  KDTree(_InputIterator __first, _InputIterator __last,
1107  _Acc const& acc = _Acc(), _Dist const& __dist = _Dist(),
1108  _Cmp const& __cmp = _Cmp(), const allocator_type& __a = allocator_type())
1109  : _Base(__a), _M_header(), _M_count(0),
1110  _M_acc(acc), _M_cmp(__cmp), _M_dist(__dist)
1111  {
1112  _M_empty_initialise();
1113  // this is slow:
1114  // this->insert(begin(), __first, __last);
1115  // this->optimise();
1116 
1117  // this is much faster, as it skips a lot of useless work
1118  // do the optimisation before inserting
1119  // Needs to be stored in a vector first as _M_optimise()
1120  // sorts the data in the passed iterators directly.
1121  std::vector<value_type> temp;
1122  temp.reserve(std::distance(__first,__last));
1123  std::copy(__first,__last,std::back_inserter(temp));
1124  _M_optimise(temp.begin(), temp.end(), 0);
1125 
1126  // NOTE: this will BREAK users that are passing in
1127  // read-once data via the iterator...
1128  // We increment __first all the way to __last once within
1129  // the distance() call, and again within the copy() call.
1130  //
1131  // This should end up using some funky C++ concepts or
1132  // type traits to check that the iterators can be used in this way...
1133  }
1134 
1135 
1136  // this will CLEAR the tree and fill it with the contents
1137  // of 'writable_vector'. it will use the passed vector directly,
1138  // and will basically resort the vector many times over while
1139  // optimising the tree.
1140  //
1141  // Paul: I use this when I have already built up a vector of data
1142  // that I want to add, and I don't mind if its contents get shuffled
1143  // by the kdtree optimise routine.
1144  void efficient_replace_and_optimise( std::vector<value_type> & writable_vector )
1145  {
1146  this->clear();
1147  _M_optimise(writable_vector.begin(), writable_vector.end(), 0);
1148  }
1149 
1150 
1151 
1152  KDTree&
1153  operator=(const KDTree& __x)
1154  {
1155  if (this != &__x)
1156  {
1157  _M_acc = __x._M_acc;
1158  _M_dist = __x._M_dist;
1159  _M_cmp = __x._M_cmp;
1160  // this is slow:
1161  // this->insert(begin(), __x.begin(), __x.end());
1162  // this->optimise();
1163 
1164  // this is much faster, as it skips a lot of useless work
1165  // do the optimisation before inserting
1166  // Needs to be stored in a vector first as _M_optimise()
1167  // sorts the data in the passed iterators directly.
1168  std::vector<value_type> temp;
1169  temp.reserve(__x.size());
1170  std::copy(__x.begin(),__x.end(),std::back_inserter(temp));
1171  efficient_replace_and_optimise(temp);
1172  }
1173  return *this;
1174  }
1175 
1177  {
1178  this->clear();
1179  }
1180 
1181  allocator_type
1183  {
1184  return _Base::get_allocator();
1185  }
1186 
1187  size_type
1188  size() const
1189  {
1190  return _M_count;
1191  }
1192 
1193  size_type
1194  max_size() const
1195  {
1196  return size_type(-1);
1197  }
1198 
1199  bool
1200  empty() const
1201  {
1202  return this->size() == 0;
1203  }
1204 
1205  void
1207  {
1208  _M_erase_subtree(_M_get_root());
1209  _M_set_leftmost(&_M_header);
1210  _M_set_rightmost(&_M_header);
1211  _M_set_root(nullptr);
1212  _M_count = 0;
1213  }
1214 
1220  _Cmp
1221  value_comp() const
1222  { return _M_cmp; }
1223 
1229  _Acc
1230  value_acc() const
1231  { return _M_acc; }
1232 
1239  const _Dist&
1241  { return _M_dist; }
1242 
1243  _Dist&
1245  { return _M_dist; }
1246 
1247  // typedef _Iterator<_Val, reference, pointer> iterator;
1249  // No mutable iterator at this stage
1251  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
1252  typedef std::reverse_iterator<iterator> reverse_iterator;
1253 
1254  // Note: the static_cast in end() is invalid (_M_header is not convertible to a _Link_type), but
1255  // that's ok as it just means undefined behaviour if the user dereferences the end() iterator.
1256 
1257  const_iterator begin() const { return const_iterator(_M_get_leftmost()); }
1258  const_iterator end() const { return const_iterator(static_cast<_Link_const_type>(&_M_header)); }
1261 
1262  iterator
1263  insert(iterator /* ignored */, const_reference __V)
1264  {
1265  return this->insert(__V);
1266  }
1267 
1268  iterator
1270  {
1271  if (!_M_get_root())
1272  {
1273  _Link_type __n = _M_new_node(__V, &_M_header);
1274  ++_M_count;
1275  _M_set_root(__n);
1276  _M_set_leftmost(__n);
1277  _M_set_rightmost(__n);
1278  return iterator(__n);
1279  }
1280  return _M_insert(_M_get_root(), __V, 0);
1281  }
1282 
1283  template <class _InputIterator>
1284  void insert(_InputIterator __first, _InputIterator __last) {
1285  for (; __first != __last; ++__first)
1286  this->insert(*__first);
1287  }
1288 
1289  void
1290  insert(iterator __pos, size_type __n, const value_type& __x)
1291  {
1292  for (; __n > 0; --__n)
1293  this->insert(__pos, __x);
1294  }
1295 
1296  template<typename _InputIterator>
1297  void
1298  insert(iterator __pos, _InputIterator __first, _InputIterator __last) {
1299  for (; __first != __last; ++__first)
1300  this->insert(__pos, *__first);
1301  }
1302 
1303  // Note: this uses the find() to location the item you want to erase.
1304  // find() compares by equivalence of location ONLY. See the comments
1305  // above find_exact() for why you may not want this.
1306  //
1307  // If you want to erase ANY item that has the same location as __V,
1308  // then use this function.
1309  //
1310  // If you want to erase a PARTICULAR item, and not any other item
1311  // that might happen to have the same location, then you should use
1312  // erase_exact().
1313  void
1315  const_iterator b = this->find(__V);
1316  this->erase(b);
1317  }
1318 
1319  void
1321  this->erase(this->find_exact(__V));
1322  }
1323 
1324  // note: kept as const because its easier to const-cast it away
1325  void
1326  erase(const_iterator const& __IT)
1327  {
1328  assert(__IT != this->end());
1329  _Link_const_type target = __IT.get_raw_node();
1330  _Link_const_type n = target;
1331  size_type level = 0;
1332  while ((n = _S_parent(n)) != &_M_header)
1333  ++level;
1334  _M_erase( const_cast<_Link_type>(target), level );
1335  _M_delete_node( const_cast<_Link_type>(target) );
1336  --_M_count;
1337  }
1338 
1339  /* this does not work since erasure changes sort order
1340  void
1341  erase(const_iterator __A, const_iterator const& __B)
1342  {
1343  if (0 && __A == this->begin() && __B == this->end())
1344  {
1345  this->clear();
1346  }
1347  else
1348  {
1349  while (__A != __B)
1350  this->erase(__A++);
1351  }
1352  }
1353 */
1354 
1355  // compares via equivalence
1356  // so if you are looking for any item with the same location,
1357  // according to the standard accessor comparisons,
1358  // then this is the function for you.
1359  template <class SearchVal>
1360  const_iterator
1361  find(SearchVal const& __V) const
1362  {
1363  if (!_M_get_root()) return this->end();
1364  return _M_find(_M_get_root(), __V, 0);
1365  }
1366 
1367  // compares via equality
1368  // if you are looking for a particular item in the tree,
1369  // and (for example) it has an ID that is checked via an == comparison
1370  // e.g.
1371  // struct Item
1372  // {
1373  // size_type unique_id;
1374  // bool operator==(Item const& a, Item const& b) { return a.unique_id == b.unique_id; }
1375  // Location location;
1376  // };
1377  // Two items may be equivalent in location. find() would return
1378  // either one of them. But no two items have the same ID, so
1379  // find_exact() would always return the item with the same location AND id.
1380  //
1381  template <class SearchVal>
1382  const_iterator
1383  find_exact(SearchVal const& __V) const
1384  {
1385  if (!_M_get_root()) return this->end();
1386  return _M_find_exact(_M_get_root(), __V, 0);
1387  }
1388 
1389  // NOTE: see notes on find_within_range().
1390  size_type
1392  {
1393  if (!_M_get_root()) return 0;
1394  _Region_ __region(__V, __R, _M_acc, _M_cmp);
1395  return this->count_within_range(__region);
1396  }
1397 
1398  size_type
1399  count_within_range(_Region_ const& __REGION) const
1400  {
1401  if (!_M_get_root()) return 0;
1402 
1403  _Region_ __bounds(__REGION);
1404  return _M_count_within_range(_M_get_root(),
1405  __REGION, __bounds, 0);
1406  }
1407 
1408  // NOTE: see notes on find_within_range().
1409  template <typename SearchVal, class Visitor>
1410  Visitor
1411  visit_within_range(SearchVal const& V, subvalue_type const R, Visitor visitor) const
1412  {
1413  if (!_M_get_root()) return visitor;
1414  _Region_ region(V, R, _M_acc, _M_cmp);
1415  return this->visit_within_range(region, visitor);
1416  }
1417 
1418  template <class Visitor>
1419  Visitor
1420  visit_within_range(_Region_ const& REGION, Visitor visitor) const
1421  {
1422  if (_M_get_root())
1423  {
1424  _Region_ bounds(REGION);
1425  return _M_visit_within_range(visitor, _M_get_root(), REGION, bounds, 0);
1426  }
1427  return visitor;
1428  }
1429 
1430  // NOTE: this will visit points based on 'Manhattan distance' aka city-block distance
1431  // aka taxicab metric. Meaning it will find all points within:
1432  // max(x_dist,max(y_dist,z_dist));
1433  // AND NOT than what you would expect: sqrt(x_dist*x_dist + y_dist*y_dist + z_dist*z_dist)
1434  //
1435  // This is because it converts the distance into a bounding-box 'region' and compares
1436  // against that.
1437  //
1438  // If you want the sqrt() behaviour, ask on the mailing list for different options.
1439  //
1440  template <typename SearchVal, typename _OutputIterator>
1441  _OutputIterator
1442  find_within_range(SearchVal const& val, subvalue_type const range,
1443  _OutputIterator out) const
1444  {
1445  if (!_M_get_root()) return out;
1446  _Region_ region(val, range, _M_acc, _M_cmp);
1447  return this->find_within_range(region, out);
1448  }
1449 
1450  template <typename _OutputIterator>
1451  _OutputIterator
1453  _OutputIterator out) const
1454  {
1455  if (_M_get_root())
1456  {
1457  _Region_ bounds(region);
1458  out = _M_find_within_range(out, _M_get_root(),
1459  region, bounds, 0);
1460  }
1461  return out;
1462  }
1463 
1464  template <class SearchVal>
1465  std::pair<const_iterator, distance_type>
1466  find_nearest (SearchVal const& __val) const
1467  {
1468  if (_M_get_root())
1469  {
1470  std::pair<const _Node<_Val>*,
1471  std::pair<size_type, typename _Acc::result_type> >
1472  best = _S_node_nearest (__K, 0, __val,
1473  _M_get_root(), &_M_header, _M_get_root(),
1474  std::sqrt(_S_accumulate_node_distance
1475  (__K, _M_dist, _M_acc, _M_get_root()->_M_value, __val)),
1476  _M_cmp, _M_acc, _M_dist,
1478  return std::pair<const_iterator, distance_type>
1479  (best.first, best.second.second);
1480  }
1481  return std::pair<const_iterator, distance_type>(end(), 0);
1482  }
1483 
1484  template <class SearchVal>
1485  std::pair<const_iterator, distance_type>
1486  find_nearest (SearchVal const& __val, distance_type __max) const
1487  {
1488  if (_M_get_root())
1489  {
1490  bool root_is_candidate = false;
1491  const _Node<_Val>* node = _M_get_root();
1492  { // scope to ensure we don't use 'root_dist' anywhere else
1493  distance_type root_dist = std::sqrt(_S_accumulate_node_distance
1494  (__K, _M_dist, _M_acc, _M_get_root()->_M_value, __val));
1495  if (root_dist <= __max)
1496  {
1497  root_is_candidate = true;
1498  __max = root_dist;
1499  }
1500  }
1501  std::pair<const _Node<_Val>*,
1502  std::pair<size_type, typename _Acc::result_type> >
1503  best = _S_node_nearest (__K, 0, __val, _M_get_root(), &_M_header,
1504  node, __max, _M_cmp, _M_acc, _M_dist,
1506  // make sure we didn't just get stuck with the root node...
1507  if (root_is_candidate || best.first != _M_get_root())
1508  return std::pair<const_iterator, distance_type>
1509  (best.first, best.second.second);
1510  }
1511  return std::pair<const_iterator, distance_type>(end(), __max);
1512  }
1513 
1514  template <class SearchVal, class _Predicate>
1515  std::pair<const_iterator, distance_type>
1516  find_nearest_if (SearchVal const& __val, distance_type __max,
1517  _Predicate __p) const
1518  {
1519  if (_M_get_root())
1520  {
1521  bool root_is_candidate = false;
1522  const _Node<_Val>* node = _M_get_root();
1523  if (__p(_M_get_root()->_M_value))
1524  {
1525  { // scope to ensure we don't use root_dist anywhere else
1526  distance_type root_dist = std::sqrt(_S_accumulate_node_distance
1527  (__K, _M_dist, _M_acc, _M_get_root()->_M_value, __val));
1528  if (root_dist <= __max)
1529  {
1530  root_is_candidate = true;
1531  root_dist = __max;
1532  }
1533  }
1534  }
1535  std::pair<const _Node<_Val>*,
1536  std::pair<size_type, typename _Acc::result_type> >
1537  best = _S_node_nearest (__K, 0, __val, _M_get_root(), &_M_header,
1538  node, __max, _M_cmp, _M_acc, _M_dist, __p);
1539  // make sure we didn't just get stuck with the root node...
1540  if (root_is_candidate || best.first != _M_get_root())
1541  return std::pair<const_iterator, distance_type>
1542  (best.first, best.second.second);
1543  }
1544  return std::pair<const_iterator, distance_type>(end(), __max);
1545  }
1546 
1547  void
1549  {
1550  std::vector<value_type> __v(this->begin(),this->end());
1551  this->clear();
1552  _M_optimise(__v.begin(), __v.end(), 0);
1553  }
1554 
1555  void
1557  { // cater for people who cannot spell :)
1558  this->optimise();
1559  }
1560 
1561  void check_tree()
1562  {
1563  _M_check_node(_M_get_root(),0);
1564  }
1565 
1566 protected:
1567 
1568  void _M_check_children( _Link_const_type child, _Link_const_type parent, size_type const level, bool to_the_left )
1569  {
1570  assert(parent);
1571  if (child)
1572  {
1573  _Node_compare_ compare(level % __K, _M_acc, _M_cmp);
1574  // REMEMBER! its a <= relationship for BOTH branches
1575  // for left-case (true), child<=node --> !(node<child)
1576  // for right-case (false), node<=child --> !(child<node)
1577  assert(!to_the_left || !compare(parent->_M_value,child->_M_value)); // check the left
1578  assert(to_the_left || !compare(child->_M_value,parent->_M_value)); // check the right
1579  // and recurse down the tree, checking everything
1580  _M_check_children(_S_left(child),parent,level,to_the_left);
1581  _M_check_children(_S_right(child),parent,level,to_the_left);
1582  }
1583  }
1584 
1585  void _M_check_node( _Link_const_type node, size_type const level )
1586  {
1587  if (node)
1588  {
1589  // (comparing on this level)
1590  // everything to the left of this node must be smaller than this
1591  _M_check_children( _S_left(node), node, level, true );
1592  // everything to the right of this node must be larger than this
1593  _M_check_children( _S_right(node), node, level, false );
1594 
1595  _M_check_node( _S_left(node), level+1 );
1596  _M_check_node( _S_right(node), level+1 );
1597  }
1598  }
1599 
1601  {
1602  _M_set_leftmost(&_M_header);
1603  _M_set_rightmost(&_M_header);
1604  _M_header._M_parent = nullptr;
1605  _M_set_root(nullptr);
1606  }
1607 
1608  iterator
1610  {
1611  _S_set_left(__N, _M_new_node(__V)); ++_M_count;
1612  _S_set_parent( _S_left(__N), __N );
1613  if (__N == _M_get_leftmost())
1614  _M_set_leftmost( _S_left(__N) );
1615  return iterator(_S_left(__N));
1616  }
1617 
1618  iterator
1620  {
1621  _S_set_right(__N, _M_new_node(__V)); ++_M_count;
1622  _S_set_parent( _S_right(__N), __N );
1623  if (__N == _M_get_rightmost())
1624  _M_set_rightmost( _S_right(__N) );
1625  return iterator(_S_right(__N));
1626  }
1627 
1628  iterator
1630  size_type const __L)
1631  {
1632  if (_Node_compare_(__L % __K, _M_acc, _M_cmp)(__V, __N->_M_value))
1633  {
1634  if (!_S_left(__N))
1635  return _M_insert_left(__N, __V);
1636  return _M_insert(_S_left(__N), __V, __L+1);
1637  }
1638  else
1639  {
1640  if (!_S_right(__N) || __N == _M_get_rightmost())
1641  return _M_insert_right(__N, __V);
1642  return _M_insert(_S_right(__N), __V, __L+1);
1643  }
1644  }
1645 
1646  _Link_type
1647  _M_erase(_Link_type dead_dad, size_type const level)
1648  {
1649  // find a new step_dad, he will become a drop-in replacement.
1650  _Link_type step_dad = _M_get_erase_replacement(dead_dad, level);
1651 
1652  // tell dead_dad's parent that his new child is step_dad
1653  if (dead_dad == _M_get_root())
1654  _M_set_root(step_dad);
1655  else if (_S_left(_S_parent(dead_dad)) == dead_dad)
1656  _S_set_left(_S_parent(dead_dad), step_dad);
1657  else
1658  _S_set_right(_S_parent(dead_dad), step_dad);
1659 
1660  // deal with the left and right edges of the tree...
1661  // if the dead_dad was at the edge, then substitute...
1662  // but if there IS no new dead, then left_most is the dead_dad's parent
1663  if (dead_dad == _M_get_leftmost())
1664  _M_set_leftmost( (step_dad ? step_dad : _S_parent(dead_dad)) );
1665  if (dead_dad == _M_get_rightmost())
1666  _M_set_rightmost( (step_dad ? step_dad : _S_parent(dead_dad)) );
1667 
1668  if (step_dad)
1669  {
1670  // step_dad gets dead_dad's parent
1671  _S_set_parent(step_dad, _S_parent(dead_dad));
1672 
1673  // first tell the children that step_dad is their new dad
1674  if (_S_left(dead_dad))
1675  _S_set_parent(_S_left(dead_dad), step_dad);
1676  if (_S_right(dead_dad))
1677  _S_set_parent(_S_right(dead_dad), step_dad);
1678 
1679  // step_dad gets dead_dad's children
1680  _S_set_left(step_dad, _S_left(dead_dad));
1681  _S_set_right(step_dad, _S_right(dead_dad));
1682  }
1683 
1684  return step_dad;
1685  }
1686 
1687 
1688 
1689  _Link_type
1691  {
1692  // if 'node' is null, then we can't do any better
1693  if (_S_is_leaf(node))
1694  return NULL;
1695 
1696  std::pair<_Link_type,size_type> candidate;
1697  // if there is nothing to the left, find a candidate on the right tree
1698  if (!_S_left(node))
1699  candidate = _M_get_j_min( std::pair<_Link_type,size_type>(_S_right(node),level), level+1);
1700  // ditto for the right
1701  else if ((!_S_right(node)))
1702  candidate = _M_get_j_max( std::pair<_Link_type,size_type>(_S_left(node),level), level+1);
1703  // we have both children ...
1704  else
1705  {
1706  // we need to do a little more work in order to find a good candidate
1707  // this is actually a technique used to choose a node from either the
1708  // left or right branch RANDOMLY, so that the tree has a greater change of
1709  // staying balanced.
1710  // If this were a true binary tree, we would always hunt down the right branch.
1711  // See top for notes.
1712  _Node_compare_ compare(level % __K, _M_acc, _M_cmp);
1713  // compare the children based on this level's criteria...
1714  // (this gives virtually random results)
1715  if (compare(_S_right(node)->_M_value, _S_left(node)->_M_value))
1716  // the right is smaller, get our replacement from the SMALLEST on the right
1717  candidate = _M_get_j_min(std::pair<_Link_type,size_type>(_S_right(node),level), level+1);
1718  else
1719  candidate = _M_get_j_max( std::pair<_Link_type,size_type>(_S_left(node),level), level+1);
1720  }
1721 
1722  // we have a candidate replacement by now.
1723  // remove it from the tree, but don't delete it.
1724  // it must be disconnected before it can be reconnected.
1725  _Link_type parent = _S_parent(candidate.first);
1726  if (_S_left(parent) == candidate.first)
1727  _S_set_left(parent, _M_erase(candidate.first, candidate.second));
1728  else
1729  _S_set_right(parent, _M_erase(candidate.first, candidate.second));
1730 
1731  return candidate.first;
1732  }
1733 
1734 
1735 
1736  // TODO: why not pass node by const-ref?
1737  std::pair<_Link_type,size_type>
1738  _M_get_j_min( std::pair<_Link_type,size_type> const node, size_type const level)
1739  {
1740  typedef std::pair<_Link_type,size_type> Result;
1741  if (_S_is_leaf(node.first))
1742  return Result(node.first,level);
1743 
1744  _Node_compare_ compare(node.second % __K, _M_acc, _M_cmp);
1745  Result candidate = node;
1746  if (_S_left(node.first))
1747  {
1748  Result left = _M_get_j_min(Result(_S_left(node.first), node.second), level+1);
1749  if (compare(left.first->_M_value, candidate.first->_M_value))
1750  candidate = left;
1751  }
1752  if (_S_right(node.first))
1753  {
1754  Result right = _M_get_j_min( Result(_S_right(node.first),node.second), level+1);
1755  if (compare(right.first->_M_value, candidate.first->_M_value))
1756  candidate = right;
1757  }
1758  if (candidate.first == node.first)
1759  return Result(candidate.first,level);
1760 
1761  return candidate;
1762  }
1763 
1764 
1765 
1766  // TODO: why not pass node by const-ref?
1767  std::pair<_Link_type,size_type>
1768  _M_get_j_max( std::pair<_Link_type,size_type> const node, size_type const level)
1769  {
1770  typedef std::pair<_Link_type,size_type> Result;
1771 
1772  if (_S_is_leaf(node.first))
1773  return Result(node.first,level);
1774 
1775  _Node_compare_ compare(node.second % __K, _M_acc, _M_cmp);
1776  Result candidate = node;
1777  if (_S_left(node.first))
1778  {
1779  Result left = _M_get_j_max( Result(_S_left(node.first),node.second), level+1);
1780  if (compare(candidate.first->_M_value, left.first->_M_value))
1781  candidate = left;
1782  }
1783  if (_S_right(node.first))
1784  {
1785  Result right = _M_get_j_max(Result(_S_right(node.first),node.second), level+1);
1786  if (compare(candidate.first->_M_value, right.first->_M_value))
1787  candidate = right;
1788  }
1789 
1790  if (candidate.first == node.first)
1791  return Result(candidate.first,level);
1792 
1793  return candidate;
1794  }
1795 
1796 
1797  void
1799  {
1800  while (__n)
1801  {
1802  _M_erase_subtree(_S_right(__n));
1803  _Link_type __t = _S_left(__n);
1804  _M_delete_node(__n);
1805  __n = __t;
1806  }
1807  }
1808 
1809  const_iterator
1810  _M_find(_Link_const_type node, const_reference value, size_type const level) const
1811  {
1812  // be aware! This is very different to normal binary searches, because of the <=
1813  // relationship used. See top for notes.
1814  // Basically we have to check ALL branches, as we may have an identical node
1815  // in different branches.
1816  const_iterator found = this->end();
1817 
1818  _Node_compare_ compare(level % __K, _M_acc, _M_cmp);
1819  if (!compare(node->_M_value,value)) // note, this is a <= test
1820  {
1821  // this line is the only difference between _M_find_exact() and _M_find()
1822  if (_M_matches_node(node, value, level))
1823  return const_iterator(node); // return right away
1824  if (_S_left(node))
1825  found = _M_find(_S_left(node), value, level+1);
1826  }
1827  if ( _S_right(node) && found == this->end() && !compare(value,node->_M_value)) // note, this is a <= test
1828  found = _M_find(_S_right(node), value, level+1);
1829  return found;
1830  }
1831 
1832  const_iterator
1834  {
1835  // be aware! This is very different to normal binary searches, because of the <=
1836  // relationship used. See top for notes.
1837  // Basically we have to check ALL branches, as we may have an identical node
1838  // in different branches.
1839  const_iterator found = this->end();
1840 
1841  _Node_compare_ compare(level % __K, _M_acc, _M_cmp);
1842  if (!compare(node->_M_value,value)) // note, this is a <= test
1843  {
1844  // this line is the only difference between _M_find_exact() and _M_find()
1845  if (value == *const_iterator(node))
1846  return const_iterator(node); // return right away
1847  if (_S_left(node))
1848  found = _M_find_exact(_S_left(node), value, level+1);
1849  }
1850 
1851  // note: no else! items that are identical can be down both branches
1852  if ( _S_right(node) && found == this->end() && !compare(value,node->_M_value)) // note, this is a <= test
1853  found = _M_find_exact(_S_right(node), value, level+1);
1854  return found;
1855  }
1856 
1857  bool
1859  size_type const __L) const
1860  {
1861  _Node_compare_ compare(__L % __K, _M_acc, _M_cmp);
1862  return !(compare(__N->_M_value, __V) || compare(__V, __N->_M_value));
1863  }
1864 
1865  bool
1867  size_type const __L = 0) const
1868  {
1869  size_type __i = __L;
1870  while ((__i = (__i + 1) % __K) != __L % __K)
1871  if (!_M_matches_node_in_d(__N, __V, __i)) return false;
1872  return true;
1873  }
1874 
1875  bool
1877  size_type __L = 0) const
1878  {
1879  return _M_matches_node_in_d(__N, __V, __L)
1880  && _M_matches_node_in_other_ds(__N, __V, __L);
1881  }
1882 
1883  size_type
1885  _Region_ const& __BOUNDS,
1886  size_type const __L) const
1887  {
1888  size_type count = 0;
1889  if (__REGION.encloses(_S_value(__N)))
1890  {
1891  ++count;
1892  }
1893  if (_S_left(__N))
1894  {
1895  _Region_ __bounds(__BOUNDS);
1896  __bounds.set_high_bound(_S_value(__N), __L);
1897  if (__REGION.intersects_with(__bounds))
1898  count += _M_count_within_range(_S_left(__N),
1899  __REGION, __bounds, __L+1);
1900  }
1901  if (_S_right(__N))
1902  {
1903  _Region_ __bounds(__BOUNDS);
1904  __bounds.set_low_bound(_S_value(__N), __L);
1905  if (__REGION.intersects_with(__bounds))
1906  count += _M_count_within_range(_S_right(__N),
1907  __REGION, __bounds, __L+1);
1908  }
1909 
1910  return count;
1911  }
1912 
1913 
1914  template <class Visitor>
1915  Visitor
1916  _M_visit_within_range(Visitor visitor,
1917  _Link_const_type N, _Region_ const& REGION,
1918  _Region_ const& BOUNDS,
1919  size_type const L) const
1920  {
1921  if (REGION.encloses(_S_value(N)))
1922  {
1923  visitor(_S_value(N));
1924  }
1925  if (_S_left(N))
1926  {
1927  _Region_ bounds(BOUNDS);
1928  bounds.set_high_bound(_S_value(N), L);
1929  if (REGION.intersects_with(bounds))
1930  visitor = _M_visit_within_range(visitor, _S_left(N),
1931  REGION, bounds, L+1);
1932  }
1933  if (_S_right(N))
1934  {
1935  _Region_ bounds(BOUNDS);
1936  bounds.set_low_bound(_S_value(N), L);
1937  if (REGION.intersects_with(bounds))
1938  visitor = _M_visit_within_range(visitor, _S_right(N),
1939  REGION, bounds, L+1);
1940  }
1941 
1942  return visitor;
1943  }
1944 
1945 
1946 
1947  template <typename _OutputIterator>
1948  _OutputIterator
1949  _M_find_within_range(_OutputIterator out,
1950  _Link_const_type __N, _Region_ const& __REGION,
1951  _Region_ const& __BOUNDS,
1952  size_type const __L) const
1953  {
1954  if (__REGION.encloses(_S_value(__N)))
1955  {
1956  *out++ = _S_value(__N);
1957  }
1958  if (_S_left(__N))
1959  {
1960  _Region_ __bounds(__BOUNDS);
1961  __bounds.set_high_bound(_S_value(__N), __L);
1962  if (__REGION.intersects_with(__bounds))
1963  out = _M_find_within_range(out, _S_left(__N),
1964  __REGION, __bounds, __L+1);
1965  }
1966  if (_S_right(__N))
1967  {
1968  _Region_ __bounds(__BOUNDS);
1969  __bounds.set_low_bound(_S_value(__N), __L);
1970  if (__REGION.intersects_with(__bounds))
1971  out = _M_find_within_range(out, _S_right(__N),
1972  __REGION, __bounds, __L+1);
1973  }
1974 
1975  return out;
1976  }
1977 
1978 
1979  template <typename _Iter>
1980  void
1981  _M_optimise(_Iter const& __A, _Iter const& __B,
1982  size_type const __L)
1983  {
1984  if (__A == __B) return;
1985  _Node_compare_ compare(__L % __K, _M_acc, _M_cmp);
1986  _Iter __m = __A + (__B - __A) / 2;
1987  std::nth_element(__A, __m, __B, compare);
1988  this->insert(*__m);
1989  if (__m != __A) _M_optimise(__A, __m, __L+1);
1990  if (++__m != __B) _M_optimise(__m, __B, __L+1);
1991  }
1992 
1993  _Link_const_type
1994  _M_get_root() const
1995  {
1996  return const_cast<_Link_const_type>(_M_root);
1997  }
1998 
1999  _Link_type
2001  {
2002  return _M_root;
2003  }
2004 
2006  {
2007  _M_root = n;
2008  }
2009 
2010  _Link_const_type
2012  {
2013  return static_cast<_Link_type>(_M_header._M_left);
2014  }
2015 
2016  void
2018  {
2019  _M_header._M_left = a;
2020  }
2021 
2022  _Link_const_type
2024  {
2025  return static_cast<_Link_type>( _M_header._M_right );
2026  }
2027 
2028  void
2030  {
2031  _M_header._M_right = a;
2032  }
2033 
2034  static _Link_type
2036  {
2037  return static_cast<_Link_type>( N->_M_parent );
2038  }
2039 
2040  static _Link_const_type
2042  {
2043  return static_cast<_Link_const_type>( N->_M_parent );
2044  }
2045 
2046  static void
2048  {
2049  N->_M_parent = p;
2050  }
2051 
2052  static void
2054  {
2055  N->_M_left = l;
2056  }
2057 
2058  static _Link_type
2060  {
2061  return static_cast<_Link_type>( N->_M_left );
2062  }
2063 
2064  static _Link_const_type
2066  {
2067  return static_cast<_Link_const_type>( N->_M_left );
2068  }
2069 
2070  static void
2072  {
2073  N->_M_right = r;
2074  }
2075 
2076  static _Link_type
2078  {
2079  return static_cast<_Link_type>( N->_M_right );
2080  }
2081 
2082  static _Link_const_type
2084  {
2085  return static_cast<_Link_const_type>( N->_M_right );
2086  }
2087 
2088  static bool
2090  {
2091  return !_S_left(N) && !_S_right(N);
2092  }
2093 
2094  static const_reference
2096  {
2097  return N->_M_value;
2098  }
2099 
2100  static const_reference
2102  {
2103  return static_cast<_Link_const_type>(N)->_M_value;
2104  }
2105 
2106  static _Link_const_type
2108  {
2109  return static_cast<_Link_const_type> ( _Node_base::_S_minimum(__X) );
2110  }
2111 
2112  static _Link_const_type
2114  {
2115  return static_cast<_Link_const_type>( _Node_base::_S_maximum(__X) );
2116  }
2117 
2118 
2119  _Link_type
2120  _M_new_node(const_reference __V, // = value_type(),
2121  _Base_ptr const __PARENT = nullptr,
2122  _Base_ptr const __LEFT = nullptr,
2123  _Base_ptr const __RIGHT = nullptr)
2124  {
2125  typename _Base::NoLeakAlloc noleak(this);
2126  _Link_type new_node = noleak.get();
2127  _Base::_M_construct_node(new_node, __V, __PARENT, __LEFT, __RIGHT);
2128  noleak.disconnect();
2129  return new_node;
2130  }
2131 
2132  /* WHAT was this for?
2133  _Link_type
2134  _M_clone_node(_Link_const_type __X)
2135  {
2136  _Link_type __ret = _M_allocate_node(__X->_M_value);
2137  // TODO
2138  return __ret;
2139  }
2140  */
2141 
2142  void
2144  {
2145  _Base::_M_destroy_node(__p);
2146  _Base::_M_deallocate_node(__p);
2147  }
2148 
2152  _Acc _M_acc;
2153  _Cmp _M_cmp;
2154  _Dist _M_dist;
2155 
2156 #ifdef KDTREE_DEFINE_OSTREAM_OPERATORS
2157  friend std::ostream&
2158  operator<<(std::ostream& o,
2160  {
2161  o << "meta node: " << tree._M_header << std::endl;
2162  o << "root node: " << tree._M_root << std::endl;
2163 
2164  if (tree.empty())
2165  return o << "[empty " << __K << "d-tree " << &tree << "]";
2166 
2167  o << "nodes total: " << tree.size() << std::endl;
2168  o << "dimensions: " << __K << std::endl;
2169 
2171  typedef typename _Tree::_Link_type _Link_type;
2172 
2173  std::stack<_Link_const_type> s;
2174  s.push(tree._M_get_root());
2175 
2176  while (!s.empty())
2177  {
2178  _Link_const_type n = s.top();
2179  s.pop();
2180  o << *n << std::endl;
2181  if (_Tree::_S_left(n)) s.push(_Tree::_S_left(n));
2182  if (_Tree::_S_right(n)) s.push(_Tree::_S_right(n));
2183  }
2184 
2185  return o;
2186  }
2187 #endif
2188 
2189 };
2190 
2191 
2192 } // namespace KDTree
2193 
2194 #endif // include guard
2195 
2196 /* COPYRIGHT --
2197  *
2198  * This file is part of libkdtree++, a C++ template KD-Tree sorting container.
2199  * libkdtree++ is (c) 2004-2007 Martin F. Krafft <libkdtree@pobox.madduck.net>
2200  * and Sylvain Bougerel <sylvain.bougerel.devel@gmail.com> distributed under the
2201  * terms of the Artistic License 2.0. See the ./COPYING file in the source tree
2202  * root for more information.
2203  * Parts of this file are (c) 2004-2007 Paul Harris <paulharris@computer.org>.
2204  *
2205  * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
2206  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES
2207  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
2208  */
Definition: KDTree.h:1054
static _Link_type _S_left(_Base_ptr N)
Definition: KDTree.h:2059
KDTree(const KDTree &__x)
Definition: KDTree.h:1086
bool _M_matches_node_in_other_ds(_Link_const_type __N, const_reference __V, size_type const __L=0) const
Definition: KDTree.h:1866
iterator insert(iterator, const_reference __V)
Definition: KDTree.h:1263
_OutputIterator find_within_range(SearchVal const &val, subvalue_type const range, _OutputIterator out) const
Definition: KDTree.h:1442
bool _M_matches_node_in_d(_Link_const_type __N, const_reference __V, size_type const __L) const
Definition: KDTree.h:1858
const_reverse_iterator rend() const
Definition: KDTree.h:1260
void efficient_replace_and_optimise(std::vector< value_type > &writable_vector)
Definition: KDTree.h:1144
void erase_exact(const_reference __V)
Definition: KDTree.h:1320
void erase(const_reference __V)
Definition: KDTree.h:1314
_Node_compare< _Val, _Acc, _Cmp > _Node_compare_
Definition: KDTree.h:1064
bool _M_matches_node(_Link_const_type __N, const_reference __V, size_type __L=0) const
Definition: KDTree.h:1876
static _Link_const_type _S_maximum(_Link_const_type __X)
Definition: KDTree.h:2113
Visitor visit_within_range(_Region_ const &REGION, Visitor visitor) const
Definition: KDTree.h:1420
_Link_const_type _M_get_rightmost() const
Definition: KDTree.h:2023
iterator _M_insert_left(_Link_type __N, const_reference __V)
Definition: KDTree.h:1609
static void _S_set_parent(_Base_ptr N, _Base_ptr p)
Definition: KDTree.h:2047
value_type const * const_pointer
Definition: KDTree.h:1070
void check_tree()
Definition: KDTree.h:1561
static _Link_const_type _S_minimum(_Link_const_type __X)
Definition: KDTree.h:2107
static void _S_set_left(_Base_ptr N, _Base_ptr l)
Definition: KDTree.h:2053
const_iterator begin() const
Definition: KDTree.h:1257
void _M_set_root(_Link_type n)
Definition: KDTree.h:2005
_Link_type _M_get_root()
Definition: KDTree.h:2000
iterator _M_insert(_Link_type __N, const_reference __V, size_type const __L)
Definition: KDTree.h:1629
void optimise()
Definition: KDTree.h:1548
void _M_delete_node(_Link_type __p)
Definition: KDTree.h:2143
_OutputIterator _M_find_within_range(_OutputIterator out, _Link_const_type __N, _Region_ const &__REGION, _Region_ const &__BOUNDS, size_type const __L) const
Definition: KDTree.h:1949
_Node< _Val > const * _Link_const_type
Definition: KDTree.h:1062
KDTree & operator=(const KDTree &__x)
Definition: KDTree.h:1153
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: KDTree.h:1251
_Link_type _M_get_erase_replacement(_Link_type node, size_type const level)
Definition: KDTree.h:1690
static _Link_const_type _S_parent(_Base_const_ptr N)
Definition: KDTree.h:2041
size_t size_type
Definition: KDTree.h:1075
size_type count_within_range(const_reference __V, subvalue_type const __R) const
Definition: KDTree.h:1391
_Node_base * _Base_ptr
Definition: KDTree.h:1059
std::pair< const_iterator, distance_type > find_nearest(SearchVal const &__val, distance_type __max) const
Definition: KDTree.h:1486
void _M_empty_initialise()
Definition: KDTree.h:1600
size_type size() const
Definition: KDTree.h:1188
_Dist _M_dist
Definition: KDTree.h:2154
bool empty() const
Definition: KDTree.h:1200
void _M_erase_subtree(_Link_type __n)
Definition: KDTree.h:1798
_Node< _Val > * _Link_type
Definition: KDTree.h:1061
value_type const & const_reference
Definition: KDTree.h:1072
allocator_type get_allocator() const
Definition: KDTree.h:1182
_Link_type _M_erase(_Link_type dead_dad, size_type const level)
Definition: KDTree.h:1647
size_type _M_count_within_range(_Link_const_type __N, _Region_ const &__REGION, _Region_ const &__BOUNDS, size_type const __L) const
Definition: KDTree.h:1884
iterator insert(const_reference __V)
Definition: KDTree.h:1269
static _Link_const_type _S_right(_Base_const_ptr N)
Definition: KDTree.h:2083
Visitor visit_within_range(SearchVal const &V, subvalue_type const R, Visitor visitor) const
Definition: KDTree.h:1411
const_iterator find(SearchVal const &__V) const
Definition: KDTree.h:1361
void _M_check_node(_Link_const_type node, size_type const level)
Definition: KDTree.h:1585
void insert(iterator __pos, _InputIterator __first, _InputIterator __last)
Definition: KDTree.h:1298
_Node_base _M_header
Definition: KDTree.h:2150
void _M_optimise(_Iter const &__A, _Iter const &__B, size_type const __L)
Definition: KDTree.h:1981
size_type count_within_range(_Region_ const &__REGION) const
Definition: KDTree.h:1399
_Base::allocator_type allocator_type
Definition: KDTree.h:1057
std::pair< _Link_type, size_type > _M_get_j_min(std::pair< _Link_type, size_type > const node, size_type const level)
Definition: KDTree.h:1738
std::reverse_iterator< iterator > reverse_iterator
Definition: KDTree.h:1252
size_type max_size() const
Definition: KDTree.h:1194
~KDTree()
Definition: KDTree.h:1176
_Alloc_base< _Val, _Alloc > _Base
Definition: KDTree.h:1056
static _Link_const_type _S_left(_Base_const_ptr N)
Definition: KDTree.h:2065
std::pair< const_iterator, distance_type > find_nearest(SearchVal const &__val) const
Definition: KDTree.h:1466
_Cmp value_comp() const
Comparator for the values in the KDTree.
Definition: KDTree.h:1221
_Acc _M_acc
Definition: KDTree.h:2152
void erase(const_iterator const &__IT)
Definition: KDTree.h:1326
void insert(iterator __pos, size_type __n, const value_type &__x)
Definition: KDTree.h:1290
void _M_set_leftmost(_Node_base *a)
Definition: KDTree.h:2017
KDTree(_InputIterator __first, _InputIterator __last, _Acc const &acc=_Acc(), _Dist const &__dist=_Dist(), _Cmp const &__cmp=_Cmp(), const allocator_type &__a=allocator_type())
Definition: KDTree.h:1106
void insert(_InputIterator __first, _InputIterator __last)
Definition: KDTree.h:1284
void optimize()
Definition: KDTree.h:1556
_Link_const_type _M_get_leftmost() const
Definition: KDTree.h:2011
_Node_base const * _Base_const_ptr
Definition: KDTree.h:1060
static bool _S_is_leaf(_Base_const_ptr N)
Definition: KDTree.h:2089
_Val value_type
Definition: KDTree.h:1068
const_iterator _M_find(_Link_const_type node, const_reference value, size_type const level) const
Definition: KDTree.h:1810
static const_reference _S_value(_Link_const_type N)
Definition: KDTree.h:2095
value_type & reference
Definition: KDTree.h:1071
void _M_check_children(_Link_const_type child, _Link_const_type parent, size_type const level, bool to_the_left)
Definition: KDTree.h:1568
_Acc value_acc() const
Accessor to the value's elements.
Definition: KDTree.h:1230
_Link_type _M_root
Definition: KDTree.h:2149
Visitor _M_visit_within_range(Visitor visitor, _Link_const_type N, _Region_ const &REGION, _Region_ const &BOUNDS, size_type const L) const
Definition: KDTree.h:1916
const _Dist & value_distance() const
Distance calculator between 2 value's element.
Definition: KDTree.h:1240
void clear()
Definition: KDTree.h:1206
const_iterator iterator
Definition: KDTree.h:1250
const_iterator end() const
Definition: KDTree.h:1258
ptrdiff_t difference_type
Definition: KDTree.h:1076
value_type * pointer
Definition: KDTree.h:1069
size_type _M_count
Definition: KDTree.h:2151
_Cmp _M_cmp
Definition: KDTree.h:2153
_Iterator< _Val, const_reference, const_pointer > const_iterator
Definition: KDTree.h:1248
std::pair< const_iterator, distance_type > find_nearest_if(SearchVal const &__val, distance_type __max, _Predicate __p) const
Definition: KDTree.h:1516
iterator _M_insert_right(_Link_type __N, const_reference __V)
Definition: KDTree.h:1619
_Dist & value_distance()
Definition: KDTree.h:1244
static void _S_set_right(_Base_ptr N, _Base_ptr r)
Definition: KDTree.h:2071
_Region< __K, _Val, typename _Acc::result_type, _Acc, _Cmp > _Region_
Definition: KDTree.h:1067
KDTree(_Acc const &__acc=_Acc(), _Dist const &__dist=_Dist(), _Cmp const &__cmp=_Cmp(), const allocator_type &__a=allocator_type())
Definition: KDTree.h:1078
_Link_type _M_new_node(const_reference __V, _Base_ptr const __PARENT=nullptr, _Base_ptr const __LEFT=nullptr, _Base_ptr const __RIGHT=nullptr)
Definition: KDTree.h:2120
const_iterator find_exact(SearchVal const &__V) const
Definition: KDTree.h:1383
std::pair< _Link_type, size_type > _M_get_j_max(std::pair< _Link_type, size_type > const node, size_type const level)
Definition: KDTree.h:1768
_Link_const_type _M_get_root() const
Definition: KDTree.h:1994
const_iterator _M_find_exact(_Link_const_type node, const_reference value, size_type const level) const
Definition: KDTree.h:1833
const_reverse_iterator rbegin() const
Definition: KDTree.h:1259
static _Link_type _S_parent(_Base_ptr N)
Definition: KDTree.h:2035
void _M_set_rightmost(_Node_base *a)
Definition: KDTree.h:2029
static _Link_type _S_right(_Base_ptr N)
Definition: KDTree.h:2077
_Dist::distance_type distance_type
Definition: KDTree.h:1074
_Acc::result_type subvalue_type
Definition: KDTree.h:1073
_OutputIterator find_within_range(_Region_ const &region, _OutputIterator out) const
Definition: KDTree.h:1452
static const_reference _S_value(_Base_const_ptr N)
Definition: KDTree.h:2101
Definition: KDTree.h:514
_Node_ * new_node
Definition: KDTree.h:516
~NoLeakAlloc()
Definition: KDTree.h:524
void disconnect()
Definition: KDTree.h:522
NoLeakAlloc(_Alloc_base *b)
Definition: KDTree.h:519
_Node_ * get()
Definition: KDTree.h:521
_Alloc_base * base
Definition: KDTree.h:515
Definition: KDTree.h:497
_Node_::_Base_ptr _Base_ptr
Definition: KDTree.h:500
void _M_construct_node(_Node_ *__p, _Tp const __V=_Tp(), _Base_ptr const __PARENT=NULL, _Base_ptr const __LEFT=NULL, _Base_ptr const __RIGHT=NULL)
Definition: KDTree.h:544
_Node< _Tp > _Node_
Definition: KDTree.h:499
_Alloc_base(allocator_type const &__A)
Definition: KDTree.h:503
allocator_type get_allocator() const
Definition: KDTree.h:507
void _M_deallocate_node(_Node_ *const __P)
Definition: KDTree.h:538
_Alloc allocator_type
Definition: KDTree.h:501
_Node_ * _M_allocate_node()
Definition: KDTree.h:532
void _M_destroy_node(_Node_ *__p)
Definition: KDTree.h:553
allocator_type _M_node_allocator
Definition: KDTree.h:529
Definition: KDTree.h:622
void _M_decrement()
Definition: KDTree.h:655
_Base_iterator(_Base_iterator const &__THAT)
Definition: KDTree.h:629
_Node_base::_Base_const_ptr _Base_const_ptr
Definition: KDTree.h:624
_Base_const_ptr _M_node
Definition: KDTree.h:625
_Base_iterator(_Base_const_ptr const __N=nullptr)
Definition: KDTree.h:627
void _M_increment()
Definition: KDTree.h:633
Definition: KDTree.h:688
_Iterator< _Val, _Ref, _Ptr > _Self
Definition: KDTree.h:695
std::bidirectional_iterator_tag iterator_category
Definition: KDTree.h:697
_Iterator< _Val, _Val &, _Val * > iterator
Definition: KDTree.h:693
_Self & operator--()
Definition: KDTree.h:740
_Ptr pointer
Definition: KDTree.h:692
_Node< _Val > const * _Link_const_type
Definition: KDTree.h:696
_Self operator++(int)
Definition: KDTree.h:732
_Iterator(_Link_const_type const __N)
Definition: KDTree.h:702
_Link_const_type get_raw_node() const
Definition: KDTree.h:707
_Iterator(iterator const &__THAT)
Definition: KDTree.h:704
_Ref reference
Definition: KDTree.h:691
_Self operator++()
Definition: KDTree.h:725
_Iterator< _Val, _Val const &, _Val const * > const_iterator
Definition: KDTree.h:694
reference operator*() const
Definition: KDTree.h:713
_Val value_type
Definition: KDTree.h:690
_Iterator()
Definition: KDTree.h:700
ptrdiff_t difference_type
Definition: KDTree.h:698
_Self operator--(int)
Definition: KDTree.h:747
pointer operator->() const
Definition: KDTree.h:719
Definition: KDTree.h:125
bool operator()(_Val const &__A, _Val const &__B) const
Definition: KDTree.h:131
_Node_compare(size_t const __DIM, _Acc const &acc, _Cmp const &cmp)
Definition: KDTree.h:127
_Acc _M_acc
Definition: KDTree.h:138
_Cmp _M_cmp
Definition: KDTree.h:139
size_t _M_DIM
Definition: KDTree.h:137
Definition: KDTree.h:47
bool _S_node_compare(const size_t __dim, const _Cmp &__cmp, const _Acc &__acc, const _ValA &__a, const _ValB &__b)
Definition: KDTree.h:152
const NodeType * _S_node_descend(const size_t __dim, const _Cmp &__cmp, const _Acc &__acc, const _Val &__val, const NodeType *__node)
Definition: KDTree.h:203
bool operator==(_Iterator< _Val, _Ref, _Ptr > const &, _Iterator< _Val, _Ref, _Ptr > const &)
Definition: KDTree.h:781
bool operator!=(_Iterator< _Val, _Ref, _Ptr > const &, _Iterator< _Val, _Ref, _Ptr > const &)
Definition: KDTree.h:799
_Dist::distance_type _S_accumulate_node_distance(const size_t __dim, const _Dist &__dist, const _Acc &__acc, const _ValA &__a, const _ValB &__b)
Definition: KDTree.h:185
std::pair< const NodeType *, std::pair< size_t, typename _Dist::distance_type > > _S_node_nearest(const size_t __k, size_t __dim, SearchVal const &__val, const NodeType *__node, const _Node_base *__end, const NodeType *__best, typename _Dist::distance_type __max, const _Cmp &__cmp, const _Acc &__acc, const _Dist &__dist, _Predicate __p)
Definition: KDTree.h:227
_Dist::distance_type _S_node_distance(const size_t __dim, const _Dist &__dist, const _Acc &__acc, const _ValA &__a, const _ValB &__b)
Definition: KDTree.h:168
const double R
Definition: Constants.h:149
std::ostream & operator<<(std::ostream &os, const AccurateMassSearchResult &amsr)
Definition: KDTree.h:408
result_type operator()(_Val const &V, size_t const N) const
Definition: KDTree.h:412
_Val::value_type result_type
Definition: KDTree.h:409
Definition: KDTree.h:49
_Node_base * _Base_ptr
Definition: KDTree.h:50
_Base_ptr _M_parent
Definition: KDTree.h:53
static _Base_ptr _S_minimum(_Base_ptr __x)
Definition: KDTree.h:63
_Base_ptr _M_right
Definition: KDTree.h:55
_Node_base const * _Base_const_ptr
Definition: KDTree.h:51
static _Base_ptr _S_maximum(_Base_ptr __x)
Definition: KDTree.h:70
_Base_ptr _M_left
Definition: KDTree.h:54
_Node_base(_Base_ptr const __PARENT=nullptr, _Base_ptr const __LEFT=nullptr, _Base_ptr const __RIGHT=nullptr)
Definition: KDTree.h:57
Definition: KDTree.h:79
_Node(_Val const &__VALUE=_Val(), _Base_ptr const __PARENT=nullptr, _Base_ptr const __LEFT=nullptr, _Base_ptr const __RIGHT=nullptr)
Definition: KDTree.h:85
_Val _M_value
Definition: KDTree.h:83
_Node * _Link_type
Definition: KDTree.h:81
Definition: KDTree.h:848
_Region & set_low_bound(value_type const &__V, size_t const __L)
Definition: KDTree.h:933
bool encloses(value_type const &__V) const
Definition: KDTree.h:914
bool intersects_with(_Region const &__THAT) const
Definition: KDTree.h:902
_Region(_Acc const &__acc=_Acc(), const _Cmp &__cmp=_Cmp())
Definition: KDTree.h:857
_SubVal subvalue_type
Definition: KDTree.h:850
_Region(Val const &__V, subvalue_type const &__R, _Acc const &__acc=_Acc(), const _Cmp &__cmp=_Cmp())
Definition: KDTree.h:872
_Acc _M_acc
Definition: KDTree.h:940
std::pair< _Region, _SubVal > _CenterPt
Definition: KDTree.h:855
_Val value_type
Definition: KDTree.h:849
_Region & set_high_bound(value_type const &__V, size_t const __L)
Definition: KDTree.h:926
subvalue_type _M_low_bounds[__K]
Definition: KDTree.h:939
_Cmp _M_cmp
Definition: KDTree.h:941
bool intersects_with(_CenterPt const &__THAT) const
Definition: KDTree.h:884
subvalue_type _M_high_bounds[__K]
Definition: KDTree.h:939
_Region(Val const &__V, _Acc const &__acc=_Acc(), const _Cmp &__cmp=_Cmp())
Definition: KDTree.h:861
Definition: KDTree.h:420
bool operator()(const _Tp &) const
Definition: KDTree.h:421
Definition: KDTree.h:439
distance_type operator()(const _Tp &__a, const _Tp &__b) const
Definition: KDTree.h:454
long _M_count
Definition: KDTree.h:462
squared_difference_counted()
Definition: KDTree.h:442
long & count() const
Definition: KDTree.h:450
void reset()
Definition: KDTree.h:446
_Dist distance_type
Definition: KDTree.h:440
Definition: KDTree.h:426
distance_type operator()(const _Tp &__a, const _Tp &__b) const
Definition: KDTree.h:430
_Dist distance_type
Definition: KDTree.h:427