Gudhi  1.1.0
 All Classes Functions Typedefs Friends Groups Pages
Hasse_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): 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 GUDHI_HASSE_DIAGRAM_H
24 #define GUDHI_HASSE_DIAGRAM_H
25 
26 #include <algorithm>
27 #include <boost/iterator/counting_iterator.hpp>
28 
29 namespace Gudhi{
30 
31 template < class HasseCpx >
32 struct Hasse_simplex
33 {
34 //Complex_ds must verify that cpx->key(sh) is the order of sh in the filtration
35  template< class Complex_ds >
36  Hasse_simplex ( Complex_ds & cpx
37  , typename Complex_ds::Simplex_handle sh )
38  : key_(cpx.key(sh))
39  , filtration_(cpx.filtration(sh))
40  , boundary_()
41  {
42  boundary_.reserve(cpx.dimension(sh)+1);
43  for( auto b_sh : cpx.boundary_simplex_range(sh) )
44  { boundary_.push_back( cpx.key(b_sh) ); }
45  }
46 
47  Hasse_simplex ( typename HasseCpx::Simplex_key key
48  , typename HasseCpx::Filtration_value fil
49  , std::vector<typename HasseCpx::Simplex_handle> boundary)
50  : key_(key)
51  , filtration_(fil)
52  , boundary_(boundary) {}
53 
54  typename HasseCpx::Simplex_key key_;
55  typename HasseCpx::Filtration_value filtration_;
56  std::vector<typename HasseCpx::Simplex_handle> boundary_;
57 };
58 
59 
60 
68 template < typename FiltrationValue = double
69  , typename SimplexKey = int
70  , typename VertexHandle = int
71  >
73 {
74 public:
75 
76  typedef Hasse_simplex<Hasse_complex> Hasse_simp;
78  typedef SimplexKey Simplex_key;
79  typedef int Simplex_handle; //index in vector complex_
80 
81  typedef boost::counting_iterator< Simplex_handle > Filtration_simplex_iterator;
82  typedef boost::iterator_range<Filtration_simplex_iterator> Filtration_simplex_range;
83 
84  typedef typename std::vector< Simplex_handle >::iterator Boundary_simplex_iterator;
85  typedef boost::iterator_range<Boundary_simplex_iterator> Boundary_simplex_range;
86 
87  typedef typename std::vector< Simplex_handle >::iterator Skeleton_simplex_iterator;
88  typedef boost::iterator_range< Skeleton_simplex_iterator > Skeleton_simplex_range;
89 
90 
91 /* only dimension 0 skeleton_simplex_range(...) */
92  Skeleton_simplex_range skeleton_simplex_range( int dim = 0 ) {
93  if(dim != 0) { std::cerr << "Dimension must be 0 \n"; }
94  return Skeleton_simplex_range(vertices_.begin(),vertices_.end());
95  }
96 
97  template < class Complex_ds >
98  Hasse_complex(Complex_ds & cpx)
99  : complex_()
100  , vertices_()
101  , threshold_(cpx.filtration())
102  , num_vertices_()
103  , dim_max_(cpx.dimension())
104  {
105  complex_.reserve(cpx.num_simplices());
106  int idx = 0;
107  for(auto cpx_sh : cpx.filtration_simplex_range())
108  {
109  complex_.push_back(Hasse_simp(cpx,cpx_sh));
110  if(dimension(idx) == 0) { vertices_.push_back(idx); }
111  ++idx;
112  }
113  }
114 
115  Hasse_complex()
116  : complex_()
117  , vertices_()
118  , threshold_(0)
119  , num_vertices_(0)
120  , dim_max_(-1) {}
121 
122  size_t num_simplices() { return complex_.size(); }
123 
124  Filtration_simplex_range filtration_simplex_range()
125  { return Filtration_simplex_range( Filtration_simplex_iterator(0)
126  , Filtration_simplex_iterator(complex_.size()) ); }
127 
128  Simplex_key key( Simplex_handle sh ) { return complex_[sh].key_; }
129 
130  Simplex_key null_key() { return -1; }
131 
132  Simplex_handle simplex( Simplex_key key )
133  {
134  if(key == null_key()) return null_simplex();
135  return key;
136  }
137 
138  Simplex_handle null_simplex() { return -1; }
139 
140  Filtration_value filtration( Simplex_handle sh ) {
141  if( sh == null_simplex() ) { return filtration(); }
142  return complex_[sh].filtration_;
143  }
144 
145  Filtration_value filtration() { return threshold_; }
146 
147  int dimension ( Simplex_handle sh ) {
148  if(complex_[sh].boundary_.empty()) return 0;
149  return complex_[sh].boundary_.size()-1;
150  }
151  int dimension () { return dim_max_; }
152 
153  std::pair<Simplex_handle,Simplex_handle> endpoints( Simplex_handle sh )
154  { return std::pair<Simplex_handle,Simplex_handle>( complex_[sh].boundary_[0]
155  , complex_[sh].boundary_[1] ) ;}
156 
157  void assign_key( Simplex_handle sh, Simplex_key key) { complex_[sh].key_ = key; }
158 
159  Boundary_simplex_range boundary_simplex_range ( Simplex_handle sh )
160  { return Boundary_simplex_range( complex_[sh].boundary_.begin()
161  , complex_[sh].boundary_.end() ); }
162 
163  void display_simplex(Simplex_handle sh)
164  {
165  std::cout << dimension(sh) << " ";
166  for(auto sh_b : boundary_simplex_range(sh)) std::cout << sh_b << " ";
167  std::cout << " " << filtration(sh) << " key=" << key(sh);
168  }
169 
170  void initialize_filtration()
171  {
172  Simplex_key key = 0;
173  for(auto & h_simp : complex_) { h_simp.key_ = key; ++key; }
174  }
175 
176  std::vector< Hasse_simp > complex_;
177  std::vector<Simplex_handle> vertices_;
178  Filtration_value threshold_;
179  size_t num_vertices_;
180  int dim_max_;
181 };
182 
183 template< typename T1, typename T2, typename T3 >
184 std::istream& operator>> ( std::istream & is
185  , Hasse_complex< T1, T2, T3 > & hcpx )
186 {
187  assert(hcpx.num_simplices() == 0);
188 
189  size_t num_simp;
190  is >> num_simp;
191  hcpx.complex_.reserve(num_simp);
192 
193  std::vector< typename Hasse_complex<T1,T2,T3>::Simplex_key > boundary;
195  typename Hasse_complex<T1,T2,T3>::Filtration_value max_fil = 0 ;
196  int max_dim = -1;
197  int key = 0 ;
198  while(read_hasse_simplex( is, boundary, fil )) //read all simplices in the file as a list of vertices
199  {
200  //insert every simplex in the simplex tree
201  hcpx.complex_.push_back( Hasse_simplex< Hasse_complex<T1,T2,T3> >(key,fil,boundary));
202 
203  if(max_dim < hcpx.dimension(key)) { max_dim = hcpx.dimension(key); }
204  if(hcpx.dimension(key) == 0) { hcpx.vertices_.push_back(key); }
205  if(max_fil < fil) { max_fil = fil; }
206 
207  ++key;
208  boundary.clear();
209  }
210 
211  hcpx.dim_max_ = max_dim;
212  hcpx.threshold_ = max_fil;
213 
214  return is;
215 }
216 
217 } // namespace GUDHI
218 
219 #endif // GUDHI_HASSE_DIAGRAM_H
Key type used as simplex identifier.
Definition: SimplexKey.h:27
Data structure representing a Hasse diagram, i.e. a complex where all codimension 1 incidence relatio...
Definition: Hasse_complex.h:72
Value type for a filtration function on a cell complex.
Definition: FiltrationValue.h:32
Handle type for the vertices of a cell complex.
Definition: VertexHandle.h:26