Simplex_tree_iterators.h
1 /* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT.
2  * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details.
3  * Author(s): ClĂ©ment Maria
4  *
5  * Copyright (C) 2014 Inria
6  *
7  * Modification(s):
8  * - 2022/04 Vincent Rouvreau: Add Simplex_tree_boundary_opposite_vertex_simplex_iterator for alpha and cech purpose
9  * - YYYY/MM Author: Description of the modification
10  */
11 
12 #ifndef SIMPLEX_TREE_SIMPLEX_TREE_ITERATORS_H_
13 #define SIMPLEX_TREE_SIMPLEX_TREE_ITERATORS_H_
14 
15 #include <gudhi/Debug_utils.h>
16 
17 #include <boost/iterator/iterator_facade.hpp>
18 
19 #include <vector>
20 #include <utility> // for std::pair
21 
22 namespace Gudhi {
23 
33 template<class SimplexTree>
34 class Simplex_tree_simplex_vertex_iterator : public boost::iterator_facade<
35  Simplex_tree_simplex_vertex_iterator<SimplexTree>,
36  typename SimplexTree::Vertex_handle const, boost::forward_traversal_tag,
37  typename SimplexTree::Vertex_handle const> {
38  public:
39  typedef typename SimplexTree::Simplex_handle Simplex_handle;
40  typedef typename SimplexTree::Siblings Siblings;
42 
44  : // any end() iterator
45  sib_(nullptr),
46  v_(st->null_vertex()) {
47  }
48 
49  Simplex_tree_simplex_vertex_iterator(SimplexTree const* st, Simplex_handle sh)
50  : sib_(st->self_siblings(sh)),
51  v_(sh->first) {
52  }
53 
54  private:
55  friend class boost::iterator_core_access;
56 
57  bool equal(Simplex_tree_simplex_vertex_iterator const &other) const {
58  return sib_ == other.sib_ && v_ == other.v_;
59  }
60 
61  Vertex_handle const& dereference() const {
62  return v_;
63  }
64 
65  void increment() {
66  v_ = sib_->parent();
67  sib_ = sib_->oncles();
68  }
69 
70  Siblings * sib_;
71  Vertex_handle v_;
72 };
73 
74 /*---------------------------------------------------------------------------*/
79 template<class SimplexTree>
80 class Simplex_tree_boundary_simplex_iterator : public boost::iterator_facade<
81  Simplex_tree_boundary_simplex_iterator<SimplexTree>,
82  typename SimplexTree::Simplex_handle const, boost::forward_traversal_tag> {
83  public:
84  using Simplex_handle = typename SimplexTree::Simplex_handle;
85  using Vertex_handle = typename SimplexTree::Vertex_handle;
86  using Siblings = typename SimplexTree::Siblings;
87  using Static_vertex_vector = typename SimplexTree::Static_vertex_vector;
88 
89  // For cython purpose only. The object it initializes should be overwritten ASAP and never used before it is overwritten.
91  : sib_(nullptr),
92  st_(nullptr) {
93  }
94 
95 // any end() iterator
97  : last_(st->null_vertex()),
98  next_(st->null_vertex()),
99  sib_(nullptr),
100  sh_(st->null_simplex()),
101  st_(st) {
102  }
103 
104  template<class SimplexHandle>
106  : last_(sh->first),
107  next_(st->null_vertex()),
108  sib_(nullptr),
109  sh_(st->null_simplex()),
110  st_(st) {
111  // Only check once at the beginning instead of for every increment, as this is expensive.
113  GUDHI_CHECK(st_->contiguous_vertices(), "The set of vertices is not { 0, ..., n } without holes");
114  Siblings * sib = st->self_siblings(sh);
115  next_ = sib->parent();
116  sib_ = sib->oncles();
117  if (sib_ != nullptr) {
120  {
121  if (sib_->oncles() == nullptr) // Only relevant for edges
122  sh_ = sib_->members_.begin() + next_;
123  else
124  sh_ = sib_->find(next_);
125  } else {
126  sh_ = sib_->find(next_);
127  }
128  }
129  }
130 
131  private:
132  friend class boost::iterator_core_access;
133  // valid when iterating along the SAME boundary.
134  bool equal(Simplex_tree_boundary_simplex_iterator const& other) const {
135  return sh_ == other.sh_;
136  }
137 
138  Simplex_handle const& dereference() const {
139  assert(sh_ != st_->null_simplex());
140  return sh_;
141  }
142 
143  void increment() {
144  if (sib_ == nullptr) {
145  sh_ = st_->null_simplex();
146  return;
147  }
148 
149  Siblings * for_sib = sib_;
150  Siblings * new_sib = sib_->oncles();
151  auto rit = suffix_.rbegin();
153  if (new_sib == nullptr) {
154  // We reached the root, use a short-cut to find a vertex.
155  if (rit == suffix_.rend()) {
156  // Segment, this vertex is the last boundary simplex
157  sh_ = for_sib->members_.begin() + last_;
158  sib_ = nullptr;
159  return;
160  } else {
161  // Dim >= 2, initial step of the descent
162  sh_ = for_sib->members_.begin() + *rit;
163  for_sib = sh_->second.children();
164  ++rit;
165  }
166  }
167  }
168 
169  for (; rit != suffix_.rend(); ++rit) {
170  sh_ = for_sib->find(*rit);
171  for_sib = sh_->second.children();
172  }
173  sh_ = for_sib->find(last_); // sh_ points to the right simplex now
174  suffix_.push_back(next_);
175  next_ = sib_->parent();
176  sib_ = new_sib;
177  }
178 
179  // Most of the storage should be moved to the range, iterators should be light.
180  Vertex_handle last_; // last vertex of the simplex
181  Vertex_handle next_; // next vertex to push in suffix_
182  Static_vertex_vector suffix_;
183  Siblings * sib_; // where the next search will start from
184  Simplex_handle sh_; // current Simplex_handle in the boundary
185  SimplexTree * st_; // simplex containing the simplicial complex
186 };
187 
191 template<class SimplexTree>
192 class Simplex_tree_boundary_opposite_vertex_simplex_iterator : public boost::iterator_facade<
193  Simplex_tree_boundary_opposite_vertex_simplex_iterator<SimplexTree>,
194  std::pair<typename SimplexTree::Simplex_handle, typename SimplexTree::Vertex_handle> const, boost::forward_traversal_tag> {
195  public:
196  using Simplex_handle = typename SimplexTree::Simplex_handle;
197  using Vertex_handle = typename SimplexTree::Vertex_handle;
198  using Siblings = typename SimplexTree::Siblings;
199  using Static_vertex_vector = typename SimplexTree::Static_vertex_vector;
200 
201  // For cython purpose only. The object it initializes should be overwritten ASAP and never used before it is
202  // overwritten.
204  : sib_(nullptr),
205  st_(nullptr) {
206  }
207 
208  // any end() iterator
210  : last_(st->null_vertex()),
211  next_(st->null_vertex()),
212  sib_(nullptr),
213  baov_(st->null_simplex(), st->null_vertex()),
214  st_(st) {
215  }
216 
217  template<class SimplexHandle>
219  : last_(sh->first),
220  next_(st->null_vertex()),
221  sib_(nullptr),
222  baov_(st->null_simplex(), sh->first),
223  st_(st) {
224  // Only check once at the beginning instead of for every increment, as this is expensive.
226  GUDHI_CHECK(st_->contiguous_vertices(), "The set of vertices is not { 0, ..., n } without holes");
227  Siblings * sib = st->self_siblings(sh);
228  next_ = sib->parent();
229  sib_ = sib->oncles();
230  if (sib_ != nullptr) {
233  if (sib_->oncles() == nullptr)
234  // Only relevant for edges
235  baov_.first = sib_->members_.begin() + next_;
236  else
237  baov_.first = sib_->find(next_);
238  } else {
239  baov_.first = sib_->find(next_);
240  }
241  }
242  }
243 
244  private:
245  friend class boost::iterator_core_access;
246 
247  // valid when iterating along the SAME boundary.
248  bool equal(Simplex_tree_boundary_opposite_vertex_simplex_iterator const& other) const {
249  return (baov_.first == other.baov_.first);
250  }
251 
252  std::pair<Simplex_handle, Vertex_handle> const& dereference() const {
253  return baov_;
254  }
255 
256  void increment() {
257  if (sib_ == nullptr) {
258  baov_.first = st_->null_simplex();
259  return; // ------>>
260  }
261  Siblings * for_sib = sib_;
262  Siblings * new_sib = sib_->oncles();
263  auto rit = suffix_.rbegin();
265  if (new_sib == nullptr) {
266  // We reached the root, use a short-cut to find a vertex.
267  if (rit == suffix_.rend()) {
268  baov_.second = baov_.first->first;
269  // Segment, this vertex is the last boundary simplex
270  baov_.first = for_sib->members_.begin() + last_;
271  sib_ = nullptr;
272  return;
273  } else {
274  // Dim >= 2, initial step of the descent
275  baov_.first = for_sib->members_.begin() + *rit;
276  for_sib = baov_.first->second.children();
277  ++rit;
278  }
279  }
280  }
281 
282  for (; rit != suffix_.rend(); ++rit) {
283  baov_.first = for_sib->find(*rit);
284  for_sib = baov_.first->second.children();
285  }
286  baov_.first = for_sib->find(last_); // baov_.first points to the right simplex now
287  suffix_.push_back(next_);
288  next_ = sib_->parent();
289  sib_ = new_sib;
290  baov_.second = suffix_.back();
291  }
292 
293  // Most of the storage should be moved to the range, iterators should be light.
294  Vertex_handle last_; // last vertex of the simplex
295  Vertex_handle next_; // next vertex to push in suffix_
296  Static_vertex_vector suffix_;
297  Siblings * sib_; // where the next search will start from
298  std::pair<Simplex_handle, Vertex_handle> baov_; // a pair containing the current Simplex_handle in the boundary and its opposite vertex
299  SimplexTree * st_; // simplex containing the simplicial complex
300 };
301 
302 /*---------------------------------------------------------------------------*/
306 template<class SimplexTree>
307 class Simplex_tree_complex_simplex_iterator : public boost::iterator_facade<
308  Simplex_tree_complex_simplex_iterator<SimplexTree>,
309  typename SimplexTree::Simplex_handle const, boost::forward_traversal_tag> {
310  public:
311  typedef typename SimplexTree::Simplex_handle Simplex_handle;
312  typedef typename SimplexTree::Siblings Siblings;
313  typedef typename SimplexTree::Vertex_handle Vertex_handle;
314 
315 // any end() iterator
317  : sib_(nullptr),
318  st_(nullptr) {
319  }
320 
322  : sib_(nullptr),
323  st_(st) {
324  if (st == nullptr || st->root() == nullptr || st->root()->members().empty()) {
325  st_ = nullptr;
326  } else {
327  sh_ = st->root()->members().begin();
328  sib_ = st->root();
329  while (st->has_children(sh_)) {
330  sib_ = sh_->second.children();
331  sh_ = sib_->members().begin();
332  }
333  }
334  }
335  private:
336  friend class boost::iterator_core_access;
337 
338 // valid when iterating along the SAME boundary.
339  bool equal(Simplex_tree_complex_simplex_iterator const& other) const {
340  if (other.st_ == nullptr) {
341  return (st_ == nullptr);
342  }
343  if (st_ == nullptr) {
344  return false;
345  }
346  return (&(sh_->second) == &(other.sh_->second));
347  }
348 
349  Simplex_handle const& dereference() const {
350  return sh_;
351  }
352 
353 // Depth first traversal.
354  void increment() {
355  ++sh_;
356  if (sh_ == sib_->members().end()) {
357  if (sib_->oncles() == nullptr) {
358  st_ = nullptr;
359  return;
360  } // reach the end
361  sh_ = sib_->oncles()->members().find(sib_->parent());
362  sib_ = sib_->oncles();
363  return;
364  }
365  while (st_->has_children(sh_)) {
366  sib_ = sh_->second.children();
367  sh_ = sib_->members().begin();
368  }
369  }
370 
371  Simplex_handle sh_;
372  Siblings * sib_;
373  SimplexTree * st_;
374 };
375 
380 template<class SimplexTree>
381 class Simplex_tree_skeleton_simplex_iterator : public boost::iterator_facade<
382  Simplex_tree_skeleton_simplex_iterator<SimplexTree>,
383  typename SimplexTree::Simplex_handle const, boost::forward_traversal_tag> {
384  public:
385  typedef typename SimplexTree::Simplex_handle Simplex_handle;
386  typedef typename SimplexTree::Siblings Siblings;
387  typedef typename SimplexTree::Vertex_handle Vertex_handle;
388 
389 // any end() iterator
391  : sib_(nullptr),
392  st_(nullptr),
393  dim_skel_(0),
394  curr_dim_(0) {
395  }
396 
398  : sib_(nullptr),
399  st_(st),
400  dim_skel_(dim_skel),
401  curr_dim_(0) {
402  if (st == nullptr || st->root() == nullptr || st->root()->members().empty()) {
403  st_ = nullptr;
404  } else {
405  sh_ = st->root()->members().begin();
406  sib_ = st->root();
407  while (st->has_children(sh_) && curr_dim_ < dim_skel_) {
408  sib_ = sh_->second.children();
409  sh_ = sib_->members().begin();
410  ++curr_dim_;
411  }
412  }
413  }
414  private:
415  friend class boost::iterator_core_access;
416 
417 // valid when iterating along the SAME boundary.
418  bool equal(Simplex_tree_skeleton_simplex_iterator const& other) const {
419  if (other.st_ == nullptr) {
420  return (st_ == nullptr);
421  }
422  if (st_ == nullptr) {
423  return false;
424  }
425  return (&(sh_->second) == &(other.sh_->second));
426  }
427 
428  Simplex_handle const& dereference() const {
429  return sh_;
430  }
431 
432 // Depth first traversal of the skeleton.
433  void increment() {
434  ++sh_;
435  if (sh_ == sib_->members().end()) {
436  if (sib_->oncles() == nullptr) {
437  st_ = nullptr;
438  return;
439  } // reach the end
440  sh_ = sib_->oncles()->members().find(sib_->parent());
441  sib_ = sib_->oncles();
442  --curr_dim_;
443  return;
444  }
445  while (st_->has_children(sh_) && curr_dim_ < dim_skel_) {
446  sib_ = sh_->second.children();
447  sh_ = sib_->members().begin();
448  ++curr_dim_;
449  }
450  }
451 
452  Simplex_handle sh_;
453  Siblings * sib_;
454  SimplexTree * st_;
455  int dim_skel_;
456  int curr_dim_;
457 };
458  // end addtogroup simplex_tree
460 
461 } // namespace Gudhi
462 
463 #endif // SIMPLEX_TREE_SIMPLEX_TREE_ITERATORS_H_
Iterator over the simplices of the boundary of a simplex and their opposite vertices.
Definition: Simplex_tree_iterators.h:194
Iterator over the simplices of the boundary of a simplex.
Definition: Simplex_tree_iterators.h:82
Iterator over the simplices of a simplicial complex.
Definition: Simplex_tree_iterators.h:309
Iterator over the vertices of a simplex in a SimplexTree.
Definition: Simplex_tree_iterators.h:37
Iterator over the simplices of the skeleton of a given dimension of the simplicial complex.
Definition: Simplex_tree_iterators.h:383
Simplex Tree data structure for representing simplicial complexes.
Definition: Simplex_tree.h:95
Dictionary::iterator Simplex_handle
Handle type to a simplex contained in the simplicial complex represented by the simplex tree.
Definition: Simplex_tree.h:175
Vertex_handle null_vertex() const
Returns a Vertex_handle different from all Vertex_handles associated to the vertices of the simplicia...
Definition: Simplex_tree.h:646
bool has_children(SimplexHandle sh) const
Returns true if the node in the simplex tree pointed by the given simplex handle has children.
Definition: Simplex_tree.h:742
Siblings * root()
Definition: Simplex_tree.h:1032
Simplex_tree_siblings< Simplex_tree, Dictionary > Siblings
Set of nodes sharing a same parent in the simplex tree.
Definition: Simplex_tree.h:127
Options::Vertex_handle Vertex_handle
Type for the vertex handle.
Definition: Simplex_tree.h:110
static Siblings * self_siblings(SimplexHandle sh)
Definition: Simplex_tree.h:1023
static Simplex_handle null_simplex()
Returns a Simplex_handle different from all Simplex_handles associated to the simplices in the simpli...
Definition: Simplex_tree.h:635
Gudhi namespace.
Definition: SimplicialComplexForAlpha.h:14
static const bool stable_simplex_handles
If true, Simplex_handle will not be invalidated after insertions or removals.
Definition: SimplexTreeOptions.h:39
static constexpr bool contiguous_vertices
If true, the list of vertices present in the complex must always be 0, ..., num_vertices-1,...
Definition: SimplexTreeOptions.h:35
Handle type for the vertices of a cell complex.
Definition: VertexHandle.h:15