7 #ifndef NIHU_CLUSTER_TREE_HPP_INCLUDED
8 #define NIHU_CLUSTER_TREE_HPP_INCLUDED
14 #include "Eigen/Dense"
15 #include "Eigen/StdVector"
32 template <
class ClusterDerived>
36 typedef ClusterDerived cluster_t;
39 typedef typename cluster_t::bounding_box_t bounding_box_t;
40 typedef typename cluster_t::location_t location_t;
41 typedef typename cluster_t::idx_list_t idx_list_t;
45 cluster_t, Eigen::aligned_allocator<cluster_t>
48 typedef typename cluster_vector_t::const_iterator iterator_t;
58 template <
class It,
class Div
ideDerived>
60 :
cluster_tree(src_begin, src_end, src_begin, src_end, divide)
74 template <
class It1,
class It2,
class Div
ideDerived>
76 : n_src(src_end - src_begin)
77 , n_rec(rec_end - rec_begin)
79 if (this->n_src + this->n_rec == 0)
80 throw std::logic_error(
"Cannot build cluster_tree from zero nodes");
82 cluster_t root_cluster;
83 root_cluster.set_level(0);
86 typedef Eigen::Matrix<double, dimension, Eigen::Dynamic> nodes_t;
87 nodes_t nodes(dimension, n_src + n_rec);
88 for (
size_t i = 0; i < n_src; ++i)
89 nodes.col(i) = src_begin[i];
90 for (
size_t i = 0; i < n_rec; ++i)
91 nodes.col(n_src + i) = rec_begin[i];
92 bounding_box_t bb(nodes);
93 root_cluster.set_bounding_box(bb);
96 idx_list_t src_node_idx(n_src);
97 std::iota(src_node_idx.begin(), src_node_idx.end(), 0);
98 root_cluster.set_src_node_idx(src_node_idx);
100 idx_list_t rec_node_idx(n_rec);
101 std::iota(rec_node_idx.begin(), rec_node_idx.end(), 0);
102 root_cluster.set_rec_node_idx(rec_node_idx);
104 this->clusters.push_back(root_cluster);
107 for (
size_t idx = 0; idx < clusters.size(); ++idx)
109 if (divide(clusters[idx]))
112 auto par_bb = clusters[idx].get_bounding_box();
115 auto par_src = clusters[idx].get_src_node_idx();
116 auto par_rec = clusters[idx].get_rec_node_idx();
119 for (
size_t i = 0; i < (1 << dimension); ++i)
121 auto child_bb = par_bb.get_child(i);
124 idx_list_t child_src(par_src.size());
125 auto q_src =
move_if(par_src.begin(), par_src.end(),
126 child_src.begin(), [&](
size_t u) {
127 return bounding_box_t::dist2idx(src_begin[u], par_bb.get_center()) == i;
129 child_src.resize(std::distance(q_src, par_src.end()));
130 par_src.erase(q_src, par_src.end());
133 idx_list_t child_rec(par_rec.size());
134 auto q_rec =
move_if(par_rec.begin(), par_rec.end(),
135 child_rec.begin(), [&](
size_t u) {
136 return bounding_box_t::dist2idx(rec_begin[u], par_bb.get_center()) == i;
138 child_rec.resize(std::distance(q_rec, par_rec.end()));
139 par_rec.erase(q_rec, par_rec.end());
142 if (child_src.empty() && child_rec.empty())
146 child.set_parent(idx);
147 child.set_bounding_box(child_bb);
148 child.set_src_node_idx(child_src);
149 child.set_rec_node_idx(child_rec);
150 child.set_level(clusters[idx].get_level() + 1);
151 clusters[idx].add_child(clusters.size());
152 clusters.push_back(child);
154 if (!par_src.empty() || !par_rec.empty())
155 throw std::runtime_error(
"Remaining nodes in divided cluster");
159 this->leaf_indices.push_back(idx);
160 if (clusters[idx].is_source())
161 this->leaf_src_indices.push_back(idx);
162 if (clusters[idx].is_receiver())
163 this->leaf_rec_indices.push_back(idx);
168 this->levels.push_back(0);
169 for (
size_t i = 0; i < this->clusters.size() - 1; ++i)
170 if (this->clusters[i].get_level() != this->clusters[i + 1].get_level())
171 this->levels.push_back(i + 1);
172 this->levels.push_back(this->clusters.size());
176 size_t get_n_src_nodes()
const
181 size_t get_n_rec_nodes()
const
191 return this->leaf_indices;
194 std::vector<size_t>
const &get_leaf_src_indices()
const
196 return this->leaf_src_indices;
199 std::vector<size_t>
const &get_leaf_rec_indices()
const
201 return this->leaf_rec_indices;
209 return this->leaf_indices.size();
219 for (
size_t i = 0; i < v.size(); ++i)
220 indices[i] = this->clusters[v[i]].get_src_node_idx();
230 return clusters[idx];
239 return clusters[idx];
247 return clusters[0].get_bounding_box().get_diameter();
256 return this->levels.size() - 1;
266 return this->levels[idx];
276 return this->levels[idx + 1];
284 return this->clusters.size();
287 iterator_t begin()
const
289 return clusters.begin();
292 iterator_t end()
const
294 return clusters.end();
306 os <<
"#Source Nodes: " << this->get_n_src_nodes() << std::endl;
307 os <<
"#Receiver Nodes: " << this->get_n_rec_nodes() << std::endl;
311 idx_list_t get_src_ids()
const
313 return this->src_node_ids;
316 idx_list_t
const &get_rec_ids()
const
318 return this->rec_node_id;
326 std::vector<size_t> leaf_indices;
327 std::vector<size_t> leaf_src_indices;
328 std::vector<size_t> leaf_rec_indices;
329 std::vector<size_t> levels;
332 template <
class ClusterDerived>
333 size_t const cluster_tree<ClusterDerived>::dimension;
337 std::ostream &
operator<<(std::ostream &os, cluster_tree<C>
const &ct)