Gudhi  1.1.0
 All Classes Functions Typedefs Friends Groups Pages
Skeleton_blocker_sub_complex.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 
23 #ifndef GUDHI_SKELETON_BLOCKER_SUB_COMPLEX_H
24 #define GUDHI_SKELETON_BLOCKER_SUB_COMPLEX_H
25 
26 #include "gudhi/Skeleton_blocker_complex.h"
27 #include "gudhi/Skeleton_blocker/Skeleton_blocker_simplex.h"
28 #include "gudhi/Utils.h"
29 
30 namespace Gudhi{
31 
32 namespace skbl {
33 
54 template<typename ComplexType>
55 class Skeleton_blocker_sub_complex : public ComplexType
56 {
57 
58 protected:
59 
60  template<class T> friend class Skeleton_blocker_link_complex;
61 
62  typedef typename ComplexType::Graph Graph;
63  typedef typename ComplexType::Edge_handle Edge_handle;
64 
65  typedef typename ComplexType::boost_vertex_handle boost_vertex_handle;
66 
67 
68 public:
69  using ComplexType::add_vertex;
70  using ComplexType::add_edge;
71  using ComplexType::add_blocker;
72 
73  typedef typename ComplexType::Vertex_handle Vertex_handle;
74  typedef typename ComplexType::Root_vertex_handle Root_vertex_handle;
75  typedef typename ComplexType::Simplex_handle Simplex_handle;
76  typedef typename ComplexType::Root_simplex_handle Root_simplex_handle;
77 
78 
79 protected:
80 
81 
83  //* @brief Returns true iff the simplex formed by all vertices contained in 'addresses_sigma_in_link'
84  //* but 'vertex_to_be_ignored' is in 'link'
85  //*/
86  /*
87  template<typename T> friend bool
88  proper_face_in_union(
89  Skeleton_blocker_sub_complex<T> & link,
90  std::vector<boost::optional<typename T::Vertex_handle> > & addresses_sigma_in_link,
91  int vertex_to_be_ignored);*/
92 
97  // template<typename T> friend bool
98  // proper_faces_in_union(Skeleton_blocker_simplex<typename T::Root_vertex_handle> & sigma, Skeleton_blocker_sub_complex<T> & link1, Skeleton_blocker_sub_complex<T> & link2){
99 
100  //template<typename T> friend bool
101  //proper_faces_in_union(Skeleton_blocker_simplex<typename T::Root_vertex_handle> & sigma, Skeleton_blocker_sub_complex<T> & link1, Skeleton_blocker_sub_complex<T> & link2);
102 
103  typedef std::map<Root_vertex_handle, Vertex_handle> IdAddressMap;
104  typedef typename IdAddressMap::value_type AddressPair;
105  typedef typename IdAddressMap::iterator IdAddressMapIterator;
106  typedef typename IdAddressMap::const_iterator IdAddressMapConstIterator;
107  std::map<Root_vertex_handle, Vertex_handle> adresses;
108 
109 
110 public:
118  Vertex_handle add_vertex(Root_vertex_handle global){
119  assert(!this->contains_vertex(global));
120  Vertex_handle address(boost::add_vertex(this->skeleton));
121  this->num_vertices_++;
122  (*this)[address].activate();
123  (*this)[address].set_id(global);
124  adresses.insert(AddressPair(global, address));
125  this->degree_.push_back(0);
126  return address;
127  }
128 
129 
135  void add_edge(Root_vertex_handle v1_root, Root_vertex_handle v2_root){
136  auto v1_sub(this->get_address(v1_root));
137  auto v2_sub(this->get_address(v2_root));
138  assert(v1_sub && v2_sub);
139  this->ComplexType::add_edge(*v1_sub, *v2_sub);
140  }
141 
147  void add_blocker(const Root_simplex_handle& blocker_root){
148  auto blocker_sub = this->get_address(blocker_root);
149  assert(blocker_sub);
150  this->add_blocker(new Simplex_handle(*blocker_sub));
151  }
152 
153 
154 
155 public:
156 
161  void make_restricted_complex(const ComplexType & parent_complex, const Simplex_handle& simplex){
162  this->clear();
163  // add vertices to the sub complex
164  for (auto x : simplex){
165  assert(parent_complex.contains_vertex(x));
166  auto x_local = this->add_vertex(parent_complex[x].get_id());
167  (*this)[x_local] = parent_complex[x];
168  }
169 
170  // add edges to the sub complex
171  for (auto x : simplex){
172  // x_neigh is the neighbor of x intersected with vertices_simplex
173  Simplex_handle x_neigh;
174  parent_complex.add_neighbours(x, x_neigh, true);
175  x_neigh.intersection(simplex);
176  for (auto y : x_neigh){
177  this->add_edge(parent_complex[x].get_id(), parent_complex[y].get_id());
178  }
179  }
180 
181  // add blockers to the sub complex
182  for (auto blocker : parent_complex.const_blocker_range()){
183  // check if it is the first time we encounter the blocker
184  if (simplex.contains(*blocker)){
185  Root_simplex_handle blocker_root(parent_complex.get_id(*(blocker)));
186  Simplex_handle blocker_restr(*(this->get_simplex_address(blocker_root)));
187  this->add_blocker(new Simplex_handle(blocker_restr));
188  }
189  }
190  }
191 
192 
193 
194  void clear(){
195  adresses.clear();
196  ComplexType::clear();
197  }
198 
203  boost::optional<Vertex_handle> get_address(Root_vertex_handle global) const{
204  boost::optional<Vertex_handle> res;
205  IdAddressMapConstIterator it = adresses.find(global);
206  if (it == adresses.end()) res.reset();
207  else res = (*it).second;
208  return res;
209  }
210 
211  // /**
212  // * Allocates a simplex in L corresponding to the simplex s in K
213  // * with its local adresses and returns an AddressSimplex.
214  // */
215  // boost::optional<Simplex_handle> get_address(const Root_simplex_handle & s) const;
216 
217 
218 //private:
223  // @remark should be private but problem with VS
224  std::vector<boost::optional<Vertex_handle> > get_addresses(const Root_simplex_handle & s) const{
225  std::vector<boost::optional<Vertex_handle> > res;
226  for (auto i : s)
227  {
228  res.push_back(get_address(i));
229  }
230  return res;
231  }
232 
233 };
234 
235 
242 template<typename ComplexType>
243 bool proper_face_in_union(
244  Skeleton_blocker_sub_complex<ComplexType> & link,
245  std::vector<boost::optional<typename ComplexType::Vertex_handle> > & addresses_sigma_in_link,
246  int vertex_to_be_ignored)
247 {
248  // we test that all vertices of 'addresses_sigma_in_link' but 'vertex_to_be_ignored'
249  // are in link1 if it is the case we construct the corresponding simplex
250  bool vertices_sigma_are_in_link = true;
251  typename ComplexType::Simplex_handle sigma_in_link;
252  for (int i = 0; i < addresses_sigma_in_link.size(); ++i){
253  if (i != vertex_to_be_ignored){
254  if (!addresses_sigma_in_link[i]){
255  vertices_sigma_are_in_link = false;
256  break;
257  }
258  else sigma_in_link.add_vertex(*addresses_sigma_in_link[i]);
259  }
260  }
261  // If one of vertices of the simplex is not in the complex then it returns false
262  // Otherwise, it tests if the simplex is in the complex
263  return vertices_sigma_are_in_link && link.contains(sigma_in_link);
264 }
265 
266 /*
267  template<typename ComplexType>
268  bool
269  proper_faces_in_union(Skeleton_blocker_simplex<typename ComplexType::Root_vertex_handle> & sigma, Skeleton_blocker_sub_complex<ComplexType> & link1, Skeleton_blocker_sub_complex<ComplexType> & link2)
270  {
271  typedef typename ComplexType::Vertex_handle Vertex_handle;
272  std::vector<boost::optional<Vertex_handle> > addresses_sigma_in_link1 = link1.get_addresses(sigma);
273  std::vector<boost::optional<Vertex_handle> > addresses_sigma_in_link2 = link2.get_addresses(sigma);
274 
275  for (int current_index = 0; current_index < addresses_sigma_in_link1.size(); ++current_index)
276  {
277 
278  if (!proper_face_in_union(link1, addresses_sigma_in_link1, current_index)
279  && !proper_face_in_union(link2, addresses_sigma_in_link2, current_index)){
280  return false;
281  }
282  }
283  return true;
284  }*/
285 
286 
287 
288 // Remark: this function should be friend in order to leave get_adresses private
289 // however doing so seemes currently not possible due to a visual studio bug c2668
290 // "the compiler does not support partial ordering of template functions as specified in the C++ Standard"
291 // http://www.serkey.com/error-c2668-ambiguous-call-to-overloaded-function-bb45ft.html
292 template<typename ComplexType>
293 bool
294 proper_faces_in_union(Skeleton_blocker_simplex<typename ComplexType::Root_vertex_handle> & sigma, Skeleton_blocker_sub_complex<ComplexType> & link1, Skeleton_blocker_sub_complex<ComplexType> & link2)
295 {
296  typedef typename ComplexType::Vertex_handle Vertex_handle;
297  std::vector<boost::optional<Vertex_handle> > addresses_sigma_in_link1 = link1.get_addresses(sigma);
298  std::vector<boost::optional<Vertex_handle> > addresses_sigma_in_link2 = link2.get_addresses(sigma);
299 
300  for (int current_index = 0; current_index < addresses_sigma_in_link1.size(); ++current_index)
301  {
302 
303  if (!proper_face_in_union(link1, addresses_sigma_in_link1, current_index)
304  && !proper_face_in_union(link2, addresses_sigma_in_link2, current_index)){
305  return false;
306  }
307  }
308  return true;
309 }
310 
311 } // namespace skbl
312 
313 } // namespace GUDHI
314 
315 
316 #endif
317 
Vertex_handle add_vertex(Root_vertex_handle global)
Definition: Skeleton_blocker_sub_complex.h:118
void clear()
Definition: Skeleton_blocker_sub_complex.h:194
void add_edge(Root_vertex_handle v1_root, Root_vertex_handle v2_root)
Definition: Skeleton_blocker_sub_complex.h:135
boost::optional< Vertex_handle > get_address(Root_vertex_handle global) const
Definition: Skeleton_blocker_sub_complex.h:203
void add_blocker(const Root_simplex_handle &blocker_root)
Definition: Skeleton_blocker_sub_complex.h:147
std::vector< boost::optional< Vertex_handle > > get_addresses(const Root_simplex_handle &s) const
Definition: Skeleton_blocker_sub_complex.h:224
boost::optional< Simplex_handle > get_simplex_address(const Root_simplex_handle &s) const
Compute the local vertices of 's' in the current complex If one of them is not present in the complex...
Definition: Skeleton_blocker_complex.h:957
void make_restricted_complex(const ComplexType &parent_complex, const Simplex_handle &simplex)
Definition: Skeleton_blocker_sub_complex.h:161
Root_vertex_handle get_id(Vertex_handle local) const
Definition: Skeleton_blocker_complex.h:511
Vertex_handle add_vertex()
Adds a vertex to the simplicial complex and returns its Vertex_handle.
Definition: Skeleton_blocker_complex.h:443
Root_vertex_handle and Vertex_handle are similar to global and local vertex descriptor used in boost ...
Definition: SkeletonBlockerDS.h:50