diff options
author | vrouvrea <vrouvrea@636b058d-ea47-450e-bf9e-a15bfbe3eedb> | 2017-11-16 09:47:15 +0000 |
---|---|---|
committer | vrouvrea <vrouvrea@636b058d-ea47-450e-bf9e-a15bfbe3eedb> | 2017-11-16 09:47:15 +0000 |
commit | 482b83945da409e7b748a0ecad56bbfdb569939b (patch) | |
tree | 3c4765f87e335ab5160b747bb1bb2204b872b453 | |
parent | aafe601c247c78a474c6af110ca5b34540a34f44 (diff) | |
parent | c438bf42d79c464104755108440d70b5dc2abf0b (diff) |
Merge last trunk modifications
Fix doxygen warnings
git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/add_utils_in_gudhi_v2@2888 636b058d-ea47-450e-bf9e-a15bfbe3eedb
Former-commit-id: b80b28a10495b6f2519b53885b1bf31be85ed7ac
49 files changed, 3756 insertions, 1302 deletions
diff --git a/CMakeGUDHIVersion.txt b/CMakeGUDHIVersion.txt index 87daf28e..bfef1590 100644 --- a/CMakeGUDHIVersion.txt +++ b/CMakeGUDHIVersion.txt @@ -1,6 +1,6 @@ set (GUDHI_MAJOR_VERSION 2) set (GUDHI_MINOR_VERSION 0) -set (GUDHI_PATCH_VERSION 1-rc2) +set (GUDHI_PATCH_VERSION 1) set(GUDHI_VERSION ${GUDHI_MAJOR_VERSION}.${GUDHI_MINOR_VERSION}.${GUDHI_PATCH_VERSION}) message(STATUS "GUDHI version : ${GUDHI_VERSION}") diff --git a/data/points/grid_10_10_10_in_0_1.weights b/data/points/grid_10_10_10_in_0_1.weights new file mode 100644 index 00000000..48926e09 --- /dev/null +++ b/data/points/grid_10_10_10_in_0_1.weights @@ -0,0 +1,1000 @@ +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 diff --git a/src/Alpha_complex/include/gudhi/Alpha_complex.h b/src/Alpha_complex/include/gudhi/Alpha_complex.h index 1ff95c3d..5f7d7622 100644 --- a/src/Alpha_complex/include/gudhi/Alpha_complex.h +++ b/src/Alpha_complex/include/gudhi/Alpha_complex.h @@ -268,8 +268,6 @@ class Alpha_complex { return false; // ----- >> } - complex.set_dimension(triangulation_->maximal_dimension()); - // -------------------------------------------------------------------------------------------- // Simplex_tree construction from loop on triangulation finite full cells list if (triangulation_->number_of_vertices() > 0) { diff --git a/src/Alpha_complex/test/Alpha_complex_unit_test.cpp b/src/Alpha_complex/test/Alpha_complex_unit_test.cpp index 7380547f..166373fe 100644 --- a/src/Alpha_complex/test/Alpha_complex_unit_test.cpp +++ b/src/Alpha_complex/test/Alpha_complex_unit_test.cpp @@ -159,7 +159,7 @@ BOOST_AUTO_TEST_CASE(Alpha_complex_from_points) { BOOST_CHECK(simplex_tree.num_simplices() == 15); std::cout << "simplex_tree.dimension()=" << simplex_tree.dimension() << std::endl; - BOOST_CHECK(simplex_tree.dimension() == 4); + BOOST_CHECK(simplex_tree.dimension() == 3); std::cout << "simplex_tree.num_vertices()=" << simplex_tree.num_vertices() << std::endl; BOOST_CHECK(simplex_tree.num_vertices() == 4); @@ -232,7 +232,7 @@ BOOST_AUTO_TEST_CASE(Alpha_complex_from_points) { BOOST_CHECK(simplex_tree.num_simplices() == 10); std::cout << "simplex_tree.dimension()=" << simplex_tree.dimension() << std::endl; - BOOST_CHECK(simplex_tree.dimension() == 4); + BOOST_CHECK(simplex_tree.dimension() == 1); std::cout << "simplex_tree.num_vertices()=" << simplex_tree.num_vertices() << std::endl; BOOST_CHECK(simplex_tree.num_vertices() == 4); diff --git a/src/Bitmap_cubical_complex/doc/Gudhi_Cubical_Complex_doc.h b/src/Bitmap_cubical_complex/doc/Gudhi_Cubical_Complex_doc.h index 5963caa3..daba15a4 100644 --- a/src/Bitmap_cubical_complex/doc/Gudhi_Cubical_Complex_doc.h +++ b/src/Bitmap_cubical_complex/doc/Gudhi_Cubical_Complex_doc.h @@ -144,7 +144,7 @@ namespace cubical_complex { * Indicate that we have imposed periodic boundary conditions in the direction x, but not in the direction y. * \section BitmapExamples Examples - * End user programs are available in example/Bitmap_cubical_complex folder. + * End user programs are available in example/Bitmap_cubical_complex and utilities/Bitmap_cubical_complex folders. * * \copyright GNU General Public License v3. */ diff --git a/src/Bitmap_cubical_complex/example/Random_bitmap_cubical_complex.cpp b/src/Bitmap_cubical_complex/example/Random_bitmap_cubical_complex.cpp index 16ad65a0..f70558f2 100644 --- a/src/Bitmap_cubical_complex/example/Random_bitmap_cubical_complex.cpp +++ b/src/Bitmap_cubical_complex/example/Random_bitmap_cubical_complex.cpp @@ -20,7 +20,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ - // for persistence algorithm #include <gudhi/reader_utils.h> #include <gudhi/Bitmap_cubical_complex.h> @@ -34,10 +33,11 @@ int main(int argc, char** argv) { srand(time(0)); - std::cout << "This program computes persistent homology, by using bitmap_cubical_complex class, of cubical " << - "complexes. The first parameter of the program is the dimension D of the bitmap. The next D parameters are " << - "number of top dimensional cubes in each dimension of the bitmap. The program will create random cubical " << - "complex of that sizes and compute persistent homology of it." << std::endl; + std::cout + << "This program computes persistent homology, by using bitmap_cubical_complex class, of cubical " + << "complexes. The first parameter of the program is the dimension D of the bitmap. The next D parameters are " + << "number of top dimensional cubes in each dimension of the bitmap. The program will create random cubical " + << "complex of that sizes and compute persistent homology of it." << std::endl; int p = 2; double min_persistence = 0; @@ -47,16 +47,16 @@ int main(int argc, char** argv) { return 1; } - size_t dimensionOfBitmap = (size_t) atoi(argv[1]); - std::vector< unsigned > sizes; + size_t dimensionOfBitmap = (size_t)atoi(argv[1]); + std::vector<unsigned> sizes; size_t multipliers = 1; for (size_t dim = 0; dim != dimensionOfBitmap; ++dim) { - unsigned sizeInThisDimension = (unsigned) atoi(argv[2 + dim]); + unsigned sizeInThisDimension = (unsigned)atoi(argv[2 + dim]); sizes.push_back(sizeInThisDimension); multipliers *= sizeInThisDimension; } - std::vector< double > data; + std::vector<double> data; for (size_t i = 0; i != multipliers; ++i) { data.push_back(rand() / static_cast<double>(RAND_MAX)); } @@ -80,4 +80,3 @@ int main(int argc, char** argv) { return 0; } - diff --git a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h index f395de65..f82e8ce9 100644 --- a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h +++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h @@ -31,7 +31,7 @@ #endif #include <limits> -#include <utility> // for pair<> +#include <utility> // for pair<> #include <algorithm> // for sort #include <vector> #include <numeric> // for iota @@ -43,7 +43,8 @@ namespace cubical_complex { // global variable, was used just for debugging. const bool globalDbg = false; -template <typename T> class is_before_in_filtration; +template <typename T> +class is_before_in_filtration; /** * @brief Cubical complex represented as a bitmap. @@ -64,7 +65,6 @@ class Bitmap_cubical_complex : public T { typedef typename T::filtration_type Filtration_value; typedef Simplex_key Simplex_handle; - //*********************************************// // Constructors //*********************************************// @@ -77,8 +77,8 @@ class Bitmap_cubical_complex : public T { /** * Constructor form a Perseus-style file. **/ - Bitmap_cubical_complex(const char* perseus_style_file) : - T(perseus_style_file), key_associated_to_simplex(this->total_number_of_cells + 1) { + Bitmap_cubical_complex(const char* perseus_style_file) + : T(perseus_style_file), key_associated_to_simplex(this->total_number_of_cells + 1) { if (globalDbg) { std::cerr << "Bitmap_cubical_complex( const char* perseus_style_file )\n"; } @@ -97,9 +97,8 @@ class Bitmap_cubical_complex : public T { * with filtration on top dimensional cells. **/ Bitmap_cubical_complex(const std::vector<unsigned>& dimensions, - const std::vector<Filtration_value>& top_dimensional_cells) : - T(dimensions, top_dimensional_cells), - key_associated_to_simplex(this->total_number_of_cells + 1) { + const std::vector<Filtration_value>& top_dimensional_cells) + : T(dimensions, top_dimensional_cells), key_associated_to_simplex(this->total_number_of_cells + 1) { for (size_t i = 0; i != this->total_number_of_cells; ++i) { this->key_associated_to_simplex[i] = i; } @@ -118,9 +117,9 @@ class Bitmap_cubical_complex : public T { **/ Bitmap_cubical_complex(const std::vector<unsigned>& dimensions, const std::vector<Filtration_value>& top_dimensional_cells, - std::vector< bool > directions_in_which_periodic_b_cond_are_to_be_imposed) : - T(dimensions, top_dimensional_cells, directions_in_which_periodic_b_cond_are_to_be_imposed), - key_associated_to_simplex(this->total_number_of_cells + 1) { + std::vector<bool> directions_in_which_periodic_b_cond_are_to_be_imposed) + : T(dimensions, top_dimensional_cells, directions_in_which_periodic_b_cond_are_to_be_imposed), + key_associated_to_simplex(this->total_number_of_cells + 1) { for (size_t i = 0; i != this->total_number_of_cells; ++i) { this->key_associated_to_simplex[i] = i; } @@ -142,9 +141,7 @@ class Bitmap_cubical_complex : public T { /** * Returns number of all cubes in the complex. **/ - size_t num_simplices()const { - return this->total_number_of_cells; - } + size_t num_simplices() const { return this->total_number_of_cells; } /** * Returns a Simplex_handle to a cube that do not exist in this complex. @@ -159,14 +156,12 @@ class Bitmap_cubical_complex : public T { /** * Returns dimension of the complex. **/ - inline size_t dimension()const { - return this->sizes.size(); - } + inline size_t dimension() const { return this->sizes.size(); } /** * Return dimension of a cell pointed by the Simplex_handle. **/ - inline unsigned dimension(Simplex_handle sh)const { + inline unsigned dimension(Simplex_handle sh) const { if (globalDbg) { std::cerr << "unsigned dimension(const Simplex_handle& sh)\n"; } @@ -199,7 +194,7 @@ class Bitmap_cubical_complex : public T { /** * Return the key of a cube pointed by the Simplex_handle. **/ - Simplex_key key(Simplex_handle sh)const { + Simplex_key key(Simplex_handle sh) const { if (globalDbg) { std::cerr << "Simplex_key key(const Simplex_handle& sh)\n"; } @@ -217,7 +212,7 @@ class Bitmap_cubical_complex : public T { std::cerr << "Simplex_handle simplex(Simplex_key key)\n"; } if (key != null_key()) { - return this->simplex_associated_to_key[ key ]; + return this->simplex_associated_to_key[key]; } return null_simplex(); } @@ -246,8 +241,8 @@ class Bitmap_cubical_complex : public T { /** * Boundary_simplex_range class provides ranges for boundary iterators. **/ - typedef typename std::vector< Simplex_handle >::iterator Boundary_simplex_iterator; - typedef typename std::vector< Simplex_handle > Boundary_simplex_range; + typedef typename std::vector<Simplex_handle>::iterator Boundary_simplex_iterator; + typedef typename std::vector<Simplex_handle> Boundary_simplex_range; /** * Filtration_simplex_iterator class provides an iterator though the whole structure in the order of filtration. @@ -257,13 +252,13 @@ class Bitmap_cubical_complex : public T { **/ class Filtration_simplex_range; - class Filtration_simplex_iterator : std::iterator< std::input_iterator_tag, Simplex_handle > { + class Filtration_simplex_iterator : std::iterator<std::input_iterator_tag, Simplex_handle> { // Iterator over all simplices of the complex in the order of the indexing scheme. // 'value_type' must be 'Simplex_handle'. public: - Filtration_simplex_iterator(Bitmap_cubical_complex* b) : b(b), position(0) { } + Filtration_simplex_iterator(Bitmap_cubical_complex* b) : b(b), position(0) {} - Filtration_simplex_iterator() : b(NULL), position(0) { } + Filtration_simplex_iterator() : b(NULL), position(0) {} Filtration_simplex_iterator operator++() { if (globalDbg) { @@ -288,14 +283,14 @@ class Bitmap_cubical_complex : public T { return (*this); } - bool operator==(const Filtration_simplex_iterator& rhs)const { + bool operator==(const Filtration_simplex_iterator& rhs) const { if (globalDbg) { std::cerr << "bool operator == ( const Filtration_simplex_iterator& rhs )\n"; } - return ( this->position == rhs.position); + return (this->position == rhs.position); } - bool operator!=(const Filtration_simplex_iterator& rhs)const { + bool operator!=(const Filtration_simplex_iterator& rhs) const { if (globalDbg) { std::cerr << "bool operator != ( const Filtration_simplex_iterator& rhs )\n"; } @@ -306,7 +301,7 @@ class Bitmap_cubical_complex : public T { if (globalDbg) { std::cerr << "Simplex_handle operator*()\n"; } - return this->b->simplex_associated_to_key[ this->position ]; + return this->b->simplex_associated_to_key[this->position]; } friend class Filtration_simplex_range; @@ -326,7 +321,7 @@ class Bitmap_cubical_complex : public T { typedef Filtration_simplex_iterator const_iterator; typedef Filtration_simplex_iterator iterator; - Filtration_simplex_range(Bitmap_cubical_complex<T>* b) : b(b) { } + Filtration_simplex_range(Bitmap_cubical_complex<T>* b) : b(b) {} Filtration_simplex_iterator begin() { if (globalDbg) { @@ -348,8 +343,6 @@ class Bitmap_cubical_complex : public T { Bitmap_cubical_complex<T>* b; }; - - //*********************************************// // Methods to access iterators from the container: @@ -357,9 +350,7 @@ class Bitmap_cubical_complex : public T { * boundary_simplex_range creates an object of a Boundary_simplex_range class * that provides ranges for the Boundary_simplex_iterator. **/ - Boundary_simplex_range boundary_simplex_range(Simplex_handle sh) { - return this->get_boundary_of_a_cell(sh); - } + Boundary_simplex_range boundary_simplex_range(Simplex_handle sh) { return this->get_boundary_of_a_cell(sh); } /** * filtration_simplex_range creates an object of a Filtration_simplex_range class @@ -374,8 +365,6 @@ class Bitmap_cubical_complex : public T { } //*********************************************// - - //*********************************************// // Elements which are in Gudhi now, but I (and in all the cases I asked also Marc) do not understand why they are // there. @@ -390,25 +379,25 @@ class Bitmap_cubical_complex : public T { * Function needed for compatibility with Gudhi. Not useful for other purposes. **/ std::pair<Simplex_handle, Simplex_handle> endpoints(Simplex_handle sh) { - std::vector< size_t > bdry = this->get_boundary_of_a_cell(sh); + std::vector<size_t> bdry = this->get_boundary_of_a_cell(sh); if (globalDbg) { std::cerr << "std::pair<Simplex_handle, Simplex_handle> endpoints( Simplex_handle sh )\n"; std::cerr << "bdry.size() : " << bdry.size() << std::endl; } // this method returns two first elements from the boundary of sh. if (bdry.size() < 2) - throw("Error in endpoints in Bitmap_cubical_complex class. The cell have less than two elements in the " - "boundary."); + throw( + "Error in endpoints in Bitmap_cubical_complex class. The cell have less than two elements in the " + "boundary."); return std::make_pair(bdry[0], bdry[1]); } - /** * Class needed for compatibility with Gudhi. Not useful for other purposes. **/ class Skeleton_simplex_range; - class Skeleton_simplex_iterator : std::iterator< std::input_iterator_tag, Simplex_handle > { + class Skeleton_simplex_iterator : std::iterator<std::input_iterator_tag, Simplex_handle> { // Iterator over all simplices of the complex in the order of the indexing scheme. // 'value_type' must be 'Simplex_handle'. public: @@ -418,15 +407,13 @@ class Bitmap_cubical_complex : public T { } // find the position of the first simplex of a dimension d this->position = 0; - while ( - (this->position != b->data.size()) && - (this->b->get_dimension_of_a_cell(this->position) != this->dimension) - ) { + while ((this->position != b->data.size()) && + (this->b->get_dimension_of_a_cell(this->position) != this->dimension)) { ++this->position; } } - Skeleton_simplex_iterator() : b(NULL), position(0), dimension(0) { } + Skeleton_simplex_iterator() : b(NULL), position(0), dimension(0) {} Skeleton_simplex_iterator operator++() { if (globalDbg) { @@ -434,10 +421,8 @@ class Bitmap_cubical_complex : public T { } // increment the position as long as you did not get to the next element of the dimension dimension. ++this->position; - while ( - (this->position != this->b->data.size()) && - (this->b->get_dimension_of_a_cell(this->position) != this->dimension) - ) { + while ((this->position != this->b->data.size()) && + (this->b->get_dimension_of_a_cell(this->position) != this->dimension)) { ++this->position; } return (*this); @@ -459,14 +444,14 @@ class Bitmap_cubical_complex : public T { return (*this); } - bool operator==(const Skeleton_simplex_iterator& rhs)const { + bool operator==(const Skeleton_simplex_iterator& rhs) const { if (globalDbg) { std::cerr << "bool operator ==\n"; } - return ( this->position == rhs.position); + return (this->position == rhs.position); } - bool operator!=(const Skeleton_simplex_iterator& rhs)const { + bool operator!=(const Skeleton_simplex_iterator& rhs) const { if (globalDbg) { std::cerr << "bool operator != ( const Skeleton_simplex_iterator& rhs )\n"; } @@ -481,6 +466,7 @@ class Bitmap_cubical_complex : public T { } friend class Skeleton_simplex_range; + private: Bitmap_cubical_complex<T>* b; size_t position; @@ -497,7 +483,7 @@ class Bitmap_cubical_complex : public T { typedef Skeleton_simplex_iterator const_iterator; typedef Skeleton_simplex_iterator iterator; - Skeleton_simplex_range(Bitmap_cubical_complex<T>* b, unsigned dimension) : b(b), dimension(dimension) { } + Skeleton_simplex_range(Bitmap_cubical_complex<T>* b, unsigned dimension) : b(b), dimension(dimension) {} Skeleton_simplex_iterator begin() { if (globalDbg) { @@ -533,8 +519,8 @@ class Bitmap_cubical_complex : public T { friend class is_before_in_filtration<T>; protected: - std::vector< size_t > key_associated_to_simplex; - std::vector< size_t > simplex_associated_to_key; + std::vector<size_t> key_associated_to_simplex; + std::vector<size_t> simplex_associated_to_key; }; // Bitmap_cubical_complex template <typename T> @@ -552,16 +538,15 @@ void Bitmap_cubical_complex<T>::initialize_simplex_associated_to_key() { #endif // we still need to deal here with a key_associated_to_simplex: - for ( size_t i = 0 ; i != simplex_associated_to_key.size() ; ++i ) { - this->key_associated_to_simplex[ simplex_associated_to_key[i] ] = i; + for (size_t i = 0; i != simplex_associated_to_key.size(); ++i) { + this->key_associated_to_simplex[simplex_associated_to_key[i]] = i; } } template <typename T> class is_before_in_filtration { public: - explicit is_before_in_filtration(Bitmap_cubical_complex<T> * CC) - : CC_(CC) { } + explicit is_before_in_filtration(Bitmap_cubical_complex<T>* CC) : CC_(CC) {} bool operator()(const typename Bitmap_cubical_complex<T>::Simplex_handle& sh1, const typename Bitmap_cubical_complex<T>::Simplex_handle& sh2) const { diff --git a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_base.h b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_base.h index 0442ac34..4adadce6 100644 --- a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_base.h +++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_base.h @@ -32,7 +32,8 @@ #include <algorithm> #include <iterator> #include <limits> -#include <utility> // for pair<> +#include <utility> +#include <stdexcept> namespace Gudhi { @@ -65,8 +66,7 @@ class Bitmap_cubical_complex_base { /** *Default constructor **/ - Bitmap_cubical_complex_base() : - total_number_of_cells(0) { } + Bitmap_cubical_complex_base() : total_number_of_cells(0) {} /** * There are a few constructors of a Bitmap_cubical_complex_base class. * First one, that takes vector<unsigned>, creates an empty bitmap of a dimension equal @@ -90,7 +90,7 @@ class Bitmap_cubical_complex_base { /** * Destructor of the Bitmap_cubical_complex_base class. **/ - virtual ~Bitmap_cubical_complex_base() { } + virtual ~Bitmap_cubical_complex_base() {} /** * The functions get_boundary_of_a_cell, get_coboundary_of_a_cell, get_dimension_of_a_cell @@ -100,8 +100,10 @@ class Bitmap_cubical_complex_base { * non-negative integer, indicating a position of a cube in the data structure. * In the case of functions that compute (co)boundary, the output is a vector if non-negative integers pointing to * the positions of (co)boundary element of the input cell. + * The boundary elements are guaranteed to be returned so that the + * incidence coefficients of boundary elements are alternating. */ - virtual inline std::vector< size_t > get_boundary_of_a_cell(size_t cell)const; + virtual inline std::vector<size_t> get_boundary_of_a_cell(size_t cell) const; /** * The functions get_coboundary_of_a_cell, get_coboundary_of_a_cell, * get_dimension_of_a_cell and get_cell_data are the basic @@ -112,13 +114,74 @@ class Bitmap_cubical_complex_base { * In the case of functions that compute (co)boundary, the output is a vector if * non-negative integers pointing to the * positions of (co)boundary element of the input cell. + * Note that unlike in the case of boundary, over here the elements are + * not guaranteed to be returned with alternating incidence numbers. + * **/ - virtual inline std::vector< size_t > get_coboundary_of_a_cell(size_t cell)const; + virtual inline std::vector<size_t> get_coboundary_of_a_cell(size_t cell) const; + /** - * In the case of get_dimension_of_a_cell function, the output is a non-negative integer - * indicating the dimension of a cell. - **/ - inline unsigned get_dimension_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}] \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) const { + // 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]) { + incidence *= -1; + } + + return incidence; + } + + /** +* In the case of get_dimension_of_a_cell function, the output is a non-negative integer +* indicating the dimension of a cell. +* 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 +**/ + inline unsigned get_dimension_of_a_cell(size_t cell) const; + /** * In the case of get_cell_data, the output parameter is a reference to the value of a cube in a given position. * This allows reading and changing the value of filtration. Note that if the value of a filtration is changed, the @@ -127,7 +190,6 @@ class Bitmap_cubical_complex_base { **/ inline T& get_cell_data(size_t cell); - /** * Typical input used to construct a baseBitmap class is a filtration given at the top dimensional cells. * Then, there are a few ways one can pick the filtration of lower dimensional @@ -141,23 +203,19 @@ class Bitmap_cubical_complex_base { /** * Returns dimension of a complex. **/ - inline unsigned dimension()const { - return sizes.size(); - } + inline unsigned dimension() const { return sizes.size(); } /** * Returns number of all cubes in the data structure. **/ - inline unsigned size()const { - return this->data.size(); - } + inline unsigned size() const { return this->data.size(); } /** * Writing to stream operator. By using it we get the values T of cells in order in which they are stored in the * structure. This procedure is used for debugging purposes. **/ template <typename K> - friend std::ostream& operator<<(std::ostream & os, const Bitmap_cubical_complex_base<K>& b); + friend std::ostream& operator<<(std::ostream& os, const Bitmap_cubical_complex_base<K>& b); /** * Function that put the input data to bins. By putting data to bins we mean rounding them to a sequence of values @@ -184,7 +242,7 @@ class Bitmap_cubical_complex_base { /** * Functions to find min and max values of filtration. **/ - std::pair< T, T > min_max_filtration(); + std::pair<T, T> min_max_filtration(); // ITERATORS @@ -192,11 +250,9 @@ class Bitmap_cubical_complex_base { * @brief Iterator through all cells in the complex (in order they appear in the structure -- i.e. * in lexicographical order). **/ - class All_cells_iterator : std::iterator< std::input_iterator_tag, T > { + class All_cells_iterator : std::iterator<std::input_iterator_tag, T> { public: - All_cells_iterator() { - this->counter = 0; - } + All_cells_iterator() { this->counter = 0; } All_cells_iterator operator++() { // first find first element of the counter that can be increased: @@ -215,14 +271,12 @@ class Bitmap_cubical_complex_base { return *this; } - bool operator==(const All_cells_iterator& rhs)const { - if (this->counter != rhs.counter)return false; + bool operator==(const All_cells_iterator& rhs) const { + if (this->counter != rhs.counter) return false; return true; } - bool operator!=(const All_cells_iterator& rhs)const { - return !(*this == rhs); - } + bool operator!=(const All_cells_iterator& rhs) const { return !(*this == rhs); } /* * The operator * returns position of a cube in the structure of cubical complex. This position can be then used as @@ -231,10 +285,9 @@ class Bitmap_cubical_complex_base { * boundary and coboundary and dimension * and in function get_cell_data to get a filtration of a cell. */ - size_t operator*() { - return this->counter; - } + size_t operator*() { return this->counter; } friend class Bitmap_cubical_complex_base; + protected: size_t counter; }; @@ -261,57 +314,47 @@ class Bitmap_cubical_complex_base { **/ class All_cells_range { public: - All_cells_range(Bitmap_cubical_complex_base* b) : b(b) { } + All_cells_range(Bitmap_cubical_complex_base* b) : b(b) {} - All_cells_iterator begin() { - return b->all_cells_iterator_begin(); - } + All_cells_iterator begin() { return b->all_cells_iterator_begin(); } + + All_cells_iterator end() { return b->all_cells_iterator_end(); } - All_cells_iterator end() { - return b->all_cells_iterator_end(); - } private: Bitmap_cubical_complex_base<T>* b; }; - All_cells_range all_cells_range() { - return All_cells_range(this); - } - + All_cells_range all_cells_range() { return All_cells_range(this); } /** * Boundary_range class provides ranges for boundary iterators. **/ - typedef typename std::vector< size_t >::const_iterator Boundary_iterator; - typedef typename std::vector< size_t > Boundary_range; + typedef typename std::vector<size_t>::const_iterator Boundary_iterator; + typedef typename std::vector<size_t> Boundary_range; /** * boundary_simplex_range creates an object of a Boundary_simplex_range class * that provides ranges for the Boundary_simplex_iterator. **/ - Boundary_range boundary_range(size_t sh) { - return this->get_boundary_of_a_cell(sh); - } + Boundary_range boundary_range(size_t sh) { return this->get_boundary_of_a_cell(sh); } /** * Coboundary_range class provides ranges for boundary iterators. **/ - typedef typename std::vector< size_t >::const_iterator Coboundary_iterator; - typedef typename std::vector< size_t > Coboundary_range; + typedef typename std::vector<size_t>::const_iterator Coboundary_iterator; + typedef typename std::vector<size_t> Coboundary_range; /** * boundary_simplex_range creates an object of a Boundary_simplex_range class * that provides ranges for the Boundary_simplex_iterator. **/ - Coboundary_range coboundary_range(size_t sh) { - return this->get_coboundary_of_a_cell(sh); - } + Coboundary_range coboundary_range(size_t sh) { return this->get_coboundary_of_a_cell(sh); } /** * @brief Iterator through top dimensional cells of the complex. The cells appear in order they are stored * in the structure (i.e. in lexicographical order) **/ - class Top_dimensional_cells_iterator : std::iterator< std::input_iterator_tag, T > { + class Top_dimensional_cells_iterator : std::iterator<std::input_iterator_tag, T> { public: Top_dimensional_cells_iterator(Bitmap_cubical_complex_base& b) : b(b) { this->counter = std::vector<size_t>(b.dimension()); @@ -321,7 +364,7 @@ class Bitmap_cubical_complex_base { Top_dimensional_cells_iterator operator++() { // first find first element of the counter that can be increased: size_t dim = 0; - while ((dim != this->b.dimension()) && (this->counter[dim] == this->b.sizes[dim] - 1))++dim; + while ((dim != this->b.dimension()) && (this->counter[dim] == this->b.sizes[dim] - 1)) ++dim; if (dim != this->b.dimension()) { ++this->counter[dim]; @@ -346,18 +389,16 @@ class Bitmap_cubical_complex_base { return *this; } - bool operator==(const Top_dimensional_cells_iterator& rhs)const { - if (&this->b != &rhs.b)return false; - if (this->counter.size() != rhs.counter.size())return false; + bool operator==(const Top_dimensional_cells_iterator& rhs) const { + if (&this->b != &rhs.b) return false; + if (this->counter.size() != rhs.counter.size()) return false; for (size_t i = 0; i != this->counter.size(); ++i) { - if (this->counter[i] != rhs.counter[i])return false; + if (this->counter[i] != rhs.counter[i]) return false; } return true; } - bool operator!=(const Top_dimensional_cells_iterator& rhs)const { - return !(*this == rhs); - } + bool operator!=(const Top_dimensional_cells_iterator& rhs) const { return !(*this == rhs); } /* * The operator * returns position of a cube in the structure of cubical complex. This position can be then used as @@ -366,11 +407,9 @@ class Bitmap_cubical_complex_base { * boundary and coboundary and dimension * and in function get_cell_data to get a filtration of a cell. */ - size_t operator*() { - return this->compute_index_in_bitmap(); - } + size_t operator*() { return this->compute_index_in_bitmap(); } - size_t compute_index_in_bitmap()const { + size_t compute_index_in_bitmap() const { size_t index = 0; for (size_t i = 0; i != this->counter.size(); ++i) { index += (2 * this->counter[i] + 1) * this->b.multipliers[i]; @@ -378,14 +417,15 @@ class Bitmap_cubical_complex_base { return index; } - void print_counter()const { + void print_counter() const { for (size_t i = 0; i != this->counter.size(); ++i) { std::cout << this->counter[i] << " "; } } friend class Bitmap_cubical_complex_base; + protected: - std::vector< size_t > counter; + std::vector<size_t> counter; Bitmap_cubical_complex_base& b; }; @@ -414,32 +454,24 @@ class Bitmap_cubical_complex_base { **/ class Top_dimensional_cells_range { public: - Top_dimensional_cells_range(Bitmap_cubical_complex_base* b) : b(b) { } + Top_dimensional_cells_range(Bitmap_cubical_complex_base* b) : b(b) {} - Top_dimensional_cells_iterator begin() { - return b->top_dimensional_cells_iterator_begin(); - } + Top_dimensional_cells_iterator begin() { return b->top_dimensional_cells_iterator_begin(); } + + Top_dimensional_cells_iterator end() { return b->top_dimensional_cells_iterator_end(); } - Top_dimensional_cells_iterator end() { - return b->top_dimensional_cells_iterator_end(); - } private: Bitmap_cubical_complex_base<T>* b; }; - Top_dimensional_cells_range top_dimensional_cells_range() { - return Top_dimensional_cells_range(this); - } - + Top_dimensional_cells_range top_dimensional_cells_range() { return Top_dimensional_cells_range(this); } //****************************************************************************************************************// //****************************************************************************************************************// //****************************************************************************************************************// //****************************************************************************************************************// - inline size_t number_cells()const { - return this->total_number_of_cells; - } + inline size_t number_cells() const { return this->total_number_of_cells; } //****************************************************************************************************************// //****************************************************************************************************************// @@ -463,7 +495,7 @@ class Bitmap_cubical_complex_base { this->total_number_of_cells = multiplier; } - size_t compute_position_in_bitmap(const std::vector< unsigned >& counter) { + size_t compute_position_in_bitmap(const std::vector<unsigned>& counter) { size_t position = 0; for (size_t i = 0; i != this->multipliers.size(); ++i) { position += this->multipliers[i] * counter[i]; @@ -471,7 +503,7 @@ class Bitmap_cubical_complex_base { return position; } - std::vector<unsigned> compute_counter_for_given_cell(size_t cell)const { + std::vector<unsigned> compute_counter_for_given_cell(size_t cell) const { std::vector<unsigned> counter; counter.reserve(this->sizes.size()); for (size_t dim = this->sizes.size(); dim != 0; --dim) { @@ -486,8 +518,7 @@ class Bitmap_cubical_complex_base { const std::vector<T>& top_dimensional_cells); Bitmap_cubical_complex_base(const char* perseus_style_file, std::vector<bool> directions); Bitmap_cubical_complex_base(const std::vector<unsigned>& sizes, std::vector<bool> directions); - Bitmap_cubical_complex_base(const std::vector<unsigned>& dimensions, - const std::vector<T>& top_dimensional_cells, + Bitmap_cubical_complex_base(const std::vector<unsigned>& dimensions, const std::vector<T>& top_dimensional_cells, std::vector<bool> directions); }; @@ -495,8 +526,8 @@ template <typename T> void Bitmap_cubical_complex_base<T>::put_data_to_bins(size_t number_of_bins) { bool bdg = false; - std::pair< T, T > min_max = this->min_max_filtration(); - T dx = (min_max.second - min_max.first) / (T) number_of_bins; + std::pair<T, T> min_max = this->min_max_filtration(); + T dx = (min_max.second - min_max.first) / (T)number_of_bins; // now put the data into the appropriate bins: for (size_t i = 0; i != this->data.size(); ++i) { @@ -514,7 +545,7 @@ void Bitmap_cubical_complex_base<T>::put_data_to_bins(size_t number_of_bins) { template <typename T> void Bitmap_cubical_complex_base<T>::put_data_to_bins(T diameter_of_bin) { bool bdg = false; - std::pair< T, T > min_max = this->min_max_filtration(); + std::pair<T, T> min_max = this->min_max_filtration(); size_t number_of_bins = (min_max.second - min_max.first) / diameter_of_bin; // now put the data into the appropriate bins: @@ -531,33 +562,32 @@ void Bitmap_cubical_complex_base<T>::put_data_to_bins(T diameter_of_bin) { } template <typename T> -std::pair< T, T > Bitmap_cubical_complex_base<T>::min_max_filtration() { - std::pair< T, T > min_max(std::numeric_limits<T>::max(), std::numeric_limits<T>::min()); +std::pair<T, T> Bitmap_cubical_complex_base<T>::min_max_filtration() { + std::pair<T, T> min_max(std::numeric_limits<T>::max(), std::numeric_limits<T>::min()); for (size_t i = 0; i != this->data.size(); ++i) { - if (this->data[i] < min_max.first)min_max.first = this->data[i]; - if (this->data[i] > min_max.second)min_max.second = this->data[i]; + if (this->data[i] < min_max.first) min_max.first = this->data[i]; + if (this->data[i] > min_max.second) min_max.second = this->data[i]; } return min_max; } template <typename K> -std::ostream& operator<<(std::ostream & out, const Bitmap_cubical_complex_base<K>& b) { - for (typename Bitmap_cubical_complex_base<K>::all_cells_const_iterator - it = b.all_cells_const_begin(); it != b.all_cells_const_end(); ++it) { +std::ostream& operator<<(std::ostream& out, const Bitmap_cubical_complex_base<K>& b) { + for (typename Bitmap_cubical_complex_base<K>::all_cells_const_iterator it = b.all_cells_const_begin(); + it != b.all_cells_const_end(); ++it) { out << *it << " "; } return out; } template <typename T> -Bitmap_cubical_complex_base<T>::Bitmap_cubical_complex_base -(const std::vector<unsigned>& sizes) { +Bitmap_cubical_complex_base<T>::Bitmap_cubical_complex_base(const std::vector<unsigned>& sizes) { this->set_up_containers(sizes); } template <typename T> -void Bitmap_cubical_complex_base<T>::setup_bitmap_based_on_top_dimensional_cells_list(const std::vector<unsigned>& sizes_in_following_directions, - const std::vector<T>& top_dimensional_cells) { +void Bitmap_cubical_complex_base<T>::setup_bitmap_based_on_top_dimensional_cells_list( + const std::vector<unsigned>& sizes_in_following_directions, const std::vector<T>& top_dimensional_cells) { this->set_up_containers(sizes_in_following_directions); size_t number_of_top_dimensional_elements = 1; @@ -566,12 +596,13 @@ void Bitmap_cubical_complex_base<T>::setup_bitmap_based_on_top_dimensional_cells } if (number_of_top_dimensional_elements != top_dimensional_cells.size()) { std::cerr << "Error in constructor Bitmap_cubical_complex_base ( std::vector<size_t> sizes_in_following_directions" - << ", std::vector<T> top_dimensional_cells ). Number of top dimensional elements that follow from " - << "sizes_in_following_directions vector is different than the size of top_dimensional_cells vector." - << std::endl; - throw("Error in constructor Bitmap_cubical_complex_base( std::vector<size_t> sizes_in_following_directions," - "std::vector<T> top_dimensional_cells ). Number of top dimensional elements that follow from " - "sizes_in_following_directions vector is different than the size of top_dimensional_cells vector."); + << ", std::vector<T> top_dimensional_cells ). Number of top dimensional elements that follow from " + << "sizes_in_following_directions vector is different than the size of top_dimensional_cells vector." + << std::endl; + throw( + "Error in constructor Bitmap_cubical_complex_base( std::vector<size_t> sizes_in_following_directions," + "std::vector<T> top_dimensional_cells ). Number of top dimensional elements that follow from " + "sizes_in_following_directions vector is different than the size of top_dimensional_cells vector."); } Bitmap_cubical_complex_base<T>::Top_dimensional_cells_iterator it(*this); @@ -584,8 +615,8 @@ void Bitmap_cubical_complex_base<T>::setup_bitmap_based_on_top_dimensional_cells } template <typename T> -Bitmap_cubical_complex_base<T>::Bitmap_cubical_complex_base -(const std::vector<unsigned>& sizes_in_following_directions, const std::vector<T>& top_dimensional_cells) { +Bitmap_cubical_complex_base<T>::Bitmap_cubical_complex_base(const std::vector<unsigned>& sizes_in_following_directions, + const std::vector<T>& top_dimensional_cells) { this->setup_bitmap_based_on_top_dimensional_cells_list(sizes_in_following_directions, top_dimensional_cells); } @@ -621,11 +652,9 @@ void Bitmap_cubical_complex_base<T>::read_perseus_style_file(const char* perseus T filtrationLevel; inFiltration >> filtrationLevel; if (dbg) { - std::cerr << "Cell of an index : " - << it.compute_index_in_bitmap() - << " and dimension: " - << this->get_dimension_of_a_cell(it.compute_index_in_bitmap()) - << " get the value : " << filtrationLevel << std::endl; + std::cerr << "Cell of an index : " << it.compute_index_in_bitmap() + << " and dimension: " << this->get_dimension_of_a_cell(it.compute_index_in_bitmap()) + << " get the value : " << filtrationLevel << std::endl; } this->get_cell_data(*it) = filtrationLevel; ++it; @@ -668,28 +697,36 @@ Bitmap_cubical_complex_base<T>::Bitmap_cubical_complex_base(const char* perseus_ } template <typename T> -std::vector< size_t > Bitmap_cubical_complex_base<T>::get_boundary_of_a_cell(size_t cell)const { - std::vector< size_t > boundary_elements; +std::vector<size_t> Bitmap_cubical_complex_base<T>::get_boundary_of_a_cell(size_t cell) const { + std::vector<size_t> boundary_elements; // Speed traded of for memory. Check if it is better in practice. - boundary_elements.reserve(this->dimension()*2); + boundary_elements.reserve(this->dimension() * 2); + size_t sum_of_dimensions = 0; size_t cell1 = cell; for (size_t i = this->multipliers.size(); i != 0; --i) { unsigned position = cell1 / this->multipliers[i - 1]; if (position % 2 == 1) { - boundary_elements.push_back(cell - this->multipliers[ i - 1 ]); - boundary_elements.push_back(cell + this->multipliers[ i - 1 ]); + 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]); + } + ++sum_of_dimensions; } cell1 = cell1 % this->multipliers[i - 1]; } + return boundary_elements; } template <typename T> -std::vector< size_t > Bitmap_cubical_complex_base<T>::get_coboundary_of_a_cell(size_t cell)const { +std::vector<size_t> Bitmap_cubical_complex_base<T>::get_coboundary_of_a_cell(size_t cell) const { std::vector<unsigned> counter = this->compute_counter_for_given_cell(cell); - std::vector< size_t > coboundary_elements; + std::vector<size_t> coboundary_elements; size_t cell1 = cell; for (size_t i = this->multipliers.size(); i != 0; --i) { unsigned position = cell1 / this->multipliers[i - 1]; @@ -697,8 +734,7 @@ std::vector< size_t > Bitmap_cubical_complex_base<T>::get_coboundary_of_a_cell(s if ((cell > this->multipliers[i - 1]) && (counter[i - 1] != 0)) { coboundary_elements.push_back(cell - this->multipliers[i - 1]); } - if ( - (cell + this->multipliers[i - 1] < this->data.size()) && (counter[i - 1] != 2 * this->sizes[i - 1])) { + if ((cell + this->multipliers[i - 1] < this->data.size()) && (counter[i - 1] != 2 * this->sizes[i - 1])) { coboundary_elements.push_back(cell + this->multipliers[i - 1]); } } @@ -708,7 +744,7 @@ std::vector< size_t > Bitmap_cubical_complex_base<T>::get_coboundary_of_a_cell(s } template <typename T> -unsigned Bitmap_cubical_complex_base<T>::get_dimension_of_a_cell(size_t cell)const { +unsigned Bitmap_cubical_complex_base<T>::get_dimension_of_a_cell(size_t cell) const { bool dbg = false; if (dbg) std::cerr << "\n\n\n Computing position o a cell of an index : " << cell << std::endl; unsigned dimension = 0; @@ -746,7 +782,7 @@ void Bitmap_cubical_complex_base<T>::impose_lower_star_filtration() { size_t size_to_reserve = 1; for (size_t i = 0; i != this->multipliers.size(); ++i) { - size_to_reserve *= (size_t) ((this->multipliers[i] - 1) / 2); + size_to_reserve *= (size_t)((this->multipliers[i] - 1) / 2); } std::vector<size_t> indices_to_consider; @@ -771,22 +807,22 @@ void Bitmap_cubical_complex_base<T>::impose_lower_star_filtration() { std::vector<size_t> bd = this->get_boundary_of_a_cell(indices_to_consider[i]); for (size_t boundaryIt = 0; boundaryIt != bd.size(); ++boundaryIt) { if (dbg) { - std::cerr << "filtration of a cell : " << bd[boundaryIt] << " is : " << this->data[ bd[boundaryIt] ] - << " while of a cell: " << indices_to_consider[i] << " is: " << this->data[ indices_to_consider[i] ] - << std::endl; + std::cerr << "filtration of a cell : " << bd[boundaryIt] << " is : " << this->data[bd[boundaryIt]] + << " while of a cell: " << indices_to_consider[i] << " is: " << this->data[indices_to_consider[i]] + << std::endl; getchar(); } - if (this->data[ bd[boundaryIt] ] > this->data[ indices_to_consider[i] ]) { - this->data[ bd[boundaryIt] ] = this->data[ indices_to_consider[i] ]; + if (this->data[bd[boundaryIt]] > this->data[indices_to_consider[i]]) { + this->data[bd[boundaryIt]] = this->data[indices_to_consider[i]]; if (dbg) { - std::cerr << "Setting the value of a cell : " << bd[boundaryIt] << " to : " - << this->data[ indices_to_consider[i] ] << std::endl; + std::cerr << "Setting the value of a cell : " << bd[boundaryIt] + << " to : " << this->data[indices_to_consider[i]] << std::endl; getchar(); } } - if (is_this_cell_considered[ bd[boundaryIt] ] == false) { + if (is_this_cell_considered[bd[boundaryIt]] == false) { new_indices_to_consider.push_back(bd[boundaryIt]); - is_this_cell_considered[ bd[boundaryIt] ] = true; + is_this_cell_considered[bd[boundaryIt]] = true; } } } @@ -795,8 +831,8 @@ void Bitmap_cubical_complex_base<T>::impose_lower_star_filtration() { } template <typename T> -bool compareFirstElementsOfTuples(const std::pair< std::pair< T, size_t >, char >& first, - const std::pair< std::pair< T, size_t >, char >& second) { +bool compareFirstElementsOfTuples(const std::pair<std::pair<T, size_t>, char>& first, + const std::pair<std::pair<T, size_t>, char>& second) { if (first.first.first < second.first.first) { return true; } else { 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..e2f86f3b 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 { @@ -41,7 +42,8 @@ namespace cubical_complex { /** * @brief Cubical complex with periodic boundary conditions represented as a bitmap. * @ingroup cubical_complex - * @details This is a class implementing a bitmap data structure with periodic boundary conditions. Most of the functions are + * @details This is a class implementing a bitmap data structure with periodic boundary conditions. Most of the + * functions are * identical to the functions from Bitmap_cubical_complex_base. * The ones that needed to be updated are the constructors and get_boundary_of_a_cell and get_coboundary_of_a_cell. */ @@ -53,7 +55,7 @@ class Bitmap_cubical_complex_periodic_boundary_conditions_base : public Bitmap_c /** * Default constructor of Bitmap_cubical_complex_periodic_boundary_conditions_base class. */ - Bitmap_cubical_complex_periodic_boundary_conditions_base() { } + Bitmap_cubical_complex_periodic_boundary_conditions_base() {} /** * A constructor of Bitmap_cubical_complex_periodic_boundary_conditions_base class that takes the following * parameters: (1) vector with numbers of top dimensional cells in all dimensions and (2) vector of booleans. If @@ -61,8 +63,9 @@ class Bitmap_cubical_complex_periodic_boundary_conditions_base : public Bitmap_c * imposed in this direction. In case of false, the periodic boundary conditions will not be imposed in the direction * i. */ - Bitmap_cubical_complex_periodic_boundary_conditions_base(const std::vector<unsigned>& sizes, - const std::vector<bool>& directions_in_which_periodic_b_cond_are_to_be_imposed); + Bitmap_cubical_complex_periodic_boundary_conditions_base( + const std::vector<unsigned>& sizes, + const std::vector<bool>& directions_in_which_periodic_b_cond_are_to_be_imposed); /** * A constructor of Bitmap_cubical_complex_periodic_boundary_conditions_base class that takes the name of Perseus * style file as an input. Please consult the documentation about the specification of the file. @@ -75,9 +78,9 @@ class Bitmap_cubical_complex_periodic_boundary_conditions_base : public Bitmap_c * value, that means that periodic boundary conditions are to be imposed in this direction. In case of false, the * periodic boundary conditions will not be imposed in the direction i. */ - Bitmap_cubical_complex_periodic_boundary_conditions_base(const std::vector<unsigned>& dimensions, - const std::vector<T>& topDimensionalCells, - const std::vector< bool >& directions_in_which_periodic_b_cond_are_to_be_imposed); + Bitmap_cubical_complex_periodic_boundary_conditions_base( + const std::vector<unsigned>& dimensions, const std::vector<T>& topDimensionalCells, + const std::vector<bool>& directions_in_which_periodic_b_cond_are_to_be_imposed); /** * Destructor of the Bitmap_cubical_complex_periodic_boundary_conditions_base class. @@ -88,17 +91,77 @@ 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; + 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; + 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; + std::vector<bool> directions_in_which_periodic_b_cond_are_to_be_imposed; void set_up_containers(const std::vector<unsigned>& sizes) { unsigned multiplier = 1; @@ -119,15 +182,19 @@ 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); - 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); + + /** + * 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); }; template <typename T> -void Bitmap_cubical_complex_periodic_boundary_conditions_base<T>::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) { +void Bitmap_cubical_complex_periodic_boundary_conditions_base<T>::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) { this->directions_in_which_periodic_b_cond_are_to_be_imposed = directions_in_which_periodic_b_cond_are_to_be_imposed; this->set_up_containers(dimensions); @@ -140,14 +207,16 @@ void Bitmap_cubical_complex_periodic_boundary_conditions_base<T>::construct_comp } template <typename T> -Bitmap_cubical_complex_periodic_boundary_conditions_base<T>::Bitmap_cubical_complex_periodic_boundary_conditions_base(const std::vector<unsigned>& sizes, - const std::vector<bool>& directions_in_which_periodic_b_cond_are_to_be_imposed) { +Bitmap_cubical_complex_periodic_boundary_conditions_base<T>::Bitmap_cubical_complex_periodic_boundary_conditions_base( + const std::vector<unsigned>& sizes, + const std::vector<bool>& directions_in_which_periodic_b_cond_are_to_be_imposed) { this->directions_in_which_periodic_b_cond_are_to_be_imposed(directions_in_which_periodic_b_cond_are_to_be_imposed); this->set_up_containers(sizes); } template <typename T> -Bitmap_cubical_complex_periodic_boundary_conditions_base<T>::Bitmap_cubical_complex_periodic_boundary_conditions_base(const char* perseus_style_file) { +Bitmap_cubical_complex_periodic_boundary_conditions_base<T>::Bitmap_cubical_complex_periodic_boundary_conditions_base( + const char* perseus_style_file) { // for Perseus style files: bool dbg = false; @@ -176,14 +245,12 @@ Bitmap_cubical_complex_periodic_boundary_conditions_base<T>::Bitmap_cubical_comp while (!inFiltration.eof()) { double filtrationLevel; inFiltration >> filtrationLevel; - if (inFiltration.eof())break; + if (inFiltration.eof()) break; if (dbg) { - std::cerr << "Cell of an index : " - << it.compute_index_in_bitmap() - << " and dimension: " - << this->get_dimension_of_a_cell(it.compute_index_in_bitmap()) - << " get the value : " << filtrationLevel << std::endl; + std::cerr << "Cell of an index : " << it.compute_index_in_bitmap() + << " and dimension: " << this->get_dimension_of_a_cell(it.compute_index_in_bitmap()) + << " get the value : " << filtrationLevel << std::endl; } this->get_cell_data(*it) = filtrationLevel; ++it; @@ -193,24 +260,24 @@ Bitmap_cubical_complex_periodic_boundary_conditions_base<T>::Bitmap_cubical_comp } template <typename T> -Bitmap_cubical_complex_periodic_boundary_conditions_base<T>::Bitmap_cubical_complex_periodic_boundary_conditions_base(const std::vector<unsigned>& sizes) { +Bitmap_cubical_complex_periodic_boundary_conditions_base<T>::Bitmap_cubical_complex_periodic_boundary_conditions_base( + const std::vector<unsigned>& sizes) { this->directions_in_which_periodic_b_cond_are_to_be_imposed = std::vector<bool>(sizes.size(), false); this->set_up_containers(sizes); } template <typename T> -Bitmap_cubical_complex_periodic_boundary_conditions_base<T>::Bitmap_cubical_complex_periodic_boundary_conditions_base(const std::vector<unsigned>& dimensions, - const std::vector<T>& topDimensionalCells) { +Bitmap_cubical_complex_periodic_boundary_conditions_base<T>::Bitmap_cubical_complex_periodic_boundary_conditions_base( + const std::vector<unsigned>& dimensions, const std::vector<T>& topDimensionalCells) { std::vector<bool> directions_in_which_periodic_b_cond_are_to_be_imposed = std::vector<bool>(dimensions.size(), false); this->construct_complex_based_on_top_dimensional_cells(dimensions, topDimensionalCells, directions_in_which_periodic_b_cond_are_to_be_imposed); } template <typename T> -Bitmap_cubical_complex_periodic_boundary_conditions_base<T>:: -Bitmap_cubical_complex_periodic_boundary_conditions_base(const std::vector<unsigned>& dimensions, - const std::vector<T>& topDimensionalCells, - const std::vector<bool>& directions_in_which_periodic_b_cond_are_to_be_imposed) { +Bitmap_cubical_complex_periodic_boundary_conditions_base<T>::Bitmap_cubical_complex_periodic_boundary_conditions_base( + const std::vector<unsigned>& dimensions, const std::vector<T>& topDimensionalCells, + const std::vector<bool>& directions_in_which_periodic_b_cond_are_to_be_imposed) { this->construct_complex_based_on_top_dimensional_cells(dimensions, topDimensionalCells, directions_in_which_periodic_b_cond_are_to_be_imposed); } @@ -218,46 +285,65 @@ Bitmap_cubical_complex_periodic_boundary_conditions_base(const std::vector<unsig // ***********************Methods************************ // template <typename T> -std::vector< size_t > Bitmap_cubical_complex_periodic_boundary_conditions_base<T>::get_boundary_of_a_cell(size_t cell) const { +std::vector<size_t> Bitmap_cubical_complex_periodic_boundary_conditions_base<T>::get_boundary_of_a_cell( + size_t cell) const { bool dbg = false; if (dbg) { std::cerr << "Computations of boundary of a cell : " << cell << std::endl; } - std::vector< size_t > boundary_elements; + 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 (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 ] << " "; + 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) { + 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 ]); + 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 ] << " "; + 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 ]); + 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 ] << " "; + 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]; } @@ -265,9 +351,10 @@ std::vector< size_t > Bitmap_cubical_complex_periodic_boundary_conditions_base<T } template <typename T> -std::vector< size_t > Bitmap_cubical_complex_periodic_boundary_conditions_base<T>::get_coboundary_of_a_cell(size_t cell) const { +std::vector<size_t> Bitmap_cubical_complex_periodic_boundary_conditions_base<T>::get_coboundary_of_a_cell( + size_t cell) const { std::vector<unsigned> counter = this->compute_counter_for_given_cell(cell); - std::vector< size_t > coboundary_elements; + std::vector<size_t> coboundary_elements; size_t cell1 = cell; for (size_t i = this->multipliers.size(); i != 0; --i) { unsigned position = cell1 / this->multipliers[i - 1]; @@ -289,7 +376,7 @@ std::vector< size_t > Bitmap_cubical_complex_periodic_boundary_conditions_base<T } else { // in this case counter[i-1] == 0. coboundary_elements.push_back(cell + this->multipliers[i - 1]); - coboundary_elements.push_back(cell + (2 * this->sizes[ i - 1 ] - 1) * this->multipliers[i - 1]); + coboundary_elements.push_back(cell + (2 * this->sizes[i - 1] - 1) * this->multipliers[i - 1]); } } } diff --git a/src/Bitmap_cubical_complex/test/Bitmap_test.cpp b/src/Bitmap_cubical_complex/test/Bitmap_test.cpp index db90eb94..4af699e9 100644 --- a/src/Bitmap_cubical_complex/test/Bitmap_test.cpp +++ b/src/Bitmap_cubical_complex/test/Bitmap_test.cpp @@ -33,17 +33,16 @@ #include <sstream> #include <vector> - typedef Gudhi::cubical_complex::Bitmap_cubical_complex_base<double> Bitmap_cubical_complex_base; typedef Gudhi::cubical_complex::Bitmap_cubical_complex<Bitmap_cubical_complex_base> Bitmap_cubical_complex; typedef Gudhi::cubical_complex::Bitmap_cubical_complex_periodic_boundary_conditions_base<double> -Bitmap_cubical_complex_periodic_boundary_conditions_base; + Bitmap_cubical_complex_periodic_boundary_conditions_base; typedef Gudhi::cubical_complex::Bitmap_cubical_complex<Bitmap_cubical_complex_periodic_boundary_conditions_base> -Bitmap_cubical_complex_periodic_boundary_conditions; + Bitmap_cubical_complex_periodic_boundary_conditions; BOOST_AUTO_TEST_CASE(check_dimension) { - std::vector< double > increasingFiltrationOfTopDimensionalCells({1, 2, 3, 4, 5, 6, 7, 8, 9}); + std::vector<double> increasingFiltrationOfTopDimensionalCells({1, 2, 3, 4, 5, 6, 7, 8, 9}); std::vector<unsigned> dimensions({3, 3}); @@ -52,29 +51,28 @@ BOOST_AUTO_TEST_CASE(check_dimension) { } BOOST_AUTO_TEST_CASE(topDimensionalCellsIterator_test) { - std::vector< double > expectedFiltrationValues1({0, 0, 0, 0, 100, 0, 0, 0, 0}); + std::vector<double> expectedFiltrationValues1({0, 0, 0, 0, 100, 0, 0, 0, 0}); - std::vector< double > expectedFiltrationValues2({1, 2, 3, 4, 5, 6, 7, 8, 9}); + std::vector<double> expectedFiltrationValues2({1, 2, 3, 4, 5, 6, 7, 8, 9}); - std::vector< double > increasingFiltrationOfTopDimensionalCells({1, 2, 3, 4, 5, 6, 7, 8, 9}); + std::vector<double> increasingFiltrationOfTopDimensionalCells({1, 2, 3, 4, 5, 6, 7, 8, 9}); - std::vector< double > oneDimensionalCycle({0, 0, 0, 0, 100, 0, 0, 0, 0}); + std::vector<double> oneDimensionalCycle({0, 0, 0, 0, 100, 0, 0, 0, 0}); std::vector<unsigned> dimensions({3, 3}); Bitmap_cubical_complex increasing(dimensions, increasingFiltrationOfTopDimensionalCells); Bitmap_cubical_complex hole(dimensions, oneDimensionalCycle); - int i = 0; - for (Bitmap_cubical_complex::Top_dimensional_cells_iterator - it = increasing.top_dimensional_cells_iterator_begin(); it != increasing.top_dimensional_cells_iterator_end(); ++it) { + for (Bitmap_cubical_complex::Top_dimensional_cells_iterator it = increasing.top_dimensional_cells_iterator_begin(); + it != increasing.top_dimensional_cells_iterator_end(); ++it) { BOOST_CHECK(increasing.get_cell_data(*it) == expectedFiltrationValues2[i]); ++i; } i = 0; - for (Bitmap_cubical_complex::Top_dimensional_cells_iterator - it = hole.top_dimensional_cells_iterator_begin(); it != hole.top_dimensional_cells_iterator_end(); ++it) { + for (Bitmap_cubical_complex::Top_dimensional_cells_iterator it = hole.top_dimensional_cells_iterator_begin(); + it != hole.top_dimensional_cells_iterator_end(); ++it) { BOOST_CHECK(hole.get_cell_data(*it) == expectedFiltrationValues1[i]); ++i; } @@ -100,24 +98,24 @@ BOOST_AUTO_TEST_CASE(compute_boundary_test_1) { std::vector<double> boundary8; boundary8.push_back(1); boundary8.push_back(15); - boundary8.push_back(7); boundary8.push_back(9); + boundary8.push_back(7); std::vector<double> boundary9; boundary9.push_back(2); boundary9.push_back(16); std::vector<double> boundary10; boundary10.push_back(3); boundary10.push_back(17); - boundary10.push_back(9); boundary10.push_back(11); + boundary10.push_back(9); std::vector<double> boundary11; boundary11.push_back(4); boundary11.push_back(18); std::vector<double> boundary12; boundary12.push_back(5); boundary12.push_back(19); - boundary12.push_back(11); boundary12.push_back(13); + boundary12.push_back(11); std::vector<double> boundary13; boundary13.push_back(6); boundary13.push_back(20); @@ -140,24 +138,24 @@ BOOST_AUTO_TEST_CASE(compute_boundary_test_1) { std::vector<double> boundary22; boundary22.push_back(15); boundary22.push_back(29); - boundary22.push_back(21); boundary22.push_back(23); + boundary22.push_back(21); std::vector<double> boundary23; boundary23.push_back(16); boundary23.push_back(30); std::vector<double> boundary24; boundary24.push_back(17); boundary24.push_back(31); - boundary24.push_back(23); boundary24.push_back(25); + boundary24.push_back(23); std::vector<double> boundary25; boundary25.push_back(18); boundary25.push_back(32); std::vector<double> boundary26; boundary26.push_back(19); boundary26.push_back(33); - boundary26.push_back(25); boundary26.push_back(27); + boundary26.push_back(25); std::vector<double> boundary27; boundary27.push_back(20); boundary27.push_back(34); @@ -180,24 +178,24 @@ BOOST_AUTO_TEST_CASE(compute_boundary_test_1) { std::vector<double> boundary36; boundary36.push_back(29); boundary36.push_back(43); - boundary36.push_back(35); boundary36.push_back(37); + boundary36.push_back(35); std::vector<double> boundary37; boundary37.push_back(30); boundary37.push_back(44); std::vector<double> boundary38; boundary38.push_back(31); boundary38.push_back(45); - boundary38.push_back(37); boundary38.push_back(39); + boundary38.push_back(37); std::vector<double> boundary39; boundary39.push_back(32); boundary39.push_back(46); std::vector<double> boundary40; boundary40.push_back(33); boundary40.push_back(47); - boundary40.push_back(39); boundary40.push_back(41); + boundary40.push_back(39); std::vector<double> boundary41; boundary41.push_back(34); boundary41.push_back(48); @@ -214,7 +212,7 @@ BOOST_AUTO_TEST_CASE(compute_boundary_test_1) { boundary47.push_back(46); boundary47.push_back(48); std::vector<double> boundary48; - std::vector< std::vector<double> > boundaries; + std::vector<std::vector<double> > boundaries; boundaries.push_back(boundary0); boundaries.push_back(boundary1); boundaries.push_back(boundary2); @@ -265,15 +263,13 @@ BOOST_AUTO_TEST_CASE(compute_boundary_test_1) { boundaries.push_back(boundary47); boundaries.push_back(boundary48); - - - std::vector< double > increasingFiltrationOfTopDimensionalCells({1, 2, 3, 4, 5, 6, 7, 8, 9}); + std::vector<double> increasingFiltrationOfTopDimensionalCells({1, 2, 3, 4, 5, 6, 7, 8, 9}); std::vector<unsigned> dimensions({3, 3}); Bitmap_cubical_complex increasing(dimensions, increasingFiltrationOfTopDimensionalCells); for (size_t i = 0; i != increasing.size(); ++i) { - std::vector< size_t > bd = increasing.get_boundary_of_a_cell(i); + std::vector<size_t> bd = increasing.get_boundary_of_a_cell(i); for (size_t j = 0; j != bd.size(); ++j) { BOOST_CHECK(boundaries[i][j] == bd[j]); } @@ -281,13 +277,12 @@ BOOST_AUTO_TEST_CASE(compute_boundary_test_1) { } BOOST_AUTO_TEST_CASE(compute_boundary_test_2) { - std::vector< double > increasingFiltrationOfTopDimensionalCells({1, 2, 3, 4, 5, 6, 7, 8, 9}); + std::vector<double> increasingFiltrationOfTopDimensionalCells({1, 2, 3, 4, 5, 6, 7, 8, 9}); std::vector<unsigned> dimensions({3, 3}); Bitmap_cubical_complex increasing(dimensions, increasingFiltrationOfTopDimensionalCells); - std::vector<double> coboundaryElements; coboundaryElements.push_back(7); coboundaryElements.push_back(1); @@ -373,9 +368,10 @@ BOOST_AUTO_TEST_CASE(compute_boundary_test_2) { coboundaryElements.push_back(40); coboundaryElements.push_back(41); coboundaryElements.push_back(47); + size_t number = 0; for (size_t i = 0; i != increasing.size(); ++i) { - std::vector< size_t > bd = increasing.get_coboundary_of_a_cell(i); + std::vector<size_t> bd = increasing.get_coboundary_of_a_cell(i); for (size_t j = 0; j != bd.size(); ++j) { BOOST_CHECK(coboundaryElements[number] == bd[j]); ++number; @@ -384,7 +380,7 @@ BOOST_AUTO_TEST_CASE(compute_boundary_test_2) { } BOOST_AUTO_TEST_CASE(compute_boundary_test_3) { - std::vector< double > increasingFiltrationOfTopDimensionalCells({1, 2, 3, 4, 5, 6, 7, 8, 9}); + std::vector<double> increasingFiltrationOfTopDimensionalCells({1, 2, 3, 4, 5, 6, 7, 8, 9}); std::vector<unsigned> dimensions({3, 3}); @@ -447,13 +443,13 @@ BOOST_AUTO_TEST_CASE(compute_boundary_test_3) { } BOOST_AUTO_TEST_CASE(Filtration_simplex_iterator_test) { - std::vector< double > increasingFiltrationOfTopDimensionalCells({1, 2, 3, 4, 5, 6, 7, 8, 9}); + std::vector<double> increasingFiltrationOfTopDimensionalCells({1, 2, 3, 4, 5, 6, 7, 8, 9}); std::vector<unsigned> dimensions({3, 3}); Bitmap_cubical_complex increasing(dimensions, increasingFiltrationOfTopDimensionalCells); - std::vector< unsigned > dim; + std::vector<unsigned> dim; dim.push_back(0); dim.push_back(0); dim.push_back(0); @@ -555,7 +551,6 @@ BOOST_AUTO_TEST_CASE(Filtration_simplex_iterator_test) { fil.push_back(9); fil.push_back(9); - Bitmap_cubical_complex::Filtration_simplex_range range = increasing.filtration_simplex_range(); size_t position = 0; for (Bitmap_cubical_complex::Filtration_simplex_iterator it = range.begin(); it != range.end(); ++it) { @@ -566,7 +561,7 @@ BOOST_AUTO_TEST_CASE(Filtration_simplex_iterator_test) { } BOOST_AUTO_TEST_CASE(boudary_operator_2d_bitmap_with_periodic_bcond) { - std::vector< double > filtration({0, 0, 0, 0}); + std::vector<double> filtration({0, 0, 0, 0}); std::vector<unsigned> dimensions({2, 2}); @@ -575,57 +570,56 @@ BOOST_AUTO_TEST_CASE(boudary_operator_2d_bitmap_with_periodic_bcond) { Bitmap_cubical_complex_periodic_boundary_conditions cmplx(dimensions, filtration, periodic_directions); BOOST_CHECK(cmplx.dimension() == 2); - std::vector<double> boundary0; std::vector<double> boundary1; - boundary1.push_back(0); boundary1.push_back(2); + boundary1.push_back(0); std::vector<double> boundary2; std::vector<double> boundary3; - boundary3.push_back(2); boundary3.push_back(0); + boundary3.push_back(2); std::vector<double> boundary4; - boundary4.push_back(0); boundary4.push_back(8); + boundary4.push_back(0); std::vector<double> boundary5; - boundary5.push_back(1); boundary5.push_back(9); + boundary5.push_back(1); boundary5.push_back(4); boundary5.push_back(6); std::vector<double> boundary6; - boundary6.push_back(2); boundary6.push_back(10); + boundary6.push_back(2); std::vector<double> boundary7; - boundary7.push_back(3); boundary7.push_back(11); + boundary7.push_back(3); boundary7.push_back(6); boundary7.push_back(4); std::vector<double> boundary8; std::vector<double> boundary9; - boundary9.push_back(8); boundary9.push_back(10); + boundary9.push_back(8); std::vector<double> boundary10; std::vector<double> boundary11; - boundary11.push_back(10); boundary11.push_back(8); + boundary11.push_back(10); std::vector<double> boundary12; - boundary12.push_back(8); boundary12.push_back(0); + boundary12.push_back(8); std::vector<double> boundary13; - boundary13.push_back(9); boundary13.push_back(1); + boundary13.push_back(9); boundary13.push_back(12); boundary13.push_back(14); std::vector<double> boundary14; - boundary14.push_back(10); boundary14.push_back(2); + boundary14.push_back(10); std::vector<double> boundary15; - boundary15.push_back(11); boundary15.push_back(3); + boundary15.push_back(11); boundary15.push_back(14); boundary15.push_back(12); - std::vector< std::vector<double> > boundaries; + std::vector<std::vector<double> > boundaries; boundaries.push_back(boundary0); boundaries.push_back(boundary1); boundaries.push_back(boundary2); @@ -644,7 +638,7 @@ BOOST_AUTO_TEST_CASE(boudary_operator_2d_bitmap_with_periodic_bcond) { boundaries.push_back(boundary15); for (size_t i = 0; i != cmplx.size(); ++i) { - std::vector< size_t > bd = cmplx.get_boundary_of_a_cell(i); + std::vector<size_t> bd = cmplx.get_boundary_of_a_cell(i); for (size_t j = 0; j != bd.size(); ++j) { BOOST_CHECK(boundaries[i][j] == bd[j]); } @@ -652,7 +646,7 @@ BOOST_AUTO_TEST_CASE(boudary_operator_2d_bitmap_with_periodic_bcond) { } BOOST_AUTO_TEST_CASE(coboudary_operator_2d_bitmap_with_periodic_bcond) { - std::vector< double > filtration({0, 0, 0, 0}); + std::vector<double> filtration({0, 0, 0, 0}); std::vector<unsigned> dimensions({2, 2}); @@ -661,7 +655,6 @@ BOOST_AUTO_TEST_CASE(coboudary_operator_2d_bitmap_with_periodic_bcond) { Bitmap_cubical_complex_periodic_boundary_conditions cmplx(dimensions, filtration, periodic_directions); BOOST_CHECK(cmplx.dimension() == 2); - std::vector<double> coboundary0; coboundary0.push_back(4); coboundary0.push_back(12); @@ -711,7 +704,7 @@ BOOST_AUTO_TEST_CASE(coboudary_operator_2d_bitmap_with_periodic_bcond) { coboundary14.push_back(15); std::vector<double> coboundary15; - std::vector< std::vector<double> > coboundaries; + std::vector<std::vector<double> > coboundaries; coboundaries.push_back(coboundary0); coboundaries.push_back(coboundary1); coboundaries.push_back(coboundary2); @@ -730,7 +723,7 @@ BOOST_AUTO_TEST_CASE(coboudary_operator_2d_bitmap_with_periodic_bcond) { coboundaries.push_back(coboundary15); for (size_t i = 0; i != cmplx.size(); ++i) { - std::vector< size_t > cbd = cmplx.get_coboundary_of_a_cell(i); + std::vector<size_t> cbd = cmplx.get_coboundary_of_a_cell(i); for (size_t j = 0; j != cbd.size(); ++j) { BOOST_CHECK(coboundaries[i][j] == cbd[j]); } @@ -738,7 +731,7 @@ BOOST_AUTO_TEST_CASE(coboudary_operator_2d_bitmap_with_periodic_bcond) { } BOOST_AUTO_TEST_CASE(bitmap_2d_with_periodic_bcond_filtration) { - std::vector< double > filtrationOrg({0, 1, 2, 3}); + std::vector<double> filtrationOrg({0, 1, 2, 3}); std::vector<unsigned> dimensions({2, 2}); @@ -747,7 +740,6 @@ BOOST_AUTO_TEST_CASE(bitmap_2d_with_periodic_bcond_filtration) { Bitmap_cubical_complex_periodic_boundary_conditions cmplx(dimensions, filtrationOrg, periodic_directions); BOOST_CHECK(cmplx.dimension() == 2); - std::vector<double> filtration; filtration.push_back(0); // 0 filtration.push_back(0); // 1 @@ -766,613 +758,821 @@ BOOST_AUTO_TEST_CASE(bitmap_2d_with_periodic_bcond_filtration) { filtration.push_back(2); // 14 filtration.push_back(3); // 15 - for (size_t i = 0; i != cmplx.size(); ++i) { BOOST_CHECK(filtration[i] == cmplx.get_cell_data(i)); } } -BOOST_AUTO_TEST_CASE(all_cells_iterator_and_boundary_iterators_in_Bitmap_cubical_complex_base_check) -{ - std::vector< double > expected_filtration; - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(1); - expected_filtration.push_back(1); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(1); - expected_filtration.push_back(1); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(1); - expected_filtration.push_back(1); - expected_filtration.push_back(2); - expected_filtration.push_back(2); - expected_filtration.push_back(2); - expected_filtration.push_back(3); - expected_filtration.push_back(3); - expected_filtration.push_back(2); - expected_filtration.push_back(2); - expected_filtration.push_back(2); - expected_filtration.push_back(3); - expected_filtration.push_back(3); - - std::vector<unsigned> expected_dimension; - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(2); - expected_dimension.push_back(1); - expected_dimension.push_back(2); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(2); - expected_dimension.push_back(1); - expected_dimension.push_back(2); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - - std::vector<size_t> expected_boundary; - expected_boundary.push_back(0); - expected_boundary.push_back(2); - expected_boundary.push_back(2); - expected_boundary.push_back(4); - expected_boundary.push_back(0); - expected_boundary.push_back(10); - expected_boundary.push_back(1); - expected_boundary.push_back(11); - expected_boundary.push_back(5); - expected_boundary.push_back(7); - expected_boundary.push_back(2); - expected_boundary.push_back(12); - expected_boundary.push_back(3); - expected_boundary.push_back(13); - expected_boundary.push_back(7); - expected_boundary.push_back(9); - expected_boundary.push_back(4); - expected_boundary.push_back(14); - expected_boundary.push_back(10); - expected_boundary.push_back(12); - expected_boundary.push_back(12); - expected_boundary.push_back(14); - expected_boundary.push_back(10); - expected_boundary.push_back(20); - expected_boundary.push_back(11); - expected_boundary.push_back(21); - expected_boundary.push_back(15); - expected_boundary.push_back(17); - expected_boundary.push_back(12); - expected_boundary.push_back(22); - expected_boundary.push_back(13); - expected_boundary.push_back(23); - expected_boundary.push_back(17); - expected_boundary.push_back(19); - expected_boundary.push_back(14); - expected_boundary.push_back(24); - expected_boundary.push_back(20); - expected_boundary.push_back(22); - expected_boundary.push_back(22); - expected_boundary.push_back(24); - - - std::vector<size_t> expected_coboundary; - expected_coboundary.push_back(5); - expected_coboundary.push_back(1); - expected_coboundary.push_back(6); - expected_coboundary.push_back(7); - expected_coboundary.push_back(1); - expected_coboundary.push_back(3); - expected_coboundary.push_back(8); - expected_coboundary.push_back(9); - expected_coboundary.push_back(3); - expected_coboundary.push_back(6); - expected_coboundary.push_back(6); - expected_coboundary.push_back(8); - expected_coboundary.push_back(8); - expected_coboundary.push_back(5); - expected_coboundary.push_back(15); - expected_coboundary.push_back(11); - expected_coboundary.push_back(6); - expected_coboundary.push_back(16); - expected_coboundary.push_back(7); - expected_coboundary.push_back(17); - expected_coboundary.push_back(11); - expected_coboundary.push_back(13); - expected_coboundary.push_back(8); - expected_coboundary.push_back(18); - expected_coboundary.push_back(9); - expected_coboundary.push_back(19); - expected_coboundary.push_back(13); - expected_coboundary.push_back(16); - expected_coboundary.push_back(16); - expected_coboundary.push_back(18); - expected_coboundary.push_back(18); - expected_coboundary.push_back(15); - expected_coboundary.push_back(21); - expected_coboundary.push_back(16); - expected_coboundary.push_back(17); - expected_coboundary.push_back(21); - expected_coboundary.push_back(23); - expected_coboundary.push_back(18); - expected_coboundary.push_back(19); - expected_coboundary.push_back(23); - - - - std::vector< unsigned > sizes(2); - sizes[0] = 2; - sizes[1] = 2; - - std::vector< double > data(4); - data[0] = 0; - data[1] = 1; - data[2] = 2; - data[3] = 3; - - Bitmap_cubical_complex_base ba( sizes , data ); - int i = 0; - int bd_it = 0; - int cbd_it = 0; - for ( Bitmap_cubical_complex_base::All_cells_iterator it = ba.all_cells_iterator_begin() ; it != ba.all_cells_iterator_end() ; ++it ) - { - BOOST_CHECK( expected_filtration[i] == ba.get_cell_data( *it ) ); - BOOST_CHECK( expected_dimension[i] == ba.get_dimension_of_a_cell( *it ) ); - - Bitmap_cubical_complex_base::Boundary_range bdrange = ba.boundary_range(*it); - for ( Bitmap_cubical_complex_base::Boundary_iterator bd = bdrange.begin() ; bd != bdrange.end() ; ++bd ) - { - BOOST_CHECK( expected_boundary[bd_it] == *bd ); - ++bd_it; - } - - Bitmap_cubical_complex_base::Coboundary_range cbdrange = ba.coboundary_range(*it); - for ( Bitmap_cubical_complex_base::Coboundary_iterator cbd = cbdrange.begin() ; cbd != cbdrange.end() ; ++cbd ) - { - BOOST_CHECK( expected_coboundary[cbd_it] == *cbd ); - ++cbd_it; - } - ++i; + +BOOST_AUTO_TEST_CASE(all_cells_iterator_and_boundary_iterators_in_Bitmap_cubical_complex_base_check) { + std::vector<double> expected_filtration; + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(1); + expected_filtration.push_back(1); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(1); + expected_filtration.push_back(1); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(1); + expected_filtration.push_back(1); + expected_filtration.push_back(2); + expected_filtration.push_back(2); + expected_filtration.push_back(2); + expected_filtration.push_back(3); + expected_filtration.push_back(3); + expected_filtration.push_back(2); + expected_filtration.push_back(2); + expected_filtration.push_back(2); + expected_filtration.push_back(3); + expected_filtration.push_back(3); + + std::vector<unsigned> expected_dimension; + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(2); + expected_dimension.push_back(1); + expected_dimension.push_back(2); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(2); + expected_dimension.push_back(1); + expected_dimension.push_back(2); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + + std::vector<size_t> expected_boundary; + expected_boundary.push_back(0); + expected_boundary.push_back(2); + expected_boundary.push_back(2); + expected_boundary.push_back(4); + expected_boundary.push_back(0); + expected_boundary.push_back(10); + expected_boundary.push_back(1); + expected_boundary.push_back(11); + expected_boundary.push_back(7); + expected_boundary.push_back(5); + expected_boundary.push_back(2); + expected_boundary.push_back(12); + expected_boundary.push_back(3); + expected_boundary.push_back(13); + expected_boundary.push_back(9); + expected_boundary.push_back(7); + expected_boundary.push_back(4); + expected_boundary.push_back(14); + expected_boundary.push_back(10); + expected_boundary.push_back(12); + expected_boundary.push_back(12); + expected_boundary.push_back(14); + expected_boundary.push_back(10); + expected_boundary.push_back(20); + expected_boundary.push_back(11); + expected_boundary.push_back(21); + expected_boundary.push_back(17); + expected_boundary.push_back(15); + expected_boundary.push_back(12); + expected_boundary.push_back(22); + expected_boundary.push_back(13); + expected_boundary.push_back(23); + expected_boundary.push_back(19); + expected_boundary.push_back(17); + expected_boundary.push_back(14); + expected_boundary.push_back(24); + expected_boundary.push_back(20); + expected_boundary.push_back(22); + expected_boundary.push_back(22); + expected_boundary.push_back(24); + + std::vector<size_t> expected_coboundary; + expected_coboundary.push_back(5); + expected_coboundary.push_back(1); + expected_coboundary.push_back(6); + expected_coboundary.push_back(7); + expected_coboundary.push_back(1); + expected_coboundary.push_back(3); + expected_coboundary.push_back(8); + expected_coboundary.push_back(9); + expected_coboundary.push_back(3); + expected_coboundary.push_back(6); + expected_coboundary.push_back(6); + expected_coboundary.push_back(8); + expected_coboundary.push_back(8); + expected_coboundary.push_back(5); + expected_coboundary.push_back(15); + expected_coboundary.push_back(11); + expected_coboundary.push_back(6); + expected_coboundary.push_back(16); + expected_coboundary.push_back(7); + expected_coboundary.push_back(17); + expected_coboundary.push_back(11); + expected_coboundary.push_back(13); + expected_coboundary.push_back(8); + expected_coboundary.push_back(18); + expected_coboundary.push_back(9); + expected_coboundary.push_back(19); + expected_coboundary.push_back(13); + expected_coboundary.push_back(16); + expected_coboundary.push_back(16); + expected_coboundary.push_back(18); + expected_coboundary.push_back(18); + expected_coboundary.push_back(15); + expected_coboundary.push_back(21); + expected_coboundary.push_back(16); + expected_coboundary.push_back(17); + expected_coboundary.push_back(21); + expected_coboundary.push_back(23); + expected_coboundary.push_back(18); + expected_coboundary.push_back(19); + expected_coboundary.push_back(23); + + std::vector<unsigned> sizes(2); + sizes[0] = 2; + sizes[1] = 2; + + std::vector<double> data(4); + data[0] = 0; + data[1] = 1; + data[2] = 2; + data[3] = 3; + + Bitmap_cubical_complex_base ba(sizes, data); + int i = 0; + int bd_it = 0; + int cbd_it = 0; + for (Bitmap_cubical_complex_base::All_cells_iterator it = ba.all_cells_iterator_begin(); + it != ba.all_cells_iterator_end(); ++it) { + BOOST_CHECK(expected_filtration[i] == ba.get_cell_data(*it)); + BOOST_CHECK(expected_dimension[i] == ba.get_dimension_of_a_cell(*it)); + + Bitmap_cubical_complex_base::Boundary_range bdrange = ba.boundary_range(*it); + for (Bitmap_cubical_complex_base::Boundary_iterator bd = bdrange.begin(); bd != bdrange.end(); ++bd) { + BOOST_CHECK(expected_boundary[bd_it] == *bd); + ++bd_it; } + + Bitmap_cubical_complex_base::Coboundary_range cbdrange = ba.coboundary_range(*it); + for (Bitmap_cubical_complex_base::Coboundary_iterator cbd = cbdrange.begin(); cbd != cbdrange.end(); ++cbd) { + BOOST_CHECK(expected_coboundary[cbd_it] == *cbd); + ++cbd_it; + } + ++i; + } } +BOOST_AUTO_TEST_CASE(all_cells_iterator_and_boundary_iterators_in_Bitmap_cubical_complex_base_check_range_check_2) { + std::vector<double> expected_filtration; + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(1); + expected_filtration.push_back(1); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(1); + expected_filtration.push_back(1); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(1); + expected_filtration.push_back(1); + expected_filtration.push_back(2); + expected_filtration.push_back(2); + expected_filtration.push_back(2); + expected_filtration.push_back(3); + expected_filtration.push_back(3); + expected_filtration.push_back(2); + expected_filtration.push_back(2); + expected_filtration.push_back(2); + expected_filtration.push_back(3); + expected_filtration.push_back(3); + + std::vector<unsigned> expected_dimension; + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(2); + expected_dimension.push_back(1); + expected_dimension.push_back(2); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(2); + expected_dimension.push_back(1); + expected_dimension.push_back(2); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + + std::vector<size_t> expected_boundary; + expected_boundary.push_back(0); + expected_boundary.push_back(2); + expected_boundary.push_back(2); + expected_boundary.push_back(4); + expected_boundary.push_back(0); + expected_boundary.push_back(10); + expected_boundary.push_back(1); + expected_boundary.push_back(11); + expected_boundary.push_back(7); + expected_boundary.push_back(5); + expected_boundary.push_back(2); + expected_boundary.push_back(12); + expected_boundary.push_back(3); + expected_boundary.push_back(13); + expected_boundary.push_back(9); + expected_boundary.push_back(7); + expected_boundary.push_back(4); + expected_boundary.push_back(14); + expected_boundary.push_back(10); + expected_boundary.push_back(12); + expected_boundary.push_back(12); + expected_boundary.push_back(14); + expected_boundary.push_back(10); + expected_boundary.push_back(20); + expected_boundary.push_back(11); + expected_boundary.push_back(21); + expected_boundary.push_back(17); + expected_boundary.push_back(15); + expected_boundary.push_back(12); + expected_boundary.push_back(22); + expected_boundary.push_back(13); + expected_boundary.push_back(23); + expected_boundary.push_back(19); + expected_boundary.push_back(17); + expected_boundary.push_back(14); + expected_boundary.push_back(24); + expected_boundary.push_back(20); + expected_boundary.push_back(22); + expected_boundary.push_back(22); + expected_boundary.push_back(24); + + std::vector<size_t> expected_coboundary; + expected_coboundary.push_back(5); + expected_coboundary.push_back(1); + expected_coboundary.push_back(6); + expected_coboundary.push_back(7); + expected_coboundary.push_back(1); + expected_coboundary.push_back(3); + expected_coboundary.push_back(8); + expected_coboundary.push_back(9); + expected_coboundary.push_back(3); + expected_coboundary.push_back(6); + expected_coboundary.push_back(6); + expected_coboundary.push_back(8); + expected_coboundary.push_back(8); + expected_coboundary.push_back(5); + expected_coboundary.push_back(15); + expected_coboundary.push_back(11); + expected_coboundary.push_back(6); + expected_coboundary.push_back(16); + expected_coboundary.push_back(7); + expected_coboundary.push_back(17); + expected_coboundary.push_back(11); + expected_coboundary.push_back(13); + expected_coboundary.push_back(8); + expected_coboundary.push_back(18); + expected_coboundary.push_back(9); + expected_coboundary.push_back(19); + expected_coboundary.push_back(13); + expected_coboundary.push_back(16); + expected_coboundary.push_back(16); + expected_coboundary.push_back(18); + expected_coboundary.push_back(18); + expected_coboundary.push_back(15); + expected_coboundary.push_back(21); + expected_coboundary.push_back(16); + expected_coboundary.push_back(17); + expected_coboundary.push_back(21); + expected_coboundary.push_back(23); + expected_coboundary.push_back(18); + expected_coboundary.push_back(19); + expected_coboundary.push_back(23); + + std::vector<unsigned> sizes(2); + sizes[0] = 2; + sizes[1] = 2; + + std::vector<double> data(4); + data[0] = 0; + data[1] = 1; + data[2] = 2; + data[3] = 3; + + Bitmap_cubical_complex_base ba(sizes, data); + int i = 0; + int bd_it = 0; + int cbd_it = 0; + + Bitmap_cubical_complex_base::All_cells_range range(&ba); + for (Bitmap_cubical_complex_base::All_cells_iterator it = range.begin(); it != range.end(); ++it) { + BOOST_CHECK(expected_filtration[i] == ba.get_cell_data(*it)); + BOOST_CHECK(expected_dimension[i] == ba.get_dimension_of_a_cell(*it)); + + Bitmap_cubical_complex_base::Boundary_range bdrange = ba.boundary_range(*it); + for (Bitmap_cubical_complex_base::Boundary_iterator bd = bdrange.begin(); bd != bdrange.end(); ++bd) { + BOOST_CHECK(expected_boundary[bd_it] == *bd); + ++bd_it; + } + Bitmap_cubical_complex_base::Coboundary_range cbdrange = ba.coboundary_range(*it); + for (Bitmap_cubical_complex_base::Coboundary_iterator cbd = cbdrange.begin(); cbd != cbdrange.end(); ++cbd) { + BOOST_CHECK(expected_coboundary[cbd_it] == *cbd); + ++cbd_it; + } + ++i; + } +} +BOOST_AUTO_TEST_CASE(all_cells_iterator_and_boundary_iterators_in_Bitmap_cubical_complex_base_check_range_check) { + std::vector<double> expected_filtration; + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(1); + expected_filtration.push_back(1); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(1); + expected_filtration.push_back(1); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(1); + expected_filtration.push_back(1); + expected_filtration.push_back(2); + expected_filtration.push_back(2); + expected_filtration.push_back(2); + expected_filtration.push_back(3); + expected_filtration.push_back(3); + expected_filtration.push_back(2); + expected_filtration.push_back(2); + expected_filtration.push_back(2); + expected_filtration.push_back(3); + expected_filtration.push_back(3); + + std::vector<unsigned> expected_dimension; + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(2); + expected_dimension.push_back(1); + expected_dimension.push_back(2); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(2); + expected_dimension.push_back(1); + expected_dimension.push_back(2); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + + std::vector<size_t> expected_boundary; + expected_boundary.push_back(0); + expected_boundary.push_back(2); + expected_boundary.push_back(2); + expected_boundary.push_back(4); + expected_boundary.push_back(0); + expected_boundary.push_back(10); + expected_boundary.push_back(1); + expected_boundary.push_back(11); + expected_boundary.push_back(7); + expected_boundary.push_back(5); + expected_boundary.push_back(2); + expected_boundary.push_back(12); + expected_boundary.push_back(3); + expected_boundary.push_back(13); + expected_boundary.push_back(9); + expected_boundary.push_back(7); + expected_boundary.push_back(4); + expected_boundary.push_back(14); + expected_boundary.push_back(10); + expected_boundary.push_back(12); + expected_boundary.push_back(12); + expected_boundary.push_back(14); + expected_boundary.push_back(10); + expected_boundary.push_back(20); + expected_boundary.push_back(11); + expected_boundary.push_back(21); + expected_boundary.push_back(17); + expected_boundary.push_back(15); + expected_boundary.push_back(12); + expected_boundary.push_back(22); + expected_boundary.push_back(13); + expected_boundary.push_back(23); + expected_boundary.push_back(19); + expected_boundary.push_back(17); + expected_boundary.push_back(14); + expected_boundary.push_back(24); + expected_boundary.push_back(20); + expected_boundary.push_back(22); + expected_boundary.push_back(22); + expected_boundary.push_back(24); + + std::vector<size_t> expected_coboundary; + expected_coboundary.push_back(5); + expected_coboundary.push_back(1); + expected_coboundary.push_back(6); + expected_coboundary.push_back(7); + expected_coboundary.push_back(1); + expected_coboundary.push_back(3); + expected_coboundary.push_back(8); + expected_coboundary.push_back(9); + expected_coboundary.push_back(3); + expected_coboundary.push_back(6); + expected_coboundary.push_back(6); + expected_coboundary.push_back(8); + expected_coboundary.push_back(8); + expected_coboundary.push_back(5); + expected_coboundary.push_back(15); + expected_coboundary.push_back(11); + expected_coboundary.push_back(6); + expected_coboundary.push_back(16); + expected_coboundary.push_back(7); + expected_coboundary.push_back(17); + expected_coboundary.push_back(11); + expected_coboundary.push_back(13); + expected_coboundary.push_back(8); + expected_coboundary.push_back(18); + expected_coboundary.push_back(9); + expected_coboundary.push_back(19); + expected_coboundary.push_back(13); + expected_coboundary.push_back(16); + expected_coboundary.push_back(16); + expected_coboundary.push_back(18); + expected_coboundary.push_back(18); + expected_coboundary.push_back(15); + expected_coboundary.push_back(21); + expected_coboundary.push_back(16); + expected_coboundary.push_back(17); + expected_coboundary.push_back(21); + expected_coboundary.push_back(23); + expected_coboundary.push_back(18); + expected_coboundary.push_back(19); + expected_coboundary.push_back(23); + + std::vector<unsigned> sizes(2); + sizes[0] = 2; + sizes[1] = 2; + + std::vector<double> data(4); + data[0] = 0; + data[1] = 1; + data[2] = 2; + data[3] = 3; + + Bitmap_cubical_complex_base ba(sizes, data); + int i = 0; + int bd_it = 0; + int cbd_it = 0; + + Bitmap_cubical_complex_base::All_cells_range range = ba.all_cells_range(); + for (Bitmap_cubical_complex_base::All_cells_iterator it = range.begin(); it != range.end(); ++it) { + BOOST_CHECK(expected_filtration[i] == ba.get_cell_data(*it)); + BOOST_CHECK(expected_dimension[i] == ba.get_dimension_of_a_cell(*it)); + + Bitmap_cubical_complex_base::Boundary_range bdrange = ba.boundary_range(*it); + for (Bitmap_cubical_complex_base::Boundary_iterator bd = bdrange.begin(); bd != bdrange.end(); ++bd) { + BOOST_CHECK(expected_boundary[bd_it] == *bd); + ++bd_it; + } + Bitmap_cubical_complex_base::Coboundary_range cbdrange = ba.coboundary_range(*it); + for (Bitmap_cubical_complex_base::Coboundary_iterator cbd = cbdrange.begin(); cbd != cbdrange.end(); ++cbd) { + BOOST_CHECK(expected_coboundary[cbd_it] == *cbd); + ++cbd_it; + } + ++i; + } +} +BOOST_AUTO_TEST_CASE(Top_dimensional_cells_iterator_range_check) { + std::vector<double> expected_filtration; + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(1); + expected_filtration.push_back(1); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(1); + expected_filtration.push_back(1); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(1); + expected_filtration.push_back(1); + expected_filtration.push_back(2); + expected_filtration.push_back(2); + expected_filtration.push_back(2); + expected_filtration.push_back(3); + expected_filtration.push_back(3); + expected_filtration.push_back(2); + expected_filtration.push_back(2); + expected_filtration.push_back(2); + expected_filtration.push_back(3); + expected_filtration.push_back(3); + + std::vector<unsigned> sizes(2); + sizes[0] = 2; + sizes[1] = 2; + + std::vector<double> data(4); + data[0] = 0; + data[1] = 1; + data[2] = 2; + data[3] = 3; + + Bitmap_cubical_complex_base ba(sizes, data); + int i = 0; + Bitmap_cubical_complex_base::Top_dimensional_cells_range range = ba.top_dimensional_cells_range(); + for (Bitmap_cubical_complex_base::Top_dimensional_cells_iterator it = range.begin(); it != range.end(); ++it) { + BOOST_CHECK(data[i] == ba.get_cell_data(*it)); + BOOST_CHECK(ba.get_dimension_of_a_cell(*it) == 2); + ++i; + } +} +BOOST_AUTO_TEST_CASE(check_if_boundary_of_boundary_is_zero_non_periodic_case_3_d) { + std::vector<unsigned> sizes(3); + sizes[0] = 3; + sizes[1] = 3; + sizes[2] = 3; + + std::vector<double> data(27, 0); + + int number_of_all_elements = (2 * sizes[0] + 1) * (2 * sizes[1] + 1) * (2 * sizes[2] + 1); + std::vector<int> elems_in_boundary(number_of_all_elements, 0); + Bitmap_cubical_complex_base ba(sizes, data); + for (Bitmap_cubical_complex_base::All_cells_iterator it = ba.all_cells_iterator_begin(); + it != ba.all_cells_iterator_end(); ++it) { + int i = 1; + Bitmap_cubical_complex_base::Boundary_range bdrange = ba.boundary_range(*it); + for (Bitmap_cubical_complex_base::Boundary_iterator bd = bdrange.begin(); bd != bdrange.end(); ++bd) { + Bitmap_cubical_complex_base::Boundary_range second_bdrange = ba.boundary_range(*bd); + int j = 1; + for (Bitmap_cubical_complex_base::Boundary_iterator bd2 = second_bdrange.begin(); bd2 != second_bdrange.end(); + ++bd2) { + elems_in_boundary[*bd2] += i * j; + j *= -1; + } + i *= -1; + } + // check if there is anything nonzero in elems_in_boundary + for (size_t i = 0; i != elems_in_boundary.size(); ++i) { + BOOST_CHECK(elems_in_boundary[i] == 0); + } + } +} -BOOST_AUTO_TEST_CASE(all_cells_iterator_and_boundary_iterators_in_Bitmap_cubical_complex_base_check_range_check_2) -{ - std::vector< double > expected_filtration; - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(1); - expected_filtration.push_back(1); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(1); - expected_filtration.push_back(1); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(1); - expected_filtration.push_back(1); - expected_filtration.push_back(2); - expected_filtration.push_back(2); - expected_filtration.push_back(2); - expected_filtration.push_back(3); - expected_filtration.push_back(3); - expected_filtration.push_back(2); - expected_filtration.push_back(2); - expected_filtration.push_back(2); - expected_filtration.push_back(3); - expected_filtration.push_back(3); - - std::vector<unsigned> expected_dimension; - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(2); - expected_dimension.push_back(1); - expected_dimension.push_back(2); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(2); - expected_dimension.push_back(1); - expected_dimension.push_back(2); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - - std::vector<size_t> expected_boundary; - expected_boundary.push_back(0); - expected_boundary.push_back(2); - expected_boundary.push_back(2); - expected_boundary.push_back(4); - expected_boundary.push_back(0); - expected_boundary.push_back(10); - expected_boundary.push_back(1); - expected_boundary.push_back(11); - expected_boundary.push_back(5); - expected_boundary.push_back(7); - expected_boundary.push_back(2); - expected_boundary.push_back(12); - expected_boundary.push_back(3); - expected_boundary.push_back(13); - expected_boundary.push_back(7); - expected_boundary.push_back(9); - expected_boundary.push_back(4); - expected_boundary.push_back(14); - expected_boundary.push_back(10); - expected_boundary.push_back(12); - expected_boundary.push_back(12); - expected_boundary.push_back(14); - expected_boundary.push_back(10); - expected_boundary.push_back(20); - expected_boundary.push_back(11); - expected_boundary.push_back(21); - expected_boundary.push_back(15); - expected_boundary.push_back(17); - expected_boundary.push_back(12); - expected_boundary.push_back(22); - expected_boundary.push_back(13); - expected_boundary.push_back(23); - expected_boundary.push_back(17); - expected_boundary.push_back(19); - expected_boundary.push_back(14); - expected_boundary.push_back(24); - expected_boundary.push_back(20); - expected_boundary.push_back(22); - expected_boundary.push_back(22); - expected_boundary.push_back(24); - - - std::vector<size_t> expected_coboundary; - expected_coboundary.push_back(5); - expected_coboundary.push_back(1); - expected_coboundary.push_back(6); - expected_coboundary.push_back(7); - expected_coboundary.push_back(1); - expected_coboundary.push_back(3); - expected_coboundary.push_back(8); - expected_coboundary.push_back(9); - expected_coboundary.push_back(3); - expected_coboundary.push_back(6); - expected_coboundary.push_back(6); - expected_coboundary.push_back(8); - expected_coboundary.push_back(8); - expected_coboundary.push_back(5); - expected_coboundary.push_back(15); - expected_coboundary.push_back(11); - expected_coboundary.push_back(6); - expected_coboundary.push_back(16); - expected_coboundary.push_back(7); - expected_coboundary.push_back(17); - expected_coboundary.push_back(11); - expected_coboundary.push_back(13); - expected_coboundary.push_back(8); - expected_coboundary.push_back(18); - expected_coboundary.push_back(9); - expected_coboundary.push_back(19); - expected_coboundary.push_back(13); - expected_coboundary.push_back(16); - expected_coboundary.push_back(16); - expected_coboundary.push_back(18); - expected_coboundary.push_back(18); - expected_coboundary.push_back(15); - expected_coboundary.push_back(21); - expected_coboundary.push_back(16); - expected_coboundary.push_back(17); - expected_coboundary.push_back(21); - expected_coboundary.push_back(23); - expected_coboundary.push_back(18); - expected_coboundary.push_back(19); - expected_coboundary.push_back(23); - - - - std::vector< unsigned > sizes(2); - sizes[0] = 2; - sizes[1] = 2; - - std::vector< double > data(4); - data[0] = 0; - data[1] = 1; - data[2] = 2; - data[3] = 3; - - Bitmap_cubical_complex_base ba( sizes , data ); - int i = 0; - int bd_it = 0; - int cbd_it = 0; - - Bitmap_cubical_complex_base::All_cells_range range(&ba); - for ( Bitmap_cubical_complex_base::All_cells_iterator it = range.begin() ; it != range.end() ; ++it ) - { - BOOST_CHECK( expected_filtration[i] == ba.get_cell_data( *it ) ); - BOOST_CHECK( expected_dimension[i] == ba.get_dimension_of_a_cell( *it ) ); - - Bitmap_cubical_complex_base::Boundary_range bdrange = ba.boundary_range(*it); - for ( Bitmap_cubical_complex_base::Boundary_iterator bd = bdrange.begin() ; bd != bdrange.end() ; ++bd ) - { - BOOST_CHECK( expected_boundary[bd_it] == *bd ); - ++bd_it; - } - - Bitmap_cubical_complex_base::Coboundary_range cbdrange = ba.coboundary_range(*it); - for ( Bitmap_cubical_complex_base::Coboundary_iterator cbd = cbdrange.begin() ; cbd != cbdrange.end() ; ++cbd ) - { - BOOST_CHECK( expected_coboundary[cbd_it] == *cbd ); - ++cbd_it; - } - ++i; +BOOST_AUTO_TEST_CASE(check_if_boundary_of_boundary_is_zero_non_periodic_case_4_d) { + std::vector<unsigned> sizes(4); + sizes[0] = 3; + sizes[1] = 3; + sizes[2] = 3; + sizes[3] = 3; + + std::vector<double> data(81, 0); + + int number_of_all_elements = (2 * sizes[0] + 1) * (2 * sizes[1] + 1) * (2 * sizes[2] + 1) * (2 * sizes[3] + 1); + std::vector<int> elems_in_boundary(number_of_all_elements, 0); + Bitmap_cubical_complex_base ba(sizes, data); + for (Bitmap_cubical_complex_base::All_cells_iterator it = ba.all_cells_iterator_begin(); + it != ba.all_cells_iterator_end(); ++it) { + int i = 1; + Bitmap_cubical_complex_base::Boundary_range bdrange = ba.boundary_range(*it); + for (Bitmap_cubical_complex_base::Boundary_iterator bd = bdrange.begin(); bd != bdrange.end(); ++bd) { + Bitmap_cubical_complex_base::Boundary_range second_bdrange = ba.boundary_range(*bd); + int j = 1; + for (Bitmap_cubical_complex_base::Boundary_iterator bd2 = second_bdrange.begin(); bd2 != second_bdrange.end(); + ++bd2) { + elems_in_boundary[*bd2] += i * j; + j *= -1; + } + i *= -1; } + // check if there is anything nonzero in elems_in_boundary + for (size_t i = 0; i != elems_in_boundary.size(); ++i) { + BOOST_CHECK(elems_in_boundary[i] == 0); + } + } } +BOOST_AUTO_TEST_CASE(check_if_boundary_of_boundary_is_zero_periodic_case_2d) { + std::vector<unsigned> sizes(2); + sizes[0] = 3; + sizes[1] = 3; + + std::vector<bool> directions_of_periodicity(2, true); + std::vector<double> data(9, 0); + + int number_of_all_elements = (2 * sizes[0]) * (2 * sizes[1]); // *(2*sizes[2]); + std::vector<int> elems_in_boundary(number_of_all_elements, 0); + Bitmap_cubical_complex_periodic_boundary_conditions ba(sizes, data, directions_of_periodicity); + for (Bitmap_cubical_complex_periodic_boundary_conditions::All_cells_iterator it = ba.all_cells_iterator_begin(); + it != ba.all_cells_iterator_end(); ++it) { + int i = 1; + + // std::cout << "Element : " << *it << std::endl; + + Bitmap_cubical_complex_periodic_boundary_conditions_base::Boundary_range bdrange = ba.boundary_range(*it); + for (Bitmap_cubical_complex_periodic_boundary_conditions::Boundary_iterator bd = bdrange.begin(); + bd != bdrange.end(); ++bd) { + // std::cout << *bd << " "; + Bitmap_cubical_complex_periodic_boundary_conditions::Boundary_range second_bdrange = ba.boundary_range(*bd); + int j = 1; + for (Bitmap_cubical_complex_periodic_boundary_conditions::Boundary_iterator bd2 = second_bdrange.begin(); + bd2 != second_bdrange.end(); ++bd2) { + elems_in_boundary[*bd2] += i * j; + j *= -1; + } + i *= -1; + } + // getchar(); + // check if there is anything nonzero in elems_in_boundary + for (size_t i = 0; i != elems_in_boundary.size(); ++i) { + BOOST_CHECK(elems_in_boundary[i] == 0); + } + } +} +BOOST_AUTO_TEST_CASE(check_if_boundary_of_boundary_is_zero_periodic_case_3d) { + std::vector<unsigned> sizes(3); + sizes[0] = 3; + sizes[1] = 3; + sizes[2] = 3; + + std::vector<bool> directions_of_periodicity(3, true); + + std::vector<double> data(27, 0); + + int number_of_all_elements = (2 * sizes[0]) * (2 * sizes[1]) * (2 * sizes[2]); + Bitmap_cubical_complex_periodic_boundary_conditions ba(sizes, data, directions_of_periodicity); + std::vector<int> elems_in_boundary(number_of_all_elements, 0); + for (Bitmap_cubical_complex_periodic_boundary_conditions::All_cells_iterator it = ba.all_cells_iterator_begin(); + it != ba.all_cells_iterator_end(); ++it) { + // std::cout << "Element : " << *it << std::endl; + + int i = 1; + + Bitmap_cubical_complex_periodic_boundary_conditions_base::Boundary_range bdrange = ba.boundary_range(*it); + for (Bitmap_cubical_complex_periodic_boundary_conditions::Boundary_iterator bd = bdrange.begin(); + bd != bdrange.end(); ++bd) { + Bitmap_cubical_complex_periodic_boundary_conditions::Boundary_range second_bdrange = ba.boundary_range(*bd); + // std::cout << *bd << " "; + int j = 1; + for (Bitmap_cubical_complex_periodic_boundary_conditions::Boundary_iterator bd2 = second_bdrange.begin(); + bd2 != second_bdrange.end(); ++bd2) { + elems_in_boundary[*bd2] += i * j; + j *= -1; + } + i *= -1; + } + // check if there is anything nonzero in elems_in_boundary + for (size_t i = 0; i != elems_in_boundary.size(); ++i) { + BOOST_CHECK(elems_in_boundary[i] == 0); + } + } +} +BOOST_AUTO_TEST_CASE(check_if_boundary_of_boundary_is_zero_periodic_case_4d) { + std::vector<unsigned> sizes(4); + sizes[0] = 3; + sizes[1] = 3; + sizes[2] = 3; + sizes[3] = 3; + + std::vector<bool> directions_of_periodicity(4, true); + + std::vector<double> data(81, 0); + + int number_of_all_elements = (2 * sizes[0]) * (2 * sizes[1]) * (2 * sizes[2]) * (2 * sizes[3]); + std::vector<int> elems_in_boundary(number_of_all_elements, 0); + Bitmap_cubical_complex_periodic_boundary_conditions ba(sizes, data, directions_of_periodicity); + for (Bitmap_cubical_complex_periodic_boundary_conditions::All_cells_iterator it = ba.all_cells_iterator_begin(); + it != ba.all_cells_iterator_end(); ++it) { + int i = 1; + + Bitmap_cubical_complex_periodic_boundary_conditions_base::Boundary_range bdrange = ba.boundary_range(*it); + for (Bitmap_cubical_complex_periodic_boundary_conditions::Boundary_iterator bd = bdrange.begin(); + bd != bdrange.end(); ++bd) { + Bitmap_cubical_complex_periodic_boundary_conditions::Boundary_range second_bdrange = ba.boundary_range(*bd); + int j = 1; + for (Bitmap_cubical_complex_periodic_boundary_conditions::Boundary_iterator bd2 = second_bdrange.begin(); + bd2 != second_bdrange.end(); ++bd2) { + elems_in_boundary[*bd2] += i * j; + j *= -1; + } + i *= -1; + } -BOOST_AUTO_TEST_CASE(all_cells_iterator_and_boundary_iterators_in_Bitmap_cubical_complex_base_check_range_check) -{ - std::vector< double > expected_filtration; - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(1); - expected_filtration.push_back(1); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(1); - expected_filtration.push_back(1); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(1); - expected_filtration.push_back(1); - expected_filtration.push_back(2); - expected_filtration.push_back(2); - expected_filtration.push_back(2); - expected_filtration.push_back(3); - expected_filtration.push_back(3); - expected_filtration.push_back(2); - expected_filtration.push_back(2); - expected_filtration.push_back(2); - expected_filtration.push_back(3); - expected_filtration.push_back(3); - - std::vector<unsigned> expected_dimension; - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(2); - expected_dimension.push_back(1); - expected_dimension.push_back(2); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(2); - expected_dimension.push_back(1); - expected_dimension.push_back(2); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - - std::vector<size_t> expected_boundary; - expected_boundary.push_back(0); - expected_boundary.push_back(2); - expected_boundary.push_back(2); - expected_boundary.push_back(4); - expected_boundary.push_back(0); - expected_boundary.push_back(10); - expected_boundary.push_back(1); - expected_boundary.push_back(11); - expected_boundary.push_back(5); - expected_boundary.push_back(7); - expected_boundary.push_back(2); - expected_boundary.push_back(12); - expected_boundary.push_back(3); - expected_boundary.push_back(13); - expected_boundary.push_back(7); - expected_boundary.push_back(9); - expected_boundary.push_back(4); - expected_boundary.push_back(14); - expected_boundary.push_back(10); - expected_boundary.push_back(12); - expected_boundary.push_back(12); - expected_boundary.push_back(14); - expected_boundary.push_back(10); - expected_boundary.push_back(20); - expected_boundary.push_back(11); - expected_boundary.push_back(21); - expected_boundary.push_back(15); - expected_boundary.push_back(17); - expected_boundary.push_back(12); - expected_boundary.push_back(22); - expected_boundary.push_back(13); - expected_boundary.push_back(23); - expected_boundary.push_back(17); - expected_boundary.push_back(19); - expected_boundary.push_back(14); - expected_boundary.push_back(24); - expected_boundary.push_back(20); - expected_boundary.push_back(22); - expected_boundary.push_back(22); - expected_boundary.push_back(24); - - - std::vector<size_t> expected_coboundary; - expected_coboundary.push_back(5); - expected_coboundary.push_back(1); - expected_coboundary.push_back(6); - expected_coboundary.push_back(7); - expected_coboundary.push_back(1); - expected_coboundary.push_back(3); - expected_coboundary.push_back(8); - expected_coboundary.push_back(9); - expected_coboundary.push_back(3); - expected_coboundary.push_back(6); - expected_coboundary.push_back(6); - expected_coboundary.push_back(8); - expected_coboundary.push_back(8); - expected_coboundary.push_back(5); - expected_coboundary.push_back(15); - expected_coboundary.push_back(11); - expected_coboundary.push_back(6); - expected_coboundary.push_back(16); - expected_coboundary.push_back(7); - expected_coboundary.push_back(17); - expected_coboundary.push_back(11); - expected_coboundary.push_back(13); - expected_coboundary.push_back(8); - expected_coboundary.push_back(18); - expected_coboundary.push_back(9); - expected_coboundary.push_back(19); - expected_coboundary.push_back(13); - expected_coboundary.push_back(16); - expected_coboundary.push_back(16); - expected_coboundary.push_back(18); - expected_coboundary.push_back(18); - expected_coboundary.push_back(15); - expected_coboundary.push_back(21); - expected_coboundary.push_back(16); - expected_coboundary.push_back(17); - expected_coboundary.push_back(21); - expected_coboundary.push_back(23); - expected_coboundary.push_back(18); - expected_coboundary.push_back(19); - expected_coboundary.push_back(23); - - - - std::vector< unsigned > sizes(2); - sizes[0] = 2; - sizes[1] = 2; - - std::vector< double > data(4); - data[0] = 0; - data[1] = 1; - data[2] = 2; - data[3] = 3; - - Bitmap_cubical_complex_base ba( sizes , data ); - int i = 0; - int bd_it = 0; - int cbd_it = 0; - - Bitmap_cubical_complex_base::All_cells_range range = ba.all_cells_range(); - for ( Bitmap_cubical_complex_base::All_cells_iterator it = range.begin() ; it != range.end() ; ++it ) - { - BOOST_CHECK( expected_filtration[i] == ba.get_cell_data( *it ) ); - BOOST_CHECK( expected_dimension[i] == ba.get_dimension_of_a_cell( *it ) ); - - Bitmap_cubical_complex_base::Boundary_range bdrange = ba.boundary_range(*it); - for ( Bitmap_cubical_complex_base::Boundary_iterator bd = bdrange.begin() ; bd != bdrange.end() ; ++bd ) - { - BOOST_CHECK( expected_boundary[bd_it] == *bd ); - ++bd_it; - } - - Bitmap_cubical_complex_base::Coboundary_range cbdrange = ba.coboundary_range(*it); - for ( Bitmap_cubical_complex_base::Coboundary_iterator cbd = cbdrange.begin() ; cbd != cbdrange.end() ; ++cbd ) - { - BOOST_CHECK( expected_coboundary[cbd_it] == *cbd ); - ++cbd_it; - } - ++i; + // check if there is anything nonzero in elems_in_boundary + for (size_t i = 0; i != elems_in_boundary.size(); ++i) { + BOOST_CHECK(elems_in_boundary[i] == 0); } + } } -BOOST_AUTO_TEST_CASE(Top_dimensional_cells_iterator_range_check) -{ - std::vector< double > expected_filtration; - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(1); - expected_filtration.push_back(1); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(1); - expected_filtration.push_back(1); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(1); - expected_filtration.push_back(1); - expected_filtration.push_back(2); - expected_filtration.push_back(2); - expected_filtration.push_back(2); - expected_filtration.push_back(3); - expected_filtration.push_back(3); - expected_filtration.push_back(2); - expected_filtration.push_back(2); - expected_filtration.push_back(2); - expected_filtration.push_back(3); - expected_filtration.push_back(3); - - - std::vector< unsigned > sizes(2); - sizes[0] = 2; - sizes[1] = 2; - - std::vector< double > data(4); - data[0] = 0; - data[1] = 1; - data[2] = 2; - data[3] = 3; - - Bitmap_cubical_complex_base ba( sizes , data ); - int i = 0; - - Bitmap_cubical_complex_base::Top_dimensional_cells_range range = ba.top_dimensional_cells_range(); - for ( Bitmap_cubical_complex_base::Top_dimensional_cells_iterator it = range.begin() ; it != range.end() ; ++it ) - { - BOOST_CHECK( data[i] == ba.get_cell_data( *it ) ); - BOOST_CHECK( ba.get_dimension_of_a_cell( *it ) == 2 ); - ++i; +BOOST_AUTO_TEST_CASE(compute_incidence_between_cells_test) { + std::vector<unsigned> sizes(3); + sizes[0] = 3; + sizes[1] = 3; + sizes[2] = 3; + + std::vector<double> data(27, 0); + + int number_of_all_elements = (2 * sizes[0] + 1) * (2 * sizes[1] + 1) * (2 * sizes[1] + 1); + Bitmap_cubical_complex_base ba(sizes, data); + std::vector<int> elems_in_boundary(number_of_all_elements, 0); + for (Bitmap_cubical_complex_base::All_cells_iterator it = ba.all_cells_iterator_begin(); + it != ba.all_cells_iterator_end(); ++it) { + Bitmap_cubical_complex_base::Boundary_range bdrange = ba.boundary_range(*it); + for (Bitmap_cubical_complex_base::Boundary_iterator bd = bdrange.begin(); bd != bdrange.end(); ++bd) { + Bitmap_cubical_complex_base::Boundary_range second_bdrange = ba.boundary_range(*bd); + for (Bitmap_cubical_complex_base::Boundary_iterator bd2 = second_bdrange.begin(); bd2 != second_bdrange.end(); + ++bd2) { + elems_in_boundary[*bd2] += + ba.compute_incidence_between_cells(*it, *bd) * ba.compute_incidence_between_cells(*bd, *bd2); + } } + // check if there is anything nonzero in elems_in_boundary + for (size_t i = 0; i != elems_in_boundary.size(); ++i) { + BOOST_CHECK(elems_in_boundary[i] == 0); + } + } } +BOOST_AUTO_TEST_CASE(compute_incidence_between_cells_test_periodic_boundary_conditions) { + std::vector<unsigned> sizes(3); + sizes[0] = 3; + sizes[1] = 3; + sizes[2] = 3; + + std::vector<bool> directions_of_periodicity(3, true); + std::vector<double> data(27, 0); + + int number_of_all_elements = (2 * sizes[0]) * (2 * sizes[1]) * (2 * sizes[2]); + Bitmap_cubical_complex_periodic_boundary_conditions ba(sizes, data, directions_of_periodicity); + + std::vector<int> elems_in_boundary(number_of_all_elements, 0); + for (Bitmap_cubical_complex_periodic_boundary_conditions::All_cells_iterator it = ba.all_cells_iterator_begin(); + it != ba.all_cells_iterator_end(); ++it) { + Bitmap_cubical_complex_periodic_boundary_conditions_base::Boundary_range bdrange = ba.boundary_range(*it); + for (Bitmap_cubical_complex_periodic_boundary_conditions::Boundary_iterator bd = bdrange.begin(); + bd != bdrange.end(); ++bd) { + // std::cout << *bd << " "; + Bitmap_cubical_complex_periodic_boundary_conditions::Boundary_range second_bdrange = ba.boundary_range(*bd); + for (Bitmap_cubical_complex_periodic_boundary_conditions::Boundary_iterator bd2 = second_bdrange.begin(); + bd2 != second_bdrange.end(); ++bd2) { + elems_in_boundary[*bd2] += + ba.compute_incidence_between_cells(*it, *bd) * ba.compute_incidence_between_cells(*bd, *bd2); + } + } + // check if there is anything nonzero in elems_in_boundary + for (size_t i = 0; i != elems_in_boundary.size(); ++i) { + BOOST_CHECK(elems_in_boundary[i] == 0); + } + } +} diff --git a/src/Bitmap_cubical_complex/utilities/Bitmap_cubical_complex.cpp b/src/Bitmap_cubical_complex/utilities/Bitmap_cubical_complex.cpp index e126caea..9d1bc08c 100644 --- a/src/Bitmap_cubical_complex/utilities/Bitmap_cubical_complex.cpp +++ b/src/Bitmap_cubical_complex/utilities/Bitmap_cubical_complex.cpp @@ -20,7 +20,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ - #include <gudhi/reader_utils.h> #include <gudhi/Bitmap_cubical_complex.h> #include <gudhi/Persistent_cohomology.h> @@ -32,16 +31,18 @@ #include <cstddef> int main(int argc, char** argv) { - std::cout << "This program computes persistent homology, by using the Bitmap_cubical_complex_base class, of cubical " << - "complexes provided in text files in Perseus style. The only number in the first line is a dimension D of a" << - "bitmap. In the lines I between 2 and D+1 there are numbers of top dimensional cells in the direction I. Let " << - "N denote product of the numbers in the lines between 2 and D. In the lines D+2 to D+2+N there are " << - "filtrations of top dimensional cells. We assume that the cells are in the lexicographical order. See " << - "CubicalOneSphere.txt or CubicalTwoSphere.txt for example.\n" << std::endl; + std::cout + << "This program computes persistent homology, by using bitmap_cubical_complex class, of cubical " + << "complexes provided in text files in Perseus style (the only numbered in the first line is a dimension D of a" + << "bitmap. In the lines I between 2 and D+1 there are numbers of top dimensional cells in the direction I. Let " + << "N denote product of the numbers in the lines between 2 and D. In the lines D+2 to D+2+N there are " + << "filtrations of top dimensional cells. We assume that the cells are in the lexicographical order. See " + << "CubicalOneSphere.txt or CubicalTwoSphere.txt for example.\n" + << std::endl; if (argc != 2) { - std::cerr << "Wrong number of parameters. Please provide the name of a file with a Perseus style bitmap at " << - "the input. The program will now terminate.\n"; + std::cerr << "Wrong number of parameters. Please provide the name of a file with a Perseus style bitmap at " + << "the input. The program will now terminate.\n"; return 1; } @@ -54,7 +55,7 @@ int main(int argc, char** argv) { // Compute the persistence diagram of the complex Persistent_cohomology pcoh(b); - int p = 2; + int p = 11; double min_persistence = 0; pcoh.init_coefficients(p); // initializes the coefficient field for homology @@ -66,7 +67,7 @@ int main(int argc, char** argv) { std::size_t last_in_path = output_file_name.find_last_of("/\\"); if (last_in_path != std::string::npos) { - output_file_name = output_file_name.substr(last_in_path+1); + output_file_name = output_file_name.substr(last_in_path + 1); } std::ofstream out(output_file_name.c_str()); @@ -77,4 +78,3 @@ int main(int argc, char** argv) { return 0; } - diff --git a/src/Bitmap_cubical_complex/utilities/Bitmap_cubical_complex_periodic_boundary_conditions.cpp b/src/Bitmap_cubical_complex/utilities/Bitmap_cubical_complex_periodic_boundary_conditions.cpp index 7f9296a6..c812cb3a 100644 --- a/src/Bitmap_cubical_complex/utilities/Bitmap_cubical_complex_periodic_boundary_conditions.cpp +++ b/src/Bitmap_cubical_complex/utilities/Bitmap_cubical_complex_periodic_boundary_conditions.cpp @@ -20,7 +20,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ - #include <gudhi/reader_utils.h> #include <gudhi/Bitmap_cubical_complex.h> #include <gudhi/Bitmap_cubical_complex_periodic_boundary_conditions_base.h> @@ -33,22 +32,24 @@ #include <string> int main(int argc, char** argv) { - std::cout << "This program computes persistent homology, by using the " << - "Bitmap_cubical_complex_periodic_boundary_conditions class, of cubical complexes provided in text files in " << - "Perseus style. The only number in the first line is a dimension D of a bitmap. In the lines I between 2 " << - "and D+1 there are numbers of top dimensional cells in the direction I. Let N denote product of the numbers " << - "in the lines between 2 and D. In the lines D+2 to D+2+N there are filtrations of top dimensional cells. We " << - "assume that the cells are in the lexicographical order. See CubicalOneSphere.txt or CubicalTwoSphere.txt for" << - " example.\n" << std::endl; + std::cout + << "This program computes persistent homology, by using " + << "Bitmap_cubical_complex_periodic_boundary_conditions class, of cubical complexes provided in text files in " + << "Perseus style (the only numbered in the first line is a dimension D of a bitmap. In the lines I between 2 " + << "and D+1 there are numbers of top dimensional cells in the direction I. Let N denote product of the numbers " + << "in the lines between 2 and D. In the lines D+2 to D+2+N there are filtrations of top dimensional cells. We " + << "assume that the cells are in the lexicographical order. See CubicalOneSphere.txt or CubicalTwoSphere.txt for" + << " example.\n" + << std::endl; if (argc != 2) { - std::cerr << "Wrong number of parameters. Please provide the name of a file with a Perseus style bitmap at " << - "the input. The program will now terminate.\n"; + std::cerr << "Wrong number of parameters. Please provide the name of a file with a Perseus style bitmap at " + << "the input. The program will now terminate.\n"; return 1; } typedef Gudhi::cubical_complex::Bitmap_cubical_complex_periodic_boundary_conditions_base<double> Bitmap_base; - typedef Gudhi::cubical_complex::Bitmap_cubical_complex< Bitmap_base > Bitmap_cubical_complex; + typedef Gudhi::cubical_complex::Bitmap_cubical_complex<Bitmap_base> Bitmap_cubical_complex; Bitmap_cubical_complex b(argv[1]); @@ -57,7 +58,7 @@ int main(int argc, char** argv) { // Compute the persistence diagram of the complex Persistent_cohomology pcoh(b, true); - int p = 2; + int p = 11; double min_persistence = 0; pcoh.init_coefficients(p); // initializes the coefficient field for homology pcoh.compute_persistent_cohomology(min_persistence); @@ -68,7 +69,7 @@ int main(int argc, char** argv) { std::size_t last_in_path = output_file_name.find_last_of("/\\"); if (last_in_path != std::string::npos) { - output_file_name = output_file_name.substr(last_in_path+1); + output_file_name = output_file_name.substr(last_in_path + 1); } std::ofstream out(output_file_name.c_str()); @@ -79,4 +80,3 @@ int main(int argc, char** argv) { return 0; } - diff --git a/src/Bottleneck_distance/example/CMakeLists.txt b/src/Bottleneck_distance/example/CMakeLists.txt index 2ae45dc5..6095d6eb 100644 --- a/src/Bottleneck_distance/example/CMakeLists.txt +++ b/src/Bottleneck_distance/example/CMakeLists.txt @@ -8,6 +8,7 @@ if (NOT CGAL_VERSION VERSION_LESS 4.8.1) if (TBB_FOUND) target_link_libraries(alpha_rips_persistence_bottleneck_distance ${TBB_LIBRARIES}) + target_link_libraries(bottleneck_basic_example ${TBB_LIBRARIES}) endif(TBB_FOUND) add_test(NAME Bottleneck_distance_example_basic COMMAND $<TARGET_FILE:bottleneck_basic_example>) diff --git a/src/Doxyfile b/src/Doxyfile index 7b506e42..d11c12a7 100644 --- a/src/Doxyfile +++ b/src/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = "GUDHI" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = "2.0.1-rc2" +PROJECT_NUMBER = "2.0.1" # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/src/Persistent_cohomology/doc/Intro_persistent_cohomology.h b/src/Persistent_cohomology/doc/Intro_persistent_cohomology.h index 576a1af8..62bbbfc5 100644 --- a/src/Persistent_cohomology/doc/Intro_persistent_cohomology.h +++ b/src/Persistent_cohomology/doc/Intro_persistent_cohomology.h @@ -172,8 +172,8 @@ Alpha_complex/alpha_complex_3d_persistence.cpp</a> computes the persistent homol 2 1 0.0934117 1.00003 2 2 0.56444 1.03938 \endcode -\li <a href="_persistent_cohomology_2exact_alpha_complex_3d_persistence_8cpp-example.html"> -Persistent_cohomology/exact_alpha_complex_3d_persistence.cpp</a> computes the persistent homology with +\li <a href="_alpha_complex_2exact_alpha_complex_3d_persistence_8cpp-example.html"> +Alpha_complex/exact_alpha_complex_3d_persistence.cpp</a> computes the persistent homology with \f$\mathbb{Z}/2\mathbb{Z}\f$ coefficients of the alpha complex on points sampling from an OFF file. Here, as CGAL computes the exact values, it is slower, but it is necessary when points are on a grid for instance. @@ -182,17 +182,17 @@ for instance. 2 0 0 inf 2 2 0.0002 0.2028 \endcode -\li <a href="_persistent_cohomology_2weighted_alpha_complex_3d_persistence_8cpp-example.html"> -Persistent_cohomology/weighted_alpha_complex_3d_persistence.cpp</a> computes the persistent homology with +\li <a href="_alpha_complex_2weighted_alpha_complex_3d_persistence_8cpp-example.html"> +Alpha_complex/weighted_alpha_complex_3d_persistence.cpp</a> computes the persistent homology with \f$\mathbb{Z}/2\mathbb{Z}\f$ coefficients of the weighted alpha complex on points sampling from an OFF file and a weights file. \code $> ./weighted_alpha_complex_3d_persistence ../../data/points/tore3D_300.off ../../data/points/tore3D_300.weights 2 0.45 \endcode \code Simplex_tree dim: 3 -2 -0 0 inf -2 1 0.0682162 1.0001 -2 1 0.0934117 1.00003 -2 2 0.56444 1.03938 \endcode +2 0 -1 inf +2 1 -0.931784 0.000103311 +2 1 -0.906588 2.60165e-05 +2 2 -0.43556 0.0393798 \endcode \li <a href="_alpha_complex_2alpha_complex_persistence_8cpp-example.html"> Alpha_complex/alpha_complex_persistence.cpp</a> computes the persistent homology with @@ -208,7 +208,8 @@ Simplex_tree dim: 3 \li <a href="_alpha_complex_2periodic_alpha_complex_3d_persistence_8cpp-example.html"> Alpha_complex/periodic_alpha_complex_3d_persistence.cpp</a> computes the persistent homology with \f$\mathbb{Z}/2\mathbb{Z}\f$ coefficients of the periodic alpha complex on points sampling from an OFF file. -\code $> ./periodic_alpha_complex_3d_persistence ../../data/points/grid_10_10_10_in_0_1.off 3 1.0 \endcode +\code $> ./periodic_alpha_complex_3d_persistence ../../data/points/grid_10_10_10_in_0_1.off +../../data/points/iso_cuboid_3_in_0_1.txt 3 1.0 \endcode \code Periodic Delaunay computed. Simplex_tree dim: 3 3 0 0 inf diff --git a/src/Persistent_cohomology/example/persistence_from_simple_simplex_tree.cpp b/src/Persistent_cohomology/example/persistence_from_simple_simplex_tree.cpp index 8214d66a..8ef479d4 100644 --- a/src/Persistent_cohomology/example/persistence_from_simple_simplex_tree.cpp +++ b/src/Persistent_cohomology/example/persistence_from_simple_simplex_tree.cpp @@ -142,7 +142,6 @@ int main(int argc, char * const argv[]) { /* An edge [11,6] */ /* An edge [10,12,2] */ - st.set_dimension(2); std::cout << "The complex contains " << st.num_simplices() << " simplices - " << st.num_vertices() << " vertices " << std::endl; diff --git a/src/Persistent_cohomology/example/plain_homology.cpp b/src/Persistent_cohomology/example/plain_homology.cpp index 50f692f2..a5ae09c8 100644 --- a/src/Persistent_cohomology/example/plain_homology.cpp +++ b/src/Persistent_cohomology/example/plain_homology.cpp @@ -64,8 +64,6 @@ int main() { st.insert_simplex_and_subfaces(edge03); st.insert_simplex(edge13); st.insert_simplex(vertex4); - // FIXME: Remove this line - st.set_dimension(2); // Sort the simplices in the order of the filtration st.initialize_filtration(); diff --git a/src/Persistent_cohomology/example/weighted_periodic_alpha_complex_3d_persistence.cpp b/src/Persistent_cohomology/example/weighted_periodic_alpha_complex_3d_persistence.cpp new file mode 100644 index 00000000..13634ff7 --- /dev/null +++ b/src/Persistent_cohomology/example/weighted_periodic_alpha_complex_3d_persistence.cpp @@ -0,0 +1,281 @@ +/* This file is part of the Gudhi Library. The Gudhi library + * (Geometric Understanding in Higher Dimensions) is a generic C++ + * library for computational topology. + * + * Author(s): Vincent Rouvreau + * + * Copyright (C) 2014 INRIA + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <boost/variant.hpp> + +#include <gudhi/Simplex_tree.h> +#include <gudhi/Persistent_cohomology.h> +#include <gudhi/Points_3D_off_io.h> + +#include <CGAL/Exact_predicates_inexact_constructions_kernel.h> +#include <CGAL/Periodic_3_regular_triangulation_traits_3.h> +#include <CGAL/Periodic_3_regular_triangulation_3.h> +#include <CGAL/Alpha_shape_3.h> +#include <CGAL/iterator.h> + +#include <fstream> +#include <cmath> +#include <string> +#include <tuple> +#include <map> +#include <utility> +#include <list> +#include <vector> +#include <cstdlib> + +#include "alpha_complex_3d_helper.h" + +// Traits +using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel; +using PK = CGAL::Periodic_3_regular_triangulation_traits_3<Kernel>; + +// Vertex type +using DsVb = CGAL::Periodic_3_triangulation_ds_vertex_base_3<>; +using Vb = CGAL::Regular_triangulation_vertex_base_3<PK,DsVb>; +using AsVb = CGAL::Alpha_shape_vertex_base_3<PK,Vb>; +// Cell type +using DsCb = CGAL::Periodic_3_triangulation_ds_cell_base_3<>; +using Cb = CGAL::Regular_triangulation_cell_base_3<PK,DsCb>; +using AsCb = CGAL::Alpha_shape_cell_base_3<PK,Cb>; +using Tds = CGAL::Triangulation_data_structure_3<AsVb,AsCb>; +using P3RT3 = CGAL::Periodic_3_regular_triangulation_3<PK,Tds>; +using Alpha_shape_3 = CGAL::Alpha_shape_3<P3RT3>; + +using Point_3 = P3RT3::Bare_point; +using Weighted_point_3 = P3RT3::Weighted_point; + +// filtration with alpha values needed type definition +using Alpha_value_type = Alpha_shape_3::FT; +using Object = CGAL::Object; +using Dispatch = + CGAL::Dispatch_output_iterator<CGAL::cpp11::tuple<Object, Alpha_value_type>, + CGAL::cpp11::tuple<std::back_insert_iterator<std::vector<Object> >, + std::back_insert_iterator<std::vector<Alpha_value_type> > > >; +using Cell_handle = Alpha_shape_3::Cell_handle; +using Facet = Alpha_shape_3::Facet; +using Edge_3 = Alpha_shape_3::Edge; +using Vertex_handle = Alpha_shape_3::Vertex_handle; +using Vertex_list = std::list<Alpha_shape_3::Vertex_handle>; + +// gudhi type definition +using ST = Gudhi::Simplex_tree<Gudhi::Simplex_tree_options_fast_persistence>; +using Filtration_value = ST::Filtration_value; +using Simplex_tree_vertex = ST::Vertex_handle; +using Alpha_shape_simplex_tree_map = std::map<Alpha_shape_3::Vertex_handle, Simplex_tree_vertex>; +using Alpha_shape_simplex_tree_pair = std::pair<Alpha_shape_3::Vertex_handle, Simplex_tree_vertex>; +using Simplex_tree_vector_vertex = std::vector<Simplex_tree_vertex>; +using Persistent_cohomology = + Gudhi::persistent_cohomology::Persistent_cohomology<ST, Gudhi::persistent_cohomology::Field_Zp>; + +void usage(const std::string& progName) { + std::cerr << "Usage: " << progName << " path_to_the_OFF_file path_to_weight_file path_to_the_cuboid_file " + "coeff_field_characteristic[integer > 0] min_persistence[float >= -1.0]\n"; + exit(-1); +} + +int main(int argc, char* const argv[]) { + // program args management + if (argc != 6) { + std::cerr << "Error: Number of arguments (" << argc << ") is not correct\n"; + usage(argv[0]); + } + + int coeff_field_characteristic = atoi(argv[4]); + Filtration_value min_persistence = strtof(argv[5], nullptr); + + // Read points from file + std::string offInputFile(argv[1]); + // Read the OFF file (input file name given as parameter) and triangulate points + Gudhi::Points_3D_off_reader<Point_3> off_reader(offInputFile); + // Check the read operation was correct + if (!off_reader.is_valid()) { + std::cerr << "Unable to read file " << offInputFile << std::endl; + usage(argv[0]); + } + + // Retrieve the triangulation + std::vector<Point_3> lp = off_reader.get_point_cloud(); + + // Read weights information from file + std::ifstream weights_ifstr(argv[2]); + std::vector<Weighted_point_3> wp; + if (weights_ifstr.good()) { + double weight = 0.0; + std::size_t index = 0; + wp.reserve(lp.size()); + // Attempt read the weight in a double format, return false if it fails + while ((weights_ifstr >> weight) && (index < lp.size())) { + wp.push_back(Weighted_point_3(lp[index], weight)); + index++; + } + if (index != lp.size()) { + std::cerr << "Bad number of weights in file " << argv[2] << std::endl; + usage(argv[0]); + } + } else { + std::cerr << "Unable to read file " << argv[2] << std::endl; + usage(argv[0]); + } + + // Read iso_cuboid_3 information from file + std::ifstream iso_cuboid_str(argv[3]); + double x_min, y_min, z_min, x_max, y_max, z_max; + if (iso_cuboid_str.good()) { + iso_cuboid_str >> x_min >> y_min >> z_min >> x_max >> y_max >> z_max; + } else { + std::cerr << "Unable to read file " << argv[3] << std::endl; + usage(argv[0]); + } + + // Define the periodic cube + P3RT3 prt(PK::Iso_cuboid_3(x_min, y_min, z_min, x_max, y_max, z_max)); + // Heuristic for inserting large point sets (if pts is reasonably large) + prt.insert(wp.begin(), wp.end(), true); + // As prt won't be modified anymore switch to 1-sheeted cover if possible + if (prt.is_triangulation_in_1_sheet()) prt.convert_to_1_sheeted_covering(); + std::cout << "Periodic Delaunay computed." << std::endl; + + // alpha shape construction from points. CGAL has a strange behavior in REGULARIZED mode. This is the default mode + // Maybe need to set it to GENERAL mode + Alpha_shape_3 as(prt, 0, Alpha_shape_3::GENERAL); + + // filtration with alpha values from alpha shape + std::vector<Object> the_objects; + std::vector<Alpha_value_type> the_alpha_values; + + Dispatch disp = CGAL::dispatch_output<Object, Alpha_value_type>(std::back_inserter(the_objects), + std::back_inserter(the_alpha_values)); + + as.filtration_with_alpha_values(disp); +#ifdef DEBUG_TRACES + std::cout << "filtration_with_alpha_values returns : " << the_objects.size() << " objects" << std::endl; +#endif // DEBUG_TRACES + + Alpha_shape_3::size_type count_vertices = 0; + Alpha_shape_3::size_type count_edges = 0; + Alpha_shape_3::size_type count_facets = 0; + Alpha_shape_3::size_type count_cells = 0; + + // Loop on objects vector + Vertex_list vertex_list; + ST simplex_tree; + Alpha_shape_simplex_tree_map map_cgal_simplex_tree; + std::vector<Alpha_value_type>::iterator the_alpha_value_iterator = the_alpha_values.begin(); + int dim_max = 0; + Filtration_value filtration_max = 0.0; + for (auto object_iterator : the_objects) { + // Retrieve Alpha shape vertex list from object + if (const Cell_handle* cell = CGAL::object_cast<Cell_handle>(&object_iterator)) { + vertex_list = from_cell<Vertex_list, Cell_handle>(*cell); + count_cells++; + if (dim_max < 3) { + // Cell is of dim 3 + dim_max = 3; + } + } else if (const Facet* facet = CGAL::object_cast<Facet>(&object_iterator)) { + vertex_list = from_facet<Vertex_list, Facet>(*facet); + count_facets++; + if (dim_max < 2) { + // Facet is of dim 2 + dim_max = 2; + } + } else if (const Edge_3* edge = CGAL::object_cast<Edge_3>(&object_iterator)) { + vertex_list = from_edge<Vertex_list, Edge_3>(*edge); + count_edges++; + if (dim_max < 1) { + // Edge_3 is of dim 1 + dim_max = 1; + } + } else if (const Vertex_handle* vertex = CGAL::object_cast<Vertex_handle>(&object_iterator)) { + count_vertices++; + vertex_list = from_vertex<Vertex_list, Vertex_handle>(*vertex); + } + // Construction of the vector of simplex_tree vertex from list of alpha_shapes vertex + Simplex_tree_vector_vertex the_simplex_tree; + for (auto the_alpha_shape_vertex : vertex_list) { + Alpha_shape_simplex_tree_map::iterator the_map_iterator = map_cgal_simplex_tree.find(the_alpha_shape_vertex); + if (the_map_iterator == map_cgal_simplex_tree.end()) { + // alpha shape not found + Simplex_tree_vertex vertex = map_cgal_simplex_tree.size(); +#ifdef DEBUG_TRACES + std::cout << "vertex [" << the_alpha_shape_vertex->point() << "] not found - insert " << vertex << std::endl; +#endif // DEBUG_TRACES + the_simplex_tree.push_back(vertex); + map_cgal_simplex_tree.insert(Alpha_shape_simplex_tree_pair(the_alpha_shape_vertex, vertex)); + } else { + // alpha shape found + Simplex_tree_vertex vertex = the_map_iterator->second; +#ifdef DEBUG_TRACES + std::cout << "vertex [" << the_alpha_shape_vertex->point() << "] found in " << vertex << std::endl; +#endif // DEBUG_TRACES + the_simplex_tree.push_back(vertex); + } + } + // Construction of the simplex_tree + Filtration_value filtr = /*std::sqrt*/ (*the_alpha_value_iterator); +#ifdef DEBUG_TRACES + std::cout << "filtration = " << filtr << std::endl; +#endif // DEBUG_TRACES + if (filtr > filtration_max) { + filtration_max = filtr; + } + simplex_tree.insert_simplex(the_simplex_tree, filtr); + if (the_alpha_value_iterator != the_alpha_values.end()) + ++the_alpha_value_iterator; + else + std::cout << "This shall not happen" << std::endl; + } + +#ifdef DEBUG_TRACES + std::cout << "vertices \t\t" << count_vertices << std::endl; + std::cout << "edges \t\t" << count_edges << std::endl; + std::cout << "facets \t\t" << count_facets << std::endl; + std::cout << "cells \t\t" << count_cells << std::endl; + + std::cout << "Information of the Simplex Tree: " << std::endl; + std::cout << " Number of vertices = " << simplex_tree.num_vertices() << " "; + std::cout << " Number of simplices = " << simplex_tree.num_simplices() << std::endl << std::endl; + std::cout << " Dimension = " << simplex_tree.dimension() << " "; +#endif // DEBUG_TRACES + +#ifdef DEBUG_TRACES + std::cout << "Iterator on vertices: " << std::endl; + for (auto vertex : simplex_tree.complex_vertex_range()) { + std::cout << vertex << " "; + } +#endif // DEBUG_TRACES + + // Sort the simplices in the order of the filtration + simplex_tree.initialize_filtration(); + + std::cout << "Simplex_tree dim: " << simplex_tree.dimension() << std::endl; + // Compute the persistence diagram of the complex + Persistent_cohomology pcoh(simplex_tree, true); + // initializes the coefficient field for homology + pcoh.init_coefficients(coeff_field_characteristic); + + pcoh.compute_persistent_cohomology(min_persistence); + + pcoh.output_diagram(); + + return 0; +} diff --git a/src/Persistent_cohomology/test/betti_numbers_unit_test.cpp b/src/Persistent_cohomology/test/betti_numbers_unit_test.cpp index da418034..0a08d200 100644 --- a/src/Persistent_cohomology/test/betti_numbers_unit_test.cpp +++ b/src/Persistent_cohomology/test/betti_numbers_unit_test.cpp @@ -62,8 +62,6 @@ BOOST_AUTO_TEST_CASE( plain_homology_betti_numbers ) st.insert_simplex_and_subfaces(edge04); st.insert_simplex(edge14); st.insert_simplex(vertex5); - // FIXME: Remove this line - st.set_dimension(3); // Sort the simplices in the order of the filtration st.initialize_filtration(); @@ -170,8 +168,6 @@ BOOST_AUTO_TEST_CASE( betti_numbers ) st.insert_simplex_and_subfaces(edge04, 2.0); st.insert_simplex(edge14, 2.0); st.insert_simplex(vertex5, 1.0); - // FIXME: Remove this line - st.set_dimension(3); // Sort the simplices in the order of the filtration st.initialize_filtration(); diff --git a/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp b/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp index f53987b6..a1c106d5 100644 --- a/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp +++ b/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp @@ -196,8 +196,6 @@ BOOST_AUTO_TEST_CASE( persistence_constructor_exception ) // To make number of simplices = 255 const short simplex_0[] = {0, 1, 2, 3, 4, 5, 6, 7}; st.insert_simplex_and_subfaces(simplex_0); - // FIXME: Remove this line - st.set_dimension(8); // Sort the simplices in the order of the filtration st.initialize_filtration(); diff --git a/src/Simplex_tree/doc/Intro_simplex_tree.h b/src/Simplex_tree/doc/Intro_simplex_tree.h index f5b72ff6..769491d9 100644 --- a/src/Simplex_tree/doc/Intro_simplex_tree.h +++ b/src/Simplex_tree/doc/Intro_simplex_tree.h @@ -67,10 +67,13 @@ Information of the Simplex Tree: Number of vertices = 10 Number of simplices = 98 \endcode * * \li <a href="_simplex_tree_2example_alpha_shapes_3_simplex_tree_from_off_file_8cpp-example.html"> - * Simplex_tree/example_alpha_shapes_3_simplex_tree_from_off_file.cpp</a> - Simplex tree is computed and displayed from a 3D alpha - * complex (Requires CGAL, GMP and GMPXX to be installed) - * + * Simplex_tree/example_alpha_shapes_3_simplex_tree_from_off_file.cpp</a> - Simplex tree is computed and displayed + * from a 3D alpha complex (Requires CGAL, GMP and GMPXX to be installed). * + * \li <a href="_simplex_tree_2graph_expansion_with_blocker_8cpp-example.html"> + * Simplex_tree/graph_expansion_with_blocker.cpp</a> - Simple simplex tree construction from a one-skeleton graph with + * a simple blocker expansion method. + * * \subsection filteredcomplexeshassecomplex Hasse complex * The second one is the Hasse_complex. The Hasse complex is a data structure representing explicitly all co-dimension * 1 incidence relations in a complex. It is consequently faster when accessing the boundary of a simplex, but is less diff --git a/src/Simplex_tree/example/CMakeLists.txt b/src/Simplex_tree/example/CMakeLists.txt index e22cc92c..8bc4ad53 100644 --- a/src/Simplex_tree/example/CMakeLists.txt +++ b/src/Simplex_tree/example/CMakeLists.txt @@ -34,5 +34,12 @@ if(GMP_FOUND AND CGAL_FOUND) "${CMAKE_SOURCE_DIR}/data/points/bunny_5000.off") install(TARGETS Simplex_tree_example_alpha_shapes_3_from_off DESTINATION bin) +endif() +add_executable ( Simplex_tree_example_graph_expansion_with_blocker graph_expansion_with_blocker.cpp ) +if (TBB_FOUND) + target_link_libraries(Simplex_tree_example_graph_expansion_with_blocker ${TBB_LIBRARIES}) endif() +add_test(NAME Simplex_tree_example_graph_expansion_with_blocker COMMAND $<TARGET_FILE:Simplex_tree_example_graph_expansion_with_blocker>) + +install(TARGETS Simplex_tree_example_graph_expansion_with_blocker DESTINATION bin) diff --git a/src/Simplex_tree/example/graph_expansion_with_blocker.cpp b/src/Simplex_tree/example/graph_expansion_with_blocker.cpp new file mode 100644 index 00000000..86bfb8cb --- /dev/null +++ b/src/Simplex_tree/example/graph_expansion_with_blocker.cpp @@ -0,0 +1,79 @@ +/* This file is part of the Gudhi Library. The Gudhi library + * (Geometric Understanding in Higher Dimensions) is a generic C++ + * library for computational topology. + * + * Author(s): Vincent Rouvreau + * + * Copyright (C) 2014 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <gudhi/Simplex_tree.h> + +#include <iostream> + +using Simplex_tree = Gudhi::Simplex_tree<>; +using Simplex_handle = Simplex_tree::Simplex_handle; + +int main(int argc, char * const argv[]) { + + // Construct the Simplex Tree with a 1-skeleton graph example + Simplex_tree simplexTree; + + simplexTree.insert_simplex({0, 1}, 0.); + simplexTree.insert_simplex({0, 2}, 1.); + simplexTree.insert_simplex({0, 3}, 2.); + simplexTree.insert_simplex({1, 2}, 3.); + simplexTree.insert_simplex({1, 3}, 4.); + simplexTree.insert_simplex({2, 3}, 5.); + simplexTree.insert_simplex({2, 4}, 6.); + simplexTree.insert_simplex({3, 6}, 7.); + simplexTree.insert_simplex({4, 5}, 8.); + simplexTree.insert_simplex({4, 6}, 9.); + simplexTree.insert_simplex({5, 6}, 10.); + simplexTree.insert_simplex({6}, 10.); + + simplexTree.expansion_with_blockers(3, [&](Simplex_handle sh){ + bool result = false; + std::cout << "Blocker on ["; + // User can loop on the vertices from the given simplex_handle i.e. + for (auto vertex : simplexTree.simplex_vertex_range(sh)) { + // We block the expansion, if the vertex '6' is in the given list of vertices + if (vertex == 6) + result = true; + std::cout << vertex << ", "; + } + std::cout << "] ( " << simplexTree.filtration(sh); + // User can re-assign a new filtration value directly in the blocker (default is the maximal value of boudaries) + simplexTree.assign_filtration(sh, simplexTree.filtration(sh) + 1.); + + std::cout << " + 1. ) = " << result << std::endl; + + return result; + }); + + std::cout << "********************************************************************\n"; + std::cout << "* The complex contains " << simplexTree.num_simplices() << " simplices"; + std::cout << " - dimension " << simplexTree.dimension() << "\n"; + std::cout << "* Iterator on Simplices in the filtration, with [filtration value]:\n"; + for (auto f_simplex : simplexTree.filtration_simplex_range()) { + std::cout << " " << "[" << simplexTree.filtration(f_simplex) << "] "; + for (auto vertex : simplexTree.simplex_vertex_range(f_simplex)) + std::cout << "(" << vertex << ")"; + std::cout << std::endl; + } + + return 0; +} diff --git a/src/Simplex_tree/example/mini_simplex_tree.cpp b/src/Simplex_tree/example/mini_simplex_tree.cpp index ad99df23..19e45361 100644 --- a/src/Simplex_tree/example/mini_simplex_tree.cpp +++ b/src/Simplex_tree/example/mini_simplex_tree.cpp @@ -52,8 +52,6 @@ int main() { auto edge03 = {0, 3}; st.insert_simplex_and_subfaces(triangle012); st.insert_simplex_and_subfaces(edge03); - // FIXME: Remove this line - st.set_dimension(2); auto edge02 = {0, 2}; ST::Simplex_handle e = st.find(edge02); diff --git a/src/Simplex_tree/example/simple_simplex_tree.cpp b/src/Simplex_tree/example/simple_simplex_tree.cpp index d8318f03..b6b65b88 100644 --- a/src/Simplex_tree/example/simple_simplex_tree.cpp +++ b/src/Simplex_tree/example/simple_simplex_tree.cpp @@ -185,7 +185,6 @@ int main(int argc, char * const argv[]) { } // ++ GENERAL VARIABLE SET - simplexTree.set_dimension(2); // Max dimension = 2 -> (2,1,0) std::cout << "********************************************************************\n"; // Display the Simplex_tree - Can not be done in the middle of 2 inserts @@ -194,9 +193,8 @@ int main(int argc, char * const argv[]) { std::cout << "* Iterator on Simplices in the filtration, with [filtration value]:\n"; for (auto f_simplex : simplexTree.filtration_simplex_range()) { std::cout << " " << "[" << simplexTree.filtration(f_simplex) << "] "; - for (auto vertex : simplexTree.simplex_vertex_range(f_simplex)) { - std::cout << static_cast<int>(vertex) << " "; - } + for (auto vertex : simplexTree.simplex_vertex_range(f_simplex)) + std::cout << "(" << vertex << ")"; std::cout << std::endl; } // [0.1] 0 @@ -249,5 +247,34 @@ int main(int argc, char * const argv[]) { std::cout << "***+ YES IT IS!\n"; else std::cout << "***- NO IT ISN'T\n"; + + simplexFound = simplexTree.find({ 0, 1 }); + std::cout << "**************IS THE SIMPLEX {0,1} IN THE SIMPLEX TREE ?\n"; + if (simplexFound != simplexTree.null_simplex()) + std::cout << "***+ YES IT IS!\n"; + else + std::cout << "***- NO IT ISN'T\n"; + + std::cout << "**************COFACES OF {0,1} IN CODIMENSION 1 ARE\n"; + for (auto& simplex : simplexTree.cofaces_simplex_range(simplexTree.find({0,1}), 1)) { + for (auto vertex : simplexTree.simplex_vertex_range(simplex)) + std::cout << "(" << vertex << ")"; + std::cout << std::endl; + } + + std::cout << "**************STARS OF {0,1} ARE\n"; + for (auto& simplex : simplexTree.star_simplex_range(simplexTree.find({0,1}))) { + for (auto vertex : simplexTree.simplex_vertex_range(simplex)) + std::cout << "(" << vertex << ")"; + std::cout << std::endl; + } + + std::cout << "**************BOUNDARIES OF {0,1,2} ARE\n"; + for (auto& simplex : simplexTree.boundary_simplex_range(simplexTree.find({0,1,2}))) { + for (auto vertex : simplexTree.simplex_vertex_range(simplex)) + std::cout << "(" << vertex << ")"; + std::cout << std::endl; + } + return 0; } diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index 37b3ea97..7da767cb 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -482,7 +482,17 @@ class Simplex_tree { } /** \brief Returns an upper bound on the dimension of the simplicial complex. */ - int dimension() const { + int upper_bound_dimension() const { + return dimension_; + } + + /** \brief Returns the dimension of the simplicial complex. + \details This function is not constant time because it can recompute dimension if required (can be triggered by + `remove_maximal_simplex()` or `prune_above_filtration()`). + */ + int dimension() { + if (dimension_to_be_lowered_) + lower_upper_bound_dimension(); return dimension_; } @@ -591,7 +601,11 @@ class Simplex_tree { // if filtration value unchanged return std::pair<Simplex_handle, bool>(null_simplex(), false); } - // otherwise the insertion has succeeded + // otherwise the insertion has succeeded - size is a size_type + if (static_cast<int>(simplex.size()) - 1 > dimension_) { + // Update dimension if needed + dimension_ = static_cast<int>(simplex.size()) - 1; + } return res_insert; } @@ -1067,6 +1081,118 @@ class Simplex_tree { } public: + /** \brief Expands a simplex tree containing only a graph. Simplices corresponding to cliques in the graph are added + * incrementally, faces before cofaces, unless the simplex has dimension larger than `max_dim` or `block_simplex` + * returns true for this simplex. + * + * @param[in] max_dim Expansion maximal dimension value. + * @param[in] block_simplex Blocker oracle. Its concept is <CODE>bool block_simplex(Simplex_handle sh)</CODE> + * + * The function identifies a candidate simplex whose faces are all already in the complex, inserts + * it with a filtration value corresponding to the maximum of the filtration values of the faces, then calls + * `block_simplex` on a `Simplex_handle` for this new simplex. If `block_simplex` returns true, the simplex is + * removed, otherwise it is kept. Note that the evaluation of `block_simplex` is a good time to update the + * filtration value of the simplex if you want a customized value. The algorithm then proceeds with the next + * candidate. + * + * @warning several candidates of the same dimension may be inserted simultaneously before calling `block_simplex`, + * so if you examine the complex in `block_simplex`, you may hit a few simplices of the same dimension that have not + * been vetted by `block_simplex` yet, or have already been rejected but not yet removed. + */ + template< typename Blocker > + void expansion_with_blockers(int max_dim, Blocker block_simplex) { + // Loop must be from the end to the beginning, as higher dimension simplex are always on the left part of the tree + for (auto& simplex : boost::adaptors::reverse(root_.members())) { + if (has_children(&simplex)) { + siblings_expansion_with_blockers(simplex.second.children(), max_dim, max_dim - 1, block_simplex); + } + } + } + + private: + /** \brief Recursive expansion with blockers of the simplex tree.*/ + template< typename Blocker > + void siblings_expansion_with_blockers(Siblings* siblings, int max_dim, int k, Blocker block_simplex) { + if (dimension_ < max_dim - k) { + dimension_ = max_dim - k; + } + if (k == 0) + return; + // No need to go deeper + if (siblings->members().size() < 2) + return; + // Reverse loop starting before the last one for 'next' to be the last one + for (auto simplex = siblings->members().rbegin() + 1; simplex != siblings->members().rend(); simplex++) { + std::vector<std::pair<Vertex_handle, Node> > intersection; + for(auto next = siblings->members().rbegin(); next != simplex; next++) { + bool to_be_inserted = true; + Filtration_value filt = simplex->second.filtration(); + // If all the boundaries are present, 'next' needs to be inserted + for (Simplex_handle border : boundary_simplex_range(simplex)) { + Simplex_handle border_child = find_child(border, next->first); + if (border_child == null_simplex()) { + to_be_inserted=false; + break; + } + filt = std::max(filt, filtration(border_child)); + } + if (to_be_inserted) { + intersection.emplace_back(next->first, Node(nullptr, filt)); + } + } + if (intersection.size() != 0) { + // Reverse the order to insert + Siblings * new_sib = new Siblings(siblings, // oncles + simplex->first, // parent + boost::adaptors::reverse(intersection)); // boost::container::ordered_unique_range_t + std::vector<Simplex_handle> blocked_new_sib_list; + // As all intersections are inserted, we can call the blocker function on all new_sib members + for (auto new_sib_member = new_sib->members().begin(); + new_sib_member != new_sib->members().end(); + new_sib_member++) { + bool blocker_result = block_simplex(new_sib_member); + // new_sib member has been blocked by the blocker function + // add it to the list to be removed - do not perform it while looping on it + if (blocker_result) + blocked_new_sib_list.push_back(new_sib_member); + } + bool removed = false; + for (auto& blocked_new_sib_member : blocked_new_sib_list){ + removed = removed || remove_maximal_simplex(blocked_new_sib_member); + } + if (removed) { + // ensure the children property + simplex->second.assign_children(siblings); + } else { + // ensure recursive call + simplex->second.assign_children(new_sib); + siblings_expansion_with_blockers(new_sib, max_dim, k - 1, block_simplex); + } + } else { + // ensure the children property + simplex->second.assign_children(siblings); + } + } + } + + /* \private Returns the Simplex_handle composed of the vertex list (from the Simplex_handle), plus the given + * Vertex_handle if the Vertex_handle is found in the Simplex_handle children list. + * Returns null_simplex() if it does not exist + */ + Simplex_handle find_child(Simplex_handle sh, Vertex_handle vh) const { + if (!has_children(sh)) + return null_simplex(); + + Simplex_handle child = sh->second.children()->find(vh); + // Specific case of boost::flat_map does not find, returns boost::flat_map::end() + // in simplex tree we want a null_simplex() + if (child == sh->second.children()->members().end()) + return null_simplex(); + + return child; + } + + public: /** \brief Write the hasse diagram of the simplicial complex in os. * * Each row in the file correspond to a simplex. A line is written: @@ -1142,6 +1268,9 @@ class Simplex_tree { * \post Some simplex tree functions require the filtration to be valid. `prune_above_filtration()` * function is not launching `initialize_filtration()` but returns the filtration modification information. If the * complex has changed , please call `initialize_filtration()` to recompute it. + * \post Note that the dimension of the simplicial complex may be lower after calling `prune_above_filtration()` + * than it was before. However, `upper_bound_dimension()` will return the old value, which remains a valid upper + * bound. If you care, you can call `dimension()` to recompute the exact dimension. */ bool prune_above_filtration(Filtration_value filtration) { return rec_prune_above_filtration(root(), filtration); @@ -1153,6 +1282,8 @@ class Simplex_tree { auto last = std::remove_if(list.begin(), list.end(), [=](Dit_value_t& simplex) { if (simplex.second.filtration() <= filt) return false; if (has_children(&simplex)) rec_delete(simplex.second.children()); + // dimension may need to be lowered + dimension_to_be_lowered_ = true; return true; }); @@ -1161,6 +1292,8 @@ class Simplex_tree { // Removing the whole siblings, parent becomes a leaf. sib->oncles()->members()[sib->parent()].assign_children(sib->oncles()); delete sib; + // dimension may need to be lowered + dimension_to_be_lowered_ = true; return true; } else { // Keeping some elements of siblings. Remove the others, and recurse in the remaining ones. @@ -1172,14 +1305,49 @@ class Simplex_tree { return modified; } + private: + /** \brief Deep search simplex tree dimension recompute. + * @return True if the dimension was modified, false otherwise. + * \pre Be sure the simplex tree has not a too low dimension value as the deep search stops when the former dimension + * has been reached (cf. `upper_bound_dimension()` and `set_dimension()` methods). + */ + bool lower_upper_bound_dimension() { + // reset automatic detection to recompute + dimension_to_be_lowered_ = false; + int new_dimension = -1; + // Browse the tree from the left to the right as higher dimension cells are more likely on the left part of the tree + for (Simplex_handle sh : complex_simplex_range()) { +#ifdef DEBUG_TRACES + for (auto vertex : simplex_vertex_range(sh)) { + std::cout << " " << vertex; + } + std::cout << std::endl; +#endif // DEBUG_TRACES + + int sh_dimension = dimension(sh); + if (sh_dimension >= dimension_) + // Stop browsing as soon as the dimension is reached, no need to go furter + return false; + new_dimension = std::max(new_dimension, sh_dimension); + } + dimension_ = new_dimension; + return true; + } + + public: /** \brief Remove a maximal simplex. * @param[in] sh Simplex handle on the maximal simplex to remove. + * @return a boolean value that is an implementation detail, and that the user is supposed to ignore * \pre Please check the simplex has no coface before removing it. * \exception std::invalid_argument In debug mode, if sh has children. - * \post Be aware that removing is shifting data in a flat_map (initialize_filtration to be done). + * \post Be aware that removing is shifting data in a flat_map (`initialize_filtration()` to be done). + * \post Note that the dimension of the simplicial complex may be lower after calling `remove_maximal_simplex()` + * than it was before. However, `upper_bound_dimension()` will return the old value, which remains a valid upper + * bound. If you care, you can call `dimension()` to recompute the exact dimension. + * \internal @return true if the leaf's branch has no other leaves (branch's children has been re-assigned), false otherwise. */ - void remove_maximal_simplex(Simplex_handle sh) { + bool remove_maximal_simplex(Simplex_handle sh) { // Guarantee the simplex has no children GUDHI_CHECK(!has_children(sh), std::invalid_argument("Simplex_tree::remove_maximal_simplex - argument has children")); @@ -1195,7 +1363,11 @@ class Simplex_tree { // Sibling is emptied : must be deleted, and its parent must point on his own Sibling child->oncles()->members().at(child->parent()).assign_children(child->oncles()); delete child; + // dimension may need to be lowered + dimension_to_be_lowered_ = true; + return true; } + return false; } private: @@ -1207,6 +1379,7 @@ class Simplex_tree { std::vector<Simplex_handle> filtration_vect_; /** \brief Upper bound on the dimension of the simplicial complex.*/ int dimension_; + bool dimension_to_be_lowered_ = false; }; // Print a Simplex_tree in os. diff --git a/src/Simplex_tree/test/CMakeLists.txt b/src/Simplex_tree/test/CMakeLists.txt index 81999de6..8684ad2a 100644 --- a/src/Simplex_tree/test/CMakeLists.txt +++ b/src/Simplex_tree/test/CMakeLists.txt @@ -3,13 +3,29 @@ project(Simplex_tree_tests) include(GUDHI_test_coverage) +# Do not forget to copy test files in current binary dir +file(COPY "simplex_tree_for_unit_test.txt" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/) + add_executable ( Simplex_tree_test_unit simplex_tree_unit_test.cpp ) target_link_libraries(Simplex_tree_test_unit ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) if (TBB_FOUND) target_link_libraries(Simplex_tree_test_unit ${TBB_LIBRARIES}) endif() -# Do not forget to copy test files in current binary dir -file(COPY "simplex_tree_for_unit_test.txt" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/) - gudhi_add_coverage_test(Simplex_tree_test_unit) + +add_executable ( Simplex_tree_remove_test_unit simplex_tree_remove_unit_test.cpp ) +target_link_libraries(Simplex_tree_remove_test_unit ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) +if (TBB_FOUND) + target_link_libraries(Simplex_tree_remove_test_unit ${TBB_LIBRARIES}) +endif() + +gudhi_add_coverage_test(Simplex_tree_remove_test_unit) + +add_executable ( Simplex_tree_iostream_operator_test_unit simplex_tree_iostream_operator_unit_test.cpp ) +target_link_libraries(Simplex_tree_iostream_operator_test_unit ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) +if (TBB_FOUND) + target_link_libraries(Simplex_tree_iostream_operator_test_unit ${TBB_LIBRARIES}) +endif() + +gudhi_add_coverage_test(Simplex_tree_iostream_operator_test_unit) diff --git a/src/Simplex_tree/test/README b/src/Simplex_tree/test/README index 21c3d871..df2ab89a 100644 --- a/src/Simplex_tree/test/README +++ b/src/Simplex_tree/test/README @@ -9,6 +9,6 @@ make To launch with details: *********************** -./SimplexTreeUT --report_level=detailed --log_level=all +./Simplex_tree_test_unit --report_level=detailed --log_level=all ==> echo $? returns 0 in case of success (non-zero otherwise) diff --git a/src/Simplex_tree/test/simplex_tree_graph_expansion_unit_test.cpp b/src/Simplex_tree/test/simplex_tree_graph_expansion_unit_test.cpp new file mode 100644 index 00000000..19ce3321 --- /dev/null +++ b/src/Simplex_tree/test/simplex_tree_graph_expansion_unit_test.cpp @@ -0,0 +1,235 @@ +#include <iostream> +#include <fstream> +#include <string> +#include <algorithm> +#include <utility> // std::pair, std::make_pair +#include <cmath> // float comparison +#include <limits> +#include <functional> // greater + +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_MODULE "simplex_tree" +#include <boost/test/unit_test.hpp> +#include <boost/mpl/list.hpp> + +// ^ +// /!\ Nothing else from Simplex_tree shall be included to test includes are well defined. +#include "gudhi/Simplex_tree.h" + +using namespace Gudhi; + +typedef boost::mpl::list<Simplex_tree<>, Simplex_tree<Simplex_tree_options_fast_persistence>> list_of_tested_variants; + + +bool AreAlmostTheSame(float a, float b) { + return std::fabs(a - b) < std::numeric_limits<float>::epsilon(); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE(simplex_tree_expansion_with_blockers_3, typeST, list_of_tested_variants) { + using Simplex_handle = typename typeST::Simplex_handle; + // Construct the Simplex Tree with a 1-skeleton graph example + typeST simplex_tree; + + simplex_tree.insert_simplex({0, 1}, 0.); + simplex_tree.insert_simplex({0, 2}, 1.); + simplex_tree.insert_simplex({0, 3}, 2.); + simplex_tree.insert_simplex({1, 2}, 3.); + simplex_tree.insert_simplex({1, 3}, 4.); + simplex_tree.insert_simplex({2, 3}, 5.); + simplex_tree.insert_simplex({2, 4}, 6.); + simplex_tree.insert_simplex({3, 6}, 7.); + simplex_tree.insert_simplex({4, 5}, 8.); + simplex_tree.insert_simplex({4, 6}, 9.); + simplex_tree.insert_simplex({5, 6}, 10.); + simplex_tree.insert_simplex({6}, 10.); + + simplex_tree.expansion_with_blockers(3, [&](Simplex_handle sh){ + bool result = false; + std::cout << "Blocker on ["; + // User can loop on the vertices from the given simplex_handle i.e. + for (auto vertex : simplex_tree.simplex_vertex_range(sh)) { + // We block the expansion, if the vertex '6' is in the given list of vertices + if (vertex == 6) + result = true; + std::cout << vertex << ", "; + } + std::cout << "] ( " << simplex_tree.filtration(sh); + // User can re-assign a new filtration value directly in the blocker (default is the maximal value of boudaries) + simplex_tree.assign_filtration(sh, simplex_tree.filtration(sh) + 1.); + + std::cout << " + 1. ) = " << result << std::endl; + + return result; + }); + + std::cout << "********************************************************************\n"; + std::cout << "simplex_tree_expansion_with_blockers_3\n"; + std::cout << "********************************************************************\n"; + std::cout << "* The complex contains " << simplex_tree.num_simplices() << " simplices"; + std::cout << " - dimension " << simplex_tree.dimension() << "\n"; + std::cout << "* Iterator on Simplices in the filtration, with [filtration value]:\n"; + for (auto f_simplex : simplex_tree.filtration_simplex_range()) { + std::cout << " " << "[" << simplex_tree.filtration(f_simplex) << "] "; + for (auto vertex : simplex_tree.simplex_vertex_range(f_simplex)) + std::cout << "(" << vertex << ")"; + std::cout << std::endl; + } + + BOOST_CHECK(simplex_tree.num_simplices() == 23); + BOOST_CHECK(simplex_tree.dimension() == 3); + // {4, 5, 6} shall be blocked + BOOST_CHECK(simplex_tree.find({4, 5, 6}) == simplex_tree.null_simplex()); + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,1,2})), 4.)); + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,1,3})), 5.)); + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,2,3})), 6.)); + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({1,2,3})), 6.)); + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,1,2,3})), 7.)); + +} + +BOOST_AUTO_TEST_CASE_TEMPLATE(simplex_tree_expansion_with_blockers_2, typeST, list_of_tested_variants) { + using Simplex_handle = typename typeST::Simplex_handle; + // Construct the Simplex Tree with a 1-skeleton graph example + typeST simplex_tree; + + simplex_tree.insert_simplex({0, 1}, 0.); + simplex_tree.insert_simplex({0, 2}, 1.); + simplex_tree.insert_simplex({0, 3}, 2.); + simplex_tree.insert_simplex({1, 2}, 3.); + simplex_tree.insert_simplex({1, 3}, 4.); + simplex_tree.insert_simplex({2, 3}, 5.); + simplex_tree.insert_simplex({2, 4}, 6.); + simplex_tree.insert_simplex({3, 6}, 7.); + simplex_tree.insert_simplex({4, 5}, 8.); + simplex_tree.insert_simplex({4, 6}, 9.); + simplex_tree.insert_simplex({5, 6}, 10.); + simplex_tree.insert_simplex({6}, 10.); + + simplex_tree.expansion_with_blockers(2, [&](Simplex_handle sh){ + bool result = false; + std::cout << "Blocker on ["; + // User can loop on the vertices from the given simplex_handle i.e. + for (auto vertex : simplex_tree.simplex_vertex_range(sh)) { + // We block the expansion, if the vertex '6' is in the given list of vertices + if (vertex == 6) + result = true; + std::cout << vertex << ", "; + } + std::cout << "] ( " << simplex_tree.filtration(sh); + // User can re-assign a new filtration value directly in the blocker (default is the maximal value of boudaries) + simplex_tree.assign_filtration(sh, simplex_tree.filtration(sh) + 1.); + + std::cout << " + 1. ) = " << result << std::endl; + + return result; + }); + + std::cout << "********************************************************************\n"; + std::cout << "simplex_tree_expansion_with_blockers_2\n"; + std::cout << "********************************************************************\n"; + std::cout << "* The complex contains " << simplex_tree.num_simplices() << " simplices"; + std::cout << " - dimension " << simplex_tree.dimension() << "\n"; + std::cout << "* Iterator on Simplices in the filtration, with [filtration value]:\n"; + for (auto f_simplex : simplex_tree.filtration_simplex_range()) { + std::cout << " " << "[" << simplex_tree.filtration(f_simplex) << "] "; + for (auto vertex : simplex_tree.simplex_vertex_range(f_simplex)) + std::cout << "(" << vertex << ")"; + std::cout << std::endl; + } + + BOOST_CHECK(simplex_tree.num_simplices() == 22); + BOOST_CHECK(simplex_tree.dimension() == 2); + // {4, 5, 6} shall be blocked + BOOST_CHECK(simplex_tree.find({4, 5, 6}) == simplex_tree.null_simplex()); + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,1,2})), 4.)); + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,1,3})), 5.)); + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,2,3})), 6.)); + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({1,2,3})), 6.)); + BOOST_CHECK(simplex_tree.find({0,1,2,3}) == simplex_tree.null_simplex()); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE(simplex_tree_expansion, typeST, list_of_tested_variants) { + // Construct the Simplex Tree with a 1-skeleton graph example + typeST simplex_tree; + + simplex_tree.insert_simplex({0, 1}, 0.); + simplex_tree.insert_simplex({0, 2}, 1.); + simplex_tree.insert_simplex({0, 3}, 2.); + simplex_tree.insert_simplex({1, 2}, 3.); + simplex_tree.insert_simplex({1, 3}, 4.); + simplex_tree.insert_simplex({2, 3}, 5.); + simplex_tree.insert_simplex({2, 4}, 6.); + simplex_tree.insert_simplex({3, 6}, 7.); + simplex_tree.insert_simplex({4, 5}, 8.); + simplex_tree.insert_simplex({4, 6}, 9.); + simplex_tree.insert_simplex({5, 6}, 10.); + simplex_tree.insert_simplex({6}, 10.); + + simplex_tree.expansion(3); + std::cout << "********************************************************************\n"; + std::cout << "simplex_tree_expansion_3\n"; + std::cout << "********************************************************************\n"; + std::cout << "* The complex contains " << simplex_tree.num_simplices() << " simplices"; + std::cout << " - dimension " << simplex_tree.dimension() << "\n"; + std::cout << "* Iterator on Simplices in the filtration, with [filtration value]:\n"; + for (auto f_simplex : simplex_tree.filtration_simplex_range()) { + std::cout << " " << "[" << simplex_tree.filtration(f_simplex) << "] "; + for (auto vertex : simplex_tree.simplex_vertex_range(f_simplex)) + std::cout << "(" << vertex << ")"; + std::cout << std::endl; + } + + BOOST_CHECK(simplex_tree.num_simplices() == 24); + BOOST_CHECK(simplex_tree.dimension() == 3); + + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({4,5,6})), 10.)); + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,1,2})), 3.)); + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,1,3})), 4.)); + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,2,3})), 5.)); + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({1,2,3})), 5.)); + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,1,2,3})), 5.)); + +} + +BOOST_AUTO_TEST_CASE_TEMPLATE(simplex_tree_expansion_2, typeST, list_of_tested_variants) { + // Construct the Simplex Tree with a 1-skeleton graph example + typeST simplex_tree; + + simplex_tree.insert_simplex({0, 1}, 0.); + simplex_tree.insert_simplex({0, 2}, 1.); + simplex_tree.insert_simplex({0, 3}, 2.); + simplex_tree.insert_simplex({1, 2}, 3.); + simplex_tree.insert_simplex({1, 3}, 4.); + simplex_tree.insert_simplex({2, 3}, 5.); + simplex_tree.insert_simplex({2, 4}, 6.); + simplex_tree.insert_simplex({3, 6}, 7.); + simplex_tree.insert_simplex({4, 5}, 8.); + simplex_tree.insert_simplex({4, 6}, 9.); + simplex_tree.insert_simplex({5, 6}, 10.); + simplex_tree.insert_simplex({6}, 10.); + + simplex_tree.expansion(2); + + std::cout << "********************************************************************\n"; + std::cout << "simplex_tree_expansion_2\n"; + std::cout << "********************************************************************\n"; + std::cout << "* The complex contains " << simplex_tree.num_simplices() << " simplices"; + std::cout << " - dimension " << simplex_tree.dimension() << "\n"; + std::cout << "* Iterator on Simplices in the filtration, with [filtration value]:\n"; + for (auto f_simplex : simplex_tree.filtration_simplex_range()) { + std::cout << " " << "[" << simplex_tree.filtration(f_simplex) << "] "; + for (auto vertex : simplex_tree.simplex_vertex_range(f_simplex)) + std::cout << "(" << vertex << ")"; + std::cout << std::endl; + } + + BOOST_CHECK(simplex_tree.num_simplices() == 23); + BOOST_CHECK(simplex_tree.dimension() == 2); + + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({4,5,6})), 10.)); + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,1,2})), 3.)); + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,1,3})), 4.)); + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,2,3})), 5.)); + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({1,2,3})), 5.)); + BOOST_CHECK(simplex_tree.find({0,1,2,3}) == simplex_tree.null_simplex()); +} diff --git a/src/Simplex_tree/test/simplex_tree_iostream_operator_unit_test.cpp b/src/Simplex_tree/test/simplex_tree_iostream_operator_unit_test.cpp new file mode 100644 index 00000000..ecb9f025 --- /dev/null +++ b/src/Simplex_tree/test/simplex_tree_iostream_operator_unit_test.cpp @@ -0,0 +1,136 @@ +#include <iostream> + +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_MODULE "simplex_tree_iostream_operator" +#include <boost/test/unit_test.hpp> +#include <boost/mpl/list.hpp> + +// ^ +// /!\ Nothing else from Simplex_tree shall be included to test includes are well defined. +#include "gudhi/Simplex_tree.h" + +using namespace Gudhi; + +struct MyOptions : Simplex_tree_options_full_featured { + // Not doing persistence, so we don't need those + static const bool store_key = false; + static const bool store_filtration = false; + // I have few vertices + typedef short Vertex_handle; +}; + +typedef boost::mpl::list<Simplex_tree<>, + Simplex_tree<Simplex_tree_options_fast_persistence> + > list_of_tested_variants; + +BOOST_AUTO_TEST_CASE_TEMPLATE(iostream_operator, Stree_type, list_of_tested_variants) { + std::cout << "********************************************************************" << std::endl; + std::cout << "SIMPLEX TREE IOSTREAM OPERATOR" << std::endl; + + Stree_type st; + + st.insert_simplex_and_subfaces({0, 1, 6, 7}, 4.0); + st.insert_simplex_and_subfaces({3, 4, 5}, 3.0); + st.insert_simplex_and_subfaces({3, 0}, 2.0); + st.insert_simplex_and_subfaces({2, 1, 0}, 3.0); + + st.initialize_filtration(); + // Display the Simplex_tree + std::cout << "The ORIGINAL complex contains " << st.num_simplices() << " simplices - dimension = " + << st.dimension() << std::endl; + std::cout << std::endl << std::endl << "Iterator on Simplices in the filtration, with [filtration value]:" << std::endl; + for (auto f_simplex : st.filtration_simplex_range()) { + std::cout << " " << "[" << st.filtration(f_simplex) << "] "; + for (auto vertex : st.simplex_vertex_range(f_simplex)) { + std::cout << (int) vertex << " "; + } + std::cout << std::endl; + } + + // st: + // 1 6 + // o---o + // /X\7/ + // o---o---o---o + // 2 0 3\X/4 + // o + // 5 + std::string iostream_file("simplex_tree_for_iostream_operator_unit_test.txt"); + std::ofstream simplex_tree_ostream(iostream_file.c_str()); + simplex_tree_ostream << st; + simplex_tree_ostream.close(); + + Stree_type read_st; + std::ifstream simplex_tree_istream(iostream_file.c_str()); + simplex_tree_istream >> read_st; + + // Display the Simplex_tree + std::cout << "The READ complex contains " << read_st.num_simplices() << " simplices - dimension = " + << read_st.dimension() << std::endl; + std::cout << std::endl << std::endl << "Iterator on Simplices in the filtration, with [filtration value]:" << std::endl; + for (auto f_simplex : read_st.filtration_simplex_range()) { + std::cout << " " << "[" << read_st.filtration(f_simplex) << "] "; + for (auto vertex : read_st.simplex_vertex_range(f_simplex)) { + std::cout << (int) vertex << " "; + } + std::cout << std::endl; + } + + BOOST_CHECK(st == read_st); +} + + +BOOST_AUTO_TEST_CASE(mini_iostream_operator) { + std::cout << "********************************************************************" << std::endl; + std::cout << "MINI SIMPLEX TREE IOSTREAM OPERATOR" << std::endl; + + Simplex_tree<MyOptions> st; + + st.insert_simplex_and_subfaces({0, 1, 6, 7}); + st.insert_simplex_and_subfaces({3, 4, 5}); + st.insert_simplex_and_subfaces({3, 0}); + st.insert_simplex_and_subfaces({2, 1, 0}); + + st.initialize_filtration(); + // Display the Simplex_tree + std::cout << "The ORIGINAL complex contains " << st.num_simplices() << " simplices - dimension = " + << st.dimension() << std::endl; + for (auto f_simplex : st.filtration_simplex_range()) { + std::cout << " " << "[" << st.filtration(f_simplex) << "] "; + for (auto vertex : st.simplex_vertex_range(f_simplex)) { + std::cout << (int) vertex << " "; + } + std::cout << std::endl; + } + + // st: + // 1 6 + // o---o + // /X\7/ + // o---o---o---o + // 2 0 3\X/4 + // o + // 5 + std::string iostream_file("simplex_tree_for_iostream_operator_unit_test.txt"); + std::ofstream simplex_tree_ostream(iostream_file.c_str()); + simplex_tree_ostream << st; + simplex_tree_ostream.close(); + + Simplex_tree<MyOptions> read_st; + std::ifstream simplex_tree_istream(iostream_file.c_str()); + simplex_tree_istream >> read_st; + + // Display the Simplex_tree + std::cout << "The READ complex contains " << read_st.num_simplices() << " simplices - dimension = " + << read_st.dimension() << std::endl; + std::cout << std::endl << std::endl << "Iterator on Simplices in the filtration, with [filtration value]:" << std::endl; + for (auto f_simplex : read_st.filtration_simplex_range()) { + std::cout << " " << "[" << read_st.filtration(f_simplex) << "] "; + for (auto vertex : read_st.simplex_vertex_range(f_simplex)) { + std::cout << (int) vertex << " "; + } + std::cout << std::endl; + } + + BOOST_CHECK(st == read_st); +} diff --git a/src/Simplex_tree/test/simplex_tree_remove_unit_test.cpp b/src/Simplex_tree/test/simplex_tree_remove_unit_test.cpp new file mode 100644 index 00000000..dc37375c --- /dev/null +++ b/src/Simplex_tree/test/simplex_tree_remove_unit_test.cpp @@ -0,0 +1,427 @@ +#include <iostream> + +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_MODULE "simplex_tree_remove" +#include <boost/test/unit_test.hpp> + +// ^ +// /!\ Nothing else from Simplex_tree shall be included to test includes are well defined. +#include "gudhi/Simplex_tree.h" + +using namespace Gudhi; + +struct MyOptions : Simplex_tree_options_full_featured { + // Not doing persistence, so we don't need those + static const bool store_key = false; + static const bool store_filtration = false; + // I have few vertices + typedef short Vertex_handle; +}; + +using Mini_stree = Simplex_tree<MyOptions>; +using Stree = Simplex_tree<>; + +BOOST_AUTO_TEST_CASE(remove_maximal_simplex) { + std::cout << "********************************************************************" << std::endl; + std::cout << "REMOVE MAXIMAL SIMPLEX" << std::endl; + + Mini_stree st; + + st.insert_simplex_and_subfaces({0, 1, 6, 7}); + st.insert_simplex_and_subfaces({3, 4, 5}); + + // Constructs a copy at this state for further test purpose + Mini_stree st_pruned = st; + + st.insert_simplex_and_subfaces({3, 0}); + st.insert_simplex_and_subfaces({2, 1, 0}); + + // Constructs a copy at this state for further test purpose + Mini_stree st_complete = st; + // st_complete and st: + // 1 6 + // o---o + // /X\7/ + // o---o---o---o + // 2 0 3\X/4 + // o + // 5 + // st_pruned: + // 1 6 + // o---o + // \7/ + // o o---o + // 0 3\X/4 + // o + // 5 + +#ifdef GUDHI_DEBUG + std::cout << "Check exception throw in debug mode" << std::endl; + // throw excpt because sh has children + BOOST_CHECK_THROW (st.remove_maximal_simplex(st.find({0, 1, 6})), std::invalid_argument); + BOOST_CHECK_THROW (st.remove_maximal_simplex(st.find({3})), std::invalid_argument); + BOOST_CHECK(st == st_complete); +#endif + std::cout << "st.remove_maximal_simplex({0, 2})" << std::endl; + st.remove_maximal_simplex(st.find({0, 2})); + std::cout << "st.remove_maximal_simplex({0, 1, 2})" << std::endl; + st.remove_maximal_simplex(st.find({0, 1, 2})); + std::cout << "st.remove_maximal_simplex({1, 2})" << std::endl; + st.remove_maximal_simplex(st.find({1, 2})); + std::cout << "st.remove_maximal_simplex({2})" << std::endl; + st.remove_maximal_simplex(st.find({2})); + std::cout << "st.remove_maximal_simplex({3})" << std::endl; + st.remove_maximal_simplex(st.find({0, 3})); + + BOOST_CHECK(st == st_pruned); + // Remove all, but as the simplex tree is not storing filtration, there is no modification + st.prune_above_filtration(0.0); + BOOST_CHECK(st == st_pruned); + + Mini_stree st_wo_seven; + + st_wo_seven.insert_simplex_and_subfaces({0, 1, 6}); + st_wo_seven.insert_simplex_and_subfaces({3, 4, 5}); + // st_wo_seven: + // 1 6 + // o---o + // \X/ + // o o---o + // 0 3\X/4 + // o + // 5 + + // Remove all 7 to test the both remove_maximal_simplex cases (when _members is empty or not) + std::cout << "st.remove_maximal_simplex({0, 1, 6, 7})" << std::endl; + st.remove_maximal_simplex(st.find({0, 1, 6, 7})); + std::cout << "st.remove_maximal_simplex({0, 1, 7})" << std::endl; + st.remove_maximal_simplex(st.find({0, 1, 7})); + std::cout << "st.remove_maximal_simplex({0, 6, 7})" << std::endl; + st.remove_maximal_simplex(st.find({0, 6, 7})); + std::cout << "st.remove_maximal_simplex({0, 7})" << std::endl; + st.remove_maximal_simplex(st.find({0, 7})); + std::cout << "st.remove_maximal_simplex({1, 6, 7})" << std::endl; + st.remove_maximal_simplex(st.find({1, 6, 7})); + std::cout << "st.remove_maximal_simplex({1, 7})" << std::endl; + st.remove_maximal_simplex(st.find({1, 7})); + std::cout << "st.remove_maximal_simplex({6, 7})" << std::endl; + st.remove_maximal_simplex(st.find({6, 7})); + std::cout << "st.remove_maximal_simplex({7})" << std::endl; + st.remove_maximal_simplex(st.find({7})); + + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 3); + + // Check dimension calls lower_upper_bound_dimension to recompute dimension + BOOST_CHECK(st.dimension() == 2); + BOOST_CHECK(st.upper_bound_dimension() == 2); + + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() + << " | st_wo_seven.upper_bound_dimension()=" << st_wo_seven.upper_bound_dimension() << std::endl; + std::cout << "st.dimension()=" << st.dimension() << " | st_wo_seven.dimension()=" << st_wo_seven.dimension() << std::endl; + BOOST_CHECK(st == st_wo_seven); +} + +BOOST_AUTO_TEST_CASE(auto_dimension_set) { + std::cout << "********************************************************************" << std::endl; + std::cout << "DIMENSION ON REMOVE MAXIMAL SIMPLEX" << std::endl; + + Mini_stree st; + + st.insert_simplex_and_subfaces({0, 1, 2}); + st.insert_simplex_and_subfaces({0, 1, 3}); + st.insert_simplex_and_subfaces({1, 2, 3, 4}); + st.insert_simplex_and_subfaces({1, 2, 3, 5}); + st.insert_simplex_and_subfaces({6, 7, 8, 9}); + st.insert_simplex_and_subfaces({6, 7, 8, 10}); + + BOOST_CHECK(st.upper_bound_dimension() == 3); + BOOST_CHECK(st.dimension() == 3); + + std::cout << "st.remove_maximal_simplex({6, 7, 8, 10})" << std::endl; + st.remove_maximal_simplex(st.find({6, 7, 8, 10})); + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 3); + BOOST_CHECK(st.dimension() == 3); + + std::cout << "st.remove_maximal_simplex({6, 7, 8, 9})" << std::endl; + st.remove_maximal_simplex(st.find({6, 7, 8, 9})); + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 3); + BOOST_CHECK(st.dimension() == 3); + + std::cout << "st.remove_maximal_simplex({1, 2, 3, 4})" << std::endl; + st.remove_maximal_simplex(st.find({1, 2, 3, 4})); + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 3); + BOOST_CHECK(st.dimension() == 3); + + std::cout << "st.remove_maximal_simplex({1, 2, 3, 5})" << std::endl; + st.remove_maximal_simplex(st.find({1, 2, 3, 5})); + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 3); + BOOST_CHECK(st.dimension() == 2); + std::cout << "st.dimension()=" << st.dimension() << std::endl; + + std::cout << "st.insert_simplex_and_subfaces({1, 2, 3, 5})" << std::endl; + st.insert_simplex_and_subfaces({1, 2, 3, 5}); + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 3); + BOOST_CHECK(st.dimension() == 3); + + std::cout << "st.insert_simplex_and_subfaces({1, 2, 3, 4})" << std::endl; + st.insert_simplex_and_subfaces({1, 2, 3, 4}); + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 3); + BOOST_CHECK(st.dimension() == 3); + + + std::cout << "st.remove_maximal_simplex({1, 2, 3, 5})" << std::endl; + st.remove_maximal_simplex(st.find({1, 2, 3, 5})); + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 3); + BOOST_CHECK(st.dimension() == 3); + + + std::cout << "st.remove_maximal_simplex({1, 2, 3, 4})" << std::endl; + st.remove_maximal_simplex(st.find({1, 2, 3, 4})); + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 3); + BOOST_CHECK(st.dimension() == 2); + std::cout << "st.dimension()=" << st.dimension() << std::endl; + + std::cout << "st.insert_simplex_and_subfaces({0, 1, 3, 4})" << std::endl; + st.insert_simplex_and_subfaces({0, 1, 3, 4}); + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 3); + BOOST_CHECK(st.dimension() == 3); + + std::cout << "st.remove_maximal_simplex({0, 1, 3, 4})" << std::endl; + st.remove_maximal_simplex(st.find({0, 1, 3, 4})); + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 3); + BOOST_CHECK(st.dimension() == 2); + std::cout << "st.dimension()=" << st.dimension() << std::endl; + + std::cout << "st.insert_simplex_and_subfaces({1, 2, 3, 5})" << std::endl; + st.insert_simplex_and_subfaces({1, 2, 3, 5}); + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 3); + BOOST_CHECK(st.dimension() == 3); + + std::cout << "st.insert_simplex_and_subfaces({1, 2, 3, 4})" << std::endl; + st.insert_simplex_and_subfaces({1, 2, 3, 4}); + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 3); + BOOST_CHECK(st.dimension() == 3); + + + // Check you can override the dimension + // This is a limit test case - shall not happen + st.set_dimension(1); + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 1); + // check dimension() and lower_upper_bound_dimension() is not giving the right answer because dimension is too low + BOOST_CHECK(st.dimension() == 1); + + + // Check you can override the dimension + // This is a limit test case - shall not happen + st.set_dimension(6); + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 6); + // check dimension() do not launch lower_upper_bound_dimension() + BOOST_CHECK(st.dimension() == 6); + + + // Reset with the correct value + st.set_dimension(3); + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 3); + BOOST_CHECK(st.dimension() == 3); + + std::cout << "st.insert_simplex_and_subfaces({0, 1, 2, 3, 4, 5, 6})" << std::endl; + st.insert_simplex_and_subfaces({0, 1, 2, 3, 4, 5, 6}); + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 6); + BOOST_CHECK(st.dimension() == 6); + + std::cout << "st.remove_maximal_simplex({0, 1, 2, 3, 4, 5, 6})" << std::endl; + st.remove_maximal_simplex(st.find({0, 1, 2, 3, 4, 5, 6})); + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 6); + BOOST_CHECK(st.dimension() == 5); + +} + +BOOST_AUTO_TEST_CASE(prune_above_filtration) { + std::cout << "********************************************************************" << std::endl; + std::cout << "PRUNE ABOVE FILTRATION" << std::endl; + + Stree st; + + st.insert_simplex_and_subfaces({0, 1, 6, 7}, 1.0); + st.insert_simplex_and_subfaces({3, 4, 5}, 2.0); + + // Constructs a copy at this state for further test purpose + Stree st_pruned = st; + st_pruned.initialize_filtration(); // reset + + st.insert_simplex_and_subfaces({3, 0}, 3.0); + st.insert_simplex_and_subfaces({2, 1, 0}, 4.0); + + // Constructs a copy at this state for further test purpose + Stree st_complete = st; + // st_complete and st: + // 1 6 + // o---o + // /X\7/ + // o---o---o---o + // 2 0 3\X/4 + // o + // 5 + // st_pruned: + // 1 6 + // o---o + // \7/ + // o o---o + // 0 3\X/4 + // o + // 5 + + bool simplex_is_changed = false; + // Check the no action cases + // greater than initial filtration value + simplex_is_changed = st.prune_above_filtration(10.0); + if (simplex_is_changed) + st.initialize_filtration(); + BOOST_CHECK(st == st_complete); + BOOST_CHECK(!simplex_is_changed); + // equal to initial filtration value + simplex_is_changed = st.prune_above_filtration(6.0); + if (simplex_is_changed) + st.initialize_filtration(); + BOOST_CHECK(st == st_complete); + BOOST_CHECK(!simplex_is_changed); + // lower than initial filtration value, but still greater than the maximum filtration value + simplex_is_changed = st.prune_above_filtration(5.0); + if (simplex_is_changed) + st.initialize_filtration(); + BOOST_CHECK(st == st_complete); + BOOST_CHECK(!simplex_is_changed); + + // Display the Simplex_tree + std::cout << "The complex contains " << st.num_simplices() << " simplices"; + std::cout << " - dimension " << st.dimension() << std::endl; + std::cout << "Iterator on Simplices in the filtration, with [filtration value]:" << std::endl; + for (auto f_simplex : st.filtration_simplex_range()) { + std::cout << " " << "[" << st.filtration(f_simplex) << "] "; + for (auto vertex : st.simplex_vertex_range(f_simplex)) { + std::cout << (int) vertex << " "; + } + std::cout << std::endl; + } + + // Check the pruned cases + simplex_is_changed = st.prune_above_filtration(2.5); + if (simplex_is_changed) + st.initialize_filtration(); + BOOST_CHECK(st == st_pruned); + BOOST_CHECK(simplex_is_changed); + + // Display the Simplex_tree + std::cout << "The complex pruned at 2.5 contains " << st.num_simplices() << " simplices"; + std::cout << " - dimension " << st.dimension() << std::endl; + + simplex_is_changed = st.prune_above_filtration(2.0); + if (simplex_is_changed) + st.initialize_filtration(); + + std::cout << "The complex pruned at 2.0 contains " << st.num_simplices() << " simplices"; + std::cout << " - dimension " << st.dimension() << std::endl; + + BOOST_CHECK(st == st_pruned); + BOOST_CHECK(!simplex_is_changed); + + Stree st_empty; + simplex_is_changed = st.prune_above_filtration(0.0); + BOOST_CHECK(simplex_is_changed == true); + if (simplex_is_changed) + st.initialize_filtration(); + + // Display the Simplex_tree + std::cout << "The complex pruned at 0.0 contains " << st.num_simplices() << " simplices"; + std::cout << " - upper_bound_dimension " << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 3); + + BOOST_CHECK(st.dimension() == -1); + std::cout << "upper_bound_dimension=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == -1); + + BOOST_CHECK(st == st_empty); + BOOST_CHECK(simplex_is_changed); + + // Test case to the limit + simplex_is_changed = st.prune_above_filtration(-1.0); + if (simplex_is_changed) + st.initialize_filtration(); + BOOST_CHECK(st == st_empty); + BOOST_CHECK(!simplex_is_changed); +} + +BOOST_AUTO_TEST_CASE(mini_prune_above_filtration) { + std::cout << "********************************************************************" << std::endl; + std::cout << "MINI PRUNE ABOVE FILTRATION" << std::endl; + + Mini_stree st; + + st.insert_simplex_and_subfaces({0, 1, 6, 7}); + st.insert_simplex_and_subfaces({3, 4, 5}); + st.insert_simplex_and_subfaces({3, 0}); + st.insert_simplex_and_subfaces({2, 1, 0}); + + // st: + // 1 6 + // o---o + // /X\7/ + // o---o---o---o + // 2 0 3\X/4 + // o + // 5 + + st.initialize_filtration(); + + // Display the Simplex_tree + std::cout << "The complex contains " << st.num_simplices() << " simplices" << std::endl; + BOOST_CHECK(st.num_simplices() == 27); + + // Test case to the limit - With these options, there is no filtration, which means filtration is 0 + bool simplex_is_changed = st.prune_above_filtration(1.0); + if (simplex_is_changed) + st.initialize_filtration(); + // Display the Simplex_tree + std::cout << "The complex pruned at 1.0 contains " << st.num_simplices() << " simplices" << std::endl; + BOOST_CHECK(!simplex_is_changed); + BOOST_CHECK(st.num_simplices() == 27); + + simplex_is_changed = st.prune_above_filtration(0.0); + if (simplex_is_changed) + st.initialize_filtration(); + // Display the Simplex_tree + std::cout << "The complex pruned at 0.0 contains " << st.num_simplices() << " simplices" << std::endl; + BOOST_CHECK(!simplex_is_changed); + BOOST_CHECK(st.num_simplices() == 27); + + // Test case to the limit + simplex_is_changed = st.prune_above_filtration(-1.0); + if (simplex_is_changed) + st.initialize_filtration(); + // Display the Simplex_tree + std::cout << "The complex pruned at -1.0 contains " << st.num_simplices() << " simplices" << std::endl; + BOOST_CHECK(simplex_is_changed); + BOOST_CHECK(st.num_simplices() == 0); + + // Display the Simplex_tree + std::cout << "The complex contains " << st.num_simplices() << " simplices" << std::endl; + +} diff --git a/src/Simplex_tree/test/simplex_tree_unit_test.cpp b/src/Simplex_tree/test/simplex_tree_unit_test.cpp index 17ddc605..580d610a 100644 --- a/src/Simplex_tree/test/simplex_tree_unit_test.cpp +++ b/src/Simplex_tree/test/simplex_tree_unit_test.cpp @@ -297,6 +297,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(simplex_tree_insertion, typeST, list_of_tested_var // Simplex_handle = boost::container::flat_map< typeST::Vertex_handle, Node >::iterator typename typeST::Simplex_handle shReturned = returnValue.first; BOOST_CHECK(shReturned == typename typeST::Simplex_handle(nullptr)); + std::cout << "st.num_vertices()=" << st.num_vertices() << std::endl; BOOST_CHECK(st.num_vertices() == (size_t) 4); // Not incremented !! BOOST_CHECK(st.dimension() == dim_max); @@ -617,9 +618,6 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(coface_on_simplex_tree, typeST, list_of_tested_var /* o */ /* 5 */ - // FIXME - st.set_dimension(3); - std::vector<typename typeST::Vertex_handle> simplex_result; std::vector<typename typeST::Simplex_handle> result; std::cout << "First test - Star of (3):" << std::endl; @@ -716,9 +714,6 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(copy_move_on_simplex_tree, typeST, list_of_tested_ /* o */ /* 5 */ - // FIXME - st.set_dimension(3); - std::cout << "Printing st - address = " << &st << std::endl; // Copy constructor @@ -868,271 +863,3 @@ BOOST_AUTO_TEST_CASE(make_filtration_non_decreasing) { BOOST_CHECK(st == st_other_copy); } - -struct MyOptions : Simplex_tree_options_full_featured { - // Not doing persistence, so we don't need those - static const bool store_key = false; - static const bool store_filtration = false; - // I have few vertices - typedef short Vertex_handle; -}; - -BOOST_AUTO_TEST_CASE(remove_maximal_simplex) { - std::cout << "********************************************************************" << std::endl; - std::cout << "REMOVE MAXIMAL SIMPLEX" << std::endl; - - - typedef Simplex_tree<MyOptions> miniST; - miniST st; - - // FIXME - st.set_dimension(3); - - st.insert_simplex_and_subfaces({0, 1, 6, 7}); - st.insert_simplex_and_subfaces({3, 4, 5}); - - // Constructs a copy at this state for further test purpose - miniST st_pruned = st; - - st.insert_simplex_and_subfaces({3, 0}); - st.insert_simplex_and_subfaces({2, 1, 0}); - - // Constructs a copy at this state for further test purpose - miniST st_complete = st; - // st_complete and st: - // 1 6 - // o---o - // /X\7/ - // o---o---o---o - // 2 0 3\X/4 - // o - // 5 - // st_pruned: - // 1 6 - // o---o - // \7/ - // o o---o - // 0 3\X/4 - // o - // 5 - -#ifdef GUDHI_DEBUG - std::cout << "Check exception throw in debug mode" << std::endl; - // throw excpt because sh has children - BOOST_CHECK_THROW (st.remove_maximal_simplex(st.find({0, 1, 6})), std::invalid_argument); - BOOST_CHECK_THROW (st.remove_maximal_simplex(st.find({3})), std::invalid_argument); - BOOST_CHECK(st == st_complete); -#endif - - st.remove_maximal_simplex(st.find({0, 2})); - st.remove_maximal_simplex(st.find({0, 1, 2})); - st.remove_maximal_simplex(st.find({1, 2})); - st.remove_maximal_simplex(st.find({2})); - st.remove_maximal_simplex(st.find({0, 3})); - - BOOST_CHECK(st == st_pruned); - // Remove all, but as the simplex tree is not storing filtration, there is no modification - st.prune_above_filtration(0.0); - BOOST_CHECK(st == st_pruned); - - miniST st_wo_seven; - // FIXME - st_wo_seven.set_dimension(3); - - st_wo_seven.insert_simplex_and_subfaces({0, 1, 6}); - st_wo_seven.insert_simplex_and_subfaces({3, 4, 5}); - // st_wo_seven: - // 1 6 - // o---o - // \X/ - // o o---o - // 0 3\X/4 - // o - // 5 - - // Remove all 7 to test the both remove_maximal_simplex cases (when _members is empty or not) - st.remove_maximal_simplex(st.find({0, 1, 6, 7})); - st.remove_maximal_simplex(st.find({0, 1, 7})); - st.remove_maximal_simplex(st.find({0, 6, 7})); - st.remove_maximal_simplex(st.find({0, 7})); - st.remove_maximal_simplex(st.find({1, 6, 7})); - st.remove_maximal_simplex(st.find({1, 7})); - st.remove_maximal_simplex(st.find({6, 7})); - st.remove_maximal_simplex(st.find({7})); - - BOOST_CHECK(st == st_wo_seven); -} - -BOOST_AUTO_TEST_CASE(prune_above_filtration) { - std::cout << "********************************************************************" << std::endl; - std::cout << "PRUNE ABOVE FILTRATION" << std::endl; - typedef Simplex_tree<> typeST; - typeST st; - - // FIXME - st.set_dimension(3); - - st.insert_simplex_and_subfaces({0, 1, 6, 7}, 1.0); - st.insert_simplex_and_subfaces({3, 4, 5}, 2.0); - - // Constructs a copy at this state for further test purpose - typeST st_pruned = st; - st_pruned.initialize_filtration(); // reset - - st.insert_simplex_and_subfaces({3, 0}, 3.0); - st.insert_simplex_and_subfaces({2, 1, 0}, 4.0); - - // Constructs a copy at this state for further test purpose - typeST st_complete = st; - // st_complete and st: - // 1 6 - // o---o - // /X\7/ - // o---o---o---o - // 2 0 3\X/4 - // o - // 5 - // st_pruned: - // 1 6 - // o---o - // \7/ - // o o---o - // 0 3\X/4 - // o - // 5 - - bool simplex_is_changed = false; - // Check the no action cases - // greater than initial filtration value - simplex_is_changed = st.prune_above_filtration(10.0); - if (simplex_is_changed) - st.initialize_filtration(); - BOOST_CHECK(st == st_complete); - BOOST_CHECK(!simplex_is_changed); - // equal to initial filtration value - simplex_is_changed = st.prune_above_filtration(6.0); - if (simplex_is_changed) - st.initialize_filtration(); - BOOST_CHECK(st == st_complete); - BOOST_CHECK(!simplex_is_changed); - // lower than initial filtration value, but still greater than the maximum filtration value - simplex_is_changed = st.prune_above_filtration(5.0); - if (simplex_is_changed) - st.initialize_filtration(); - BOOST_CHECK(st == st_complete); - BOOST_CHECK(!simplex_is_changed); - - // Display the Simplex_tree - std::cout << "The complex contains " << st.num_simplices() << " simplices"; - std::cout << " - dimension " << st.dimension() << std::endl; - std::cout << "Iterator on Simplices in the filtration, with [filtration value]:" << std::endl; - for (auto f_simplex : st.filtration_simplex_range()) { - std::cout << " " << "[" << st.filtration(f_simplex) << "] "; - for (auto vertex : st.simplex_vertex_range(f_simplex)) { - std::cout << (int) vertex << " "; - } - std::cout << std::endl; - } - - // Check the pruned cases - simplex_is_changed = st.prune_above_filtration(2.5); - if (simplex_is_changed) - st.initialize_filtration(); - BOOST_CHECK(st == st_pruned); - BOOST_CHECK(simplex_is_changed); - - // Display the Simplex_tree - std::cout << "The complex pruned at 2.5 contains " << st.num_simplices() << " simplices"; - std::cout << " - dimension " << st.dimension() << std::endl; - - simplex_is_changed = st.prune_above_filtration(2.0); - if (simplex_is_changed) - st.initialize_filtration(); - - std::cout << "The complex pruned at 2.0 contains " << st.num_simplices() << " simplices"; - std::cout << " - dimension " << st.dimension() << std::endl; - - BOOST_CHECK(st == st_pruned); - BOOST_CHECK(!simplex_is_changed); - - typeST st_empty; - // FIXME - st_empty.set_dimension(3); - simplex_is_changed = st.prune_above_filtration(0.0); - if (simplex_is_changed) - st.initialize_filtration(); - - // Display the Simplex_tree - std::cout << "The complex pruned at 0.0 contains " << st.num_simplices() << " simplices"; - std::cout << " - dimension " << st.dimension() << std::endl; - - BOOST_CHECK(st == st_empty); - BOOST_CHECK(simplex_is_changed); - - // Test case to the limit - simplex_is_changed = st.prune_above_filtration(-1.0); - if (simplex_is_changed) - st.initialize_filtration(); - BOOST_CHECK(st == st_empty); - BOOST_CHECK(!simplex_is_changed); -} - -BOOST_AUTO_TEST_CASE(mini_prune_above_filtration) { - std::cout << "********************************************************************" << std::endl; - std::cout << "MINI PRUNE ABOVE FILTRATION" << std::endl; - typedef Simplex_tree<MyOptions> typeST; - typeST st; - - // FIXME - st.set_dimension(3); - - st.insert_simplex_and_subfaces({0, 1, 6, 7}); - st.insert_simplex_and_subfaces({3, 4, 5}); - st.insert_simplex_and_subfaces({3, 0}); - st.insert_simplex_and_subfaces({2, 1, 0}); - - // st: - // 1 6 - // o---o - // /X\7/ - // o---o---o---o - // 2 0 3\X/4 - // o - // 5 - - st.initialize_filtration(); - - // Display the Simplex_tree - std::cout << "The complex contains " << st.num_simplices() << " simplices" << std::endl; - BOOST_CHECK(st.num_simplices() == 27); - - // Test case to the limit - With these options, there is no filtration, which means filtration is 0 - bool simplex_is_changed = st.prune_above_filtration(1.0); - if (simplex_is_changed) - st.initialize_filtration(); - // Display the Simplex_tree - std::cout << "The complex pruned at 1.0 contains " << st.num_simplices() << " simplices" << std::endl; - BOOST_CHECK(!simplex_is_changed); - BOOST_CHECK(st.num_simplices() == 27); - - simplex_is_changed = st.prune_above_filtration(0.0); - if (simplex_is_changed) - st.initialize_filtration(); - // Display the Simplex_tree - std::cout << "The complex pruned at 0.0 contains " << st.num_simplices() << " simplices" << std::endl; - BOOST_CHECK(!simplex_is_changed); - BOOST_CHECK(st.num_simplices() == 27); - - // Test case to the limit - simplex_is_changed = st.prune_above_filtration(-1.0); - if (simplex_is_changed) - st.initialize_filtration(); - // Display the Simplex_tree - std::cout << "The complex pruned at -1.0 contains " << st.num_simplices() << " simplices" << std::endl; - BOOST_CHECK(simplex_is_changed); - BOOST_CHECK(st.num_simplices() == 0); - - // Display the Simplex_tree - std::cout << "The complex contains " << st.num_simplices() << " simplices" << std::endl; - -} diff --git a/src/Tangential_complex/include/gudhi/Tangential_complex.h b/src/Tangential_complex/include/gudhi/Tangential_complex.h index a5cefd6a..6f061922 100644 --- a/src/Tangential_complex/include/gudhi/Tangential_complex.h +++ b/src/Tangential_complex/include/gudhi/Tangential_complex.h @@ -155,7 +155,7 @@ class Tangential_complex { >::type Triangulation; typedef typename Triangulation::Geom_traits Tr_traits; typedef typename Triangulation::Weighted_point Tr_point; - typedef typename Triangulation::Bare_point Tr_bare_point; + typedef typename Tr_traits::Base::Point_d Tr_bare_point; typedef typename Triangulation::Vertex_handle Tr_vertex_handle; typedef typename Triangulation::Full_cell_handle Tr_full_cell_handle; typedef typename Tr_traits::Vector_d Tr_vector; diff --git a/src/Witness_complex/doc/Witness_complex_doc.h b/src/Witness_complex/doc/Witness_complex_doc.h index 171a185f..20834be0 100644 --- a/src/Witness_complex/doc/Witness_complex_doc.h +++ b/src/Witness_complex/doc/Witness_complex_doc.h @@ -107,7 +107,7 @@ int main(int argc, char * const argv[]) { Here is an example of constructing a strong witness complex filtration and computing persistence on it: - \include Witness_complex/example_strong_witness_persistence.cpp + \include Witness_complex/strong_witness_persistence.cpp \copyright GNU General Public License v3. diff --git a/src/Witness_complex/include/gudhi/Strong_witness_complex.h b/src/Witness_complex/include/gudhi/Strong_witness_complex.h index 6f4bcf60..c18335d3 100644 --- a/src/Witness_complex/include/gudhi/Strong_witness_complex.h +++ b/src/Witness_complex/include/gudhi/Strong_witness_complex.h @@ -127,7 +127,6 @@ class Strong_witness_complex { if ((Landmark_id)simplex.size() - 1 > complex_dim) complex_dim = simplex.size() - 1; } - complex.set_dimension(complex_dim); return true; } diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index bcfe8484..53c38520 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -130,7 +130,6 @@ class Witness_complex { } k++; } - complex.set_dimension(k-1); return true; } diff --git a/src/cmake/modules/GUDHI_doxygen_target.cmake b/src/cmake/modules/GUDHI_doxygen_target.cmake index d2cb952d..f3e2d9f5 100644 --- a/src/cmake/modules/GUDHI_doxygen_target.cmake +++ b/src/cmake/modules/GUDHI_doxygen_target.cmake @@ -3,6 +3,11 @@ find_package(Doxygen) if(DOXYGEN_FOUND) # configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY) + #starting from cmake 3.9 the usage of DOXYGEN_EXECUTABLE is deprecated + if(TARGET Doxygen::doxygen) + get_property(DOXYGEN_EXECUTABLE TARGET Doxygen::doxygen PROPERTY IMPORTED_LOCATION) + endif() + add_custom_target(doxygen ${DOXYGEN_EXECUTABLE} ${GUDHI_USER_VERSION_DIR}/Doxyfile WORKING_DIRECTORY ${GUDHI_USER_VERSION_DIR} DEPENDS ${GUDHI_USER_VERSION_DIR}/Doxyfile ${GUDHI_DOXYGEN_DEPENDENCY} diff --git a/src/cmake/modules/GUDHI_third_party_libraries.cmake b/src/cmake/modules/GUDHI_third_party_libraries.cmake index f2bbafdc..8269c3bf 100644 --- a/src/cmake/modules/GUDHI_third_party_libraries.cmake +++ b/src/cmake/modules/GUDHI_third_party_libraries.cmake @@ -54,10 +54,12 @@ if(CGAL_FOUND) endforeach(CGAL_INCLUDE_DIR ${CGAL_INCLUDE_DIRS}) endif(NOT CGAL_VERSION VERSION_GREATER 4.9.0) - # For dev version - include_directories(BEFORE "src/common/include/gudhi_patches") - # For user version - include_directories(BEFORE "include/gudhi_patches") + if (NOT CGAL_VERSION VERSION_GREATER 4.11.0) + # For dev version + include_directories(BEFORE "src/common/include/gudhi_patches") + # For user version + include_directories(BEFORE "include/gudhi_patches") + endif (NOT CGAL_VERSION VERSION_GREATER 4.11.0) endif() endif() diff --git a/src/cmake/modules/GUDHI_user_version_target.cmake b/src/cmake/modules/GUDHI_user_version_target.cmake index cff64ad2..4abc2574 100644 --- a/src/cmake/modules/GUDHI_user_version_target.cmake +++ b/src/cmake/modules/GUDHI_user_version_target.cmake @@ -48,7 +48,11 @@ if (NOT CMAKE_VERSION VERSION_LESS 2.8.11) copy_directory ${CMAKE_SOURCE_DIR}/src/GudhUI ${GUDHI_USER_VERSION_DIR}/GudhUI) set(GUDHI_DIRECTORIES "doc;example;concept;utilities") - set(GUDHI_INCLUDE_DIRECTORIES "include/gudhi;include/gudhi_patches") + if (NOT CGAL_VERSION VERSION_GREATER 4.11.0) + set(GUDHI_INCLUDE_DIRECTORIES "include/gudhi;include/gudhi_patches") + else () + set(GUDHI_INCLUDE_DIRECTORIES "include/gudhi") + endif () foreach(GUDHI_MODULE ${GUDHI_MODULES_FULL_LIST}) foreach(GUDHI_DIRECTORY ${GUDHI_DIRECTORIES}) diff --git a/src/common/doc/main_page.h b/src/common/doc/main_page.h index 9071b566..1838a136 100644 --- a/src/common/doc/main_page.h +++ b/src/common/doc/main_page.h @@ -273,17 +273,25 @@ make doxygen * Library</a> (CGAL \cite cgal:eb-15b) and will not be built if CGAL is not installed: * \li <a href="_alpha_complex_2alpha_complex_3d_persistence_8cpp-example.html"> * Alpha_complex/alpha_complex_3d_persistence.cpp</a> - * \li <a href="_persistent_cohomology_2exact_alpha_complex_3d_persistence_8cpp-example.html"> - * Persistent_cohomology/exact_alpha_complex_3d_persistence.cpp</a> - * \li <a href="_persistent_cohomology_2weighted_alpha_complex_3d_persistence_8cpp-example.html"> - * Persistent_cohomology/weighted_alpha_complex_3d_persistence.cpp</a> + * \li <a href="_alpha_complex_2exact_alpha_complex_3d_persistence_8cpp-example.html"> + * Alpha_complex/exact_alpha_complex_3d_persistence.cpp</a> + * \li <a href="_alpha_complex_2weighted_alpha_complex_3d_persistence_8cpp-example.html"> + * Alpha_complex/weighted_alpha_complex_3d_persistence.cpp</a> * \li <a href="_simplex_tree_2example_alpha_shapes_3_simplex_tree_from_off_file_8cpp-example.html"> * Simplex_tree/example_alpha_shapes_3_simplex_tree_from_off_file.cpp</a> * - * The following example requires CGAL version ≥ 4.6.0: - * \li <a href="_witness_complex_2witness_complex_sphere_8cpp-example.html"> - * Witness_complex/witness_complex_sphere.cpp</a> - * + * The following examples/utilities require CGAL version ≥ 4.6.0: + * \li <a href="_witness_complex_2strong_witness_persistence_8cpp-example.html"> + * Witness_complex/strong_witness_persistence.cpp</a> + * \li <a href="_witness_complex_2weak_witness_persistence_8cpp-example.html"> + * Witness_complex/weak_witness_persistence.cpp</a> + * \li <a href="_witness_complex_2example_strong_witness_complex_off_8cpp-example.html"> + * Witness_complex/example_strong_witness_complex_off.cpp</a> + * \li <a href="_witness_complex_2example_witness_complex_off_8cpp-example.html"> + * Witness_complex/example_witness_complex_off.cpp</a> + * \li <a href="_witness_complex_2example_witness_complex_sphere_8cpp-example.html"> + * Witness_complex/example_witness_complex_sphere.cpp</a> + * * The following example requires CGAL version ≥ 4.7.0: * \li <a href="_alpha_complex_2_alpha_complex_from_off_8cpp-example.html"> * Alpha_complex/Alpha_complex_from_off.cpp</a> @@ -301,8 +309,8 @@ make doxygen * Bottleneck_distance/alpha_rips_persistence_bottleneck_distance.cpp.cpp</a> * \li <a href="_bottleneck_distance_2bottleneck_basic_example_8cpp-example.html"> * Bottleneck_distance/bottleneck_basic_example.cpp</a> - * \li <a href="_bottleneck_distance_2bottleneck_read_file_example_8cpp-example.html"> - * Bottleneck_distance/bottleneck_read_file_example.cpp</a> + * \li <a href="_bottleneck_distance_2bottleneck_read_file_8cpp-example.html"> + * Bottleneck_distance/bottleneck_read_file.cpp</a> * \li <a href="_spatial_searching_2example_spatial_searching_8cpp-example.html"> * Spatial_searching/example_spatial_searching.cpp</a> * \li <a href="_subsampling_2example_choose_n_farthest_points_8cpp-example.html"> @@ -351,6 +359,16 @@ make doxygen * Tangential_complex/example_basic.cpp</a> * \li <a href="_tangential_complex_2example_with_perturb_8cpp-example.html"> * Tangential_complex/example_with_perturb.cpp</a> + * \li <a href="_witness_complex_2strong_witness_persistence_8cpp-example.html"> + * Witness_complex/strong_witness_persistence.cpp</a> + * \li <a href="_witness_complex_2weak_witness_persistence_8cpp-example.html"> + * Witness_complex/weak_witness_persistence.cpp</a> + * \li <a href="_witness_complex_2example_strong_witness_complex_off_8cpp-example.html"> + * Witness_complex/example_strong_witness_complex_off.cpp</a> + * \li <a href="_witness_complex_2example_witness_complex_off_8cpp-example.html"> + * Witness_complex/example_witness_complex_off.cpp</a> + * \li <a href="_witness_complex_2example_witness_complex_sphere_8cpp-example.html"> + * Witness_complex/example_witness_complex_sphere.cpp</a> * * \subsection tbb Threading Building Blocks * <a target="_blank" href="https://www.threadingbuildingblocks.org/">Intel® TBB</a> lets you easily write parallel @@ -368,8 +386,12 @@ make doxygen * Alpha_complex/alpha_complex_3d_persistence.cpp</a> * \li <a href="_alpha_complex_2alpha_complex_persistence_8cpp-example.html"> * Alpha_complex/alpha_complex_persistence.cpp</a> + * \li <a href="_alpha_complex_2exact_alpha_complex_3d_persistence_8cpp-example.html"> + * Alpha_complex/exact_alpha_complex_3d_persistence.cpp</a> * \li <a href="_alpha_complex_2periodic_alpha_complex_3d_persistence_8cpp-example.html"> * Alpha_complex/periodic_alpha_complex_3d_persistence.cpp</a> + * \li <a href="_alpha_complex_2weighted_alpha_complex_3d_persistence_8cpp-example.html"> + * Alpha_complex/weighted_alpha_complex_3d_persistence.cpp</a> * \li <a href="_bitmap_cubical_complex_2_bitmap_cubical_complex_8cpp-example.html"> * Bitmap_cubical_complex/Bitmap_cubical_complex.cpp</a> * \li <a href="_bitmap_cubical_complex_2_bitmap_cubical_complex_periodic_boundary_conditions_8cpp-example.html"> @@ -382,6 +404,12 @@ make doxygen * Simplex_tree/example_alpha_shapes_3_simplex_tree_from_off_file.cpp</a> * \li <a href="_simplex_tree_2simplex_tree_from_cliques_of_graph_8cpp-example.html"> * Simplex_tree/simplex_tree_from_cliques_of_graph.cpp</a> + * \li <a href="_simplex_tree_2graph_expansion_with_blocker_8cpp-example.html"> + * Simplex_tree/graph_expansion_with_blocker.cpp</a> + * \li <a href="_persistent_cohomology_2alpha_complex_3d_persistence_8cpp-example.html"> + * Persistent_cohomology/alpha_complex_3d_persistence.cpp</a> + * \li <a href="_persistent_cohomology_2alpha_complex_persistence_8cpp-example.html"> + * Persistent_cohomology/alpha_complex_persistence.cpp</a> * \li <a href="_persistent_cohomology_2rips_persistence_via_boundary_matrix_8cpp-example.html"> * Persistent_cohomology/rips_persistence_via_boundary_matrix.cpp</a> * \li <a href="_persistent_cohomology_2persistence_from_file_8cpp-example.html"> @@ -408,7 +436,13 @@ make doxygen * Rips_complex/rips_distance_matrix_persistence.cpp</a> * \li <a href="_rips_complex_2rips_persistence_8cpp-example.html"> * Rips_complex/rips_persistence.cpp</a> - * + * \li <a href="_witness_complex_2strong_witness_persistence_8cpp-example.html"> + * Witness_complex/strong_witness_persistence.cpp</a> + * \li <a href="_witness_complex_2weak_witness_persistence_8cpp-example.html"> + * Witness_complex/weak_witness_persistence.cpp</a> + * \li <a href="_witness_complex_2example_nearest_landmark_table_8cpp-example.html"> + * Witness_complex/example_nearest_landmark_table.cpp</a> + * * \section Contributions Bug reports and contributions * Please help us improving the quality of the GUDHI library. You may report bugs or suggestions to: * \verbatim Contact: gudhi-users@lists.gforge.inria.fr \endverbatim @@ -434,10 +468,12 @@ make doxygen * @example Alpha_complex/Alpha_complex_from_points.cpp * @example Alpha_complex/alpha_complex_3d_persistence.cpp * @example Alpha_complex/alpha_complex_persistence.cpp + * @example Alpha_complex/exact_alpha_complex_3d_persistence.cpp * @example Alpha_complex/periodic_alpha_complex_3d_persistence.cpp + * @example Alpha_complex/weighted_alpha_complex_3d_persistence.cpp * @example Bottleneck_distance/alpha_rips_persistence_bottleneck_distance.cpp * @example Bottleneck_distance/bottleneck_basic_example.cpp - * @example Bottleneck_distance/bottleneck_read_file_example.cpp + * @example Bottleneck_distance/bottleneck_read_file.cpp * @example Bitmap_cubical_complex/Bitmap_cubical_complex.cpp * @example Bitmap_cubical_complex/Bitmap_cubical_complex_periodic_boundary_conditions.cpp * @example Bitmap_cubical_complex/Random_bitmap_cubical_complex.cpp @@ -446,8 +482,6 @@ make doxygen * @example Contraction/Garland_heckbert.cpp * @example Contraction/Rips_contraction.cpp * @example Persistent_cohomology/rips_persistence_via_boundary_matrix.cpp - * @example Persistent_cohomology/exact_alpha_complex_3d_persistence.cpp - * @example Persistent_cohomology/weighted_alpha_complex_3d_persistence.cpp * @example Persistent_cohomology/persistence_from_file.cpp * @example Persistent_cohomology/persistence_from_simple_simplex_tree.cpp * @example Persistent_cohomology/plain_homology.cpp @@ -462,6 +496,7 @@ make doxygen * @example Simplex_tree/simple_simplex_tree.cpp * @example Simplex_tree/example_alpha_shapes_3_simplex_tree_from_off_file.cpp * @example Simplex_tree/simplex_tree_from_cliques_of_graph.cpp + * @example Simplex_tree/graph_expansion_with_blocker.cpp * @example Skeleton_blocker/Skeleton_blocker_from_simplices.cpp * @example Skeleton_blocker/Skeleton_blocker_iteration.cpp * @example Skeleton_blocker/Skeleton_blocker_link.cpp @@ -474,9 +509,9 @@ make doxygen * @example Tangential_complex/example_with_perturb.cpp * @example Witness_complex/example_nearest_landmark_table.cpp * @example Witness_complex/example_strong_witness_complex_off.cpp - * @example Witness_complex/example_strong_witness_persistence.cpp * @example Witness_complex/example_witness_complex_off.cpp - * @example Witness_complex/example_witness_complex_persistence.cpp * @example Witness_complex/example_witness_complex_sphere.cpp + * @example Witness_complex/weak_witness_persistence.cpp + * @example Witness_complex/strong_witness_persistence.cpp */ diff --git a/src/cython/CMakeLists.txt b/src/cython/CMakeLists.txt index ec8589f0..afca9d60 100644 --- a/src/cython/CMakeLists.txt +++ b/src/cython/CMakeLists.txt @@ -185,6 +185,19 @@ if(CYTHON_FOUND) add_gudhi_py_test(test_tangential_complex) + # Witness complex AND Subsampling + add_test(NAME euclidean_strong_witness_complex_diagram_persistence_from_off_file_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py" + --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -a 1.0 -n 20 -d 2) + + add_test(NAME euclidean_witness_complex_diagram_persistence_from_off_file_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/euclidean_witness_complex_diagram_persistence_from_off_file_example.py" + --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -a 1.0 -n 20 -d 2) + # Subsampling add_gudhi_py_test(test_subsampling) @@ -218,18 +231,6 @@ if(CYTHON_FOUND) if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.6.0) # Euclidean witness - add_test(NAME euclidean_strong_witness_complex_diagram_persistence_from_off_file_example_py_test - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py" - --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -a 1.0 -n 20 -d 2) - - add_test(NAME euclidean_witness_complex_diagram_persistence_from_off_file_example_py_test - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/euclidean_witness_complex_diagram_persistence_from_off_file_example.py" - --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -a 1.0 -n 20 -d 2) - add_gudhi_py_test(test_euclidean_witness_complex) endif (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.6.0) diff --git a/src/cython/cython/simplex_tree.pyx b/src/cython/cython/simplex_tree.pyx index 45487158..32b91028 100644 --- a/src/cython/cython/simplex_tree.pyx +++ b/src/cython/cython/simplex_tree.pyx @@ -312,7 +312,7 @@ cdef class SimplexTree: """This function returns the persistence of the simplicial complex. :param homology_coeff_field: The homology coefficient field. Must be a - prime number + prime number. Default value is 11. :type homology_coeff_field: int. :param min_persistence: The minimum persistence value to take into account (strictly greater than min_persistence). Default value is diff --git a/src/cython/doc/citation.rst b/src/cython/doc/citation.rst index 6cdfb7cc..f4fdf83b 100644 --- a/src/cython/doc/citation.rst +++ b/src/cython/doc/citation.rst @@ -12,4 +12,4 @@ Manual, as well as for publications directly related to the GUDHI library. GUDHI bibtex ************ -.. literalinclude:: how_to_cite_gudhi.bib +.. literalinclude:: ../../biblio/how_to_cite_gudhi.bib diff --git a/src/cython/doc/cubical_complex_user.rst b/src/cython/doc/cubical_complex_user.rst index 36fa3ba9..2bfac62a 100644 --- a/src/cython/doc/cubical_complex_user.rst +++ b/src/cython/doc/cubical_complex_user.rst @@ -59,7 +59,7 @@ directions, allows to determine, dimension, neighborhood, boundary and coboundar :math:`C \in \mathcal{K}`. .. figure:: - img/Cubical_complex_representation.png + ../../doc/Bitmap_cubical_complex/Cubical_complex_representation.png :alt: Cubical complex. :figclass: align-center @@ -87,7 +87,7 @@ in the example below). Next, in lexicographical order, the filtration of top dim 20 4 7 6 5 in the example below). .. figure:: - img/exampleBitmap.png + ../../doc/Bitmap_cubical_complex/exampleBitmap.png :alt: Example of a input data. :figclass: align-center @@ -95,9 +95,9 @@ in the example below). Next, in lexicographical order, the filtration of top dim The input file for the following complex is: -.. literalinclude:: cubicalcomplexdoc.txt +.. literalinclude:: ../../data/bitmap/cubicalcomplexdoc.txt -.. centered:: data/bitmap/cubicalcomplexdoc.txt +.. centered:: ../../data/bitmap/cubicalcomplexdoc.txt .. testcode:: @@ -128,9 +128,9 @@ complex with periodic boundary conditions. One can also use Perseus style input conditions in a given direction, then number of top dimensional cells in this direction have to be multiplied by -1. For instance: -.. literalinclude:: periodiccubicalcomplexdoc.txt +.. literalinclude:: ../../data/bitmap/periodiccubicalcomplexdoc.txt -.. centered:: data/bitmap/periodiccubicalcomplexdoc.txt +.. centered:: ../../data/bitmap/periodiccubicalcomplexdoc.txt Indicate that we have imposed periodic boundary conditions in the direction x, but not in the direction y. diff --git a/src/cython/doc/installation.rst b/src/cython/doc/installation.rst index f98a5039..c182f176 100644 --- a/src/cython/doc/installation.rst +++ b/src/cython/doc/installation.rst @@ -68,31 +68,32 @@ The :doc:`Alpha complex </alpha_complex_user>`, C++ library which provides easy access to efficient and reliable geometric algorithms. -Having CGAL version 4.6.0 or higher installed is recommended. The procedure to -install this library according to your operating system is detailed +Having CGAL, the Computational Geometry Algorithms Library, version 4.7.0 or +higher installed is recommended. The procedure to install this library +according to your operating system is detailed `here <http://doc.cgal.org/latest/Manual/installation.html>`_. -The following examples require the Computational Geometry Algorithms Library: - -.. only:: builder_html - - * :download:`euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py <../example/euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py>` - * :download:`euclidean_witness_complex_diagram_persistence_from_off_file_example.py <../example/euclidean_witness_complex_diagram_persistence_from_off_file_example.py>` - -The following example requires CGAL version ≥ 4.7.0: +The following examples requires CGAL version ≥ 4.7.0: .. only:: builder_html * :download:`alpha_complex_diagram_persistence_from_off_file_example.py <../example/alpha_complex_diagram_persistence_from_off_file_example.py>` * :download:`alpha_complex_from_points_example.py <../example/alpha_complex_from_points_example.py>` -The following example requires CGAL version ≥ 4.8.0: +The following examples requires CGAL version ≥ 4.8.0: .. only:: builder_html * :download:`bottleneck_basic_example.py <../example/bottleneck_basic_example.py>` * :download:`tangential_complex_plain_homology_from_off_file_example.py <../example/tangential_complex_plain_homology_from_off_file_example.py>` +The following examples requires CGAL version ≥ 4.8.1: + +.. only:: builder_html + + * :download:`euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py <../example/euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py>` + * :download:`euclidean_witness_complex_diagram_persistence_from_off_file_example.py <../example/euclidean_witness_complex_diagram_persistence_from_off_file_example.py>` + Eigen3 ====== diff --git a/src/cython/example/simplex_tree_example.py b/src/cython/example/simplex_tree_example.py index 831d9da8..51a60e73 100755 --- a/src/cython/example/simplex_tree_example.py +++ b/src/cython/example/simplex_tree_example.py @@ -48,8 +48,6 @@ if st.insert([0, 1, 2], filtration=4.0): else: print("Not inserted...") -# FIXME: Remove this line -st.set_dimension(3) print("dimension=", st.dimension()) st.initialize_filtration() diff --git a/src/cython/include/Tangential_complex_interface.h b/src/cython/include/Tangential_complex_interface.h index 5e9dc0e4..ecf014b3 100644 --- a/src/cython/include/Tangential_complex_interface.h +++ b/src/cython/include/Tangential_complex_interface.h @@ -106,8 +106,6 @@ class Tangential_complex_interface { void create_simplex_tree(Simplex_tree<>* simplex_tree) { int max_dim = tangential_complex_->create_complex<Gudhi::Simplex_tree<Gudhi::Simplex_tree_options_full_featured>>(*simplex_tree); - // FIXME - simplex_tree->set_dimension(max_dim); simplex_tree->initialize_filtration(); } diff --git a/src/cython/test/test_cubical_complex.py b/src/cython/test/test_cubical_complex.py index 9a365823..0e81554d 100755 --- a/src/cython/test/test_cubical_complex.py +++ b/src/cython/test/test_cubical_complex.py @@ -62,17 +62,17 @@ def test_dimension_or_perseus_file_constructor(): assert cub.__is_defined() == False assert cub.__is_persistence_defined() == False -def test_dimension_constructor(): +def test_dimension_simple_constructor(): cub = CubicalComplex(dimensions=[3, 3], top_dimensional_cells = [1,2,3,4,5,6,7,8,9]) assert cub.__is_defined() == True assert cub.__is_persistence_defined() == False - assert cub.persistence() == [(1, (0.0, 100.0)), (0, (0.0, float('inf')))] + assert cub.persistence() == [(0, (1.0, float('inf')))] assert cub.__is_persistence_defined() == True - assert cub.betti_numbers() == [1, 0] - assert cub.persistent_betti_numbers(0, 1000) == [0, 0] + assert cub.betti_numbers() == [1, 0, 0] + assert cub.persistent_betti_numbers(0, 1000) == [0, 0, 0] -def test_dimension_constructor(): +def test_dimension_file_constructor(): # Create test file test_file = open('CubicalOneSphere.txt', 'w') test_file.write('2\n3\n3\n0\n0\n0\n0\n100\n0\n0\n0\n0\n') diff --git a/src/cython/test/test_simplex_tree.py b/src/cython/test/test_simplex_tree.py index 4d452d7d..801d52b7 100755 --- a/src/cython/test/test_simplex_tree.py +++ b/src/cython/test/test_simplex_tree.py @@ -34,9 +34,13 @@ def test_insertion(): # insert test assert st.insert([0, 1]) == True + + assert st.dimension() == 1 + assert st.insert([0, 1, 2], filtration=4.0) == True - # FIXME: Remove this line - st.set_dimension(2) + + assert st.dimension() == 2 + assert st.num_simplices() == 7 assert st.num_vertices() == 3 @@ -86,8 +90,9 @@ def test_insertion(): assert st.find([2]) == True st.initialize_filtration() - assert st.persistence() == [(1, (4.0, float('inf'))), (0, (0.0, float('inf')))] + assert st.persistence(persistence_dim_max = True) == [(1, (4.0, float('inf'))), (0, (0.0, float('inf')))] assert st.__is_persistence_defined() == True + assert st.betti_numbers() == [1, 1] assert st.persistent_betti_numbers(-0.1, 10000.0) == [0, 0] assert st.persistent_betti_numbers(0.0, 10000.0) == [1, 0] |