Garfield++ 4.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
KDTree.hh
Go to the documentation of this file.
1#ifndef G_KDTREE2_H
2#define G_KDTREE2_H
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
10// Implement a kd tree for fast searching of points in a fixed data base
11// in k-dimensional Euclidean space.
12
13#include <vector>
14#include <array>
15#include <queue>
16#include <algorithm>
17
18namespace Garfield {
19
20typedef std::vector<std::vector<double> > KDTreeArray;
21
22class KDTreeNode;
23
24/// Search result
25
27 double dis; //< square Euclidean distance
28 size_t idx; //< index
29};
30
31/// Main k-d tree class.
32/// Fast search of points in k-dimensional Euclidean space.
33
34class KDTree {
35public:
36 // Reference to the underlying data to be included in the tree.
38
39 size_t m_dim;
40 bool sort_results = false;
41
42public:
43 KDTree() = delete;
44 /// Constructor.
45 KDTree(KDTreeArray& data_in);
46 /// Destructor.
47 ~KDTree();
48
49 /** Search for nn nearest neighbours around a point.
50 * \param qv input point
51 * \param nn number of nearest neighbours
52 * \param result indices and distances of the nearest neighbours
53 */
54 void n_nearest(const std::vector<double>& qv, const unsigned int nn,
55 std::vector<KDTreeResult>& result) const;
56
57 /** Search for nn nearest neighbours around a node of the input data,
58 * excluding neighbors within a decorrelation interval.
59 * \param idx index of the input point
60 * \param ndecorrel decorrelation interval
61 * \param nn number of nearest neighbours
62 * \param result indices and distances of the nearest neighbours
63 */
64 void n_nearest_around_point(const unsigned int idx,
65 const unsigned int ndecorrel,
66 const unsigned int nn,
67 std::vector<KDTreeResult>& result) const;
68
69 /** Search for all neighbors in a ball of size r2
70 * \param qv input point
71 * \param r2 ball size (square Euclidean distance)
72 * \param result indices and distances of the nearest neighbours
73 */
74 void r_nearest(const std::vector<double>& qv, const double r2,
75 std::vector<KDTreeResult>& result) const;
76
77 /// Like r_nearest, but around an existing point,
78 /// with decorrelation interval.
79 void r_nearest_around_point(const unsigned int idx,
80 const unsigned int ndecorrel, const double r2,
81 std::vector<KDTreeResult>& result) const;
82
83 friend class KDTreeNode;
84private:
85 KDTreeNode* m_root = nullptr;
86
87 // Index for the tree leaves. Data in a leaf with bounds [l,u] are
88 // in 'data[ind[l],*] to data[ind[u],*]
89 std::vector<size_t> m_ind;
90
91 static constexpr int bucketsize = 12; // global constant.
92
93private:
94 KDTreeNode* build_tree_for_range(int l, int u, KDTreeNode* parent);
95 int select_on_coordinate_value(int c, double alpha, int l, int u);
96 std::array<double, 2> spread_in_coordinate(const int c, const int l, const int u) const;
97};
98
99/// A node in the k-d tree.
100
102public:
103 /// Constructor
104 KDTreeNode(int dim);
105 /// Destructor
106 ~KDTreeNode();
107
108private:
109 friend class KDTree;
110
111 // Dimension to cut.
112 size_t cut_dim = 0;
113 // Cut value.
114 double cut_val = 0.;
115 double cut_val_left = 0.;
116 double cut_val_right = 0.;
117 // Extents in index array for searching
118 int m_l = 0;
119 int m_u = 0;
120 // [min,max] of the box enclosing all points
121 std::vector<std::array<double, 2> > box;
122
123 // Pointers to left and right nodes.
124 KDTreeNode *left = nullptr;
125 KDTreeNode *right = nullptr;
126
127 // Recursive innermost core routines for searching.
128 void search_n(const int idx0, const int nd,
129 const unsigned int nn, double& r2,
130 const std::vector<double>& qv, const KDTree& tree,
131 std::priority_queue<KDTreeResult>& res) const;
132 void search_r(const int idx0, const int nd, const double r2,
133 const std::vector<double>& qv, const KDTree& tree,
134 std::vector<KDTreeResult>& res) const;
135
136 // Return true if the bounding box for this node is within the
137 // search range around a point.
138 bool box_in_search_range(const double r2,
139 const std::vector<double>& qv) const;
140
141 // For processing final buckets.
142 void process_terminal_node_n(const int idx0, const int nd,
143 const unsigned int nn, double& r2,
144 const std::vector<double>& qv,
145 const KDTree& tree,
146 std::priority_queue<KDTreeResult>& res) const;
147 void process_terminal_node_r(const int idx0, const int nd,
148 const double r2,
149 const std::vector<double>& qv,
150 const KDTree& tree,
151 std::vector<KDTreeResult>& res) const;
152
153};
154
155}
156
157#endif
A node in the k-d tree.
Definition: KDTree.hh:101
~KDTreeNode()
Destructor.
Definition: KDTree.cc:227
bool sort_results
Definition: KDTree.hh:40
const KDTreeArray & m_data
Definition: KDTree.hh:37
void n_nearest_around_point(const unsigned int idx, const unsigned int ndecorrel, const unsigned int nn, std::vector< KDTreeResult > &result) const
Definition: KDTree.cc:189
void r_nearest(const std::vector< double > &qv, const double r2, std::vector< KDTreeResult > &result) const
Definition: KDTree.cc:205
~KDTree()
Destructor.
Definition: KDTree.cc:50
size_t m_dim
Definition: KDTree.hh:39
void n_nearest(const std::vector< double > &qv, const unsigned int nn, std::vector< KDTreeResult > &result) const
Definition: KDTree.cc:174
void r_nearest_around_point(const unsigned int idx, const unsigned int ndecorrel, const double r2, std::vector< KDTreeResult > &result) const
Definition: KDTree.cc:213
std::vector< std::vector< double > > KDTreeArray
Definition: KDTree.hh:20
Search result.
Definition: KDTree.hh:26