ClusterTree.hpp
Go to the documentation of this file.
1 /*
2  * STRUMPACK -- STRUctured Matrices PACKage, Copyright (c) 2014, The
3  * Regents of the University of California, through Lawrence Berkeley
4  * National Laboratory (subject to receipt of any required approvals
5  * from the U.S. Dept. of Energy). All rights reserved.
6  *
7  * If you have questions about your rights to use or distribute this
8  * software, please contact Berkeley Lab's Technology Transfer
9  * Department at TTD@lbl.gov.
10  *
11  * NOTICE. This software is owned by the U.S. Department of Energy. As
12  * such, the U.S. Government has been granted for itself and others
13  * acting on its behalf a paid-up, nonexclusive, irrevocable,
14  * worldwide license in the Software to reproduce, prepare derivative
15  * works, and perform publicly and display publicly. Beginning five
16  * (5) years after the date permission to assert copyright is obtained
17  * from the U.S. Department of Energy, and subject to any subsequent
18  * five (5) year renewals, the U.S. Government is granted for itself
19  * and others acting on its behalf a paid-up, nonexclusive,
20  * irrevocable, worldwide license in the Software to reproduce,
21  * prepare derivative works, distribute copies to the public, perform
22  * publicly and display publicly, and to permit others to do so.
23  *
24  * Developers: Pieter Ghysels, Francois-Henry Rouet, Xiaoye S. Li.
25  * (Lawrence Berkeley National Lab, Computational Research
26  * Division).
27  *
28  */
33 #ifndef CLUSTER_TREE_HPP
34 #define CLUSTER_TREE_HPP
35 
36 #include <vector>
37 #include <unordered_map>
38 #include <cassert>
39 #include <iostream>
40 
41 namespace strumpack {
42  namespace structured {
43 
62  class ClusterTree {
63  public:
68  int size;
69 
75  std::vector<ClusterTree> c;
76 
80  ClusterTree() : size(0) {}
81 
89  ClusterTree(int n) : size(n) {}
90 
99  const ClusterTree& refine(int leaf_size) {
100  assert(c.empty());
101  if (size >= 2*leaf_size) {
102  c.resize(2);
103  c[0].size = size/2;
104  c[0].refine(leaf_size);
105  c[1].size = size - size/2;
106  c[1].refine(leaf_size);
107  }
108  return *this;
109  }
110 
114  void print() const {
115  for (auto& ch : c) ch.print();
116  std::cout << size << " ";
117  }
118 
125  int nodes() const {
126  int nr_nodes = 1;
127  for (auto& ch : c)
128  nr_nodes += ch.nodes();
129  return nr_nodes;
130  }
131 
137  int levels() const {
138  int lvls = 0;
139  for (auto& ch : c)
140  lvls = std::max(lvls, ch.levels());
141  return lvls + 1;
142  }
143 
153  truncate_complete_rec(1, min_levels());
154  }
155 
171  void expand_complete(bool allow_zero_nodes) {
172  expand_complete_rec(1, levels(), allow_zero_nodes);
173  }
174 
182  void expand_complete_levels(int lvls) {
183  expand_complete_levels_rec(1, lvls);
184  }
185 
195  template<typename integer_t> static ClusterTree
196  deserialize(const std::vector<integer_t>& buf) {
197  return deserialize(buf.data());
198  }
199 
209  template<typename integer_t> static ClusterTree
210  deserialize(const integer_t* buf) {
211  ClusterTree t;
212  int n = buf[0];
213  int pid = n-1;
214  t.de_serialize_rec(buf+1, buf+n+1, buf+2*n+1, pid);
215  return t;
216  }
217 
228  std::vector<int> serialize() const {
229  int n = nodes(), pid = 0;
230  std::vector<int> buf(3*n+1);
231  buf[0] = n;
232  serialize_rec(buf.data()+1, buf.data()+n+1, buf.data()+2*n+1, pid);
233  return buf;
234  }
235 
242  bool is_complete() const {
243  if (c.empty()) return true;
244  else return c[0].levels() == c[1].levels();
245  }
246 
252  template<typename integer_t>
253  std::vector<integer_t> leaf_sizes() const {
254  std::vector<integer_t> lf;
255  leaf_sizes_rec(lf);
256  return lf;
257  }
258 
266  std::pair<std::vector<int>,std::vector<int>>
267  map_from_complete_to_leafs(int lvls) const {
268  int n = (1 << lvls) - 1;
269  std::vector<int> map0(n, -1), map1(n, -1);
270  int leaf = 0;
271  complete_to_orig_rec(1, map0, map1, leaf);
272  for (int i=0; i<n; i++) {
273  if (map0[i] == -1) map0[i] = map0[(i+1)/2-1];
274  if (map1[i] == -1) map1[i] = map1[(i+1)/2-1];
275  }
276  // std::cout << "nodes=" << nodes() << " levels()=" << levels()
277  // << " lvls=" << lvls << " map0/map1 = [";
278  // for (int i=0; i<n; i++)
279  // std::cout << map0[i] << "/" << map1[i] << " ";
280  // std::cout << std::endl;
281  return {map0, map1};
282  }
283 
284  private:
285  int min_levels() const {
286  int lvls = levels();
287  for (auto& ch : c)
288  lvls = std::min(lvls, 1 + ch.min_levels());
289  return lvls;
290  }
291  void truncate_complete_rec(int lvl, int lvls) {
292  if (lvl == lvls) c.clear();
293  else
294  for (auto& ch : c)
295  ch.truncate_complete_rec(lvl+1, lvls);
296  }
297  void expand_complete_rec(int lvl, int lvls, bool allow_zero_nodes) {
298  if (c.empty()) {
299  if (lvl != lvls) {
300  c.resize(2);
301  if (allow_zero_nodes) {
302  c[0].size = size;
303  c[1].size = 0;
304  } else {
305  int l1 = 1 << (lvls - lvl - 1);
306  c[0].size = size - l1;
307  c[1].size = l1;
308  }
309  c[0].expand_complete_rec(lvl+1, lvls, allow_zero_nodes);
310  c[1].expand_complete_rec(lvl+1, lvls, allow_zero_nodes);
311  }
312  } else
313  for (auto& ch : c)
314  ch.expand_complete_rec(lvl+1, lvls, allow_zero_nodes);
315  }
316 
317  void complete_to_orig_rec
318  (int id, std::vector<int>& map0, std::vector<int>& map1,
319  int& leaf) const {
320  if (c.empty()) map0[id-1] = map1[id-1] = leaf++;
321  else {
322  c[0].complete_to_orig_rec(id*2, map0, map1, leaf);
323  c[1].complete_to_orig_rec(id*2+1, map0, map1, leaf);
324  map0[id-1] = map0[id*2-1];
325  map1[id-1] = map1[id*2];
326  }
327  }
328 
329  void expand_complete_levels_rec(int lvl, int lvls) {
330  if (c.empty()) {
331  if (lvl != lvls) {
332  c.resize(2);
333  c[0].size = size / 2;
334  c[1].size = size - size / 2;
335  c[0].expand_complete_levels_rec(lvl+1, lvls);
336  c[1].expand_complete_levels_rec(lvl+1, lvls);
337  }
338  } else
339  for (auto& ch : c)
340  ch.expand_complete_levels_rec(lvl+1, lvls);
341  }
342  template<typename integer_t>
343  void leaf_sizes_rec(std::vector<integer_t>& lf) const {
344  for (auto& ch : c)
345  ch.leaf_sizes_rec(lf);
346  if (c.empty())
347  lf.push_back(size);
348  }
349  void serialize_rec(int* sizes, int* lchild, int* rchild, int& pid) const {
350  if (!c.empty()) {
351  c[0].serialize_rec(sizes, lchild, rchild, pid);
352  auto lroot = pid;
353  c[1].serialize_rec(sizes, lchild, rchild, pid);
354  lchild[pid] = lroot-1;
355  rchild[pid] = pid-1;
356  } else lchild[pid] = rchild[pid] = -1;
357  sizes[pid++] = size;
358  }
359 
360  template<typename integer_t> void de_serialize_rec
361  (const integer_t* sizes, const integer_t* lchild,
362  const integer_t* rchild, int& pid) {
363  size = sizes[pid--];
364  if (rchild[pid+1] != -1) {
365  c.resize(2);
366  c[1].de_serialize_rec(sizes, lchild, rchild, pid);
367  c[0].de_serialize_rec(sizes, lchild, rchild, pid);
368  }
369  }
370  };
371 
372  } // end namespace structured
373 } // end namespace strumpack
374 
375 #endif
The cluster tree, or partition tree that represents the partitioning of the rows or columns of a hier...
Definition: ClusterTree.hpp:62
std::pair< std::vector< int >, std::vector< int > > map_from_complete_to_leafs(int lvls) const
Definition: ClusterTree.hpp:267
bool is_complete() const
Definition: ClusterTree.hpp:242
void expand_complete(bool allow_zero_nodes)
Definition: ClusterTree.hpp:171
const ClusterTree & refine(int leaf_size)
Definition: ClusterTree.hpp:99
void print() const
Definition: ClusterTree.hpp:114
std::vector< integer_t > leaf_sizes() const
Definition: ClusterTree.hpp:253
void truncate_complete()
Definition: ClusterTree.hpp:152
static ClusterTree deserialize(const integer_t *buf)
Definition: ClusterTree.hpp:210
int levels() const
Definition: ClusterTree.hpp:137
ClusterTree()
Definition: ClusterTree.hpp:80
static ClusterTree deserialize(const std::vector< integer_t > &buf)
Definition: ClusterTree.hpp:196
int size
Definition: ClusterTree.hpp:68
ClusterTree(int n)
Definition: ClusterTree.hpp:89
int nodes() const
Definition: ClusterTree.hpp:125
std::vector< ClusterTree > c
Definition: ClusterTree.hpp:75
std::vector< int > serialize() const
Definition: ClusterTree.hpp:228
void expand_complete_levels(int lvls)
Definition: ClusterTree.hpp:182
Definition: StrumpackOptions.hpp:42