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