Gudhi  1.2.0
 All Classes Functions Variables Typedefs Friends Groups Pages
Trie.h
1 /* This file is part of the Gudhi Library. The Gudhi library
2  * (Geometric Understanding in Higher Dimensions) is a generic C++
3  * library for computational topology.
4  *
5  * Author(s): David Salinas
6  *
7  * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France)
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <http://www.gnu.org/licenses/>.
21  *
22  */
23 
24 
25 #ifndef SKELETON_BLOCKER_INTERNAL_TRIE_H_
26 #define SKELETON_BLOCKER_INTERNAL_TRIE_H_
27 
28 #include <memory>
29 #include <vector>
30 #include <deque>
31 #include <set>
32 
33 namespace Gudhi {
34 
35 namespace skbl {
36 
37 template<typename SimplexHandle>
38 struct Trie {
39  typedef SimplexHandle Simplex_handle;
40  typedef typename SimplexHandle::Vertex_handle Vertex_handle;
41 
42  Vertex_handle v;
43  std::vector<std::shared_ptr<Trie> > childs;
44  // std::vector<std::unique_ptr<Trie> > childs; -> use of deleted function
45  private:
46  const Trie* parent_;
47 
48  public:
49  Trie() : parent_(0) { }
50 
51  Trie(Vertex_handle v_) : v(v_), parent_(0) { }
52 
53  Trie(Vertex_handle v_, Trie* parent) : v(v_), parent_(parent) { }
54 
55  bool operator==(const Trie& other) const {
56  return (v == other.v);
57  }
58 
59  void add_child(Trie* child) {
60  if (child) {
61  std::shared_ptr<Trie> ptr_to_add(child);
62  childs.push_back(ptr_to_add);
63  child->parent_ = this;
64  }
65  }
66 
67  typedef typename Simplex_handle::Simplex_vertex_const_iterator Simplex_vertex_const_iterator;
68 
69  Trie* make_trie(Simplex_vertex_const_iterator s_it, Simplex_vertex_const_iterator s_end) {
70  if (s_it == s_end) {
71  return 0;
72  } else {
73  Trie* res = new Trie(*s_it);
74  Trie* child = make_trie(++s_it, s_end);
75  res->add_child(child);
76  return res;
77  }
78  }
79 
80  private:
81  // go down recursively in the tree while advancing the simplex iterator.
82  // when it reaches a leaf, it inserts the remaining that is not present
83  void add_simplex_helper(Simplex_vertex_const_iterator s_it, Simplex_vertex_const_iterator s_end) {
84  assert(*s_it == v);
85  ++s_it;
86  if (s_it == s_end) return;
87  if (!is_leaf()) {
88  for (auto child : childs) {
89  if (child->v == *s_it)
90  return child->add_simplex_helper(s_it, s_end);
91  }
92  // s_it is not found and needs to be inserted
93  }
94  // not leaf -> remaining of s needs to be inserted
95  Trie * son_with_what_remains_of_s(make_trie(s_it, s_end));
96  add_child(son_with_what_remains_of_s);
97  return;
98  }
99 
100  void maximal_faces_helper(std::vector<Simplex_handle>& res) const {
101  if (is_leaf()) res.push_back(simplex());
102  else
103  for (auto child : childs)
104  child->maximal_faces_helper(res);
105  }
106 
107  public:
111  void add_simplex(const Simplex_handle& s) {
112  if (s.empty()) return;
113  assert(v == s.first_vertex());
114  add_simplex_helper(s.begin(), s.end());
115  }
116 
117  std::vector<Simplex_handle> maximal_faces() const {
118  std::vector<Simplex_handle> res;
119  maximal_faces_helper(res);
120  return res;
121  }
122 
126  void add_vertices_up_to_the_root(Simplex_handle& res) const {
127  res.add_vertex(v);
128  if (parent_)
129  parent_->add_vertices_up_to_the_root(res);
130  }
131 
132  Simplex_handle simplex() const {
133  Simplex_handle res;
134  add_vertices_up_to_the_root(res);
135  return res;
136  }
137 
138  bool is_leaf() const {
139  return childs.empty();
140  }
141 
142  bool is_root() const {
143  return parent_ == 0;
144  }
145 
146  const Trie* parent() {
147  return parent_;
148  }
149 
150  void remove_leaf() {
151  assert(is_leaf);
152  if (!is_root())
153  parent_->childs.erase(this);
154  }
155 
159  bool contains(const Simplex_handle& s) const {
160  Trie const* current = this;
161  if (s.empty()) return true;
162  if (current->v != s.first_vertex()) return false;
163  auto s_pos = s.begin();
164  ++s_pos;
165  while (s_pos != s.end() && current != 0) {
166  bool found = false;
167  for (const auto child : current->childs) {
168  if (child->v == *s_pos) {
169  ++s_pos;
170  current = child.get();
171  found = true;
172  break;
173  }
174  }
175  if (!found) return false;
176  }
177  return current != 0;
178  }
179 
180  Trie* go_bottom_left() {
181  if (is_leaf())
182  return this;
183  else
184  return (*childs.begin())->go_bottom_left();
185  }
186 
187  friend std::ostream& operator<<(std::ostream& stream, const Trie& trie) {
188  stream << "T( " << trie.v << " ";
189  for (auto t : trie.childs)
190  stream << *t;
191  stream << ")";
192  return stream;
193  }
194 };
195 
196 template<typename SimplexHandle>
197 struct Tries {
198  typedef typename SimplexHandle::Vertex_handle Vertex_handle;
199  typedef SimplexHandle Simplex_handle;
200 
201  typedef Trie<Simplex_handle> STrie;
202 
203  template<typename SimpleHandleOutputIterator>
204  Tries(unsigned num_vertices, SimpleHandleOutputIterator simplex_begin, SimpleHandleOutputIterator simplex_end) :
205  cofaces_(num_vertices, 0) {
206  for (auto i = 0u; i < num_vertices; ++i)
207  cofaces_[i] = new STrie(Vertex_handle(i));
208  for (auto s_it = simplex_begin; s_it != simplex_end; ++s_it) {
209  if (s_it->dimension() >= 1)
210  cofaces_[s_it->first_vertex()]->add_simplex(*s_it);
211  }
212  }
213 
214  ~Tries() {
215  for (STrie* t : cofaces_)
216  delete t;
217  }
218 
219  // return a simplex that consists in all u such uv is an edge and u>v
220 
221  Simplex_handle positive_neighbors(Vertex_handle v) const {
222  Simplex_handle res;
223  for (auto child : cofaces_[v]->childs)
224  res.add_vertex(child->v);
225  return res;
226  }
227 
228  bool contains(const Simplex_handle& s) const {
229  auto first_v = s.first_vertex();
230  return cofaces_[first_v]->contains(s);
231  }
232 
233  friend std::ostream& operator<<(std::ostream& stream, const Tries& tries) {
234  for (auto trie : tries.cofaces_)
235  stream << *trie << std::endl;
236  return stream;
237  }
238 
239  // init_next_dimension must be called first
240 
241  std::vector<Simplex_handle> next_dimension_simplices() const {
242  std::vector<Simplex_handle> res;
243  while (!to_see_.empty() && to_see_.front()->simplex().dimension() == current_dimension_) {
244  res.emplace_back(to_see_.front()->simplex());
245  for (auto child : to_see_.front()->childs)
246  to_see_.push_back(child.get());
247  to_see_.pop_front();
248  }
249  ++current_dimension_;
250  return res;
251  }
252 
253  void init_next_dimension() const {
254  for (auto trie : cofaces_)
255  to_see_.push_back(trie);
256  }
257 
258  private:
259  mutable std::deque<STrie*> to_see_;
260  mutable unsigned current_dimension_ = 0;
261  std::vector<STrie*> cofaces_;
262 };
263 
264 } // namespace skbl
265 
266 } // namespace Gudhi
267 
268 #endif // SKELETON_BLOCKER_INTERNAL_TRIE_H_
void add_vertex(T v)
Definition: Skeleton_blocker_simplex.h:124
T first_vertex() const
Definition: Skeleton_blocker_simplex.h:225
Abstract simplex used in Skeleton blockers data-structure.
Definition: Skeleton_blocker_simplex.h:50