11#ifndef BITMAP_CUBICAL_COMPLEX_BASE_H_ 
   12#define BITMAP_CUBICAL_COMPLEX_BASE_H_ 
   14#include <gudhi/Bitmap_cubical_complex/counter.h> 
   16#include <boost/config.hpp> 
   31namespace cubical_complex {
 
   55  typedef T filtration_type;
 
  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);
 
  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;
 
  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.");
 
  161        number_of_position_in_which_counters_do_not_agree = i;
 
  166    if (number_of_full_faces_that_comes_before % 2) incidence = -1;
 
  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]) {
 
  207  inline unsigned dimension()
 const { 
return sizes.size(); }
 
  212  inline std::size_t 
size()
 const { 
return this->data.size(); }
 
  218  template <
typename K>
 
  256    typedef std::input_iterator_tag iterator_category;
 
  257    typedef std::size_t value_type;
 
  258    typedef std::ptrdiff_t difference_type;
 
  259    typedef value_type* pointer;
 
  260    typedef value_type reference;
 
  282      if (this->
counter != rhs.counter) 
return false;
 
  295    std::size_t operator*() { 
return this->
counter; }
 
  315    a.counter = this->data.size();
 
  340  typedef typename std::vector<std::size_t> Boundary_range;
 
  352  typedef typename std::vector<std::size_t> Coboundary_range;
 
  366    typedef std::input_iterator_tag iterator_category;
 
  367    typedef std::size_t value_type;
 
  368    typedef std::ptrdiff_t difference_type;
 
  369    typedef value_type* pointer;
 
  370    typedef value_type reference;
 
  380      while ((dim != this->b.
dimension()) && (this->counter[dim] == this->b.sizes[dim] - 1)) ++dim;
 
  384        for (std::size_t i = 0; i != dim; ++i) {
 
  406      if (&this->b != &rhs.b) 
return false;
 
  407      if (this->
counter.size() != rhs.counter.size()) 
return false;
 
  408      for (std::size_t i = 0; i != this->
counter.size(); ++i) {
 
  409        if (this->
counter[i] != rhs.counter[i]) 
return false;
 
  423    std::size_t operator*() { 
return this->compute_index_in_bitmap(); }
 
  425    std::size_t compute_index_in_bitmap()
 const {
 
  426      std::size_t index = 0;
 
  427      for (std::size_t i = 0; i != this->
counter.size(); ++i) {
 
  428        index += (2 * this->
counter[i] + 1) * this->b.multipliers[i];
 
  433    void print_counter()
 const {
 
  434      for (std::size_t i = 0; i != this->
counter.size(); ++i) {
 
  435        std::clog << this->
counter[i] << 
" ";
 
  441    std::vector<std::size_t> 
counter;
 
  458    for (std::size_t i = 0; i != this->
dimension(); ++i) {
 
  459      a.counter[i] = this->sizes[i] - 1;
 
  487  inline std::size_t number_cells()
 const { 
return this->total_number_of_cells; }
 
  495  std::vector<unsigned> sizes;
 
  496  std::vector<unsigned> multipliers;
 
  498  std::size_t total_number_of_cells;
 
  500  void set_up_containers(
const std::vector<unsigned>& sizes) {
 
  501    unsigned multiplier = 1;
 
  502    for (std::size_t i = 0; i != sizes.size(); ++i) {
 
  503      this->sizes.push_back(sizes[i]);
 
  504      this->multipliers.push_back(multiplier);
 
  505      multiplier *= 2 * sizes[i] + 1;
 
  507    this->data = std::vector<T>(multiplier, std::numeric_limits<T>::infinity());
 
  508    this->total_number_of_cells = multiplier;
 
  511  std::size_t compute_position_in_bitmap(
const std::vector<unsigned>& counter) {
 
  512    std::size_t position = 0;
 
  513    for (std::size_t i = 0; i != this->multipliers.size(); ++i) {
 
  514      position += this->multipliers[i] * counter[i];
 
  519  std::vector<unsigned> compute_counter_for_given_cell(std::size_t cell)
 const {
 
  520    std::vector<unsigned> counter;
 
  521    counter.reserve(this->sizes.size());
 
  522    for (std::size_t dim = this->sizes.size(); dim != 0; --dim) {
 
  523      counter.push_back(cell / this->multipliers[dim - 1]);
 
  524      cell = cell % this->multipliers[dim - 1];
 
  526    std::reverse(counter.begin(), counter.end());
 
  529  void read_perseus_style_file(
const char* perseus_style_file);
 
  530  void setup_bitmap_based_on_top_dimensional_cells_list(
const std::vector<unsigned>& sizes_in_following_directions,
 
  531                                                        const std::vector<T>& top_dimensional_cells);
 
  535                              std::vector<bool> directions);
 
  542  std::pair<T, T> min_max = this->min_max_filtration();
 
  543  T dx = (min_max.second - min_max.first) / (T)number_of_bins;
 
  546  for (std::size_t i = 0; i != this->data.size(); ++i) {
 
  548      std::clog << 
"Before binning : " << this->data[i] << std::endl;
 
  550    this->data[i] = min_max.first + dx * (this->data[i] - min_max.first) / number_of_bins;
 
  552      std::clog << 
"After binning : " << this->data[i] << std::endl;
 
  560  std::pair<T, T> min_max = this->min_max_filtration();
 
  562  std::size_t number_of_bins = (min_max.second - min_max.first) / diameter_of_bin;
 
  564  for (std::size_t i = 0; i != this->data.size(); ++i) {
 
  566      std::clog << 
"Before binning : " << this->data[i] << std::endl;
 
  568    this->data[i] = min_max.first + diameter_of_bin * (this->data[i] - min_max.first) / number_of_bins;
 
  570      std::clog << 
"After binning : " << this->data[i] << std::endl;
 
  577  std::pair<T, T> min_max(std::numeric_limits<T>::infinity(), -std::numeric_limits<T>::infinity());
 
  578  for (std::size_t i = 0; i != this->data.size(); ++i) {
 
  579    if (this->data[i] < min_max.first) min_max.first = this->data[i];
 
  580    if (this->data[i] > min_max.second) min_max.second = this->data[i];
 
  588       it != b.all_cells_const_end(); ++it) {
 
  596  this->set_up_containers(sizes);
 
  601    const std::vector<unsigned>& sizes_in_following_directions, 
const std::vector<T>& top_dimensional_cells) {
 
  602  this->set_up_containers(sizes_in_following_directions);
 
  604  std::size_t number_of_top_dimensional_elements = 1;
 
  605  for (std::size_t i = 0; i != sizes_in_following_directions.size(); ++i) {
 
  606    number_of_top_dimensional_elements *= sizes_in_following_directions[i];
 
  608  if (number_of_top_dimensional_elements != top_dimensional_cells.size()) {
 
  609    std::cerr << 
"Error in constructor Bitmap_cubical_complex_base ( std::vector<std::size_t> " 
  610              << 
"sizes_in_following_directions, std::vector<T> top_dimensional_cells ). Number of top dimensional " 
  611              << 
"elements that follow from sizes_in_following_directions vector is different than the size of " 
  612              << 
"top_dimensional_cells vector." 
  615        "Error in constructor Bitmap_cubical_complex_base( std::vector<std::size_t> sizes_in_following_directions," 
  616        "std::vector<T> top_dimensional_cells ). Number of top dimensional elements that follow from " 
  617        "sizes_in_following_directions vector is different than the size of top_dimensional_cells vector.");
 
  620  Bitmap_cubical_complex_base<T>::Top_dimensional_cells_iterator it(*
this);
 
  621  std::size_t index = 0;
 
  622  for (it = this->top_dimensional_cells_iterator_begin(); it != this->top_dimensional_cells_iterator_end(); ++it) {
 
  623    this->get_cell_data(*it) = top_dimensional_cells[index];
 
  626  this->impose_lower_star_filtration();
 
  631  if (this->get_dimension_of_a_cell(splx) == this->dimension()){
return splx;}
 
  633    for (
auto v : this->get_coboundary_of_a_cell(splx)){
 
  634      if(this->get_cell_data(v) == this->get_cell_data(splx)){
 
  635        return this->get_top_dimensional_coface_of_a_cell(v);
 
  639  BOOST_UNREACHABLE_RETURN(-2);
 
  644                                                            const std::vector<T>& top_dimensional_cells) {
 
  645  this->setup_bitmap_based_on_top_dimensional_cells_list(sizes_in_following_directions, top_dimensional_cells);
 
  651  std::ifstream inFiltration;
 
  652  inFiltration.open(perseus_style_file);
 
  653  unsigned dimensionOfData;
 
  654  inFiltration >> dimensionOfData;
 
  657    std::clog << 
"dimensionOfData : " << dimensionOfData << std::endl;
 
  660  std::vector<unsigned> sizes;
 
  661  sizes.reserve(dimensionOfData);
 
  663  std::size_t dimensions = 1;
 
  664  for (std::size_t i = 0; i != dimensionOfData; ++i) {
 
  665    unsigned size_in_this_dimension;
 
  666    inFiltration >> size_in_this_dimension;
 
  667    sizes.push_back(size_in_this_dimension);
 
  668    dimensions *= size_in_this_dimension;
 
  670      std::clog << 
"size_in_this_dimension : " << size_in_this_dimension << std::endl;
 
  673  this->set_up_containers(sizes);
 
  675  Bitmap_cubical_complex_base<T>::Top_dimensional_cells_iterator it(*
this);
 
  676  it = this->top_dimensional_cells_iterator_begin();
 
  678  T filtrationLevel = 0.;
 
  679  std::size_t filtration_counter = 0;
 
  680  while (!inFiltration.eof()) {
 
  682    getline(inFiltration, line);
 
  683    if (line.length() != 0) {
 
  684      int n = sscanf(line.c_str(), 
"%lf", &filtrationLevel);
 
  686        std::string perseus_error(
"Bad Perseus file format. This line is incorrect : " + line);
 
  687        throw std::ios_base::failure(perseus_error.c_str());
 
  691        std::clog << 
"Cell of an index : " << it.compute_index_in_bitmap()
 
  692                  << 
" and dimension: " << this->get_dimension_of_a_cell(it.compute_index_in_bitmap())
 
  693                  << 
" get the value : " << filtrationLevel << std::endl;
 
  695      this->get_cell_data(*it) = filtrationLevel;
 
  697      ++filtration_counter;
 
  701  if (filtration_counter != dimensions) {
 
  702    std::string perseus_error(
"Bad Perseus file format. Read " + std::to_string(filtration_counter) + 
" expected " + \
 
  703      std::to_string(dimensions) + 
" values");
 
  704    throw std::ios_base::failure(perseus_error.c_str());
 
  707  inFiltration.close();
 
  708  this->impose_lower_star_filtration();
 
  713                                                            std::vector<bool> directions) {
 
  717  this->read_perseus_style_file(perseus_style_file);
 
  722                                                            std::vector<bool> directions) {
 
  726  this->set_up_containers(sizes);
 
  731                                                            const std::vector<T>& top_dimensional_cells,
 
  732                                                            std::vector<bool> directions) {
 
  736  this->setup_bitmap_based_on_top_dimensional_cells_list(dimensions, top_dimensional_cells);
 
  741  this->read_perseus_style_file(perseus_style_file);
 
  746  std::vector<std::size_t> boundary_elements;
 
  749  boundary_elements.reserve(this->dimension() * 2);
 
  751  std::size_t sum_of_dimensions = 0;
 
  752  std::size_t cell1 = cell;
 
  753  for (std::size_t i = this->multipliers.size(); i != 0; --i) {
 
  754    unsigned position = cell1 / this->multipliers[i - 1];
 
  755    if (position % 2 == 1) {
 
  756      if (sum_of_dimensions % 2) {
 
  757        boundary_elements.push_back(cell + this->multipliers[i - 1]);
 
  758        boundary_elements.push_back(cell - this->multipliers[i - 1]);
 
  760        boundary_elements.push_back(cell - this->multipliers[i - 1]);
 
  761        boundary_elements.push_back(cell + this->multipliers[i - 1]);
 
  765    cell1 = cell1 % this->multipliers[i - 1];
 
  768  return boundary_elements;
 
  773  std::vector<unsigned> 
counter = this->compute_counter_for_given_cell(cell);
 
  774  std::vector<std::size_t> coboundary_elements;
 
  775  std::size_t cell1 = cell;
 
  776  for (std::size_t i = this->multipliers.size(); i != 0; --i) {
 
  777    unsigned position = cell1 / this->multipliers[i - 1];
 
  778    if (position % 2 == 0) {
 
  779      if ((cell > this->multipliers[i - 1]) && (
counter[i - 1] != 0)) {
 
  780        coboundary_elements.push_back(cell - this->multipliers[i - 1]);
 
  782      if ((cell + this->multipliers[i - 1] < this->data.size()) && (
counter[i - 1] != 2 * this->sizes[i - 1])) {
 
  783        coboundary_elements.push_back(cell + this->multipliers[i - 1]);
 
  786    cell1 = cell1 % this->multipliers[i - 1];
 
  788  return coboundary_elements;
 
  794  if (dbg) std::clog << 
"\n\n\n Computing position o a cell of an index : " << cell << std::endl;
 
  795  unsigned dimension = 0;
 
  796  for (std::size_t i = this->multipliers.size(); i != 0; --i) {
 
  797    unsigned position = cell / this->multipliers[i - 1];
 
  800      std::clog << 
"i-1 :" << i - 1 << std::endl;
 
  801      std::clog << 
"cell : " << cell << std::endl;
 
  802      std::clog << 
"position : " << position << std::endl;
 
  803      std::clog << 
"multipliers[" << i - 1 << 
"] = " << this->multipliers[i - 1] << std::endl;
 
  806    if (position % 2 == 1) {
 
  807      if (dbg) std::clog << 
"Nonzero length in this direction \n";
 
  810    cell = cell % this->multipliers[i - 1];
 
  817  return this->data[cell];
 
  825  std::vector<bool> is_this_cell_considered(this->data.size(), 
false);
 
  827  std::size_t size_to_reserve = 1;
 
  828  for (std::size_t i = 0; i != this->multipliers.size(); ++i) {
 
  829    size_to_reserve *= (std::size_t)((this->multipliers[i] - 1) / 2);
 
  832  std::vector<std::size_t> indices_to_consider;
 
  833  indices_to_consider.reserve(size_to_reserve);
 
  837  for (it = this->top_dimensional_cells_iterator_begin(); it != this->top_dimensional_cells_iterator_end(); ++it) {
 
  838    indices_to_consider.push_back(it.compute_index_in_bitmap());
 
  841  while (indices_to_consider.size()) {
 
  843      std::clog << 
"indices_to_consider in this iteration \n";
 
  844      for (std::size_t i = 0; i != indices_to_consider.size(); ++i) {
 
  845        std::clog << indices_to_consider[i] << 
"  ";
 
  848    std::vector<std::size_t> new_indices_to_consider;
 
  849    for (std::size_t i = 0; i != indices_to_consider.size(); ++i) {
 
  850      std::vector<std::size_t> bd = this->get_boundary_of_a_cell(indices_to_consider[i]);
 
  851      for (std::size_t boundaryIt = 0; boundaryIt != bd.size(); ++boundaryIt) {
 
  853          std::clog << 
"filtration of a cell : " << bd[boundaryIt] << 
" is : " << this->data[bd[boundaryIt]]
 
  854                    << 
" while of a cell: " << indices_to_consider[i] << 
" is: " << this->data[indices_to_consider[i]]
 
  857        if (this->data[bd[boundaryIt]] > this->data[indices_to_consider[i]]) {
 
  858          this->data[bd[boundaryIt]] = this->data[indices_to_consider[i]];
 
  860            std::clog << 
"Setting the value of a cell : " << bd[boundaryIt]
 
  861                      << 
" to : " << this->data[indices_to_consider[i]] << std::endl;
 
  864        if (is_this_cell_considered[bd[boundaryIt]] == 
false) {
 
  865          new_indices_to_consider.push_back(bd[boundaryIt]);
 
  866          is_this_cell_considered[bd[boundaryIt]] = 
true;
 
  870    indices_to_consider.swap(new_indices_to_consider);
 
  875bool compareFirstElementsOfTuples(
const std::pair<std::pair<T, std::size_t>, 
char>& first,
 
  876                                  const std::pair<std::pair<T, std::size_t>, 
char>& second) {
 
  877  if (first.first.first < second.first.first) {
 
  880    if (first.first.first > second.first.first) {
 
  884    return first.second < second.second;
 
  890namespace Cubical_complex = cubical_complex;
 
Iterator through all cells in the complex (in order they appear in the structure – i....
Definition: Bitmap_cubical_complex_base.h:254
All_cells_range class provides ranges for All_cells_iterator.
Definition: Bitmap_cubical_complex_base.h:322
Iterator through top dimensional cells of the complex. The cells appear in order they are stored in t...
Definition: Bitmap_cubical_complex_base.h:364
Top_dimensional_cells_iterator_range class provides ranges for Top_dimensional_cells_iterator_range.
Definition: Bitmap_cubical_complex_base.h:468
Cubical complex represented as a bitmap, class with basic implementation.
Definition: Bitmap_cubical_complex_base.h:53
All_cells_iterator all_cells_iterator_end()
Definition: Bitmap_cubical_complex_base.h:313
std::vector< std::size_t >::const_iterator Coboundary_iterator
Definition: Bitmap_cubical_complex_base.h:351
Bitmap_cubical_complex_base()
Definition: Bitmap_cubical_complex_base.h:60
void put_data_to_bins(std::size_t number_of_bins)
Definition: Bitmap_cubical_complex_base.h:539
void impose_lower_star_filtration()
Definition: Bitmap_cubical_complex_base.h:821
std::size_t size() const
Definition: Bitmap_cubical_complex_base.h:212
All_cells_iterator all_cells_iterator_begin()
Definition: Bitmap_cubical_complex_base.h:305
virtual std::vector< std::size_t > get_coboundary_of_a_cell(std::size_t cell) const
Definition: Bitmap_cubical_complex_base.h:772
unsigned get_dimension_of_a_cell(std::size_t cell) const
Definition: Bitmap_cubical_complex_base.h:792
unsigned dimension() const
Definition: Bitmap_cubical_complex_base.h:207
Top_dimensional_cells_iterator top_dimensional_cells_iterator_begin()
Definition: Bitmap_cubical_complex_base.h:448
friend std::ostream & operator<<(std::ostream &os, const Bitmap_cubical_complex_base< K > &b)
Definition: Bitmap_cubical_complex_base.h:586
virtual std::vector< std::size_t > get_boundary_of_a_cell(std::size_t cell) const
Definition: Bitmap_cubical_complex_base.h:745
Coboundary_range coboundary_range(std::size_t sh)
Definition: Bitmap_cubical_complex_base.h:358
std::pair< T, T > min_max_filtration()
Definition: Bitmap_cubical_complex_base.h:576
Top_dimensional_cells_iterator top_dimensional_cells_iterator_end()
Definition: Bitmap_cubical_complex_base.h:456
std::vector< std::size_t >::const_iterator Boundary_iterator
Definition: Bitmap_cubical_complex_base.h:339
size_t get_top_dimensional_coface_of_a_cell(size_t splx)
Definition: Bitmap_cubical_complex_base.h:630
T & get_cell_data(std::size_t cell)
Definition: Bitmap_cubical_complex_base.h:816
Boundary_range boundary_range(std::size_t sh)
Definition: Bitmap_cubical_complex_base.h:346
virtual int compute_incidence_between_cells(std::size_t coface, std::size_t face) const
Definition: Bitmap_cubical_complex_base.h:143
virtual ~Bitmap_cubical_complex_base()
Definition: Bitmap_cubical_complex_base.h:84
This is an implementation of a counter being a vector of integers.
Definition: counter.h:32