Cell_complex.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): Siargey Kachanovich
4  *
5  * Copyright (C) 2019 Inria
6  *
7  * Modification(s):
8  * - YYYY/MM Author: Description of the modification
9  */
10 
11 #ifndef CELL_COMPLEX_H_
12 #define CELL_COMPLEX_H_
13 
14 #include <Eigen/Dense>
15 
16 #include <vector>
17 #include <map>
18 #include <utility> // for std::make_pair
19 
20 #include <gudhi/IO/output_debug_traces_to_html.h> // for DEBUG_TRACES
21 #include <gudhi/Permutahedral_representation/Simplex_comparator.h>
22 #include <gudhi/Coxeter_triangulation/Cell_complex/Hasse_diagram_cell.h> // for Hasse_cell
23 
24 namespace Gudhi {
25 
26 namespace coxeter_triangulation {
27 
37 template <class Out_simplex_map_>
38 class Cell_complex {
39  public:
43  using Simplex_handle = typename Out_simplex_map_::key_type;
54  using Simplex_cell_map = std::map<Simplex_handle, Hasse_cell*, Simplex_comparator<Simplex_handle> >;
58  using Simplex_cell_maps = std::vector<Simplex_cell_map>;
59 
63  using Cell_simplex_map = std::map<Hasse_cell*, Simplex_handle>;
64 
68  using Cell_point_map = std::map<Hasse_cell*, Eigen::VectorXd>;
69 
70  private:
71  Hasse_cell* insert_cell(const Simplex_handle& simplex, std::size_t cell_d, bool is_boundary) {
72  Simplex_cell_maps& simplex_cell_maps = (is_boundary ? boundary_simplex_cell_maps_ : interior_simplex_cell_maps_);
73 #ifdef DEBUG_TRACES
74  CC_detail_list& cc_detail_list =
75  (is_boundary ? cc_boundary_detail_lists[cell_d] : cc_interior_detail_lists[cell_d]);
76  cc_detail_list.emplace_back(simplex);
77 #endif
78  Simplex_cell_map& simplex_cell_map = simplex_cell_maps[cell_d];
79  auto map_it = simplex_cell_map.find(simplex);
80  if (map_it == simplex_cell_map.end()) {
81  hasse_cells_.push_back(new Hasse_cell(is_boundary, cell_d));
82  Hasse_cell* new_cell = hasse_cells_.back();
83  simplex_cell_map.emplace(simplex, new_cell);
84  cell_simplex_map_.emplace(new_cell, simplex);
85 #ifdef DEBUG_TRACES
86  cc_detail_list.back().status_ = CC_detail_info::Result_type::inserted;
87 #endif
88  return new_cell;
89  }
90 #ifdef DEBUG_TRACES
91  CC_detail_info& cc_info = cc_detail_list.back();
92  cc_info.trigger_ = to_string(map_it->first);
93  cc_info.status_ = CC_detail_info::Result_type::self;
94 #endif
95  return map_it->second;
96  }
97 
98  void expand_level(std::size_t cell_d) {
99  bool is_manifold_with_boundary = boundary_simplex_cell_maps_.size() > 0;
100  for (auto& sc_pair : interior_simplex_cell_maps_[cell_d - 1]) {
101  const Simplex_handle& simplex = sc_pair.first;
102  Hasse_cell* cell = sc_pair.second;
103  for (Simplex_handle coface : simplex.coface_range(cod_d_ + cell_d)) {
104  Hasse_cell* new_cell = insert_cell(coface, cell_d, false);
105  new_cell->get_boundary().emplace_back(cell, 1);
106  }
107  }
108 
109  if (is_manifold_with_boundary) {
110  for (auto& sc_pair : boundary_simplex_cell_maps_[cell_d - 1]) {
111  const Simplex_handle& simplex = sc_pair.first;
112  Hasse_cell* cell = sc_pair.second;
113  if (cell_d != intr_d_)
114  for (Simplex_handle coface : simplex.coface_range(cod_d_ + cell_d + 1)) {
115  Hasse_cell* new_cell = insert_cell(coface, cell_d, true);
116  new_cell->get_boundary().emplace_back(cell, 1);
117  }
118  auto map_it = interior_simplex_cell_maps_[cell_d].find(simplex);
119  if (map_it == interior_simplex_cell_maps_[cell_d].end())
120  std::cerr << "Cell_complex::expand_level error: A boundary cell does not have an interior counterpart.\n";
121  else {
122  Hasse_cell* i_cell = map_it->second;
123  i_cell->get_boundary().emplace_back(cell, 1);
124  }
125  }
126  }
127  }
128 
129  void construct_complex_(const Out_simplex_map_& out_simplex_map) {
130 #ifdef DEBUG_TRACES
131  cc_interior_summary_lists.resize(interior_simplex_cell_maps_.size());
132  cc_interior_prejoin_lists.resize(interior_simplex_cell_maps_.size());
133  cc_interior_detail_lists.resize(interior_simplex_cell_maps_.size());
134 #endif
135  for (auto& os_pair : out_simplex_map) {
136  const Simplex_handle& simplex = os_pair.first;
137  const Eigen::VectorXd& point = os_pair.second;
138  Hasse_cell* new_cell = insert_cell(simplex, 0, false);
139  cell_point_map_.emplace(new_cell, point);
140  }
141  for (std::size_t cell_d = 1;
142  cell_d < interior_simplex_cell_maps_.size() && !interior_simplex_cell_maps_[cell_d - 1].empty(); ++cell_d) {
143  expand_level(cell_d);
144  }
145  }
146 
147  void construct_complex_(const Out_simplex_map_& interior_simplex_map, const Out_simplex_map_& boundary_simplex_map) {
148 #ifdef DEBUG_TRACES
149  cc_interior_summary_lists.resize(interior_simplex_cell_maps_.size());
150  cc_interior_prejoin_lists.resize(interior_simplex_cell_maps_.size());
151  cc_interior_detail_lists.resize(interior_simplex_cell_maps_.size());
152  cc_boundary_summary_lists.resize(boundary_simplex_cell_maps_.size());
153  cc_boundary_prejoin_lists.resize(boundary_simplex_cell_maps_.size());
154  cc_boundary_detail_lists.resize(boundary_simplex_cell_maps_.size());
155 #endif
156  for (auto& os_pair : boundary_simplex_map) {
157  const Simplex_handle& simplex = os_pair.first;
158  const Eigen::VectorXd& point = os_pair.second;
159  Hasse_cell* new_cell = insert_cell(simplex, 0, true);
160  cell_point_map_.emplace(new_cell, point);
161  }
162  for (auto& os_pair : interior_simplex_map) {
163  const Simplex_handle& simplex = os_pair.first;
164  const Eigen::VectorXd& point = os_pair.second;
165  Hasse_cell* new_cell = insert_cell(simplex, 0, false);
166  cell_point_map_.emplace(new_cell, point);
167  }
168 #ifdef DEBUG_TRACES
169  for (const auto& sc_pair : interior_simplex_cell_maps_[0])
170  cc_interior_summary_lists[0].push_back(CC_summary_info(sc_pair));
171  for (const auto& sc_pair : boundary_simplex_cell_maps_[0])
172  cc_boundary_summary_lists[0].push_back(CC_summary_info(sc_pair));
173 #endif
174 
175  for (std::size_t cell_d = 1;
176  cell_d < interior_simplex_cell_maps_.size() && !interior_simplex_cell_maps_[cell_d - 1].empty(); ++cell_d) {
177  expand_level(cell_d);
178 
179 #ifdef DEBUG_TRACES
180  for (const auto& sc_pair : interior_simplex_cell_maps_[cell_d])
181  cc_interior_summary_lists[cell_d].push_back(CC_summary_info(sc_pair));
182  if (cell_d < boundary_simplex_cell_maps_.size())
183  for (const auto& sc_pair : boundary_simplex_cell_maps_[cell_d])
184  cc_boundary_summary_lists[cell_d].push_back(CC_summary_info(sc_pair));
185 #endif
186  }
187  }
188 
189  public:
199  void construct_complex(const Out_simplex_map_& out_simplex_map) {
200  interior_simplex_cell_maps_.resize(intr_d_ + 1);
201  if (!out_simplex_map.empty()) cod_d_ = out_simplex_map.begin()->first.dimension();
202  construct_complex_(out_simplex_map);
203  }
204 
216  void construct_complex(const Out_simplex_map_& out_simplex_map, std::size_t limit_dimension) {
217  interior_simplex_cell_maps_.resize(limit_dimension + 1);
218  if (!out_simplex_map.empty()) cod_d_ = out_simplex_map.begin()->first.dimension();
219  construct_complex_(out_simplex_map);
220  }
221 
234  void construct_complex(const Out_simplex_map_& interior_simplex_map, const Out_simplex_map_& boundary_simplex_map) {
235  interior_simplex_cell_maps_.resize(intr_d_ + 1);
236  boundary_simplex_cell_maps_.resize(intr_d_);
237  if (!interior_simplex_map.empty()) cod_d_ = interior_simplex_map.begin()->first.dimension();
238  construct_complex_(interior_simplex_map, boundary_simplex_map);
239  }
240 
255  void construct_complex(const Out_simplex_map_& interior_simplex_map, const Out_simplex_map_& boundary_simplex_map,
256  std::size_t limit_dimension) {
257  interior_simplex_cell_maps_.resize(limit_dimension + 1);
258  boundary_simplex_cell_maps_.resize(limit_dimension);
259  if (!interior_simplex_map.empty()) cod_d_ = interior_simplex_map.begin()->first.dimension();
260  construct_complex_(interior_simplex_map, boundary_simplex_map);
261  }
262 
266  std::size_t intrinsic_dimension() const { return intr_d_; }
267 
273  const Simplex_cell_maps& interior_simplex_cell_maps() const { return interior_simplex_cell_maps_; }
274 
280  const Simplex_cell_maps& boundary_simplex_cell_maps() const { return boundary_simplex_cell_maps_; }
281 
289  const Simplex_cell_map& interior_simplex_cell_map(std::size_t cell_d) const {
290  return interior_simplex_cell_maps_[cell_d];
291  }
292 
300  const Simplex_cell_map& boundary_simplex_cell_map(std::size_t cell_d) const {
301  return boundary_simplex_cell_maps_[cell_d];
302  }
303 
309  const Cell_simplex_map& cell_simplex_map() const { return cell_simplex_map_; }
310 
315  const Cell_point_map& cell_point_map() const { return cell_point_map_; }
316 
323 
324  ~Cell_complex() {
325  for (Hasse_cell* hs_ptr : hasse_cells_) delete hs_ptr;
326  }
327 
328  private:
329  std::size_t intr_d_, cod_d_;
330  Simplex_cell_maps interior_simplex_cell_maps_, boundary_simplex_cell_maps_;
331  Cell_simplex_map cell_simplex_map_;
332  Cell_point_map cell_point_map_;
333  std::vector<Hasse_cell*> hasse_cells_;
334 };
335 
336 } // namespace coxeter_triangulation
337 
338 } // namespace Gudhi
339 
340 #endif
Data structure to store a cell in a Hasse diagram.
Definition: Hasse_diagram_cell.h:49
A class that constructs the cell complex from the output provided by the class Gudhi::coxeter_triangu...
Definition: Cell_complex.h:38
std::map< Hasse_cell *, Eigen::VectorXd > Cell_point_map
Type of a map from vertex cells in the cell complex to the permutahedral representations of their Car...
Definition: Cell_complex.h:68
const Cell_point_map & cell_point_map() const
Returns a map from the vertex cells in the cell complex of type Gudhi::Hasse_cell to their Cartesian ...
Definition: Cell_complex.h:315
void construct_complex(const Out_simplex_map_ &out_simplex_map, std::size_t limit_dimension)
Constructs the skeleton of the cell complex that approximates an -dimensional manifold without bounda...
Definition: Cell_complex.h:216
const Simplex_cell_maps & boundary_simplex_cell_maps() const
Returns a vector of maps from the cells of various dimensions on the boundary of the cell complex of ...
Definition: Cell_complex.h:280
std::map< Hasse_cell *, Simplex_handle > Cell_simplex_map
Type of a map from cells in the cell complex to the permutahedral representations of the correspondin...
Definition: Cell_complex.h:63
Cell_complex(std::size_t intrinsic_dimension)
Constructor for the class Cell_complex.
Definition: Cell_complex.h:322
const Simplex_cell_map & interior_simplex_cell_map(std::size_t cell_d) const
Returns a map from the cells of a given dimension in the interior of the cell complex of type Gudhi::...
Definition: Cell_complex.h:289
void construct_complex(const Out_simplex_map_ &interior_simplex_map, const Out_simplex_map_ &boundary_simplex_map)
Constructs the the cell complex that approximates an -dimensional manifold with boundary embedded in ...
Definition: Cell_complex.h:234
const Cell_simplex_map & cell_simplex_map() const
Returns a map from the cells in the cell complex of type Gudhi::Hasse_cell to the permutahedral repre...
Definition: Cell_complex.h:309
Gudhi::Hasse_diagram::Hasse_diagram_cell< int, double, bool > Hasse_cell
Type of a cell in the cell complex. Always is Gudhi::Hasse_cell from the Hasse diagram module....
Definition: Cell_complex.h:49
void construct_complex(const Out_simplex_map_ &out_simplex_map)
Constructs the the cell complex that approximates an -dimensional manifold without boundary embedded ...
Definition: Cell_complex.h:199
std::vector< Simplex_cell_map > Simplex_cell_maps
Type of a vector of maps from permutahedral representations of simplices in the ambient triangulation...
Definition: Cell_complex.h:58
typename Out_simplex_map_::key_type Simplex_handle
Type of a simplex in the ambient triangulation. Is a model of the concept SimplexInCoxeterTriangulati...
Definition: Cell_complex.h:43
void construct_complex(const Out_simplex_map_ &interior_simplex_map, const Out_simplex_map_ &boundary_simplex_map, std::size_t limit_dimension)
Constructs the skeleton of the cell complex that approximates an -dimensional manifold with boundary ...
Definition: Cell_complex.h:255
const Simplex_cell_maps & interior_simplex_cell_maps() const
Returns a vector of maps from the cells of various dimensions in the interior of the cell complex of ...
Definition: Cell_complex.h:273
std::map< Simplex_handle, Hasse_cell *, Simplex_comparator< Simplex_handle > > Simplex_cell_map
Type of a map from permutahedral representations of simplices in the ambient triangulation to the cor...
Definition: Cell_complex.h:54
const Simplex_cell_map & boundary_simplex_cell_map(std::size_t cell_d) const
Returns a map from the cells of a given dimension on the boundary of the cell complex of type Gudhi::...
Definition: Cell_complex.h:300
std::size_t intrinsic_dimension() const
Returns the dimension of the cell complex.
Definition: Cell_complex.h:266
Gudhi namespace.
Definition: SimplicialComplexForAlpha.h:14