Bitmap_cubical_complex_base.h
1 /* This file is part of the Gudhi Library. The Gudhi library
2  * (Geometric Understanding in Higher Dimensions) is a generic C++
3  * library for computational topology.
4  *
5  * Author(s): Pawel Dlotko
6  *
7  * Copyright (C) 2015 Inria
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 #ifndef BITMAP_CUBICAL_COMPLEX_BASE_H_
24 #define BITMAP_CUBICAL_COMPLEX_BASE_H_
25 
26 #include <gudhi/Bitmap_cubical_complex/counter.h>
27 
28 #include <iostream>
29 #include <vector>
30 #include <string>
31 #include <fstream>
32 #include <algorithm>
33 #include <iterator>
34 #include <limits>
35 #include <utility>
36 #include <stdexcept>
37 #include <cstddef>
38 
39 namespace Gudhi {
40 
41 namespace cubical_complex {
42 
62 template <typename T>
64  public:
65  typedef T filtration_type;
66 
70  Bitmap_cubical_complex_base() : total_number_of_cells(0) {}
77  Bitmap_cubical_complex_base(const std::vector<unsigned>& sizes);
84  Bitmap_cubical_complex_base(const char* perseus_style_file);
89  Bitmap_cubical_complex_base(const std::vector<unsigned>& dimensions, const std::vector<T>& top_dimensional_cells);
90 
95 
107  virtual inline std::vector<std::size_t> get_boundary_of_a_cell(std::size_t cell) const;
122  virtual inline std::vector<std::size_t> get_coboundary_of_a_cell(std::size_t cell) const;
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::cout << "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 unsigned 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::cout << 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::cerr << "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::cerr << "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::cerr << "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::cerr << "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>
618 Bitmap_cubical_complex_base<T>::Bitmap_cubical_complex_base(const std::vector<unsigned>& sizes_in_following_directions,
619  const std::vector<T>& top_dimensional_cells) {
620  this->setup_bitmap_based_on_top_dimensional_cells_list(sizes_in_following_directions, top_dimensional_cells);
621 }
622 
623 template <typename T>
624 void Bitmap_cubical_complex_base<T>::read_perseus_style_file(const char* perseus_style_file) {
625  bool dbg = false;
626  std::ifstream inFiltration;
627  inFiltration.open(perseus_style_file);
628  unsigned dimensionOfData;
629  inFiltration >> dimensionOfData;
630 
631  if (dbg) {
632  std::cerr << "dimensionOfData : " << dimensionOfData << std::endl;
633  }
634 
635  std::vector<unsigned> sizes;
636  sizes.reserve(dimensionOfData);
637  // all dimensions multiplied
638  std::size_t dimensions = 1;
639  for (std::size_t i = 0; i != dimensionOfData; ++i) {
640  unsigned size_in_this_dimension;
641  inFiltration >> size_in_this_dimension;
642  sizes.push_back(size_in_this_dimension);
643  dimensions *= size_in_this_dimension;
644  if (dbg) {
645  std::cerr << "size_in_this_dimension : " << size_in_this_dimension << std::endl;
646  }
647  }
648  this->set_up_containers(sizes);
649 
652 
653  T filtrationLevel;
654  for (std::size_t i = 0; i < dimensions; ++i) {
655  if (!(inFiltration >> filtrationLevel) || (inFiltration.eof())) {
656  throw std::ios_base::failure("Bad Perseus file format.");
657  }
658  if (dbg) {
659  std::cerr << "Cell of an index : " << it.compute_index_in_bitmap()
660  << " and dimension: " << this->get_dimension_of_a_cell(it.compute_index_in_bitmap())
661  << " get the value : " << filtrationLevel << std::endl;
662  }
663  this->get_cell_data(*it) = filtrationLevel;
664  ++it;
665  }
666 
667  inFiltration.close();
669 }
670 
671 template <typename T>
673  std::vector<bool> directions) {
674  // this constructor is here just for compatibility with a class that creates cubical complexes with periodic boundary
675  // conditions.
676  // It ignores the last parameter of the function.
677  this->read_perseus_style_file(perseus_style_file);
678 }
679 
680 template <typename T>
681 Bitmap_cubical_complex_base<T>::Bitmap_cubical_complex_base(const std::vector<unsigned>& sizes,
682  std::vector<bool> directions) {
683  // this constructor is here just for compatibility with a class that creates cubical complexes with periodic boundary
684  // conditions.
685  // It ignores the last parameter of the function.
686  this->set_up_containers(sizes);
687 }
688 
689 template <typename T>
690 Bitmap_cubical_complex_base<T>::Bitmap_cubical_complex_base(const std::vector<unsigned>& dimensions,
691  const std::vector<T>& top_dimensional_cells,
692  std::vector<bool> directions) {
693  // this constructor is here just for compatibility with a class that creates cubical complexes with periodic boundary
694  // conditions.
695  // It ignores the last parameter of the function.
696  this->setup_bitmap_based_on_top_dimensional_cells_list(dimensions, top_dimensional_cells);
697 }
698 
699 template <typename T>
701  this->read_perseus_style_file(perseus_style_file);
702 }
703 
704 template <typename T>
705 std::vector<std::size_t> Bitmap_cubical_complex_base<T>::get_boundary_of_a_cell(std::size_t cell) const {
706  std::vector<std::size_t> boundary_elements;
707 
708  // Speed traded of for memory. Check if it is better in practice.
709  boundary_elements.reserve(this->dimension() * 2);
710 
711  std::size_t sum_of_dimensions = 0;
712  std::size_t cell1 = cell;
713  for (std::size_t i = this->multipliers.size(); i != 0; --i) {
714  unsigned position = cell1 / this->multipliers[i - 1];
715  if (position % 2 == 1) {
716  if (sum_of_dimensions % 2) {
717  boundary_elements.push_back(cell + this->multipliers[i - 1]);
718  boundary_elements.push_back(cell - this->multipliers[i - 1]);
719  } else {
720  boundary_elements.push_back(cell - this->multipliers[i - 1]);
721  boundary_elements.push_back(cell + this->multipliers[i - 1]);
722  }
723  ++sum_of_dimensions;
724  }
725  cell1 = cell1 % this->multipliers[i - 1];
726  }
727 
728  return boundary_elements;
729 }
730 
731 template <typename T>
732 std::vector<std::size_t> Bitmap_cubical_complex_base<T>::get_coboundary_of_a_cell(std::size_t cell) const {
733  std::vector<unsigned> counter = this->compute_counter_for_given_cell(cell);
734  std::vector<std::size_t> coboundary_elements;
735  std::size_t cell1 = cell;
736  for (std::size_t i = this->multipliers.size(); i != 0; --i) {
737  unsigned position = cell1 / this->multipliers[i - 1];
738  if (position % 2 == 0) {
739  if ((cell > this->multipliers[i - 1]) && (counter[i - 1] != 0)) {
740  coboundary_elements.push_back(cell - this->multipliers[i - 1]);
741  }
742  if ((cell + this->multipliers[i - 1] < this->data.size()) && (counter[i - 1] != 2 * this->sizes[i - 1])) {
743  coboundary_elements.push_back(cell + this->multipliers[i - 1]);
744  }
745  }
746  cell1 = cell1 % this->multipliers[i - 1];
747  }
748  return coboundary_elements;
749 }
750 
751 template <typename T>
753  bool dbg = false;
754  if (dbg) std::cerr << "\n\n\n Computing position o a cell of an index : " << cell << std::endl;
755  unsigned dimension = 0;
756  for (std::size_t i = this->multipliers.size(); i != 0; --i) {
757  unsigned position = cell / this->multipliers[i - 1];
758 
759  if (dbg) {
760  std::cerr << "i-1 :" << i - 1 << std::endl;
761  std::cerr << "cell : " << cell << std::endl;
762  std::cerr << "position : " << position << std::endl;
763  std::cerr << "multipliers[" << i - 1 << "] = " << this->multipliers[i - 1] << std::endl;
764  }
765 
766  if (position % 2 == 1) {
767  if (dbg) std::cerr << "Nonzero length in this direction \n";
768  dimension++;
769  }
770  cell = cell % this->multipliers[i - 1];
771  }
772  return dimension;
773 }
774 
775 template <typename T>
777  return this->data[cell];
778 }
779 
780 template <typename T>
782  bool dbg = false;
783 
784  // this vector will be used to check which elements have already been taken care of in imposing lower star filtration
785  std::vector<bool> is_this_cell_considered(this->data.size(), false);
786 
787  std::size_t size_to_reserve = 1;
788  for (std::size_t i = 0; i != this->multipliers.size(); ++i) {
789  size_to_reserve *= (std::size_t)((this->multipliers[i] - 1) / 2);
790  }
791 
792  std::vector<std::size_t> indices_to_consider;
793  indices_to_consider.reserve(size_to_reserve);
794  // we assume here that we already have a filtration on the top dimensional cells and
795  // we have to extend it to lower ones.
797  for (it = this->top_dimensional_cells_iterator_begin(); it != this->top_dimensional_cells_iterator_end(); ++it) {
798  indices_to_consider.push_back(it.compute_index_in_bitmap());
799  }
800 
801  while (indices_to_consider.size()) {
802  if (dbg) {
803  std::cerr << "indices_to_consider in this iteration \n";
804  for (std::size_t i = 0; i != indices_to_consider.size(); ++i) {
805  std::cout << indices_to_consider[i] << " ";
806  }
807  }
808  std::vector<std::size_t> new_indices_to_consider;
809  for (std::size_t i = 0; i != indices_to_consider.size(); ++i) {
810  std::vector<std::size_t> bd = this->get_boundary_of_a_cell(indices_to_consider[i]);
811  for (std::size_t boundaryIt = 0; boundaryIt != bd.size(); ++boundaryIt) {
812  if (dbg) {
813  std::cerr << "filtration of a cell : " << bd[boundaryIt] << " is : " << this->data[bd[boundaryIt]]
814  << " while of a cell: " << indices_to_consider[i] << " is: " << this->data[indices_to_consider[i]]
815  << std::endl;
816  }
817  if (this->data[bd[boundaryIt]] > this->data[indices_to_consider[i]]) {
818  this->data[bd[boundaryIt]] = this->data[indices_to_consider[i]];
819  if (dbg) {
820  std::cerr << "Setting the value of a cell : " << bd[boundaryIt]
821  << " to : " << this->data[indices_to_consider[i]] << std::endl;
822  }
823  }
824  if (is_this_cell_considered[bd[boundaryIt]] == false) {
825  new_indices_to_consider.push_back(bd[boundaryIt]);
826  is_this_cell_considered[bd[boundaryIt]] = true;
827  }
828  }
829  }
830  indices_to_consider.swap(new_indices_to_consider);
831  }
832 }
833 
834 template <typename T>
835 bool compareFirstElementsOfTuples(const std::pair<std::pair<T, std::size_t>, char>& first,
836  const std::pair<std::pair<T, std::size_t>, char>& second) {
837  if (first.first.first < second.first.first) {
838  return true;
839  } else {
840  if (first.first.first > second.first.first) {
841  return false;
842  }
843  // in this case first.first.first == second.first.first, so we need to compare dimensions
844  return first.second < second.second;
845  }
846 }
847 
848 } // namespace cubical_complex
849 
850 namespace Cubical_complex = cubical_complex;
851 
852 } // namespace Gudhi
853 
854 #endif // BITMAP_CUBICAL_COMPLEX_BASE_H_
void impose_lower_star_filtration()
Definition: Bitmap_cubical_complex_base.h:781
unsigned size() const
Definition: Bitmap_cubical_complex_base.h:212
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:776
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:63
virtual ~Bitmap_cubical_complex_base()
Definition: Bitmap_cubical_complex_base.h:94
unsigned get_dimension_of_a_cell(std::size_t cell) const
Definition: Bitmap_cubical_complex_base.h:752
All_cells_iterator all_cells_iterator_begin()
Definition: Bitmap_cubical_complex_base.h:299
Definition: SimplicialComplexForAlpha.h:26
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:44
Bitmap_cubical_complex_base()
Definition: Bitmap_cubical_complex_base.h:70
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:732
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
virtual std::vector< std::size_t > get_boundary_of_a_cell(std::size_t cell) const
Definition: Bitmap_cubical_complex_base.h:705
GUDHI  Version 2.2.0  - C++ library for Topological Data Analysis (TDA) and Higher Dimensional Geometry Understanding.  - Copyright : GPL v3 Generated on Thu Jun 14 2018 15:00:54 for GUDHI by Doxygen 1.8.13