Kd_tree_search.h
1 /* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT.
2  * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details.
3  * Author(s): Clement Jamin
4  *
5  * Copyright (C) 2016 Inria
6  *
7  * Modification(s):
8  * - 2019/08 Vincent Rouvreau: Fix issue #10 for CGAL and Eigen3
9  * - YYYY/MM Author: Description of the modification
10  */
11 
12 #ifndef KD_TREE_SEARCH_H_
13 #define KD_TREE_SEARCH_H_
14 
15 #include <CGAL/Orthogonal_k_neighbor_search.h>
16 #include <CGAL/Orthogonal_incremental_neighbor_search.h>
17 #include <CGAL/Search_traits.h>
18 #include <CGAL/Search_traits_adapter.h>
19 #include <CGAL/Fuzzy_sphere.h>
20 #include <CGAL/property_map.h>
21 #include <CGAL/version.h> // for CGAL_VERSION_NR
22 
23 #include <Eigen/src/Core/util/Macros.h> // for EIGEN_VERSION_AT_LEAST
24 
25 #include <boost/property_map/property_map.hpp>
26 #include <boost/iterator/counting_iterator.hpp>
27 
28 #include <cstddef>
29 #include <vector>
30 
31 // Make compilation fail - required for external projects - https://github.com/GUDHI/gudhi-devel/issues/10
32 #if CGAL_VERSION_NR < 1041101000
33 # error Kd_tree_search is only available for CGAL >= 4.11
34 #endif
35 
36 #if !EIGEN_VERSION_AT_LEAST(3,1,0)
37 # error Kd_tree_search is only available for Eigen3 >= 3.1.0 installed with CGAL
38 #endif
39 
40 namespace Gudhi {
41 namespace spatial_searching {
42 
43 
69 template <typename Search_traits, typename Point_range>
71  typedef boost::iterator_property_map<
72  typename Point_range::const_iterator,
73  CGAL::Identity_property_map<std::ptrdiff_t> > Point_property_map;
74 
75  public:
77  typedef Search_traits Traits;
79  typedef typename Traits::FT FT;
81  typedef typename Point_range::value_type Point;
82 
83  typedef CGAL::Search_traits<
84  FT, Point,
85  typename Traits::Cartesian_const_iterator_d,
86  typename Traits::Construct_cartesian_const_iterator_d> Traits_base;
87 
88  typedef CGAL::Search_traits_adapter<
89  std::ptrdiff_t,
90  Point_property_map,
91  Traits_base> STraits;
92  typedef CGAL::Distance_adapter<
93  std::ptrdiff_t,
94  Point_property_map,
95  CGAL::Euclidean_distance<Traits_base> > Orthogonal_distance;
96 
97  typedef CGAL::Orthogonal_k_neighbor_search<STraits> K_neighbor_search;
98  typedef typename K_neighbor_search::Tree Tree;
99  typedef typename K_neighbor_search::Distance Distance;
103  typedef K_neighbor_search KNS_range;
104 
105  typedef CGAL::Orthogonal_incremental_neighbor_search<
106  STraits, Distance, CGAL::Sliding_midpoint<STraits>, Tree>
107  Incremental_neighbor_search;
111  typedef Incremental_neighbor_search INS_range;
112 
113  typedef CGAL::Fuzzy_sphere<STraits> Fuzzy_sphere;
117  Kd_tree_search(Point_range const& points)
118  : m_points(points),
119  m_tree(boost::counting_iterator<std::ptrdiff_t>(0),
120  boost::counting_iterator<std::ptrdiff_t>(points.size()),
121  typename Tree::Splitter(),
122  STraits(std::begin(points))) {
123  // Build the tree now (we don't want to wait for the first query)
124  m_tree.build();
125  }
126 
132  template <typename Point_indices_range>
134  Point_range const& points,
135  Point_indices_range const& only_these_points)
136  : m_points(points),
137  m_tree(
138  only_these_points.begin(), only_these_points.end(),
139  typename Tree::Splitter(),
140  STraits(std::begin(points))) {
141  // Build the tree now (we don't want to wait for the first query)
142  m_tree.build();
143  }
144 
151  Point_range const& points,
152  std::size_t begin_idx, std::size_t past_the_end_idx)
153  : m_points(points),
154  m_tree(
155  boost::counting_iterator<std::ptrdiff_t>(begin_idx),
156  boost::counting_iterator<std::ptrdiff_t>(past_the_end_idx),
157  typename Tree::Splitter(),
158  STraits(std::begin(points))) {
159  // Build the tree now (we don't want to wait for the first query)
160  m_tree.build();
161  }
162 
163  // Be careful, this function invalidates the tree,
164  // which will be recomputed at the next query
165  void insert(std::ptrdiff_t point_idx) {
166  m_tree.insert(point_idx);
167  }
168 
176  Point const& p,
177  unsigned int k,
178  bool sorted = true,
179  FT eps = FT(0)) const {
180  // Initialize the search structure, and search all N points
181  // Note that we need to pass the Distance explicitly since it needs to
182  // know the property map
183  K_neighbor_search search(
184  m_tree,
185  p,
186  k,
187  eps,
188  true,
189  Orthogonal_distance(std::begin(m_points)), sorted);
190 
191  return search;
192  }
193 
201  INS_range incremental_nearest_neighbors(Point const& p, FT eps = FT(0)) const {
202  // Initialize the search structure, and search all N points
203  // Note that we need to pass the Distance explicitly since it needs to
204  // know the property map
205  Incremental_neighbor_search search(
206  m_tree,
207  p,
208  eps,
209  true,
210  Orthogonal_distance(std::begin(m_points)) );
211 
212  return search;
213  }
214 
222  Point const& p,
223  unsigned int k,
224  bool sorted = true,
225  FT eps = FT(0)) const {
226  // Initialize the search structure, and search all N points
227  // Note that we need to pass the Distance explicitly since it needs to
228  // know the property map
229  K_neighbor_search search(
230  m_tree,
231  p,
232  k,
233  eps,
234  false,
235  Orthogonal_distance(std::begin(m_points)), sorted);
236 
237  return search;
238  }
239 
247  INS_range incremental_furthest_neighbors(Point const& p, FT eps = FT(0)) const {
248  // Initialize the search structure, and search all N points
249  // Note that we need to pass the Distance explicitly since it needs to
250  // know the property map
251  Incremental_neighbor_search search(
252  m_tree,
253  p,
254  eps,
255  false,
256  Orthogonal_distance(std::begin(m_points)) );
257 
258  return search;
259  }
260 
267  template <typename OutputIterator>
268  void all_near_neighbors(Point const& p,
269  FT radius,
270  OutputIterator it,
271  FT eps = FT(0)) const {
272  m_tree.search(it, Fuzzy_sphere(p, radius, eps, m_tree.traits()));
273  }
274 
275  int tree_depth() const {
276  return m_tree.root()->depth();
277  }
278 
279  private:
280  Point_range const& m_points;
281  Tree m_tree;
282 };
283 
284 } // namespace spatial_searching
285 } // namespace Gudhi
286 
287 #endif // KD_TREE_SEARCH_H_
Spatial tree data structure to perform (approximate) nearest and furthest neighbor search...
Definition: Kd_tree_search.h:70
Kd_tree_search(Point_range const &points, std::size_t begin_idx, std::size_t past_the_end_idx)
Constructor.
Definition: Kd_tree_search.h:150
Kd_tree_search(Point_range const &points, Point_indices_range const &only_these_points)
Constructor.
Definition: Kd_tree_search.h:133
Incremental_neighbor_search INS_range
The range returned by an incremental nearest or furthest neighbor search. Its value type is std::pair...
Definition: Kd_tree_search.h:111
K_neighbor_search KNS_range
The range returned by a k-nearest or k-furthest neighbor search. Its value type is std::pair<std::siz...
Definition: Kd_tree_search.h:103
INS_range incremental_furthest_neighbors(Point const &p, FT eps=FT(0)) const
Search incrementally for the furthest neighbors from a query point.
Definition: Kd_tree_search.h:247
KNS_range k_nearest_neighbors(Point const &p, unsigned int k, bool sorted=true, FT eps=FT(0)) const
Search for the k-nearest neighbors from a query point.
Definition: Kd_tree_search.h:175
Kd_tree_search(Point_range const &points)
Constructor.
Definition: Kd_tree_search.h:117
Definition: SimplicialComplexForAlpha.h:14
INS_range incremental_nearest_neighbors(Point const &p, FT eps=FT(0)) const
Search incrementally for the nearest neighbors from a query point.
Definition: Kd_tree_search.h:201
KNS_range k_furthest_neighbors(Point const &p, unsigned int k, bool sorted=true, FT eps=FT(0)) const
Search for the k-furthest points from a query point.
Definition: Kd_tree_search.h:221
Traits::FT FT
Number type used for distances.
Definition: Kd_tree_search.h:79
void all_near_neighbors(Point const &p, FT radius, OutputIterator it, FT eps=FT(0)) const
Search for all the neighbors in a ball.
Definition: Kd_tree_search.h:268
Point_range::value_type Point
The point type.
Definition: Kd_tree_search.h:81
Search_traits Traits
The Traits.
Definition: Kd_tree_search.h:77
GUDHI  Version 3.1.1  - C++ library for Topological Data Analysis (TDA) and Higher Dimensional Geometry Understanding.  - Copyright : MIT Generated on Fri Feb 7 2020 16:35:36 for GUDHI by Doxygen 1.8.13