Gudhi  1.1.0
 All Classes Functions Typedefs Friends Groups Pages
Simplex_tree_iterators.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): Clément Maria
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 #ifndef SRC_SIMPLEX_TREE_INCLUDE_GUDHI_SIMPLEX_TREE_SIMPLEX_TREE_ITERATORS_H_
24 #define SRC_SIMPLEX_TREE_INCLUDE_GUDHI_SIMPLEX_TREE_SIMPLEX_TREE_ITERATORS_H_
25 
26 #include <boost/iterator/iterator_facade.hpp>
27 
28 #include <vector>
29 
30 namespace Gudhi {
31 
32 /* \addtogroup simplex_tree
33  * Iterators and range types for the Simplex_tree.
34  * @{
35  */
36 
37 /* \brief Iterator over the vertices of a simplex
38  * in a SimplexTree.
39  *
40  * Forward iterator, 'value_type' is SimplexTree::Vertex_handle.*/
41 template<class SimplexTree>
42 class Simplex_tree_simplex_vertex_iterator : public boost::iterator_facade<
43  Simplex_tree_simplex_vertex_iterator<SimplexTree>,
44  typename SimplexTree::Vertex_handle const, boost::forward_traversal_tag,
45  typename SimplexTree::Vertex_handle const> {
46  public:
47  typedef typename SimplexTree::Simplex_handle Simplex_handle;
48  typedef typename SimplexTree::Siblings Siblings;
49  typedef typename SimplexTree::Vertex_handle Vertex_handle;
50 
51  explicit Simplex_tree_simplex_vertex_iterator(SimplexTree * st)
52  : // any end() iterator
53  sib_(NULL),
54  v_(st->null_vertex()) {
55  }
56 
57  Simplex_tree_simplex_vertex_iterator(SimplexTree * st, Simplex_handle sh)
58  : sib_(st->self_siblings(sh)),
59  v_(sh->first) {
60  }
61 
62  private:
63  friend class boost::iterator_core_access;
64 
65  bool equal(Simplex_tree_simplex_vertex_iterator const &other) const {
66  return sib_ == other.sib_ && v_ == other.v_;
67  }
68 
69  Vertex_handle const& dereference() const {
70  return v_;
71  }
72 
73  void increment() {
74  v_ = sib_->parent();
75  sib_ = sib_->oncles();
76  }
77 
78  Siblings * sib_;
79  Vertex_handle v_;
80 };
81 
82 /*---------------------------------------------------------------------------*/
83 /* \brief Iterator over the simplices of the boundary of a
84  * simplex.
85  *
86  * Forward iterator, value_type is SimplexTree::Simplex_handle.*/
87 template<class SimplexTree>
88 class Simplex_tree_boundary_simplex_iterator : public boost::iterator_facade<
89  Simplex_tree_boundary_simplex_iterator<SimplexTree>,
90  typename SimplexTree::Simplex_handle const, boost::forward_traversal_tag> {
91  public:
92  typedef typename SimplexTree::Simplex_handle Simplex_handle;
93  typedef typename SimplexTree::Vertex_handle Vertex_handle;
94  typedef typename SimplexTree::Siblings Siblings;
95 
96 // any end() iterator
97  explicit Simplex_tree_boundary_simplex_iterator(SimplexTree * st)
98  : last_(st->null_vertex()),
99  sib_(NULL) {
100  }
101 
102  Simplex_tree_boundary_simplex_iterator(SimplexTree * st, Simplex_handle sh)
103  : suffix_(),
104  st_(st) {
105  last_ = sh->first;
106  Siblings * sib = st->self_siblings(sh);
107  next_ = sib->parent();
108  sib_ = sib->oncles(); /* \todo check if NULL*/
109  if (sib_ != NULL) {
110  sh_ = sib_->find(next_);
111  } else {
112  last_ = st->null_vertex();
113  } // vertex: == end()
114  }
115 
116  private:
117  friend class boost::iterator_core_access;
118 // valid when iterating along the SAME boundary.
119  bool equal(Simplex_tree_boundary_simplex_iterator const& other) const {
120  return (sib_ == other.sib_ && last_ == other.last_);
121  }
122 
123  Simplex_handle const& dereference() const {
124  return sh_;
125  }
126 
127  void increment() {
128  if (sib_ == NULL) {
129  last_ = st_->null_vertex();
130  return;
131  }
132 
133  Siblings * for_sib = sib_;
134  for (typename std::vector<Vertex_handle>::reverse_iterator rit = suffix_
135  .rbegin(); rit != suffix_.rend(); ++rit) {
136  sh_ = for_sib->find(*rit);
137  for_sib = sh_->second.children();
138  }
139  sh_ = for_sib->find(last_); // sh_ points to the right simplex now
140  suffix_.push_back(next_);
141  next_ = sib_->parent();
142  sib_ = sib_->oncles();
143  }
144 
145  Vertex_handle last_; // last vertex of the simplex
146  Vertex_handle next_; // next vertex to push in suffix_
147  std::vector<Vertex_handle> suffix_;
148  Siblings * sib_; // where the next search will start from
149  Simplex_handle sh_; // current Simplex_handle in the boundary
150  SimplexTree * st_; // simplex containing the simplicial complex
151 };
152 /*---------------------------------------------------------------------------*/
153 /* \brief Iterator over the simplices of a simplicial complex.
154  *
155  * Forward iterator, value_type is SimplexTree::Simplex_handle.*/
156 template<class SimplexTree>
157 class Simplex_tree_complex_simplex_iterator : public boost::iterator_facade<
158  Simplex_tree_complex_simplex_iterator<SimplexTree>,
159  typename SimplexTree::Simplex_handle const, boost::forward_traversal_tag> {
160  public:
161  typedef typename SimplexTree::Simplex_handle Simplex_handle;
162  typedef typename SimplexTree::Siblings Siblings;
163  typedef typename SimplexTree::Vertex_handle Vertex_handle;
164 
165 // any end() iterator
166  Simplex_tree_complex_simplex_iterator()
167  : st_(NULL) {
168  }
169 
170  explicit Simplex_tree_complex_simplex_iterator(SimplexTree * st)
171  : st_(st) {
172  if (st == NULL || st->root() == NULL || st->root()->members().empty()) {
173  st_ = NULL;
174  } else {
175  sh_ = st->root()->members().begin();
176  sib_ = st->root();
177  while (st->has_children(sh_)) {
178  sib_ = sh_->second.children();
179  sh_ = sib_->members().begin();
180  }
181  }
182  }
183  private:
184  friend class boost::iterator_core_access;
185 
186 // valid when iterating along the SAME boundary.
187  bool equal(Simplex_tree_complex_simplex_iterator const& other) const {
188  if (other.st_ == NULL) {
189  return (st_ == NULL);
190  }
191  if (st_ == NULL) {
192  return false;
193  }
194  return (&(sh_->second) == &(other.sh_->second));
195  }
196 
197  Simplex_handle const& dereference() const {
198  return sh_;
199  }
200 
201 // Depth first traversal.
202  void increment() {
203  ++sh_;
204  if (sh_ == sib_->members().end()) {
205  if (sib_->oncles() == NULL) {
206  st_ = NULL;
207  return;
208  } // reach the end
209  sh_ = sib_->oncles()->members().find(sib_->parent());
210  sib_ = sib_->oncles();
211  return;
212  }
213  while (st_->has_children(sh_)) {
214  sib_ = sh_->second.children();
215  sh_ = sib_->members().begin();
216  }
217  }
218 
219  Simplex_handle sh_;
220  Siblings * sib_;
221  SimplexTree * st_;
222 };
223 
224 /* \brief Iterator over the simplices of the skeleton of a given
225  * dimension of the simplicial complex.
226  *
227  * Forward iterator, value_type is SimplexTree::Simplex_handle.*/
228 template<class SimplexTree>
229 class Simplex_tree_skeleton_simplex_iterator : public boost::iterator_facade<
230  Simplex_tree_skeleton_simplex_iterator<SimplexTree>,
231  typename SimplexTree::Simplex_handle const, boost::forward_traversal_tag> {
232  public:
233  typedef typename SimplexTree::Simplex_handle Simplex_handle;
234  typedef typename SimplexTree::Siblings Siblings;
235  typedef typename SimplexTree::Vertex_handle Vertex_handle;
236 
237 // any end() iterator
238  Simplex_tree_skeleton_simplex_iterator()
239  : st_(NULL) {
240  }
241 
242  Simplex_tree_skeleton_simplex_iterator(SimplexTree * st, int dim_skel)
243  : st_(st),
244  dim_skel_(dim_skel),
245  curr_dim_(0) {
246  if (st == NULL || st->root() == NULL || st->root()->members().empty()) {
247  st_ = NULL;
248  } else {
249  sh_ = st->root()->members().begin();
250  sib_ = st->root();
251  while (st->has_children(sh_) && curr_dim_ < dim_skel_) {
252  sib_ = sh_->second.children();
253  sh_ = sib_->members().begin();
254  ++curr_dim_;
255  }
256  }
257  }
258  private:
259  friend class boost::iterator_core_access;
260 
261 // valid when iterating along the SAME boundary.
262  bool equal(Simplex_tree_skeleton_simplex_iterator const& other) const {
263  if (other.st_ == NULL) {
264  return (st_ == NULL);
265  }
266  if (st_ == NULL) {
267  return false;
268  }
269  return (&(sh_->second) == &(other.sh_->second));
270  }
271 
272  Simplex_handle const& dereference() const {
273  return sh_;
274  }
275 
276 // Depth first traversal of the skeleton.
277  void increment() {
278  ++sh_;
279  if (sh_ == sib_->members().end()) {
280  if (sib_->oncles() == NULL) {
281  st_ = NULL;
282  return;
283  } // reach the end
284  sh_ = sib_->oncles()->members().find(sib_->parent());
285  sib_ = sib_->oncles();
286  --curr_dim_;
287  return;
288  }
289  while (st_->has_children(sh_) && curr_dim_ < dim_skel_) {
290  sib_ = sh_->second.children();
291  sh_ = sib_->members().begin();
292  ++curr_dim_;
293  }
294  }
295 
296  Simplex_handle sh_;
297  Siblings * sib_;
298  SimplexTree * st_;
299  int dim_skel_;
300  int curr_dim_;
301 };
302 
303 /* @} */ // end addtogroup simplex_tree
304 } // namespace Gudhi
305 
306 #endif // SRC_SIMPLEX_TREE_INCLUDE_GUDHI_SIMPLEX_TREE_SIMPLEX_TREE_ITERATORS_H_