All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
Loading...
Searching...
No Matches
Bitmap_cubical_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): Pawel Dlotko
4 *
5 * Copyright (C) 2015 Inria
6 *
7 * Modification(s):
8 * - YYYY/MM Author: Description of the modification
9 */
10
11#ifndef BITMAP_CUBICAL_COMPLEX_H_
12#define BITMAP_CUBICAL_COMPLEX_H_
13
14#include <gudhi/Bitmap_cubical_complex_base.h>
15#include <gudhi/Bitmap_cubical_complex_periodic_boundary_conditions_base.h>
16
17#ifdef GUDHI_USE_TBB
18#include <tbb/parallel_sort.h>
19#endif
20
21#include <limits>
22#include <utility> // for pair<>
23#include <algorithm> // for sort
24#include <vector>
25#include <numeric> // for iota
26#include <cstddef>
27
28namespace Gudhi {
29
30namespace cubical_complex {
31
32// global variable, was used just for debugging.
33const bool globalDbg = false;
34
35template <typename T>
36class is_before_in_filtration;
37
47template <typename T>
48class Bitmap_cubical_complex : public T {
49 public:
50 //*********************************************//
51 // Typedefs and typenames
52 //*********************************************//
53 typedef std::size_t Simplex_key;
54 typedef typename T::filtration_type Filtration_value;
55 typedef Simplex_key Simplex_handle;
56
57 //*********************************************//
58 // Constructors
59 //*********************************************//
60 // Over here we need to define various input types. I am proposing the following ones:
61 // Perseus style
62 // TODO(PD) H5 files?
63 // TODO(PD) binary files with little endiangs / big endians ?
64 // TODO(PD) constructor from a vector of elements of a type T. ?
65
69 Bitmap_cubical_complex(const char* perseus_style_file)
70 : T(perseus_style_file), key_associated_to_simplex(this->total_number_of_cells + 1) {
71 if (globalDbg) {
72 std::clog << "Bitmap_cubical_complex( const char* perseus_style_file )\n";
73 }
74 for (std::size_t i = 0; i != this->total_number_of_cells; ++i) {
75 this->key_associated_to_simplex[i] = i;
76 }
77 // we initialize this only once, in each constructor, when the bitmap is constructed.
78 // If the user decide to change some elements of the bitmap, then this procedure need
79 // to be called again.
81 }
82
88 Bitmap_cubical_complex(const std::vector<unsigned>& dimensions,
89 const std::vector<Filtration_value>& top_dimensional_cells)
90 : T(dimensions, top_dimensional_cells), key_associated_to_simplex(this->total_number_of_cells + 1) {
91 for (std::size_t i = 0; i != this->total_number_of_cells; ++i) {
92 this->key_associated_to_simplex[i] = i;
93 }
94 // we initialize this only once, in each constructor, when the bitmap is constructed.
95 // If the user decide to change some elements of the bitmap, then this procedure need
96 // to be called again.
98 }
99
107 Bitmap_cubical_complex(const std::vector<unsigned>& dimensions,
108 const std::vector<Filtration_value>& top_dimensional_cells,
109 std::vector<bool> directions_in_which_periodic_b_cond_are_to_be_imposed)
110 : T(dimensions, top_dimensional_cells, directions_in_which_periodic_b_cond_are_to_be_imposed),
111 key_associated_to_simplex(this->total_number_of_cells + 1) {
112 for (std::size_t i = 0; i != this->total_number_of_cells; ++i) {
113 this->key_associated_to_simplex[i] = i;
114 }
115 // we initialize this only once, in each constructor, when the bitmap is constructed.
116 // If the user decide to change some elements of the bitmap, then this procedure need
117 // to be called again.
119 }
120
125
126 //*********************************************//
127 // Other 'easy' functions
128 //*********************************************//
129
133 std::size_t num_simplices() const { return this->total_number_of_cells; }
134
138 static Simplex_handle null_simplex() {
139 if (globalDbg) {
140 std::clog << "Simplex_handle null_simplex()\n";
141 }
142 return std::numeric_limits<Simplex_handle>::max();
143 }
144
148 inline std::size_t dimension() const { return this->sizes.size(); }
149
153 inline unsigned dimension(Simplex_handle sh) const {
154 if (globalDbg) {
155 std::clog << "unsigned dimension(const Simplex_handle& sh)\n";
156 }
157 if (sh != null_simplex()) return this->get_dimension_of_a_cell(sh);
158 return -1;
159 }
160
164 Filtration_value filtration(Simplex_handle sh) {
165 if (globalDbg) {
166 std::clog << "Filtration_value filtration(const Simplex_handle& sh)\n";
167 }
168 // Returns the filtration value of a simplex.
169 if (sh != null_simplex()) return this->data[sh];
170 return std::numeric_limits<Filtration_value>::infinity();
171 }
172
176 static Simplex_key null_key() {
177 if (globalDbg) {
178 std::clog << "Simplex_key null_key()\n";
179 }
180 return std::numeric_limits<Simplex_handle>::max();
181 }
182
186 Simplex_key key(Simplex_handle sh) const {
187 if (globalDbg) {
188 std::clog << "Simplex_key key(const Simplex_handle& sh)\n";
189 }
190 if (sh != null_simplex()) {
191 return this->key_associated_to_simplex[sh];
192 }
193 return this->null_key();
194 }
195
199 Simplex_handle simplex(Simplex_key key) {
200 if (globalDbg) {
201 std::clog << "Simplex_handle simplex(Simplex_key key)\n";
202 }
203 if (key != null_key()) {
204 return this->simplex_associated_to_key[key];
205 }
206 return null_simplex();
207 }
208
212 void assign_key(Simplex_handle sh, Simplex_key key) {
213 if (globalDbg) {
214 std::clog << "void assign_key(Simplex_handle& sh, Simplex_key key)\n";
215 }
216 if (key == null_key()) return;
217 this->key_associated_to_simplex[sh] = key;
218 this->simplex_associated_to_key[key] = sh;
219 }
220
225
226 //*********************************************//
227 // Iterators
228 //*********************************************//
229
233 typedef typename std::vector<Simplex_handle>::iterator Boundary_simplex_iterator;
234 typedef typename std::vector<Simplex_handle> Boundary_simplex_range;
235
243
244 class Filtration_simplex_iterator {
245 // Iterator over all simplices of the complex in the order of the indexing scheme.
246 // 'value_type' must be 'Simplex_handle'.
247 public:
248 typedef std::input_iterator_tag iterator_category;
249 typedef Simplex_handle value_type;
250 typedef std::ptrdiff_t difference_type;
251 typedef value_type* pointer;
252 typedef value_type reference;
253
254 Filtration_simplex_iterator(Bitmap_cubical_complex* b) : b(b), position(0) {}
255
256 Filtration_simplex_iterator() : b(NULL), position(0) {}
257
258 Filtration_simplex_iterator operator++() {
259 if (globalDbg) {
260 std::clog << "Filtration_simplex_iterator operator++\n";
261 }
262 ++this->position;
263 return (*this);
264 }
265
266 Filtration_simplex_iterator operator++(int) {
267 Filtration_simplex_iterator result = *this;
268 ++(*this);
269 return result;
270 }
271
272 Filtration_simplex_iterator& operator=(const Filtration_simplex_iterator& rhs) {
273 if (globalDbg) {
274 std::clog << "Filtration_simplex_iterator operator =\n";
275 }
276 this->b = rhs.b;
277 this->position = rhs.position;
278 return (*this);
279 }
280
281 bool operator==(const Filtration_simplex_iterator& rhs) const {
282 if (globalDbg) {
283 std::clog << "bool operator == ( const Filtration_simplex_iterator& rhs )\n";
284 }
285 return (this->position == rhs.position);
286 }
287
288 bool operator!=(const Filtration_simplex_iterator& rhs) const {
289 if (globalDbg) {
290 std::clog << "bool operator != ( const Filtration_simplex_iterator& rhs )\n";
291 }
292 return !(*this == rhs);
293 }
294
295 Simplex_handle operator*() {
296 if (globalDbg) {
297 std::clog << "Simplex_handle operator*()\n";
298 }
299 return this->b->simplex_associated_to_key[this->position];
300 }
301
302 friend class Filtration_simplex_range;
303
304 private:
305 Bitmap_cubical_complex<T>* b;
306 std::size_t position;
307 };
308
313 // Range over the simplices of the complex in the order of the filtration.
314 // .begin() and .end() return type Filtration_simplex_iterator.
315 public:
316 typedef Filtration_simplex_iterator const_iterator;
317 typedef Filtration_simplex_iterator iterator;
318
320
321 Filtration_simplex_iterator begin() {
322 if (globalDbg) {
323 std::clog << "Filtration_simplex_iterator begin() \n";
324 }
325 return Filtration_simplex_iterator(this->b);
326 }
327
328 Filtration_simplex_iterator end() {
329 if (globalDbg) {
330 std::clog << "Filtration_simplex_iterator end()\n";
331 }
332 Filtration_simplex_iterator it(this->b);
333 it.position = this->b->simplex_associated_to_key.size();
334 return it;
335 }
336
337 private:
339 };
340
341 //*********************************************//
342 // Methods to access iterators from the container:
343
348 Boundary_simplex_range boundary_simplex_range(Simplex_handle sh) { return this->get_boundary_of_a_cell(sh); }
349
355 if (globalDbg) {
356 std::clog << "Filtration_simplex_range filtration_simplex_range()\n";
357 }
358 // Returns a range over the simplices of the complex in the order of the filtration
359 return Filtration_simplex_range(this);
360 }
361 //*********************************************//
362
363 //*********************************************//
364 // Elements which are in Gudhi now, but I (and in all the cases I asked also Marc) do not understand why they are
365 // there.
366 // TODO(PD) the file IndexingTag.h in the Gudhi library contains an empty structure, so
367 // I understand that this is something that was planned (for simplicial maps?)
368 // but was never finished. The only idea I have here is to use the same empty structure from
369 // IndexingTag.h file, but only if the compiler needs it. If the compiler
370 // do not need it, then I would rather not add here elements which I do not understand.
371 // typedef Indexing_tag
372
376 std::pair<Simplex_handle, Simplex_handle> endpoints(Simplex_handle sh) {
377 std::vector<std::size_t> bdry = this->get_boundary_of_a_cell(sh);
378 if (globalDbg) {
379 std::clog << "std::pair<Simplex_handle, Simplex_handle> endpoints( Simplex_handle sh )\n";
380 std::clog << "bdry.size() : " << bdry.size() << "\n";
381 }
382 // this method returns two first elements from the boundary of sh.
383 if (bdry.size() < 2)
384 throw(
385 "Error in endpoints in Bitmap_cubical_complex class. The cell have less than two elements in the "
386 "boundary.");
387 return std::make_pair(bdry[0], bdry[1]);
388 }
389
393 class Skeleton_simplex_range;
394
395 class Skeleton_simplex_iterator {
396 // Iterator over all simplices of the complex in the order of the indexing scheme.
397 // 'value_type' must be 'Simplex_handle'.
398 public:
399 typedef std::input_iterator_tag iterator_category;
400 typedef Simplex_handle value_type;
401 typedef std::ptrdiff_t difference_type;
402 typedef value_type* pointer;
403 typedef value_type reference;
404
405 Skeleton_simplex_iterator(Bitmap_cubical_complex* b, std::size_t d) : b(b), dimension(d) {
406 if (globalDbg) {
407 std::clog << "Skeleton_simplex_iterator ( Bitmap_cubical_complex* b , std::size_t d )\n";
408 }
409 // find the position of the first simplex of a dimension d
410 this->position = 0;
411 while ((this->position != b->data.size()) &&
412 (this->b->get_dimension_of_a_cell(this->position) != this->dimension)) {
413 ++this->position;
414 }
415 }
416
417 Skeleton_simplex_iterator() : b(NULL), position(0), dimension(0) {}
418
419 Skeleton_simplex_iterator operator++() {
420 if (globalDbg) {
421 std::clog << "Skeleton_simplex_iterator operator++()\n";
422 }
423 // increment the position as long as you did not get to the next element of the dimension dimension.
424 ++this->position;
425 while ((this->position != this->b->data.size()) &&
426 (this->b->get_dimension_of_a_cell(this->position) != this->dimension)) {
427 ++this->position;
428 }
429 return (*this);
430 }
431
432 Skeleton_simplex_iterator operator++(int) {
433 Skeleton_simplex_iterator result = *this;
434 ++(*this);
435 return result;
436 }
437
438 Skeleton_simplex_iterator& operator=(const Skeleton_simplex_iterator& rhs) {
439 if (globalDbg) {
440 std::clog << "Skeleton_simplex_iterator operator =\n";
441 }
442 this->b = rhs.b;
443 this->position = rhs.position;
444 this->dimension = rhs.dimension;
445 return (*this);
446 }
447
448 bool operator==(const Skeleton_simplex_iterator& rhs) const {
449 if (globalDbg) {
450 std::clog << "bool operator ==\n";
451 }
452 return (this->position == rhs.position);
453 }
454
455 bool operator!=(const Skeleton_simplex_iterator& rhs) const {
456 if (globalDbg) {
457 std::clog << "bool operator != ( const Skeleton_simplex_iterator& rhs )\n";
458 }
459 return !(*this == rhs);
460 }
461
462 Simplex_handle operator*() {
463 if (globalDbg) {
464 std::clog << "Simplex_handle operator*() \n";
465 }
466 return this->position;
467 }
468
469 friend class Skeleton_simplex_range;
470
471 private:
472 Bitmap_cubical_complex<T>* b;
473 std::size_t position;
474 unsigned dimension;
475 };
476
481 // Range over the simplices of the complex in the order of the filtration.
482 // .begin() and .end() return type Filtration_simplex_iterator.
483 public:
484 typedef Skeleton_simplex_iterator const_iterator;
485 typedef Skeleton_simplex_iterator iterator;
486
487 Skeleton_simplex_range(Bitmap_cubical_complex<T>* b, unsigned dimension) : b(b), dimension(dimension) {}
488
489 Skeleton_simplex_iterator begin() {
490 if (globalDbg) {
491 std::clog << "Skeleton_simplex_iterator begin()\n";
492 }
493 return Skeleton_simplex_iterator(this->b, this->dimension);
494 }
495
496 Skeleton_simplex_iterator end() {
497 if (globalDbg) {
498 std::clog << "Skeleton_simplex_iterator end()\n";
499 }
500 Skeleton_simplex_iterator it(this->b, this->dimension);
501 it.position = this->b->data.size();
502 return it;
503 }
504
505 private:
507 unsigned dimension;
508 };
509
514 if (globalDbg) {
515 std::clog << "Skeleton_simplex_range skeleton_simplex_range( unsigned dimension )\n";
516 }
517 return Skeleton_simplex_range(this, dimension);
518 }
519
520 friend class is_before_in_filtration<T>;
521
522 protected:
523 std::vector<std::size_t> key_associated_to_simplex;
524 std::vector<std::size_t> simplex_associated_to_key;
525}; // Bitmap_cubical_complex
526
527template <typename T>
529 if (globalDbg) {
530 std::clog << "void Bitmap_cubical_complex<T>::initialize_elements_ordered_according_to_filtration() \n";
531 }
532 this->simplex_associated_to_key = std::vector<std::size_t>(this->data.size());
533 std::iota(std::begin(simplex_associated_to_key), std::end(simplex_associated_to_key), 0);
534#ifdef GUDHI_USE_TBB
535 tbb::parallel_sort(simplex_associated_to_key.begin(), simplex_associated_to_key.end(),
536 is_before_in_filtration<T>(this));
537#else
538 std::sort(simplex_associated_to_key.begin(), simplex_associated_to_key.end(), is_before_in_filtration<T>(this));
539#endif
540
541 // we still need to deal here with a key_associated_to_simplex:
542 for (std::size_t i = 0; i != simplex_associated_to_key.size(); ++i) {
543 this->key_associated_to_simplex[simplex_associated_to_key[i]] = i;
544 }
545}
546
547template <typename T>
548class is_before_in_filtration {
549 public:
550 explicit is_before_in_filtration(Bitmap_cubical_complex<T>* CC) : CC_(CC) {}
551
552 bool operator()(const typename Bitmap_cubical_complex<T>::Simplex_handle& sh1,
553 const typename Bitmap_cubical_complex<T>::Simplex_handle& sh2) const {
554 // Not using st_->filtration(sh1) because it uselessly tests for null_simplex.
555 typedef typename T::filtration_type Filtration_value;
556 Filtration_value fil1 = CC_->data[sh1];
557 Filtration_value fil2 = CC_->data[sh2];
558 if (fil1 != fil2) {
559 return fil1 < fil2;
560 }
561 // in this case they are on the same filtration level, so the dimension decide.
562 std::size_t dim1 = CC_->get_dimension_of_a_cell(sh1);
563 std::size_t dim2 = CC_->get_dimension_of_a_cell(sh2);
564 if (dim1 != dim2) {
565 return dim1 < dim2;
566 }
567 // in this case both filtration and dimensions of the considered cubes are the same. To have stable sort, we simply
568 // compare their positions in the bitmap:
569 return sh1 < sh2;
570 }
571
572 protected:
573 Bitmap_cubical_complex<T>* CC_;
574};
575
576} // namespace cubical_complex
577
578namespace Cubical_complex = cubical_complex;
579
580} // namespace Gudhi
581
582#endif // BITMAP_CUBICAL_COMPLEX_H_
Filtration_simplex_range provides the ranges for Filtration_simplex_iterator.
Definition: Bitmap_cubical_complex.h:312
Class needed for compatibility with Gudhi. Not useful for other purposes.
Definition: Bitmap_cubical_complex.h:480
Cubical complex represented as a bitmap.
Definition: Bitmap_cubical_complex.h:48
std::pair< Simplex_handle, Simplex_handle > endpoints(Simplex_handle sh)
Definition: Bitmap_cubical_complex.h:376
Bitmap_cubical_complex(const std::vector< unsigned > &dimensions, const std::vector< Filtration_value > &top_dimensional_cells)
Definition: Bitmap_cubical_complex.h:88
Bitmap_cubical_complex(const std::vector< unsigned > &dimensions, const std::vector< Filtration_value > &top_dimensional_cells, std::vector< bool > directions_in_which_periodic_b_cond_are_to_be_imposed)
Definition: Bitmap_cubical_complex.h:107
Filtration_simplex_range filtration_simplex_range()
Definition: Bitmap_cubical_complex.h:354
Bitmap_cubical_complex(const char *perseus_style_file)
Definition: Bitmap_cubical_complex.h:69
Simplex_key key(Simplex_handle sh) const
Definition: Bitmap_cubical_complex.h:186
std::size_t dimension() const
Definition: Bitmap_cubical_complex.h:148
std::vector< Simplex_handle >::iterator Boundary_simplex_iterator
Definition: Bitmap_cubical_complex.h:233
Filtration_value filtration(Simplex_handle sh)
Definition: Bitmap_cubical_complex.h:164
Boundary_simplex_range boundary_simplex_range(Simplex_handle sh)
Definition: Bitmap_cubical_complex.h:348
void assign_key(Simplex_handle sh, Simplex_key key)
Definition: Bitmap_cubical_complex.h:212
static Simplex_key null_key()
Definition: Bitmap_cubical_complex.h:176
Simplex_handle simplex(Simplex_key key)
Definition: Bitmap_cubical_complex.h:199
unsigned dimension(Simplex_handle sh) const
Definition: Bitmap_cubical_complex.h:153
void initialize_simplex_associated_to_key()
Definition: Bitmap_cubical_complex.h:528
std::size_t num_simplices() const
Definition: Bitmap_cubical_complex.h:133
Skeleton_simplex_range skeleton_simplex_range(unsigned dimension)
Definition: Bitmap_cubical_complex.h:513
static Simplex_handle null_simplex()
Definition: Bitmap_cubical_complex.h:138
virtual ~Bitmap_cubical_complex()
Definition: Bitmap_cubical_complex.h:124
Value type for a filtration function on a cell complex.
Definition: FiltrationValue.h:20