Gudhi  1.2.0
 All Classes Functions Variables Typedefs Friends Groups Pages
Skeleton_blockers_simplices_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): David Salinas
6  *
7  * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 #ifndef SKELETON_BLOCKER_ITERATORS_SKELETON_BLOCKERS_SIMPLICES_ITERATORS_H_
23 #define SKELETON_BLOCKER_ITERATORS_SKELETON_BLOCKERS_SIMPLICES_ITERATORS_H_
24 
25 #include <gudhi/Skeleton_blocker_link_complex.h>
26 #include <gudhi/Skeleton_blocker/Skeleton_blocker_link_superior.h>
27 #include <gudhi/Skeleton_blocker/internal/Trie.h>
28 #include <gudhi/Utils.h>
29 
30 #include <boost/iterator/iterator_facade.hpp>
31 
32 #include <memory>
33 #include <list>
34 #include <iostream>
35 
36 namespace Gudhi {
37 
38 namespace skbl {
39 
48 template<typename SkeletonBlockerComplex, typename Link>
50 public boost::iterator_facade < Simplex_around_vertex_iterator<SkeletonBlockerComplex, Link>
51 , typename SkeletonBlockerComplex::Simplex_handle
52 , boost::forward_traversal_tag
53 , typename SkeletonBlockerComplex::Simplex_handle
54 > {
55  friend class boost::iterator_core_access;
56  typedef SkeletonBlockerComplex Complex;
57  typedef typename Complex::Vertex_handle Vertex_handle;
58  typedef typename Complex::Edge_handle Edge_handle;
59  typedef typename Complex::Simplex_handle Simplex_handle;
60 
61  // Link_vertex_handle == Complex_Vertex_handle but this renaming helps avoiding confusion
62  typedef typename Link::Vertex_handle Link_vertex_handle;
63 
64  typedef typename Gudhi::skbl::Trie<Simplex_handle> Trie;
65 
66  private:
67  const Complex* complex;
68  Vertex_handle v;
69  std::shared_ptr<Link> link_v;
70  std::shared_ptr<Trie> trie;
71  std::list<Trie*> nodes_to_be_seen; // todo deque
72 
73  public:
74  Simplex_around_vertex_iterator() : complex(0) {}
75 
76  Simplex_around_vertex_iterator(const Complex* complex_, Vertex_handle v_) :
77  complex(complex_),
78  v(v_),
79  link_v(new Link(*complex_, v_)),
80  trie(new Trie(v_)) {
81  compute_trie_and_nodes_to_be_seen();
82  }
83 
84  // todo avoid useless copy
85  // todo currently just work if copy begin iterator
87  complex(other.complex),
88  v(other.v),
89  link_v(other.link_v),
90  trie(other.trie),
91  nodes_to_be_seen(other.nodes_to_be_seen) {
92  if (!other.is_end()) {}
93  }
94 
98  Simplex_around_vertex_iterator(const Complex* complex_, Vertex_handle v_, bool end) :
99  complex(complex_),
100  v(v_) {
101  set_end();
102  }
103 
104  private:
105  void compute_trie_and_nodes_to_be_seen() {
106  // once we go through every simplices passing through v0
107  // we remove v0. That way, it prevents from passing a lot of times
108  // though edges leaving v0.
109  // another solution would have been to provides an adjacency iterator
110  // to superior vertices that avoids lower ones.
111  while (!link_v->empty()) {
112  auto v0 = *(link_v->vertex_range().begin());
113  trie->add_child(build_trie(v0, trie.get()));
114  link_v->remove_vertex(v0);
115  }
116  nodes_to_be_seen.push_back(trie.get());
117  }
118 
119  Trie* build_trie(Link_vertex_handle link_vh, Trie* parent) {
120  Trie* res = new Trie(parent_vertex(link_vh), parent);
121  for (Link_vertex_handle nv : link_v->vertex_range(link_vh)) {
122  if (link_vh < nv) {
123  Simplex_handle simplex_node_plus_nv(res->simplex());
124  simplex_node_plus_nv.add_vertex(parent_vertex(nv));
125  if (complex->contains(simplex_node_plus_nv)) {
126  res->add_child(build_trie(nv, res));
127  }
128  }
129  }
130  return res;
131  }
132 
133  bool is_node_in_complex(Trie* trie) {
134  return true;
135  }
136 
137  Vertex_handle parent_vertex(Link_vertex_handle link_vh) const {
138  return complex->convert_handle_from_another_complex(*link_v, link_vh);
139  }
140 
141  public:
142  friend std::ostream& operator<<(std::ostream& stream, const Simplex_around_vertex_iterator& savi) {
143  stream << savi.trie << std::endl;
144  stream << "(" << savi.nodes_to_be_seen.size() << ") nodes to see\n";
145  return stream;
146  }
147 
148  bool equal(const Simplex_around_vertex_iterator& other) const {
149  bool same_complex = (complex == other.complex);
150  if (!same_complex)
151  return false;
152 
153  if (!(v == other.v))
154  return false;
155 
156  bool both_empty = nodes_to_be_seen.empty() && other.nodes_to_be_seen.empty();
157  if (both_empty)
158  return true;
159 
160  bool both_non_empty = !nodes_to_be_seen.empty() && !other.nodes_to_be_seen.empty();
161 
162  if (!both_non_empty) return false; // one is empty the other is not
163 
164  bool same_node = (**(nodes_to_be_seen.begin()) == **(other.nodes_to_be_seen.begin()));
165  return same_node;
166  }
167 
168  void increment() {
169  assert(!is_end());
170  Trie* first_node = nodes_to_be_seen.front();
171 
172  nodes_to_be_seen.pop_front();
173 
174  for (auto childs : first_node->childs) {
175  nodes_to_be_seen.push_back(childs.get());
176  }
177  }
178 
179  Simplex_handle dereference() const {
180  assert(!nodes_to_be_seen.empty());
181  Trie* first_node = nodes_to_be_seen.front();
182  return first_node->simplex();
183  }
184 
185  Simplex_handle get_trie_address() const {
186  assert(!nodes_to_be_seen.empty());
187  return nodes_to_be_seen.front();
188  }
189 
190  private:
191  void set_end() {
192  nodes_to_be_seen.clear();
193  }
194 
195  bool is_end() const {
196  return nodes_to_be_seen.empty();
197  }
198 };
199 
200 template<typename SkeletonBlockerComplex>
201 class Simplex_iterator :
202 public boost::iterator_facade < Simplex_iterator<SkeletonBlockerComplex>
203 , typename SkeletonBlockerComplex::Simplex_handle
204 , boost::forward_traversal_tag
205 , typename SkeletonBlockerComplex::Simplex_handle
206 > {
207  typedef Skeleton_blocker_link_superior<SkeletonBlockerComplex> Link;
208 
209  friend class boost::iterator_core_access;
210 
211  template<class SkBlDS> friend class Skeleton_blocker_complex;
212 
213  typedef SkeletonBlockerComplex Complex;
214  typedef typename Complex::Vertex_handle Vertex_handle;
215  typedef typename Complex::Edge_handle Edge_handle;
216  typedef typename Complex::Simplex_handle Simplex_handle;
217  typedef typename Complex::Complex_vertex_iterator Complex_vertex_iterator;
218  typedef typename Link::Vertex_handle Link_vertex_handle;
219 
220  private:
221  const Complex* complex_;
222  Complex_vertex_iterator current_vertex_;
223 
224  typedef Simplex_around_vertex_iterator<SkeletonBlockerComplex, Link> SAVI;
225  SAVI current_simplex_around_current_vertex_;
226  SAVI simplices_around_current_vertex_end_;
227 
228  public:
229  Simplex_iterator() : complex_(0) { }
230 
231  Simplex_iterator(const Complex* complex) :
232  complex_(complex),
233  current_vertex_(complex->vertex_range().begin()),
234  current_simplex_around_current_vertex_(complex, *current_vertex_),
235  simplices_around_current_vertex_end_(complex, *current_vertex_, true) {
236  // should not be called if the complex is empty
237  assert(!complex->empty());
238  }
239 
240  private:
241  // todo return to private
242  Simplex_iterator(const Complex* complex, bool end) :
243  complex_(complex) {
244  set_end();
245  }
246 
247  public:
248  Simplex_iterator(const Simplex_iterator& other)
249  :
250  complex_(other.complex_),
251  current_vertex_(other.current_vertex_),
252  current_simplex_around_current_vertex_(other.current_simplex_around_current_vertex_),
253  simplices_around_current_vertex_end_(other.simplices_around_current_vertex_end_) { }
254 
255  friend Simplex_iterator make_begin_iterator(const Complex* complex) {
256  if (complex->empty())
257  return make_end_simplex_iterator(complex);
258  else
259  return Simplex_iterator(complex);
260  }
261 
262  friend Simplex_iterator make_end_simplex_iterator(const Complex* complex) {
263  return Simplex_iterator(complex, true);
264  }
265 
266  bool equal(const Simplex_iterator& other) const {
267  if (complex_ != other.complex_) return false;
268  if (current_vertex_ != other.current_vertex_) return false;
269  if (is_end() && other.is_end()) return true;
270  if (current_simplex_around_current_vertex_ != other.current_simplex_around_current_vertex_)
271  return false;
272  return true;
273  }
274 
275  void increment() {
276  if (current_simplex_around_current_vertex_ != simplices_around_current_vertex_end_) {
277  current_simplex_around_current_vertex_.increment();
278  if (current_simplex_around_current_vertex_ == simplices_around_current_vertex_end_)
279  goto_next_vertex();
280  } else {
281  goto_next_vertex();
282  }
283  }
284 
285  void goto_next_vertex() {
286  current_vertex_.increment();
287  if (!is_end()) {
288  current_simplex_around_current_vertex_ = SAVI(complex_, *current_vertex_);
289  simplices_around_current_vertex_end_ = SAVI(complex_, *current_vertex_, true);
290  }
291  }
292 
293  Simplex_handle dereference() const {
294  return current_simplex_around_current_vertex_.dereference();
295  }
296 
297  private:
298  void set_end() {
299  current_vertex_ = complex_->vertex_range().end();
300  }
301 
302  bool is_end() const {
303  return (current_vertex_ == complex_->vertex_range().end());
304  }
305 };
306 
307 } // namespace skbl
308 
309 } // namespace Gudhi
310 
311 #endif // SKELETON_BLOCKER_ITERATORS_SKELETON_BLOCKERS_SIMPLICES_ITERATORS_H_
void add_vertex(T v)
Definition: Skeleton_blocker_simplex.h:124
Simplex_around_vertex_iterator(const Complex *complex_, Vertex_handle v_, bool end)
Definition: Skeleton_blockers_simplices_iterators.h:98
Abstract simplex used in Skeleton blockers data-structure.
Definition: Skeleton_blocker_simplex.h:50
Definition: Skeleton_blockers_simplices_iterators.h:49
Definition: SkeletonBlockerDS.h:60
Iterator on the vertices of a simplicial complex.
Definition: Skeleton_blockers_vertices_iterators.h:39