summaryrefslogtreecommitdiff
path: root/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_periodic_boundary_conditions_base.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_periodic_boundary_conditions_base.h')
-rw-r--r--src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_periodic_boundary_conditions_base.h130
1 files changed, 116 insertions, 14 deletions
diff --git a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_periodic_boundary_conditions_base.h b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_periodic_boundary_conditions_base.h
index c3cc93dd..30d6bf4f 100644
--- a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_periodic_boundary_conditions_base.h
+++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_periodic_boundary_conditions_base.h
@@ -28,6 +28,7 @@
#include <cmath>
#include <limits> // for numeric_limits<>
#include <vector>
+#include <stdexcept>
namespace Gudhi {
@@ -88,14 +89,84 @@ class Bitmap_cubical_complex_periodic_boundary_conditions_base : public Bitmap_c
/**
* A version of a function that return boundary of a given cell for an object of
* Bitmap_cubical_complex_periodic_boundary_conditions_base class.
+ * The boundary elements are guaranteed to be returned so that the
+ * incidence coefficients are alternating.
*/
virtual std::vector< size_t > get_boundary_of_a_cell(size_t cell) const;
/**
* A version of a function that return coboundary of a given cell for an object of
* Bitmap_cubical_complex_periodic_boundary_conditions_base class.
+ * Note that unlike in the case of boundary, over here the elements are
+ * not guaranteed to be returned with alternating incidence numbers.
+ * To compute incidence between cells use compute_incidence_between_cells
+ * procedure
*/
virtual std::vector< size_t > get_coboundary_of_a_cell(size_t cell) const;
+
+
+ /**
+ * This procedure compute incidence numbers between cubes. For a cube \f$A\f$ of
+ * dimension n and a cube \f$B \subset A\f$ of dimension n-1, an incidence
+ * between \f$A\f$ and \f$B\f$ is the integer with which \f$B\f$ appears in the boundary of \f$A\f$.
+ * Note that first parameter is a cube of dimension n,
+ * and the second parameter is an adjusted cube in dimension n-1.
+ * Given \f$A = [b_1,e_1] \times \ldots \ [b_{j-1},e_{j-1}] \times [b_{j},e_{j}] \times [b_{j+1},e_{j+1}] \times \ldots \times [b_{n},e_{n}] \f$
+ * such that \f$ b_{j} \neq e_{j} \f$
+ * and \f$B = [b_1,e_1] \times \ldots \ [b_{j-1},e_{j-1}] \times [a,a] \times [b_{j+1},e_{j+1}] \times \ldots \times [b_{n},e_{n}]s \f$
+ * where \f$ a = b_{j}\f$ or \f$ a = e_{j}\f$, the incidence between \f$A\f$ and \f$B\f$
+ * computed by this procedure is given by formula:
+ * \f$ c\ (-1)^{\sum_{i=1}^{j-1} dim [b_{i},e_{i}]} \f$
+ * Where \f$ dim [b_{i},e_{i}] = 0 \f$ if \f$ b_{i}=e_{i} \f$ and 1 in other case.
+ * c is -1 if \f$ a = b_{j}\f$ and 1 if \f$ a = e_{j}\f$.
+ * @exception std::logic_error In case when the cube \f$B\f$ is not n-1
+ * dimensional face of a cube \f$A\f$.
+ **/
+ virtual int compute_incidence_between_cells( size_t coface , size_t face )
+ {
+ //first get the counters for coface and face:
+ std::vector<unsigned> coface_counter = this->compute_counter_for_given_cell( coface );
+ std::vector<unsigned> face_counter = this->compute_counter_for_given_cell( face );
+
+ //coface_counter and face_counter should agree at all positions except from one:
+ int number_of_position_in_which_counters_do_not_agree = -1;
+ size_t number_of_full_faces_that_comes_before = 0;
+ for ( size_t i = 0 ; i != coface_counter.size() ; ++i )
+ {
+ if ( (coface_counter[i]%2 == 1)&&(number_of_position_in_which_counters_do_not_agree==-1) )
+ {
+ ++number_of_full_faces_that_comes_before;
+ }
+ if ( coface_counter[i] != face_counter[i] )
+ {
+ if ( number_of_position_in_which_counters_do_not_agree != -1 )
+ {
+ std::cout << "Cells given to compute_incidence_between_cells procedure do not form a pair of coface-face.\n";
+ throw std::logic_error("Cells given to compute_incidence_between_cells procedure do not form a pair of coface-face.");
+ }
+ number_of_position_in_which_counters_do_not_agree = i;
+ }
+ }
+
+ int incidence = 1;
+ if ( number_of_full_faces_that_comes_before%2 )incidence = -1;
+ //if the face cell is on the right from coface cell:
+ if ( (coface_counter[number_of_position_in_which_counters_do_not_agree]+1 ==
+ face_counter[number_of_position_in_which_counters_do_not_agree])
+ ||
+ (
+ (coface_counter[number_of_position_in_which_counters_do_not_agree] != 1)
+ &&
+ (face_counter[number_of_position_in_which_counters_do_not_agree]==0)
+ )
+ )
+ {
+ incidence *= -1;
+ }
+
+ return incidence;
+ }
+
protected:
std::vector< bool > directions_in_which_periodic_b_cond_are_to_be_imposed;
@@ -119,6 +190,10 @@ class Bitmap_cubical_complex_periodic_boundary_conditions_base : public Bitmap_c
Bitmap_cubical_complex_periodic_boundary_conditions_base(const std::vector<unsigned>& sizes);
Bitmap_cubical_complex_periodic_boundary_conditions_base(const std::vector<unsigned>& dimensions,
const std::vector<T>& topDimensionalCells);
+
+ /**
+ * A procedure used to construct the data structures in the class.
+ **/
void construct_complex_based_on_top_dimensional_cells(const std::vector<unsigned>& dimensions,
const std::vector<T>& topDimensionalCells,
const std::vector<bool>& directions_in_which_periodic_b_cond_are_to_be_imposed);
@@ -222,45 +297,72 @@ std::vector< size_t > Bitmap_cubical_complex_periodic_boundary_conditions_base<T
bool dbg = false;
if (dbg) {
std::cerr << "Computations of boundary of a cell : " << cell << std::endl;
- }
+ }
std::vector< size_t > boundary_elements;
+ boundary_elements.reserve(this->dimension()*2);
size_t cell1 = cell;
+ size_t sum_of_dimensions = 0;
+
for (size_t i = this->multipliers.size(); i != 0; --i) {
unsigned position = cell1 / this->multipliers[i - 1];
// this cell have a nonzero length in this direction, therefore we can compute its boundary in this direction.
-
if (position % 2 == 1) {
// if there are no periodic boundary conditions in this direction, we do not have to do anything.
- if (!directions_in_which_periodic_b_cond_are_to_be_imposed[i - 1]) {
- // std::cerr << "A\n";
- boundary_elements.push_back(cell - this->multipliers[ i - 1 ]);
- boundary_elements.push_back(cell + this->multipliers[ i - 1 ]);
+ if (!directions_in_which_periodic_b_cond_are_to_be_imposed[i - 1]) {
+ //std::cerr << "A\n";
+ if ( sum_of_dimensions%2 )
+ {
+ boundary_elements.push_back(cell - this->multipliers[ i - 1 ]);
+ boundary_elements.push_back(cell + this->multipliers[ i - 1 ]);
+ }
+ else
+ {
+ boundary_elements.push_back(cell + this->multipliers[ i - 1 ]);
+ boundary_elements.push_back(cell - this->multipliers[ i - 1 ]);
+ }
if (dbg) {
std::cerr << cell - this->multipliers[ i - 1 ] << " " << cell + this->multipliers[ i - 1 ] << " ";
}
} else {
// in this direction we have to do boundary conditions. Therefore, we need to check if we are not at the end.
if (position != 2 * this->sizes[ i - 1 ] - 1) {
- // std::cerr << "B\n";
- boundary_elements.push_back(cell - this->multipliers[ i - 1 ]);
- boundary_elements.push_back(cell + this->multipliers[ i - 1 ]);
+ //std::cerr << "B\n";
+ if ( sum_of_dimensions%2 )
+ {
+ boundary_elements.push_back(cell - this->multipliers[ i - 1 ]);
+ boundary_elements.push_back(cell + this->multipliers[ i - 1 ]);
+ }
+ else
+ {
+ boundary_elements.push_back(cell + this->multipliers[ i - 1 ]);
+ boundary_elements.push_back(cell - this->multipliers[ i - 1 ]);
+ }
if (dbg) {
std::cerr << cell - this->multipliers[ i - 1 ] << " " << cell + this->multipliers[ i - 1 ] << " ";
}
} else {
- // std::cerr << "C\n";
- boundary_elements.push_back(cell - this->multipliers[ i - 1 ]);
- boundary_elements.push_back(cell - (2 * this->sizes[ i - 1 ] - 1) * this->multipliers[ i - 1 ]);
+ //std::cerr << "C\n";
+ if ( sum_of_dimensions%2 )
+ {
+ boundary_elements.push_back(cell - this->multipliers[ i - 1 ]);
+ boundary_elements.push_back(cell - (2 * this->sizes[ i - 1 ] - 1) * this->multipliers[ i - 1 ]);
+ }
+ else
+ {
+ boundary_elements.push_back(cell - (2 * this->sizes[ i - 1 ] - 1) * this->multipliers[ i - 1 ]);
+ boundary_elements.push_back(cell - this->multipliers[ i - 1 ]);
+ }
if (dbg) {
std::cerr << cell - this->multipliers[ i - 1 ] << " " <<
cell - (2 * this->sizes[ i - 1 ] - 1) * this->multipliers[ i - 1 ] << " ";
}
}
}
+ ++sum_of_dimensions;
}
cell1 = cell1 % this->multipliers[i - 1];
- }
+ }
return boundary_elements;
}
@@ -295,7 +397,7 @@ std::vector< size_t > Bitmap_cubical_complex_periodic_boundary_conditions_base<T
}
cell1 = cell1 % this->multipliers[i - 1];
- }
+ }
return coboundary_elements;
}