PandaRoot
kdtree.h
Go to the documentation of this file.
1 #ifndef __KDTREE_HPP
2 #define __KDTREE_HPP
3 
4 // (c) Matthew B. Kennel, Institute for Nonlinear Science, UCSD (2004)
5 //
6 // Licensed under the Academic Free License version 1.1 found in file LICENSE
7 // with additional provisions in that same file.
8 //
9 // Implement a kd tree for fast searching of points in a fixed data base
10 // in k-dimensional Euclidean space.
11 
12 #include <vector>
13 #include <algorithm>
14 
15 #include <boost/multi_array.hpp>
16 #include <boost/array.hpp>
17 
18 namespace kdtree {
19 
20 typedef boost::multi_array<double, 2> KDTreeArray;
21 typedef boost::const_multi_array_ref<double, 2> KDTreeROArray;
22 
23 typedef struct {
24  double lower, upper;
25 } interval;
26 
27 // let the compiler know that this is a names of classes.
28 class KDTreeNode;
29 class SearchRecord;
30 
31 struct KDTreeResult {
32  public:
33  double dis; // square distance
34  int idx; // neighbor index
35 };
36 
37 class KDTreeResultVector : public std::vector<KDTreeResult> {
38  // inherit a std::vector<KDTreeResult>
39  // but, optionally maintain it in heap form as a priority
40  // queue.
41  public:
42  //
43  // add one new element to the list of results, and
44  // keep it in heap order. To keep it in ordinary, as inserted,
45  // order, then simply use push_back() as inherited
46  // via std::vector<>
47 
48  void push_element_and_heapify(KDTreeResult &);
49  double replace_maxpri_elt_return_new_maxpri(KDTreeResult &);
50 
51  double max_value();
52  // return the distance which has the maximum value of all on list,
53  // assuming that ALL insertions were made by
54  // push_element_and_heapify()
55 };
56 
57 class KDTree {
58  public:
59  const KDTreeArray &the_data;
60  // "the_data" is a reference to the underlying multi_array of the
61  // data to be included in the tree.
62  //
63  // NOTE: this structure does *NOT* own the storage underlying this.
64  // Hence, it would be a very bad idea to change the underlying data
65  // during use of the search facilities of this tree.
66  // Also, the user must deallocate the memory underlying it.
67 
68  const int N; // number of data points
69  int dim;
70  bool sort_results; // sorting result?
71  const bool rearrange; // are we rearranging?
72 
73  public:
74  // constructor, has optional 'dim_in' feature, to use only
75  // first 'dim_in' components for definition of nearest neighbors.
76  KDTree(KDTreeArray &data_in, bool rearrange_in = true, int dim_in = -1);
77 
78  // destructor
79  ~KDTree();
80 
81  public:
82  void n_nearest_brute_force(std::vector<double> &qv, int nn, KDTreeResultVector &result);
83  // search for n nearest to a given query vector 'qv' usin
84  // exhaustive slow search. For debugging, usually.
85 
86  void n_nearest(std::vector<double> &qv, int nn, KDTreeResultVector &result);
87  // search for n nearest to a given query vector 'qv'.
88 
89  void n_nearest_around_point(int idxin, int correltime, int nn, KDTreeResultVector &result);
90  // search for 'nn' nearest to point [idxin] of the input data, excluding
91  // neighbors within correltime
92 
93  void r_nearest(std::vector<double> &qv, double r2, KDTreeResultVector &result);
94  // search for all neighbors in ball of size (square Euclidean distance)
95  // r2. Return number of neighbors in 'result.size()',
96 
97  void r_nearest_around_point(int idxin, int correltime, double r2, KDTreeResultVector &result);
98  // like 'r_nearest', but around existing point, with decorrelation
99  // interval.
100 
101  int r_count(std::vector<double> &qv, double r2);
102  // count number of neighbors within square distance r2.
103 
104  int r_count_around_point(int idxin, int correltime, double r2);
105  // like r_count, c
106 
107  friend class KDTreeNode;
108  friend class SearchRecord;
109 
110  private:
111  KDTreeNode *root; // the root pointer
112 
113  const KDTreeArray *data;
114  // pointing either to the_data or an internal
115  // rearranged data as necessary
116 
117  std::vector<int> ind;
118  // the index for the tree leaves. Data in a leaf with bounds [l,u] are
119  // in 'the_data[ind[l],*] to the_data[ind[u],*]
120 
121  KDTreeArray rearranged_data;
122  // if rearrange is true then this is the rearranged data storage.
123 
124  // no of points per node, standard was 12
125  static const int bucketsize = 120; // global constant.
126 
127  private:
128  void set_data(KDTreeArray &din);
129  void build_tree(); // builds the tree. Used upon construction.
130  KDTreeNode *build_tree_for_range(int l, int u, KDTreeNode *parent);
131  void select_on_coordinate(int c, int k, int l, int u);
132  int select_on_coordinate_value(int c, double alpha, int l, int u);
133  void spread_in_coordinate(int c, int l, int u, interval &interv);
134 };
135 
136 class KDTreeNode {
137  public:
138  KDTreeNode(int dim);
139  ~KDTreeNode();
140 
141  private:
142  // visible to self and KDTree.
143  friend class KDTree; // allow kdtree to access private data
144 
145  int cut_dim; // dimension to cut;
146  double cut_val, cut_val_left, cut_val_right; // cut value
147  int l, u; // extents in index array for searching
148 
149  std::vector<interval> box; // [min,max] of the box enclosing all points
150 
151  KDTreeNode *left, *right; // pointers to left and right nodes.
152 
153  void search(SearchRecord &sr);
154  // recursive innermost core routine for searching..
155 
156  bool box_in_search_range(SearchRecord &sr);
157  // return true if the bounding box for this node is within the
158  // search range given by the searchvector and maximum ballsize in 'sr'.
159 
160  void check_query_in_bound(SearchRecord &sr); // debugging only
161 
162  // for processing final buckets.
163  void process_terminal_node(SearchRecord &sr);
164  void process_terminal_node_fixedball(SearchRecord &sr);
165 };
166 
167 } // namespace kdtree
168 
169 #endif
boost::multi_array< double, 2 > KDTreeArray
Definition: kdtree.h:20
const int N
Definition: kdtree.h:68
double upper
Definition: kdtree.h:24
const bool rearrange
Definition: kdtree.h:71
bool sort_results
Definition: kdtree.h:70
const KDTreeArray & the_data
Definition: kdtree.h:59
Definition: kdtree.h:18
double alpha
Definition: f_Init.h:7
boost::const_multi_array_ref< double, 2 > KDTreeROArray
Definition: kdtree.h:21