Bitmap_cubical_complex_base.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_BASE_H_
12 #define BITMAP_CUBICAL_COMPLEX_BASE_H_
13 
14 #include <gudhi/Bitmap_cubical_complex/counter.h>
15 
16 #include <boost/config.hpp>
17 
18 #include <iostream>
19 #include <vector>
20 #include <string>
21 #include <fstream>
22 #include <algorithm>
23 #include <iterator>
24 #include <limits>
25 #include <utility>
26 #include <stdexcept>
27 #include <cstddef>
28 
29 namespace Gudhi {
30 
31 namespace cubical_complex {
32 
52 template <typename T>
54  public:
55  typedef T filtration_type;
56 
60  Bitmap_cubical_complex_base() : total_number_of_cells(0) {}
67  Bitmap_cubical_complex_base(const std::vector<unsigned>& sizes);
74  Bitmap_cubical_complex_base(const char* perseus_style_file);
79  Bitmap_cubical_complex_base(const std::vector<unsigned>& dimensions, const std::vector<T>& top_dimensional_cells);
80 
85 
97  virtual inline std::vector<std::size_t> get_boundary_of_a_cell(std::size_t cell) const;
112  virtual inline std::vector<std::size_t> get_coboundary_of_a_cell(std::size_t cell) const;
113 
122  inline size_t get_top_dimensional_coface_of_a_cell(size_t splx);
123 
143  virtual int compute_incidence_between_cells(std::size_t coface, std::size_t face) const {
144  // first get the counters for coface and face:
145  std::vector<unsigned> coface_counter = this->compute_counter_for_given_cell(coface);
146  std::vector<unsigned> face_counter = this->compute_counter_for_given_cell(face);
147 
148  // coface_counter and face_counter should agree at all positions except from one:
149  int number_of_position_in_which_counters_do_not_agree = -1;
150  std::size_t number_of_full_faces_that_comes_before = 0;
151  for (std::size_t i = 0; i != coface_counter.size(); ++i) {
152  if ((coface_counter[i] % 2 == 1) && (number_of_position_in_which_counters_do_not_agree == -1)) {
153  ++number_of_full_faces_that_comes_before;
154  }
155  if (coface_counter[i] != face_counter[i]) {
156  if (number_of_position_in_which_counters_do_not_agree != -1) {
157  std::cerr << "Cells given to compute_incidence_between_cells procedure do not form a pair of coface-face.\n";
158  throw std::logic_error(
159  "Cells given to compute_incidence_between_cells procedure do not form a pair of coface-face.");
160  }
161  number_of_position_in_which_counters_do_not_agree = i;
162  }
163  }
164 
165  int incidence = 1;
166  if (number_of_full_faces_that_comes_before % 2) incidence = -1;
167  // if the face cell is on the right from coface cell:
168  if (coface_counter[number_of_position_in_which_counters_do_not_agree] + 1 ==
169  face_counter[number_of_position_in_which_counters_do_not_agree]) {
170  incidence *= -1;
171  }
172 
173  return incidence;
174  }
175 
184  inline unsigned get_dimension_of_a_cell(std::size_t cell) const;
185 
192  inline T& get_cell_data(std::size_t cell);
193 
202  void impose_lower_star_filtration(); // assume that top dimensional cells are already set.
203 
207  inline unsigned dimension() const { return sizes.size(); }
208 
212  inline std::size_t size() const { return this->data.size(); }
213 
218  template <typename K>
219  friend std::ostream& operator<<(std::ostream& os, const Bitmap_cubical_complex_base<K>& b);
220 
229  void put_data_to_bins(std::size_t number_of_bins);
230 
241  void put_data_to_bins(T diameter_of_bin);
242 
246  std::pair<T, T> min_max_filtration();
247 
248  // ITERATORS
249 
254  class All_cells_iterator : std::iterator<std::input_iterator_tag, T> {
255  public:
256  All_cells_iterator() { this->counter = 0; }
257 
258  All_cells_iterator operator++() {
259  // first find first element of the counter that can be increased:
260  ++this->counter;
261  return *this;
262  }
263 
264  All_cells_iterator operator++(int) {
265  All_cells_iterator result = *this;
266  ++(*this);
267  return result;
268  }
269 
270  All_cells_iterator& operator=(const All_cells_iterator& rhs) {
271  this->counter = rhs.counter;
272  return *this;
273  }
274 
275  bool operator==(const All_cells_iterator& rhs) const {
276  if (this->counter != rhs.counter) return false;
277  return true;
278  }
279 
280  bool operator!=(const All_cells_iterator& rhs) const { return !(*this == rhs); }
281 
282  /*
283  * The operator * returns position of a cube in the structure of cubical complex. This position can be then used as
284  * an argument of the following functions:
285  * get_boundary_of_a_cell, get_coboundary_of_a_cell, get_dimension_of_a_cell to get information about the cell
286  * boundary and coboundary and dimension
287  * and in function get_cell_data to get a filtration of a cell.
288  */
289  std::size_t operator*() { return this->counter; }
290  friend class Bitmap_cubical_complex_base;
291 
292  protected:
293  std::size_t counter;
294  };
295 
301  return a;
302  }
303 
309  a.counter = this->data.size();
310  return a;
311  }
312 
317  public:
319 
320  All_cells_iterator begin() { return b->all_cells_iterator_begin(); }
321 
322  All_cells_iterator end() { return b->all_cells_iterator_end(); }
323 
324  private:
326  };
327 
328  All_cells_range all_cells_range() { return All_cells_range(this); }
329 
333  typedef typename std::vector<std::size_t>::const_iterator Boundary_iterator;
334  typedef typename std::vector<std::size_t> Boundary_range;
335 
340  Boundary_range boundary_range(std::size_t sh) { return this->get_boundary_of_a_cell(sh); }
341 
345  typedef typename std::vector<std::size_t>::const_iterator Coboundary_iterator;
346  typedef typename std::vector<std::size_t> Coboundary_range;
347 
352  Coboundary_range coboundary_range(std::size_t sh) { return this->get_coboundary_of_a_cell(sh); }
353 
358  class Top_dimensional_cells_iterator : std::iterator<std::input_iterator_tag, T> {
359  public:
361  this->counter = std::vector<std::size_t>(b.dimension());
362  // std::fill( this->counter.begin() , this->counter.end() , 0 );
363  }
364 
365  Top_dimensional_cells_iterator operator++() {
366  // first find first element of the counter that can be increased:
367  std::size_t dim = 0;
368  while ((dim != this->b.dimension()) && (this->counter[dim] == this->b.sizes[dim] - 1)) ++dim;
369 
370  if (dim != this->b.dimension()) {
371  ++this->counter[dim];
372  for (std::size_t i = 0; i != dim; ++i) {
373  this->counter[i] = 0;
374  }
375  } else {
376  ++this->counter[0];
377  }
378  return *this;
379  }
380 
381  Top_dimensional_cells_iterator operator++(int) {
382  Top_dimensional_cells_iterator result = *this;
383  ++(*this);
384  return result;
385  }
386 
388  this->counter = rhs.counter;
389  this->b = rhs.b;
390  return *this;
391  }
392 
393  bool operator==(const Top_dimensional_cells_iterator& rhs) const {
394  if (&this->b != &rhs.b) return false;
395  if (this->counter.size() != rhs.counter.size()) return false;
396  for (std::size_t i = 0; i != this->counter.size(); ++i) {
397  if (this->counter[i] != rhs.counter[i]) return false;
398  }
399  return true;
400  }
401 
402  bool operator!=(const Top_dimensional_cells_iterator& rhs) const { return !(*this == rhs); }
403 
404  /*
405  * The operator * returns position of a cube in the structure of cubical complex. This position can be then used as
406  * an argument of the following functions:
407  * get_boundary_of_a_cell, get_coboundary_of_a_cell, get_dimension_of_a_cell to get information about the cell
408  * boundary and coboundary and dimension
409  * and in function get_cell_data to get a filtration of a cell.
410  */
411  std::size_t operator*() { return this->compute_index_in_bitmap(); }
412 
413  std::size_t compute_index_in_bitmap() const {
414  std::size_t index = 0;
415  for (std::size_t i = 0; i != this->counter.size(); ++i) {
416  index += (2 * this->counter[i] + 1) * this->b.multipliers[i];
417  }
418  return index;
419  }
420 
421  void print_counter() const {
422  for (std::size_t i = 0; i != this->counter.size(); ++i) {
423  std::clog << this->counter[i] << " ";
424  }
425  }
426  friend class Bitmap_cubical_complex_base;
427 
428  protected:
429  std::vector<std::size_t> counter;
431  };
432 
438  return a;
439  }
440 
446  for (std::size_t i = 0; i != this->dimension(); ++i) {
447  a.counter[i] = this->sizes[i] - 1;
448  }
449  a.counter[0]++;
450  return a;
451  }
452 
457  public:
459 
461 
463 
464  private:
466  };
467 
468  Top_dimensional_cells_range top_dimensional_cells_range() { return Top_dimensional_cells_range(this); }
469 
470  //****************************************************************************************************************//
471  //****************************************************************************************************************//
472  //****************************************************************************************************************//
473  //****************************************************************************************************************//
474 
475  inline std::size_t number_cells() const { return this->total_number_of_cells; }
476 
477  //****************************************************************************************************************//
478  //****************************************************************************************************************//
479  //****************************************************************************************************************//
480  //****************************************************************************************************************//
481 
482  protected:
483  std::vector<unsigned> sizes;
484  std::vector<unsigned> multipliers;
485  std::vector<T> data;
486  std::size_t total_number_of_cells;
487 
488  void set_up_containers(const std::vector<unsigned>& sizes) {
489  unsigned multiplier = 1;
490  for (std::size_t i = 0; i != sizes.size(); ++i) {
491  this->sizes.push_back(sizes[i]);
492  this->multipliers.push_back(multiplier);
493  multiplier *= 2 * sizes[i] + 1;
494  }
495  this->data = std::vector<T>(multiplier, std::numeric_limits<T>::infinity());
496  this->total_number_of_cells = multiplier;
497  }
498 
499  std::size_t compute_position_in_bitmap(const std::vector<unsigned>& counter) {
500  std::size_t position = 0;
501  for (std::size_t i = 0; i != this->multipliers.size(); ++i) {
502  position += this->multipliers[i] * counter[i];
503  }
504  return position;
505  }
506 
507  std::vector<unsigned> compute_counter_for_given_cell(std::size_t cell) const {
508  std::vector<unsigned> counter;
509  counter.reserve(this->sizes.size());
510  for (std::size_t dim = this->sizes.size(); dim != 0; --dim) {
511  counter.push_back(cell / this->multipliers[dim - 1]);
512  cell = cell % this->multipliers[dim - 1];
513  }
514  std::reverse(counter.begin(), counter.end());
515  return counter;
516  }
517  void read_perseus_style_file(const char* perseus_style_file);
518  void setup_bitmap_based_on_top_dimensional_cells_list(const std::vector<unsigned>& sizes_in_following_directions,
519  const std::vector<T>& top_dimensional_cells);
520  Bitmap_cubical_complex_base(const char* perseus_style_file, std::vector<bool> directions);
521  Bitmap_cubical_complex_base(const std::vector<unsigned>& sizes, std::vector<bool> directions);
522  Bitmap_cubical_complex_base(const std::vector<unsigned>& dimensions, const std::vector<T>& top_dimensional_cells,
523  std::vector<bool> directions);
524 };
525 
526 template <typename T>
527 void Bitmap_cubical_complex_base<T>::put_data_to_bins(std::size_t number_of_bins) {
528  bool dbg = false;
529 
530  std::pair<T, T> min_max = this->min_max_filtration();
531  T dx = (min_max.second - min_max.first) / (T)number_of_bins;
532 
533  // now put the data into the appropriate bins:
534  for (std::size_t i = 0; i != this->data.size(); ++i) {
535  if (dbg) {
536  std::clog << "Before binning : " << this->data[i] << std::endl;
537  }
538  this->data[i] = min_max.first + dx * (this->data[i] - min_max.first) / number_of_bins;
539  if (dbg) {
540  std::clog << "After binning : " << this->data[i] << std::endl;
541  }
542  }
543 }
544 
545 template <typename T>
547  bool dbg = false;
548  std::pair<T, T> min_max = this->min_max_filtration();
549 
550  std::size_t number_of_bins = (min_max.second - min_max.first) / diameter_of_bin;
551  // now put the data into the appropriate bins:
552  for (std::size_t i = 0; i != this->data.size(); ++i) {
553  if (dbg) {
554  std::clog << "Before binning : " << this->data[i] << std::endl;
555  }
556  this->data[i] = min_max.first + diameter_of_bin * (this->data[i] - min_max.first) / number_of_bins;
557  if (dbg) {
558  std::clog << "After binning : " << this->data[i] << std::endl;
559  }
560  }
561 }
562 
563 template <typename T>
565  std::pair<T, T> min_max(std::numeric_limits<T>::infinity(), -std::numeric_limits<T>::infinity());
566  for (std::size_t i = 0; i != this->data.size(); ++i) {
567  if (this->data[i] < min_max.first) min_max.first = this->data[i];
568  if (this->data[i] > min_max.second) min_max.second = this->data[i];
569  }
570  return min_max;
571 }
572 
573 template <typename K>
574 std::ostream& operator<<(std::ostream& out, const Bitmap_cubical_complex_base<K>& b) {
575  for (typename Bitmap_cubical_complex_base<K>::all_cells_const_iterator it = b.all_cells_const_begin();
576  it != b.all_cells_const_end(); ++it) {
577  out << *it << " ";
578  }
579  return out;
580 }
581 
582 template <typename T>
584  this->set_up_containers(sizes);
585 }
586 
587 template <typename T>
589  const std::vector<unsigned>& sizes_in_following_directions, const std::vector<T>& top_dimensional_cells) {
590  this->set_up_containers(sizes_in_following_directions);
591 
592  std::size_t number_of_top_dimensional_elements = 1;
593  for (std::size_t i = 0; i != sizes_in_following_directions.size(); ++i) {
594  number_of_top_dimensional_elements *= sizes_in_following_directions[i];
595  }
596  if (number_of_top_dimensional_elements != top_dimensional_cells.size()) {
597  std::cerr << "Error in constructor Bitmap_cubical_complex_base ( std::vector<std::size_t> "
598  << "sizes_in_following_directions, std::vector<T> top_dimensional_cells ). Number of top dimensional "
599  << "elements that follow from sizes_in_following_directions vector is different than the size of "
600  << "top_dimensional_cells vector."
601  << std::endl;
602  throw(
603  "Error in constructor Bitmap_cubical_complex_base( std::vector<std::size_t> sizes_in_following_directions,"
604  "std::vector<T> top_dimensional_cells ). Number of top dimensional elements that follow from "
605  "sizes_in_following_directions vector is different than the size of top_dimensional_cells vector.");
606  }
607 
609  std::size_t index = 0;
610  for (it = this->top_dimensional_cells_iterator_begin(); it != this->top_dimensional_cells_iterator_end(); ++it) {
611  this->get_cell_data(*it) = top_dimensional_cells[index];
612  ++index;
613  }
615 }
616 
617 template <typename T>
619  if (this->get_dimension_of_a_cell(splx) == this->dimension()){return splx;}
620  else{
621  for (auto v : this->get_coboundary_of_a_cell(splx)){
622  if(this->get_cell_data(v) == this->get_cell_data(splx)){
623  return this->get_top_dimensional_coface_of_a_cell(v);
624  }
625  }
626  }
627  BOOST_UNREACHABLE_RETURN(-2);
628 }
629 
630 template <typename T>
631 Bitmap_cubical_complex_base<T>::Bitmap_cubical_complex_base(const std::vector<unsigned>& sizes_in_following_directions,
632  const std::vector<T>& top_dimensional_cells) {
633  this->setup_bitmap_based_on_top_dimensional_cells_list(sizes_in_following_directions, top_dimensional_cells);
634 }
635 
636 template <typename T>
637 void Bitmap_cubical_complex_base<T>::read_perseus_style_file(const char* perseus_style_file) {
638  bool dbg = false;
639  std::ifstream inFiltration;
640  inFiltration.open(perseus_style_file);
641  unsigned dimensionOfData;
642  inFiltration >> dimensionOfData;
643 
644  if (dbg) {
645  std::clog << "dimensionOfData : " << dimensionOfData << std::endl;
646  }
647 
648  std::vector<unsigned> sizes;
649  sizes.reserve(dimensionOfData);
650  // all dimensions multiplied
651  std::size_t dimensions = 1;
652  for (std::size_t i = 0; i != dimensionOfData; ++i) {
653  unsigned size_in_this_dimension;
654  inFiltration >> size_in_this_dimension;
655  sizes.push_back(size_in_this_dimension);
656  dimensions *= size_in_this_dimension;
657  if (dbg) {
658  std::clog << "size_in_this_dimension : " << size_in_this_dimension << std::endl;
659  }
660  }
661  this->set_up_containers(sizes);
662 
665 
666  T filtrationLevel = 0.;
667  std::size_t filtration_counter = 0;
668  while (!inFiltration.eof()) {
669  std::string line;
670  getline(inFiltration, line);
671  if (line.length() != 0) {
672  int n = sscanf(line.c_str(), "%lf", &filtrationLevel);
673  if (n != 1) {
674  std::string perseus_error("Bad Perseus file format. This line is incorrect : " + line);
675  throw std::ios_base::failure(perseus_error.c_str());
676  }
677 
678  if (dbg) {
679  std::clog << "Cell of an index : " << it.compute_index_in_bitmap()
680  << " and dimension: " << this->get_dimension_of_a_cell(it.compute_index_in_bitmap())
681  << " get the value : " << filtrationLevel << std::endl;
682  }
683  this->get_cell_data(*it) = filtrationLevel;
684  ++it;
685  ++filtration_counter;
686  }
687  }
688 
689  if (filtration_counter != dimensions) {
690  std::string perseus_error("Bad Perseus file format. Read " + std::to_string(filtration_counter) + " expected " + \
691  std::to_string(dimensions) + " values");
692  throw std::ios_base::failure(perseus_error.c_str());
693  }
694 
695  inFiltration.close();
697 }
698 
699 template <typename T>
701  std::vector<bool> directions) {
702  // this constructor is here just for compatibility with a class that creates cubical complexes with periodic boundary
703  // conditions.
704  // It ignores the last parameter of the function.
705  this->read_perseus_style_file(perseus_style_file);
706 }
707 
708 template <typename T>
709 Bitmap_cubical_complex_base<T>::Bitmap_cubical_complex_base(const std::vector<unsigned>& sizes,
710  std::vector<bool> directions) {
711  // this constructor is here just for compatibility with a class that creates cubical complexes with periodic boundary
712  // conditions.
713  // It ignores the last parameter of the function.
714  this->set_up_containers(sizes);
715 }
716 
717 template <typename T>
718 Bitmap_cubical_complex_base<T>::Bitmap_cubical_complex_base(const std::vector<unsigned>& dimensions,
719  const std::vector<T>& top_dimensional_cells,
720  std::vector<bool> directions) {
721  // this constructor is here just for compatibility with a class that creates cubical complexes with periodic boundary
722  // conditions.
723  // It ignores the last parameter of the function.
724  this->setup_bitmap_based_on_top_dimensional_cells_list(dimensions, top_dimensional_cells);
725 }
726 
727 template <typename T>
729  this->read_perseus_style_file(perseus_style_file);
730 }
731 
732 template <typename T>
733 std::vector<std::size_t> Bitmap_cubical_complex_base<T>::get_boundary_of_a_cell(std::size_t cell) const {
734  std::vector<std::size_t> boundary_elements;
735 
736  // Speed traded of for memory. Check if it is better in practice.
737  boundary_elements.reserve(this->dimension() * 2);
738 
739  std::size_t sum_of_dimensions = 0;
740  std::size_t cell1 = cell;
741  for (std::size_t i = this->multipliers.size(); i != 0; --i) {
742  unsigned position = cell1 / this->multipliers[i - 1];
743  if (position % 2 == 1) {
744  if (sum_of_dimensions % 2) {
745  boundary_elements.push_back(cell + this->multipliers[i - 1]);
746  boundary_elements.push_back(cell - this->multipliers[i - 1]);
747  } else {
748  boundary_elements.push_back(cell - this->multipliers[i - 1]);
749  boundary_elements.push_back(cell + this->multipliers[i - 1]);
750  }
751  ++sum_of_dimensions;
752  }
753  cell1 = cell1 % this->multipliers[i - 1];
754  }
755 
756  return boundary_elements;
757 }
758 
759 template <typename T>
760 std::vector<std::size_t> Bitmap_cubical_complex_base<T>::get_coboundary_of_a_cell(std::size_t cell) const {
761  std::vector<unsigned> counter = this->compute_counter_for_given_cell(cell);
762  std::vector<std::size_t> coboundary_elements;
763  std::size_t cell1 = cell;
764  for (std::size_t i = this->multipliers.size(); i != 0; --i) {
765  unsigned position = cell1 / this->multipliers[i - 1];
766  if (position % 2 == 0) {
767  if ((cell > this->multipliers[i - 1]) && (counter[i - 1] != 0)) {
768  coboundary_elements.push_back(cell - this->multipliers[i - 1]);
769  }
770  if ((cell + this->multipliers[i - 1] < this->data.size()) && (counter[i - 1] != 2 * this->sizes[i - 1])) {
771  coboundary_elements.push_back(cell + this->multipliers[i - 1]);
772  }
773  }
774  cell1 = cell1 % this->multipliers[i - 1];
775  }
776  return coboundary_elements;
777 }
778 
779 template <typename T>
781  bool dbg = false;
782  if (dbg) std::clog << "\n\n\n Computing position o a cell of an index : " << cell << std::endl;
783  unsigned dimension = 0;
784  for (std::size_t i = this->multipliers.size(); i != 0; --i) {
785  unsigned position = cell / this->multipliers[i - 1];
786 
787  if (dbg) {
788  std::clog << "i-1 :" << i - 1 << std::endl;
789  std::clog << "cell : " << cell << std::endl;
790  std::clog << "position : " << position << std::endl;
791  std::clog << "multipliers[" << i - 1 << "] = " << this->multipliers[i - 1] << std::endl;
792  }
793 
794  if (position % 2 == 1) {
795  if (dbg) std::clog << "Nonzero length in this direction \n";
796  dimension++;
797  }
798  cell = cell % this->multipliers[i - 1];
799  }
800  return dimension;
801 }
802 
803 template <typename T>
805  return this->data[cell];
806 }
807 
808 template <typename T>
810  bool dbg = false;
811 
812  // this vector will be used to check which elements have already been taken care of in imposing lower star filtration
813  std::vector<bool> is_this_cell_considered(this->data.size(), false);
814 
815  std::size_t size_to_reserve = 1;
816  for (std::size_t i = 0; i != this->multipliers.size(); ++i) {
817  size_to_reserve *= (std::size_t)((this->multipliers[i] - 1) / 2);
818  }
819 
820  std::vector<std::size_t> indices_to_consider;
821  indices_to_consider.reserve(size_to_reserve);
822  // we assume here that we already have a filtration on the top dimensional cells and
823  // we have to extend it to lower ones.
825  for (it = this->top_dimensional_cells_iterator_begin(); it != this->top_dimensional_cells_iterator_end(); ++it) {
826  indices_to_consider.push_back(it.compute_index_in_bitmap());
827  }
828 
829  while (indices_to_consider.size()) {
830  if (dbg) {
831  std::clog << "indices_to_consider in this iteration \n";
832  for (std::size_t i = 0; i != indices_to_consider.size(); ++i) {
833  std::clog << indices_to_consider[i] << " ";
834  }
835  }
836  std::vector<std::size_t> new_indices_to_consider;
837  for (std::size_t i = 0; i != indices_to_consider.size(); ++i) {
838  std::vector<std::size_t> bd = this->get_boundary_of_a_cell(indices_to_consider[i]);
839  for (std::size_t boundaryIt = 0; boundaryIt != bd.size(); ++boundaryIt) {
840  if (dbg) {
841  std::clog << "filtration of a cell : " << bd[boundaryIt] << " is : " << this->data[bd[boundaryIt]]
842  << " while of a cell: " << indices_to_consider[i] << " is: " << this->data[indices_to_consider[i]]
843  << std::endl;
844  }
845  if (this->data[bd[boundaryIt]] > this->data[indices_to_consider[i]]) {
846  this->data[bd[boundaryIt]] = this->data[indices_to_consider[i]];
847  if (dbg) {
848  std::clog << "Setting the value of a cell : " << bd[boundaryIt]
849  << " to : " << this->data[indices_to_consider[i]] << std::endl;
850  }
851  }
852  if (is_this_cell_considered[bd[boundaryIt]] == false) {
853  new_indices_to_consider.push_back(bd[boundaryIt]);
854  is_this_cell_considered[bd[boundaryIt]] = true;
855  }
856  }
857  }
858  indices_to_consider.swap(new_indices_to_consider);
859  }
860 }
861 
862 template <typename T>
863 bool compareFirstElementsOfTuples(const std::pair<std::pair<T, std::size_t>, char>& first,
864  const std::pair<std::pair<T, std::size_t>, char>& second) {
865  if (first.first.first < second.first.first) {
866  return true;
867  } else {
868  if (first.first.first > second.first.first) {
869  return false;
870  }
871  // in this case first.first.first == second.first.first, so we need to compare dimensions
872  return first.second < second.second;
873  }
874 }
875 
876 } // namespace cubical_complex
877 
878 namespace Cubical_complex = cubical_complex;
879 
880 } // namespace Gudhi
881 
882 #endif // BITMAP_CUBICAL_COMPLEX_BASE_H_
void impose_lower_star_filtration()
Definition: Bitmap_cubical_complex_base.h:809
unsigned dimension() const
Definition: Bitmap_cubical_complex_base.h:207
void put_data_to_bins(std::size_t number_of_bins)
Definition: Bitmap_cubical_complex_base.h:527
T & get_cell_data(std::size_t cell)
Definition: Bitmap_cubical_complex_base.h:804
Boundary_range boundary_range(std::size_t sh)
Definition: Bitmap_cubical_complex_base.h:340
Cubical complex represented as a bitmap, class with basic implementation.
Definition: Bitmap_cubical_complex_base.h:53
virtual ~Bitmap_cubical_complex_base()
Definition: Bitmap_cubical_complex_base.h:84
unsigned get_dimension_of_a_cell(std::size_t cell) const
Definition: Bitmap_cubical_complex_base.h:780
All_cells_iterator all_cells_iterator_begin()
Definition: Bitmap_cubical_complex_base.h:299
Definition: SimplicialComplexForAlpha.h:14
virtual int compute_incidence_between_cells(std::size_t coface, std::size_t face) const
Definition: Bitmap_cubical_complex_base.h:143
This is an implementation of a counter being a vector of integers.
Definition: counter.h:32
Bitmap_cubical_complex_base()
Definition: Bitmap_cubical_complex_base.h:60
std::size_t size() const
Definition: Bitmap_cubical_complex_base.h:212
Top_dimensional_cells_iterator top_dimensional_cells_iterator_end()
Definition: Bitmap_cubical_complex_base.h:444
Top_dimensional_cells_iterator top_dimensional_cells_iterator_begin()
Definition: Bitmap_cubical_complex_base.h:436
Top_dimensional_cells_iterator_range class provides ranges for Top_dimensional_cells_iterator_range.
Definition: Bitmap_cubical_complex_base.h:456
Coboundary_range coboundary_range(std::size_t sh)
Definition: Bitmap_cubical_complex_base.h:352
All_cells_iterator all_cells_iterator_end()
Definition: Bitmap_cubical_complex_base.h:307
std::vector< std::size_t >::const_iterator Coboundary_iterator
Definition: Bitmap_cubical_complex_base.h:345
Iterator through all cells in the complex (in order they appear in the structure – i...
Definition: Bitmap_cubical_complex_base.h:254
std::pair< T, T > min_max_filtration()
Definition: Bitmap_cubical_complex_base.h:564
All_cells_range class provides ranges for All_cells_iterator.
Definition: Bitmap_cubical_complex_base.h:316
std::vector< std::size_t >::const_iterator Boundary_iterator
Definition: Bitmap_cubical_complex_base.h:333
virtual std::vector< std::size_t > get_coboundary_of_a_cell(std::size_t cell) const
Definition: Bitmap_cubical_complex_base.h:760
Iterator through top dimensional cells of the complex. The cells appear in order they are stored in t...
Definition: Bitmap_cubical_complex_base.h:358
size_t get_top_dimensional_coface_of_a_cell(size_t splx)
Definition: Bitmap_cubical_complex_base.h:618
virtual std::vector< std::size_t > get_boundary_of_a_cell(std::size_t cell) const
Definition: Bitmap_cubical_complex_base.h:733
GUDHI  Version 3.3.0  - C++ library for Topological Data Analysis (TDA) and Higher Dimensional Geometry Understanding.  - Copyright : MIT Generated on Tue Aug 11 2020 11:09:13 for GUDHI by Doxygen 1.8.13