Toplex_map.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: François Godi, Vincent Rouvreau
4  *
5  * Copyright (C) 2018 INRIA
6  *
7  * Modification(s):
8  * - YYYY/MM Author: Description of the modification
9  */
10 
11 #ifndef TOPLEX_MAP_H
12 #define TOPLEX_MAP_H
13 
14 #include <vector>
15 #include <set>
16 #include <unordered_set>
17 #include <unordered_map>
18 #include <memory>
19 #include <limits>
20 
21 namespace Gudhi {
22 
29 class Toplex_map {
30  public:
32  using Vertex = std::size_t;
33 
35  using Simplex = std::set<Vertex>;
36 
38  using Simplex_ptr = std::shared_ptr<Toplex_map::Simplex>;
39 
40  struct Sptr_hash {
41  std::size_t operator()(const Toplex_map::Simplex_ptr& s) const;
42  };
43 
44  struct Sptr_equal {
45  std::size_t operator()(const Toplex_map::Simplex_ptr& a, const Toplex_map::Simplex_ptr& b) const;
46  };
47 
49  using Simplex_ptr_set = std::unordered_set<Toplex_map::Simplex_ptr, Sptr_hash, Sptr_equal>;
50 
53  template <typename Input_vertex_range>
54  void insert_simplex(const Input_vertex_range& vertex_range);
55 
58  template <typename Input_vertex_range>
59  void remove_simplex(const Input_vertex_range& vertex_range);
60 
62  template <typename Input_vertex_range>
63  bool membership(const Input_vertex_range& vertex_range) const;
64 
66  template <typename Input_vertex_range>
67  bool maximality(const Input_vertex_range& vertex_range) const;
68 
72  template <typename Input_vertex_range>
73  Toplex_map::Simplex_ptr_set maximal_cofaces(const Input_vertex_range& vertex_range,
74  const std::size_t max_number = 0) const;
75 
78  Toplex_map::Simplex_ptr_set maximal_simplices(const std::size_t max_number = 0) const {
79  return maximal_cofaces(Simplex(), max_number);
80  }
81 
85  Vertex contraction(const Vertex x, const Vertex y);
86 
88  void remove_vertex(const Vertex x);
89 
91  std::size_t num_maximal_simplices() const { return maximal_simplices().size(); }
92 
94  std::size_t num_vertices() const { return t0.size(); }
95 
96  std::set<Vertex> unitary_collapse(const Vertex k, const Vertex d);
97 
100  template <typename Input_vertex_range>
101  void insert_independent_simplex(const Input_vertex_range& vertex_range);
102 
103  protected:
105  template <typename Input_vertex_range>
106  Vertex best_index(const Input_vertex_range& vertex_range) const;
107 
109  std::unordered_map<Vertex, Toplex_map::Simplex_ptr_set> t0;
110 
111  const Vertex VERTEX_UPPER_BOUND = std::numeric_limits<Vertex>::max();
112 
114  void erase_maximal(const Toplex_map::Simplex_ptr& sptr);
115 };
116 
117 // Pointers are also used as key in the hash sets.
118 template <typename Input_vertex_range>
119 Toplex_map::Simplex_ptr get_key(const Input_vertex_range& vertex_range);
120 
121 // Is the first simplex a face of the second ?
122 template <typename Input_vertex_range1, typename Input_vertex_range2>
123 bool included(const Input_vertex_range1& vertex_range1, const Input_vertex_range2& vertex_range2);
124 
125 // All the facets of the given simplex.
126 template <typename Input_vertex_range>
127 std::vector<Toplex_map::Simplex> facets(const Input_vertex_range& vertex_range);
128 
129 template <typename Input_vertex_range>
130 void Toplex_map::insert_simplex(const Input_vertex_range& vertex_range) {
131  if (membership(vertex_range)) return;
132  bool replace_facets = true;
133  for (const Toplex_map::Simplex& facet : facets(vertex_range))
134  if (!maximality(facet)) {
135  replace_facets = false;
136  break;
137  }
138  if (replace_facets)
139  for (const Toplex_map::Simplex& facet : facets(vertex_range)) erase_maximal(get_key(facet));
140  else
141  for (const Vertex& v : vertex_range)
142  if (t0.count(v))
143  for (const Toplex_map::Simplex_ptr& fptr : Simplex_ptr_set(t0.at(v)))
144  // Copy constructor needed because the set is modified
145  if (included(*fptr, vertex_range)) erase_maximal(fptr);
146  // We erase all the maximal faces of the simplex
147  insert_independent_simplex(vertex_range);
148 }
149 
150 template <typename Input_vertex_range>
151 void Toplex_map::remove_simplex(const Input_vertex_range& vertex_range) {
152  if (vertex_range.begin() == vertex_range.end()) t0.clear();
153  // Removal of the empty simplex means cleaning everything
154  else {
155  const Vertex& v = best_index(vertex_range);
156  if (t0.count(v))
157  for (const Toplex_map::Simplex_ptr& sptr : Simplex_ptr_set(t0.at(v)))
158  // Copy constructor needed because the set is modified
159  if (included(vertex_range, *sptr)) {
160  erase_maximal(sptr);
161  for (const Toplex_map::Simplex& f : facets(vertex_range))
163  // We add the facets which are new maximal simplices
164  }
165  }
166 }
167 
168 template <typename Input_vertex_range>
169 bool Toplex_map::membership(const Input_vertex_range& vertex_range) const {
170  if (t0.size() == 0) return false;
171  const Vertex& v = best_index(vertex_range);
172  if (!t0.count(v)) return false;
173  if (maximality(vertex_range)) return true;
174  for (const Toplex_map::Simplex_ptr& sptr : t0.at(v))
175  if (included(vertex_range, *sptr)) return true;
176  return false;
177 }
178 
179 template <typename Input_vertex_range>
180 bool Toplex_map::maximality(const Input_vertex_range& vertex_range) const {
181  const Vertex& v = best_index(vertex_range);
182  if (!t0.count(v)) return false;
183  return t0.at(v).count(get_key(vertex_range));
184 }
185 
186 template <typename Input_vertex_range>
187 Toplex_map::Simplex_ptr_set Toplex_map::maximal_cofaces(const Input_vertex_range& vertex_range,
188  const std::size_t max_number) const {
189  Simplex_ptr_set cofaces;
190  if (maximality(vertex_range))
191  cofaces.emplace(get_key(vertex_range));
192  else if (vertex_range.begin() == vertex_range.end())
193  for (const auto& kv : t0)
194  for (const Toplex_map::Simplex_ptr& sptr : kv.second) {
195  // kv.second is a Simplex_ptr_set
196  cofaces.emplace(sptr);
197  if (cofaces.size() == max_number) return cofaces;
198  }
199  else {
200  const Vertex& v = best_index(vertex_range);
201  if (t0.count(v))
202  for (const Toplex_map::Simplex_ptr& sptr : t0.at(v))
203  if (included(vertex_range, *sptr)) {
204  cofaces.emplace(sptr);
205  if (cofaces.size() == max_number) return cofaces;
206  }
207  }
208  return cofaces;
209 }
210 
212  if (!t0.count(x)) return y;
213  if (!t0.count(y)) return x;
214  int k, d;
215  if (t0.at(x).size() > t0.at(y).size())
216  k = x, d = y;
217  else
218  k = y, d = x;
219  for (const Toplex_map::Simplex_ptr& sptr : Simplex_ptr_set(t0.at(d))) {
220  // Copy constructor needed because the set is modified
221  Simplex sigma(*sptr);
222  erase_maximal(sptr);
223  sigma.erase(d);
224  sigma.insert(k);
225  insert_simplex(sigma);
226  }
227  return k;
228 }
229 
230 std::set<Toplex_map::Vertex> Toplex_map::unitary_collapse(const Toplex_map::Vertex k, const Toplex_map::Vertex d) {
232  for (const Toplex_map::Simplex_ptr& sptr : Simplex_ptr_set(t0.at(d))) {
233  // Copy constructor needed because the set is modified
234  Simplex sigma(*sptr);
235  erase_maximal(sptr);
236  sigma.erase(d);
237  for (const Vertex v : sigma) r.insert(v);
238  sigma.insert(k);
239  insert_simplex(sigma);
240  }
241  return r;
242 }
243 
244 template <typename Input_vertex_range>
245 void Toplex_map::insert_independent_simplex(const Input_vertex_range& vertex_range) {
246  auto key = get_key(vertex_range);
247  for (const Vertex& v : vertex_range) {
248  if (!t0.count(v)) t0.emplace(v, Simplex_ptr_set());
249  t0.at(v).emplace(key);
250  }
251 }
252 
254  for (const Toplex_map::Simplex_ptr& sptr : Simplex_ptr_set(t0.at(x))) {
255  Simplex sigma(*sptr);
256  erase_maximal(sptr);
257  sigma.erase(x);
258  insert_simplex(sigma);
259  }
260 }
261 
262 inline void Toplex_map::erase_maximal(const Toplex_map::Simplex_ptr& sptr) {
263  Simplex sigma(*sptr);
264  if (sptr->size() == 0) sigma.insert(VERTEX_UPPER_BOUND);
265  for (const Vertex& v : sigma) {
266  t0.at(v).erase(sptr);
267  if (t0.at(v).size() == 0) t0.erase(v);
268  }
269 }
270 
271 template <typename Input_vertex_range>
272 Toplex_map::Vertex Toplex_map::best_index(const Input_vertex_range& vertex_range) const {
273  std::size_t min = std::numeric_limits<size_t>::max();
274  Vertex arg_min = VERTEX_UPPER_BOUND;
275  for (const Vertex& v : vertex_range)
276  if (!t0.count(v))
277  return v;
278  else if (t0.at(v).size() < min)
279  min = t0.at(v).size(), arg_min = v;
280  return arg_min;
281 }
282 
283 std::size_t Toplex_map::Sptr_equal::operator()(const Toplex_map::Simplex_ptr& s1,
284  const Toplex_map::Simplex_ptr& s2) const {
285  if (s1->size() != s2->size()) return false;
286  return included(*s1, *s2);
287  // inclusion tests equality for same size simplices
288 }
289 
290 std::size_t Toplex_map::Sptr_hash::operator()(const Toplex_map::Simplex_ptr& s) const {
291  std::hash<double> h_f;
292  // double hash works better than int hash
293  size_t h = 0;
294  for (const Vertex& v : *s) h += h_f(static_cast<double>(v));
295  return h;
296 }
297 
298 template <typename Input_vertex_range>
299 Toplex_map::Simplex_ptr get_key(const Input_vertex_range& vertex_range) {
300  Toplex_map::Simplex s(vertex_range.begin(), vertex_range.end());
301  return std::make_shared<Toplex_map::Simplex>(s);
302 }
303 
304 template <typename Input_vertex_range1, typename Input_vertex_range2>
305 bool included(const Input_vertex_range1& vertex_range1, const Input_vertex_range2& vertex_range2) {
306  Toplex_map::Simplex s2(vertex_range2.begin(), vertex_range2.end());
307  for (const Toplex_map::Vertex& v : vertex_range1)
308  if (!s2.count(v)) return false;
309  return true;
310 }
311 
312 template <typename Input_vertex_range>
313 std::vector<Toplex_map::Simplex> facets(const Input_vertex_range& vertex_range) {
314  std::vector<Toplex_map::Simplex> facets;
315  Toplex_map::Simplex f(vertex_range.begin(), vertex_range.end());
316  for (const Toplex_map::Vertex& v : vertex_range) {
317  f.erase(v);
318  facets.emplace_back(f);
319  f.insert(v);
320  }
321  return facets;
322 }
323 
324 } // namespace Gudhi
325 
326 #endif /* TOPLEX_MAP_H */
Toplex map data structure for representing unfiltered simplicial complexes.
Definition: Toplex_map.h:29
Toplex_map::Simplex_ptr_set maximal_cofaces(const Input_vertex_range &vertex_range, const std::size_t max_number=0) const
Definition: Toplex_map.h:187
std::unordered_set< Toplex_map::Simplex_ptr, Sptr_hash, Sptr_equal > Simplex_ptr_set
Definition: Toplex_map.h:49
void remove_vertex(const Vertex x)
Definition: Toplex_map.h:253
Toplex_map::Simplex_ptr_set maximal_simplices(const std::size_t max_number=0) const
Definition: Toplex_map.h:78
std::size_t num_vertices() const
Number of vertices.
Definition: Toplex_map.h:94
std::shared_ptr< Toplex_map::Simplex > Simplex_ptr
Definition: Toplex_map.h:38
std::size_t num_maximal_simplices() const
Number of maximal simplices.
Definition: Toplex_map.h:91
bool membership(const Input_vertex_range &vertex_range) const
Definition: Toplex_map.h:169
Vertex contraction(const Vertex x, const Vertex y)
Definition: Toplex_map.h:211
void remove_simplex(const Input_vertex_range &vertex_range)
Removes the given simplex and its cofaces from the complex. Its faces are kept inside.
Definition: Toplex_map.h:151
bool maximality(const Input_vertex_range &vertex_range) const
Definition: Toplex_map.h:180
std::set< Vertex > Simplex
Definition: Toplex_map.h:35
void insert_independent_simplex(const Input_vertex_range &vertex_range)
Definition: Toplex_map.h:245
std::size_t Vertex
Definition: Toplex_map.h:32
void insert_simplex(const Input_vertex_range &vertex_range)
Adds the given simplex to the complex. Nothing happens if the simplex is already in the complex (i....
Definition: Toplex_map.h:130
Gudhi namespace.
Definition: SimplicialComplexForAlpha.h:14