Loading...
Searching...
No Matches
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
21namespace Gudhi {
22
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.
118template <typename Input_vertex_range>
119Toplex_map::Simplex_ptr get_key(const Input_vertex_range& vertex_range);
120
121// Is the first simplex a face of the second ?
122template <typename Input_vertex_range1, typename Input_vertex_range2>
123bool included(const Input_vertex_range1& vertex_range1, const Input_vertex_range2& vertex_range2);
124
125// All the facets of the given simplex.
126template <typename Input_vertex_range>
127std::vector<Toplex_map::Simplex> facets(const Input_vertex_range& vertex_range);
128
129template <typename Input_vertex_range>
130void 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
150template <typename Input_vertex_range>
151void 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
168template <typename Input_vertex_range>
169bool 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
179template <typename Input_vertex_range>
180bool 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
186template <typename Input_vertex_range>
187Toplex_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
230std::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
244template <typename Input_vertex_range>
245void 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
262inline 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
271template <typename Input_vertex_range>
272Toplex_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
283std::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
290std::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
298template <typename Input_vertex_range>
299Toplex_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
304template <typename Input_vertex_range1, typename Input_vertex_range2>
305bool 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
312template <typename Input_vertex_range>
313std::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