Bitmap_cubical_complex_periodic_boundary_conditions_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 Sophia-Saclay (France)
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_PERIODIC_BOUNDARY_CONDITIONS_BASE_H_
24 #define BITMAP_CUBICAL_COMPLEX_PERIODIC_BOUNDARY_CONDITIONS_BASE_H_
25 
26 #include <gudhi/Bitmap_cubical_complex_base.h>
27 
28 #include <cmath>
29 #include <limits> // for numeric_limits<>
30 #include <vector>
31 
32 namespace Gudhi {
33 
34 namespace cubical_complex {
35 
36 // in this class, we are storing all the elements which are in normal bitmap (i.e. the bitmap without the periodic
37 // boundary conditions). But, we set up the iterators and the procedures to compute boundary and coboundary in the way
38 // that it is all right. We assume here that all the cells that are on the left / bottom and so on remains, while all
39 // the cells on the right / top are not in the Bitmap_cubical_complex_periodic_boundary_conditions_base
40 
48 template <typename T>
50  public:
51  // constructors that take an extra parameter:
52 
64  Bitmap_cubical_complex_periodic_boundary_conditions_base(const std::vector<unsigned>& sizes,
65  const std::vector<bool>& directions_in_which_periodic_b_cond_are_to_be_imposed);
78  Bitmap_cubical_complex_periodic_boundary_conditions_base(const std::vector<unsigned>& dimensions,
79  const std::vector<T>& topDimensionalCells,
80  const std::vector< bool >& directions_in_which_periodic_b_cond_are_to_be_imposed);
81 
86 
87  // overwritten methods co compute boundary and coboundary
92  virtual std::vector< size_t > get_boundary_of_a_cell(size_t cell) const;
93 
98  virtual std::vector< size_t > get_coboundary_of_a_cell(size_t cell) const;
99 
100  protected:
101  std::vector< bool > directions_in_which_periodic_b_cond_are_to_be_imposed;
102 
103  void set_up_containers(const std::vector<unsigned>& sizes) {
104  unsigned multiplier = 1;
105  for (size_t i = 0; i != sizes.size(); ++i) {
106  this->sizes.push_back(sizes[i]);
107  this->multipliers.push_back(multiplier);
108 
109  if (directions_in_which_periodic_b_cond_are_to_be_imposed[i]) {
110  multiplier *= 2 * sizes[i];
111  } else {
112  multiplier *= 2 * sizes[i] + 1;
113  }
114  }
115  // std::reverse( this->sizes.begin() , this->sizes.end() );
116  this->data = std::vector<T>(multiplier, std::numeric_limits<T>::max());
117  this->total_number_of_cells = multiplier;
118  }
119  Bitmap_cubical_complex_periodic_boundary_conditions_base(const std::vector<unsigned>& sizes);
120  Bitmap_cubical_complex_periodic_boundary_conditions_base(const std::vector<unsigned>& dimensions,
121  const std::vector<T>& topDimensionalCells);
122  void construct_complex_based_on_top_dimensional_cells(const std::vector<unsigned>& dimensions,
123  const std::vector<T>& topDimensionalCells,
124  const std::vector<bool>& directions_in_which_periodic_b_cond_are_to_be_imposed);
125 };
126 
127 template <typename T>
129  const std::vector<T>& topDimensionalCells,
130  const std::vector<bool>& directions_in_which_periodic_b_cond_are_to_be_imposed) {
131  this->directions_in_which_periodic_b_cond_are_to_be_imposed = directions_in_which_periodic_b_cond_are_to_be_imposed;
132  this->set_up_containers(dimensions);
133 
134  size_t i = 0;
135  for (auto it = this->top_dimensional_cells_iterator_begin(); it != this->top_dimensional_cells_iterator_end(); ++it) {
136  this->get_cell_data(*it) = topDimensionalCells[i];
137  ++i;
138  }
140 }
141 
142 template <typename T>
144  const std::vector<bool>& directions_in_which_periodic_b_cond_are_to_be_imposed) {
145  this->directions_in_which_periodic_b_cond_are_to_be_imposed(directions_in_which_periodic_b_cond_are_to_be_imposed);
146  this->set_up_containers(sizes);
147 }
148 
149 template <typename T>
151  // for Perseus style files:
152  bool dbg = false;
153 
154  std::ifstream inFiltration;
155  inFiltration.open(perseus_style_file);
156  unsigned dimensionOfData;
157  inFiltration >> dimensionOfData;
158 
159  this->directions_in_which_periodic_b_cond_are_to_be_imposed = std::vector<bool>(dimensionOfData, false);
160 
161  std::vector<unsigned> sizes;
162  sizes.reserve(dimensionOfData);
163  for (size_t i = 0; i != dimensionOfData; ++i) {
164  int size_in_this_dimension;
165  inFiltration >> size_in_this_dimension;
166  if (size_in_this_dimension < 0) {
167  this->directions_in_which_periodic_b_cond_are_to_be_imposed[i] = true;
168  }
169  sizes.push_back(abs(size_in_this_dimension));
170  }
171  this->set_up_containers(sizes);
172 
175 
176  while (!inFiltration.eof()) {
177  double filtrationLevel;
178  inFiltration >> filtrationLevel;
179  if (inFiltration.eof())break;
180 
181  if (dbg) {
182  std::cerr << "Cell of an index : "
183  << it.compute_index_in_bitmap()
184  << " and dimension: "
185  << this->get_dimension_of_a_cell(it.compute_index_in_bitmap())
186  << " get the value : " << filtrationLevel << std::endl;
187  }
188  this->get_cell_data(*it) = filtrationLevel;
189  ++it;
190  }
191  inFiltration.close();
193 }
194 
195 template <typename T>
197  this->directions_in_which_periodic_b_cond_are_to_be_imposed = std::vector<bool>(sizes.size(), false);
198  this->set_up_containers(sizes);
199 }
200 
201 template <typename T>
203  const std::vector<T>& topDimensionalCells) {
204  std::vector<bool> directions_in_which_periodic_b_cond_are_to_be_imposed = std::vector<bool>(dimensions.size(), false);
205  this->construct_complex_based_on_top_dimensional_cells(dimensions, topDimensionalCells,
206  directions_in_which_periodic_b_cond_are_to_be_imposed);
207 }
208 
209 template <typename T>
211 Bitmap_cubical_complex_periodic_boundary_conditions_base(const std::vector<unsigned>& dimensions,
212  const std::vector<T>& topDimensionalCells,
213  const std::vector<bool>& directions_in_which_periodic_b_cond_are_to_be_imposed) {
214  this->construct_complex_based_on_top_dimensional_cells(dimensions, topDimensionalCells,
215  directions_in_which_periodic_b_cond_are_to_be_imposed);
216 }
217 
218 // ***********************Methods************************ //
219 
220 template <typename T>
222  bool dbg = false;
223  if (dbg) {
224  std::cerr << "Computations of boundary of a cell : " << cell << std::endl;
225  }
226 
227  std::vector< size_t > boundary_elements;
228  size_t cell1 = cell;
229  for (size_t i = this->multipliers.size(); i != 0; --i) {
230  unsigned position = cell1 / this->multipliers[i - 1];
231  // this cell have a nonzero length in this direction, therefore we can compute its boundary in this direction.
232 
233  if (position % 2 == 1) {
234  // if there are no periodic boundary conditions in this direction, we do not have to do anything.
235  if (!directions_in_which_periodic_b_cond_are_to_be_imposed[i - 1]) {
236  // std::cerr << "A\n";
237  boundary_elements.push_back(cell - this->multipliers[ i - 1 ]);
238  boundary_elements.push_back(cell + this->multipliers[ i - 1 ]);
239  if (dbg) {
240  std::cerr << cell - this->multipliers[ i - 1 ] << " " << cell + this->multipliers[ i - 1 ] << " ";
241  }
242  } else {
243  // in this direction we have to do boundary conditions. Therefore, we need to check if we are not at the end.
244  if (position != 2 * this->sizes[ i - 1 ] - 1) {
245  // std::cerr << "B\n";
246  boundary_elements.push_back(cell - this->multipliers[ i - 1 ]);
247  boundary_elements.push_back(cell + this->multipliers[ i - 1 ]);
248  if (dbg) {
249  std::cerr << cell - this->multipliers[ i - 1 ] << " " << cell + this->multipliers[ i - 1 ] << " ";
250  }
251  } else {
252  // std::cerr << "C\n";
253  boundary_elements.push_back(cell - this->multipliers[ i - 1 ]);
254  boundary_elements.push_back(cell - (2 * this->sizes[ i - 1 ] - 1) * this->multipliers[ i - 1 ]);
255  if (dbg) {
256  std::cerr << cell - this->multipliers[ i - 1 ] << " " <<
257  cell - (2 * this->sizes[ i - 1 ] - 1) * this->multipliers[ i - 1 ] << " ";
258  }
259  }
260  }
261  }
262  cell1 = cell1 % this->multipliers[i - 1];
263  }
264  return boundary_elements;
265 }
266 
267 template <typename T>
269  std::vector<unsigned> counter = this->compute_counter_for_given_cell(cell);
270  std::vector< size_t > coboundary_elements;
271  size_t cell1 = cell;
272  for (size_t i = this->multipliers.size(); i != 0; --i) {
273  unsigned position = cell1 / this->multipliers[i - 1];
274  // if the cell has zero length in this direction, then it will have cbd in this direction.
275  if (position % 2 == 0) {
276  if (!this->directions_in_which_periodic_b_cond_are_to_be_imposed[i - 1]) {
277  // no periodic boundary conditions in this direction
278  if ((counter[i - 1] != 0) && (cell > this->multipliers[i - 1])) {
279  coboundary_elements.push_back(cell - this->multipliers[i - 1]);
280  }
281  if ((counter[i - 1] != 2 * this->sizes[i - 1]) && (cell + this->multipliers[i - 1] < this->data.size())) {
282  coboundary_elements.push_back(cell + this->multipliers[i - 1]);
283  }
284  } else {
285  // we want to have periodic boundary conditions in this direction
286  if (counter[i - 1] != 0) {
287  coboundary_elements.push_back(cell - this->multipliers[i - 1]);
288  coboundary_elements.push_back(cell + this->multipliers[i - 1]);
289  } else {
290  // in this case counter[i-1] == 0.
291  coboundary_elements.push_back(cell + this->multipliers[i - 1]);
292  coboundary_elements.push_back(cell + (2 * this->sizes[ i - 1 ] - 1) * this->multipliers[i - 1]);
293  }
294  }
295  }
296 
297  cell1 = cell1 % this->multipliers[i - 1];
298  }
299  return coboundary_elements;
300 }
301 
302 } // namespace cubical_complex
303 
304 namespace Cubical_complex = cubical_complex;
305 
306 } // namespace Gudhi
307 
308 #endif // BITMAP_CUBICAL_COMPLEX_PERIODIC_BOUNDARY_CONDITIONS_BASE_H_
void impose_lower_star_filtration()
Definition: Bitmap_cubical_complex_base.h:741
Cubical complex with periodic boundary conditions represented as a bitmap.
Definition: Bitmap_cubical_complex_periodic_boundary_conditions_base.h:49
Cubical complex represented as a bitmap, class with basic implementation.
Definition: Bitmap_cubical_complex_base.h:61
Definition: SimplicialComplexForAlpha.h:26
This is an implementation of a counter being a vector of integers.
Definition: counter.h:43
Bitmap_cubical_complex_periodic_boundary_conditions_base()
Definition: Bitmap_cubical_complex_periodic_boundary_conditions_base.h:56
unsigned get_dimension_of_a_cell(size_t cell) const
Definition: Bitmap_cubical_complex_base.h:711
Top_dimensional_cells_iterator top_dimensional_cells_iterator_end()
Definition: Bitmap_cubical_complex_base.h:403
Top_dimensional_cells_iterator top_dimensional_cells_iterator_begin()
Definition: Bitmap_cubical_complex_base.h:395
virtual std::vector< size_t > get_coboundary_of_a_cell(size_t cell) const
Definition: Bitmap_cubical_complex_periodic_boundary_conditions_base.h:268
virtual ~Bitmap_cubical_complex_periodic_boundary_conditions_base()
Definition: Bitmap_cubical_complex_periodic_boundary_conditions_base.h:85
T & get_cell_data(size_t cell)
Definition: Bitmap_cubical_complex_base.h:736
virtual std::vector< size_t > get_boundary_of_a_cell(size_t cell) const
Definition: Bitmap_cubical_complex_periodic_boundary_conditions_base.h:221
Iterator through top dimensional cells of the complex. The cells appear in order they are stored in t...
Definition: Bitmap_cubical_complex_base.h:314
GUDHI  Version 2.0.1  - C++ library for Topological Data Analysis (TDA) and Higher Dimensional Geometry Understanding. Generated on Mon Oct 2 2017 10:20:49 for GUDHI by doxygen 1.8.11