summaryrefslogtreecommitdiff
path: root/src/Persistent_cohomology/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/Persistent_cohomology/test')
-rw-r--r--src/Persistent_cohomology/test/CMakeLists.txt37
-rw-r--r--src/Persistent_cohomology/test/README29
-rw-r--r--src/Persistent_cohomology/test/betti_numbers_unit_test.cpp287
-rw-r--r--src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp212
-rw-r--r--src/Persistent_cohomology/test/persistent_cohomology_unit_test_multi_field.cpp115
-rw-r--r--src/Persistent_cohomology/test/simplex_tree_file_for_multi_field_unit_test.txt58
-rw-r--r--src/Persistent_cohomology/test/simplex_tree_file_for_unit_test.txt98
7 files changed, 836 insertions, 0 deletions
diff --git a/src/Persistent_cohomology/test/CMakeLists.txt b/src/Persistent_cohomology/test/CMakeLists.txt
new file mode 100644
index 00000000..f8baf861
--- /dev/null
+++ b/src/Persistent_cohomology/test/CMakeLists.txt
@@ -0,0 +1,37 @@
+project(Persistent_cohomology_tests)
+
+include(GUDHI_test_coverage)
+
+add_executable ( Persistent_cohomology_test_unit persistent_cohomology_unit_test.cpp )
+target_link_libraries(Persistent_cohomology_test_unit ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
+add_executable ( Persistent_cohomology_test_betti_numbers betti_numbers_unit_test.cpp )
+target_link_libraries(Persistent_cohomology_test_betti_numbers ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
+if (TBB_FOUND)
+ target_link_libraries(Persistent_cohomology_test_unit ${TBB_LIBRARIES})
+ target_link_libraries(Persistent_cohomology_test_betti_numbers ${TBB_LIBRARIES})
+endif(TBB_FOUND)
+
+# Do not forget to copy test results files in current binary dir
+file(COPY "${CMAKE_SOURCE_DIR}/src/Persistent_cohomology/test/simplex_tree_file_for_unit_test.txt"
+ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/)
+
+# Unitary tests
+gudhi_add_coverage_test(Persistent_cohomology_test_unit)
+gudhi_add_coverage_test(Persistent_cohomology_test_betti_numbers)
+
+if(GMPXX_FOUND AND GMP_FOUND)
+ add_executable ( Persistent_cohomology_test_unit_multi_field persistent_cohomology_unit_test_multi_field.cpp )
+ target_link_libraries(Persistent_cohomology_test_unit_multi_field
+ ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} ${GMPXX_LIBRARIES} ${GMP_LIBRARIES})
+ if (TBB_FOUND)
+ target_link_libraries(Persistent_cohomology_test_unit_multi_field ${TBB_LIBRARIES})
+ endif(TBB_FOUND)
+
+ # Do not forget to copy test results files in current binary dir
+ file(COPY "${CMAKE_SOURCE_DIR}/src/Persistent_cohomology/test/simplex_tree_file_for_multi_field_unit_test.txt"
+ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/)
+ # Unitary tests
+ gudhi_add_coverage_test(Persistent_cohomology_test_unit_multi_field)
+
+endif(GMPXX_FOUND AND GMP_FOUND)
+
diff --git a/src/Persistent_cohomology/test/README b/src/Persistent_cohomology/test/README
new file mode 100644
index 00000000..0c41feed
--- /dev/null
+++ b/src/Persistent_cohomology/test/README
@@ -0,0 +1,29 @@
+To compile:
+***********
+
+cd /path-to-gudhi/
+cmake .
+cd /path-to-test/
+make
+
+To launch with details:
+***********************
+
+SINGLE FIELD
+------------
+./Persistent_cohomology_test_unit --report_level=detailed --log_level=all
+
+ ==> echo $? returns 0 in case of success (non-zero otherwise)
+
+MULTI FIELD
+-----------
+./Persistent_cohomology_test_unit_multi_field --report_level=detailed --log_level=all
+
+ ==> echo $? returns 0 in case of success (non-zero otherwise)
+
+BETTI NUMBERS
+-------------
+./Persistent_cohomology_test_betti_numbers --report_level=detailed --log_level=all
+
+ ==> echo $? returns 0 in case of success (non-zero otherwise)
+
diff --git a/src/Persistent_cohomology/test/betti_numbers_unit_test.cpp b/src/Persistent_cohomology/test/betti_numbers_unit_test.cpp
new file mode 100644
index 00000000..0a08d200
--- /dev/null
+++ b/src/Persistent_cohomology/test/betti_numbers_unit_test.cpp
@@ -0,0 +1,287 @@
+#include <iostream>
+#include <string>
+#include <algorithm>
+#include <utility> // std::pair, std::make_pair
+#include <cmath> // float comparison
+#include <limits>
+
+#define BOOST_TEST_DYN_LINK
+#define BOOST_TEST_MODULE "betti_numbers"
+#include <boost/test/unit_test.hpp>
+
+#include <gudhi/Simplex_tree.h>
+#include <gudhi/Persistent_cohomology.h>
+
+struct MiniSTOptions : Gudhi::Simplex_tree_options_full_featured {
+ // Implicitly use 0 as filtration value for all simplices
+ static const bool store_filtration = false;
+ // The persistence algorithm needs this
+ static const bool store_key = true;
+ // I have few vertices
+ typedef short Vertex_handle;
+};
+
+using Mini_simplex_tree = Gudhi::Simplex_tree<MiniSTOptions>;
+using Mini_st_persistence =
+ Gudhi::persistent_cohomology::Persistent_cohomology<Mini_simplex_tree, Gudhi::persistent_cohomology::Field_Zp>;
+
+/*
+ * Compare two intervals by dimension, then by length.
+ */
+template<class Simplicial_complex>
+struct cmp_intervals_by_dim_then_length {
+ explicit cmp_intervals_by_dim_then_length(Simplicial_complex * sc)
+ : sc_(sc) { }
+
+ template<typename Persistent_interval>
+ bool operator()(const Persistent_interval & p1, const Persistent_interval & p2) {
+ if (sc_->dimension(get < 0 > (p1)) == sc_->dimension(get < 0 > (p2)))
+ return (sc_->filtration(get < 1 > (p1)) - sc_->filtration(get < 0 > (p1))
+ > sc_->filtration(get < 1 > (p2)) - sc_->filtration(get < 0 > (p2)));
+ else
+ return (sc_->dimension(get < 0 > (p1)) > sc_->dimension(get < 0 > (p2)));
+ }
+ Simplicial_complex* sc_;
+};
+
+BOOST_AUTO_TEST_CASE( plain_homology_betti_numbers )
+{
+ Mini_simplex_tree st;
+
+ /* Complex to build. */
+ /* 1 4 */
+ /* o---o */
+ /* /3\ / */
+ /* o---o o */
+ /* 2 0 5 */
+ const short tetra0123[] = {0, 1, 2, 3};
+ const short edge04[] = {0, 4};
+ const short edge14[] = {1, 4};
+ const short vertex5[] = {5};
+ st.insert_simplex_and_subfaces(tetra0123);
+ st.insert_simplex_and_subfaces(edge04);
+ st.insert_simplex(edge14);
+ st.insert_simplex(vertex5);
+
+ // Sort the simplices in the order of the filtration
+ st.initialize_filtration();
+
+ // Class for homology computation
+ Mini_st_persistence pcoh(st);
+
+ // Initialize the coefficient field Z/3Z for homology
+ pcoh.init_coefficients(3);
+
+ // Compute the persistence diagram of the complex
+ pcoh.compute_persistent_cohomology();
+
+ // Print the result. The format is, on each line: 2 dim 0 inf
+ // where 2 represents the field, dim the dimension of the feature.
+ // 2 0 0 inf
+ // 2 0 0 inf
+ // 2 1 0 inf
+ // means that in Z/2Z-homology, the Betti numbers are b0=2 and b1=1.
+
+ std::cout << "BETTI NUMBERS" << std::endl;
+
+ BOOST_CHECK(pcoh.betti_number(0) == 2);
+ BOOST_CHECK(pcoh.betti_number(1) == 1);
+ BOOST_CHECK(pcoh.betti_number(2) == 0);
+
+ std::vector<int> bns = pcoh.betti_numbers();
+ BOOST_CHECK(bns.size() == 3);
+ BOOST_CHECK(bns[0] == 2);
+ BOOST_CHECK(bns[1] == 1);
+ BOOST_CHECK(bns[2] == 0);
+
+ std::cout << "GET PERSISTENT PAIRS" << std::endl;
+
+ // Custom sort and output persistence
+ cmp_intervals_by_dim_then_length<Mini_simplex_tree> cmp(&st);
+ auto persistent_pairs = pcoh.get_persistent_pairs();
+
+ std::sort(std::begin(persistent_pairs), std::end(persistent_pairs), cmp);
+
+ BOOST_CHECK(persistent_pairs.size() == 3);
+ // persistent_pairs[0] = 2 1 0 inf
+ BOOST_CHECK(st.dimension(get<0>(persistent_pairs[0])) == 1);
+ BOOST_CHECK(st.filtration(get<0>(persistent_pairs[0])) == 0);
+ BOOST_CHECK(get<1>(persistent_pairs[0]) == st.null_simplex());
+
+ // persistent_pairs[1] = 2 0 0 inf
+ BOOST_CHECK(st.dimension(get<0>(persistent_pairs[1])) == 0);
+ BOOST_CHECK(st.filtration(get<0>(persistent_pairs[1])) == 0);
+ BOOST_CHECK(get<1>(persistent_pairs[1]) == st.null_simplex());
+
+ // persistent_pairs[2] = 2 0 0 inf
+ BOOST_CHECK(st.dimension(get<0>(persistent_pairs[2])) == 0);
+ BOOST_CHECK(st.filtration(get<0>(persistent_pairs[2])) == 0);
+ BOOST_CHECK(get<1>(persistent_pairs[2]) == st.null_simplex());
+
+ std::cout << "INTERVALS IN DIMENSION" << std::endl;
+
+ auto intervals_in_dimension_0 = pcoh.intervals_in_dimension(0);
+ std::cout << "intervals_in_dimension_0.size() = " << intervals_in_dimension_0.size() << std::endl;
+ for (std::size_t i = 0; i < intervals_in_dimension_0.size(); i++)
+ std::cout << "intervals_in_dimension_0[" << i << "] = [" << intervals_in_dimension_0[i].first << "," <<
+ intervals_in_dimension_0[i].second << "]" << std::endl;
+ BOOST_CHECK(intervals_in_dimension_0.size() == 2);
+ BOOST_CHECK(intervals_in_dimension_0[0].first == 0);
+ BOOST_CHECK(intervals_in_dimension_0[0].second == std::numeric_limits<Mini_simplex_tree::Filtration_value>::infinity());
+ BOOST_CHECK(intervals_in_dimension_0[1].first == 0);
+ BOOST_CHECK(intervals_in_dimension_0[1].second == std::numeric_limits<Mini_simplex_tree::Filtration_value>::infinity());
+
+
+ auto intervals_in_dimension_1 = pcoh.intervals_in_dimension(1);
+ std::cout << "intervals_in_dimension_1.size() = " << intervals_in_dimension_1.size() << std::endl;
+ for (std::size_t i = 0; i < intervals_in_dimension_1.size(); i++)
+ std::cout << "intervals_in_dimension_1[" << i << "] = [" << intervals_in_dimension_1[i].first << "," <<
+ intervals_in_dimension_1[i].second << "]" << std::endl;
+ BOOST_CHECK(intervals_in_dimension_1.size() == 1);
+ BOOST_CHECK(intervals_in_dimension_1[0].first == 0);
+ BOOST_CHECK(intervals_in_dimension_1[0].second == std::numeric_limits<Mini_simplex_tree::Filtration_value>::infinity());
+
+ auto intervals_in_dimension_2 = pcoh.intervals_in_dimension(2);
+ std::cout << "intervals_in_dimension_2.size() = " << intervals_in_dimension_2.size() << std::endl;
+ BOOST_CHECK(intervals_in_dimension_2.size() == 0);
+}
+
+using Simplex_tree = Gudhi::Simplex_tree<>;
+using St_persistence =
+ Gudhi::persistent_cohomology::Persistent_cohomology<Simplex_tree, Gudhi::persistent_cohomology::Field_Zp>;
+
+BOOST_AUTO_TEST_CASE( betti_numbers )
+{
+ Simplex_tree st;
+
+ /* Complex to build. */
+ /* 1 4 */
+ /* o---o */
+ /* /3\ / */
+ /* o---o o */
+ /* 2 0 5 */
+ const short tetra0123[] = {0, 1, 2, 3};
+ const short edge04[] = {0, 4};
+ const short edge14[] = {1, 4};
+ const short vertex5[] = {5};
+ st.insert_simplex_and_subfaces(tetra0123, 4.0);
+ st.insert_simplex_and_subfaces(edge04, 2.0);
+ st.insert_simplex(edge14, 2.0);
+ st.insert_simplex(vertex5, 1.0);
+
+ // Sort the simplices in the order of the filtration
+ st.initialize_filtration();
+
+ // Class for homology computation
+ St_persistence pcoh(st);
+
+ // Initialize the coefficient field Z/3Z for homology
+ pcoh.init_coefficients(3);
+
+ // Compute the persistence diagram of the complex
+ pcoh.compute_persistent_cohomology();
+
+ // Check the Betti numbers are b0=2, b1=1 and b2=0.
+ BOOST_CHECK(pcoh.betti_number(0) == 2);
+ BOOST_CHECK(pcoh.betti_number(1) == 1);
+ BOOST_CHECK(pcoh.betti_number(2) == 0);
+
+ // Check the Betti numbers are b0=2, b1=1 and b2=0.
+ std::vector<int> bns = pcoh.betti_numbers();
+ BOOST_CHECK(bns.size() == 3);
+ BOOST_CHECK(bns[0] == 2);
+ BOOST_CHECK(bns[1] == 1);
+ BOOST_CHECK(bns[2] == 0);
+
+ // Check the persistent Betti numbers in [4., 10.] are b0=2, b1=1 and b2=0.
+ BOOST_CHECK(pcoh.persistent_betti_number(0, 4., 10.) == 2);
+ BOOST_CHECK(pcoh.persistent_betti_number(1, 4., 10.) == 1);
+ BOOST_CHECK(pcoh.persistent_betti_number(2, 4., 10.) == 0);
+
+ // Check the persistent Betti numbers in [2., 100.] are b0=2, b1=0 and b2=0.
+ BOOST_CHECK(pcoh.persistent_betti_number(0, 2., 100.) == 2);
+ BOOST_CHECK(pcoh.persistent_betti_number(1, 2., 100.) == 0);
+ BOOST_CHECK(pcoh.persistent_betti_number(2, 2., 100.) == 0);
+
+ // Check the persistent Betti numbers in [1., 1000.] are b0=1, b1=0 and b2=0.
+ BOOST_CHECK(pcoh.persistent_betti_number(0, 1., 1000.) == 1);
+ BOOST_CHECK(pcoh.persistent_betti_number(1, 1., 1000.) == 0);
+ BOOST_CHECK(pcoh.persistent_betti_number(2, 1., 1000.) == 0);
+
+ // Check the persistent Betti numbers in [.9, 1000.] are b0=0, b1=0 and b2=0.
+ BOOST_CHECK(pcoh.persistent_betti_number(0, .9, 1000.) == 0);
+ BOOST_CHECK(pcoh.persistent_betti_number(1, .9, 1000.) == 0);
+ BOOST_CHECK(pcoh.persistent_betti_number(2, .9, 1000.) == 0);
+
+ // Check the persistent Betti numbers in [4.1, 10000.] are b0=2, b1=1 and b2=0.
+ bns = pcoh.persistent_betti_numbers(4.1, 10000.);
+ BOOST_CHECK(bns[0] == 2);
+ BOOST_CHECK(bns[1] == 1);
+ BOOST_CHECK(bns[2] == 0);
+
+ // Check the persistent Betti numbers in [2.1, 100000.] are b0=2, b1=0 and b2=0.
+ bns = pcoh.persistent_betti_numbers(2.1, 100000.);
+ BOOST_CHECK(bns[0] == 2);
+ BOOST_CHECK(bns[1] == 0);
+ BOOST_CHECK(bns[2] == 0);
+
+ // Check the persistent Betti numbers in [1.1, 1000000.] are b0=1, b1=0 and b2=0.
+ bns = pcoh.persistent_betti_numbers(1.1, 1000000.);
+ BOOST_CHECK(bns[0] == 1);
+ BOOST_CHECK(bns[1] == 0);
+ BOOST_CHECK(bns[2] == 0);
+
+ // Check the persistent Betti numbers in [.1, 10000000.] are b0=0, b1=0 and b2=0.
+ bns = pcoh.persistent_betti_numbers(.1, 10000000.);
+ BOOST_CHECK(bns[0] == 0);
+ BOOST_CHECK(bns[1] == 0);
+ BOOST_CHECK(bns[2] == 0);
+
+ // Custom sort and output persistence
+ cmp_intervals_by_dim_then_length<Simplex_tree> cmp(&st);
+ auto persistent_pairs = pcoh.get_persistent_pairs();
+
+ std::sort(std::begin(persistent_pairs), std::end(persistent_pairs), cmp);
+
+ BOOST_CHECK(persistent_pairs.size() == 3);
+ // persistent_pairs[0] = 2 1 4 inf
+ BOOST_CHECK(st.dimension(get<0>(persistent_pairs[0])) == 1);
+ BOOST_CHECK(st.filtration(get<0>(persistent_pairs[0])) == 4);
+ BOOST_CHECK(get<1>(persistent_pairs[0]) == st.null_simplex());
+
+ // persistent_pairs[1] = 2 0 2 inf
+ BOOST_CHECK(st.dimension(get<0>(persistent_pairs[1])) == 0);
+ BOOST_CHECK(st.filtration(get<0>(persistent_pairs[1])) == 2);
+ BOOST_CHECK(get<1>(persistent_pairs[1]) == st.null_simplex());
+
+ // persistent_pairs[2] = 2 0 1 inf
+ BOOST_CHECK(st.dimension(get<0>(persistent_pairs[2])) == 0);
+ BOOST_CHECK(st.filtration(get<0>(persistent_pairs[2])) == 1);
+ BOOST_CHECK(get<1>(persistent_pairs[2]) == st.null_simplex());
+
+ std::cout << "INTERVALS IN DIMENSION" << std::endl;
+
+ auto intervals_in_dimension_0 = pcoh.intervals_in_dimension(0);
+ std::cout << "intervals_in_dimension_0.size() = " << intervals_in_dimension_0.size() << std::endl;
+ for (std::size_t i = 0; i < intervals_in_dimension_0.size(); i++)
+ std::cout << "intervals_in_dimension_0[" << i << "] = [" << intervals_in_dimension_0[i].first << "," <<
+ intervals_in_dimension_0[i].second << "]" << std::endl;
+ BOOST_CHECK(intervals_in_dimension_0.size() == 2);
+ BOOST_CHECK(intervals_in_dimension_0[0].first == 2);
+ BOOST_CHECK(intervals_in_dimension_0[0].second == std::numeric_limits<Mini_simplex_tree::Filtration_value>::infinity());
+ BOOST_CHECK(intervals_in_dimension_0[1].first == 1);
+ BOOST_CHECK(intervals_in_dimension_0[1].second == std::numeric_limits<Mini_simplex_tree::Filtration_value>::infinity());
+
+ auto intervals_in_dimension_1 = pcoh.intervals_in_dimension(1);
+ std::cout << "intervals_in_dimension_1.size() = " << intervals_in_dimension_1.size() << std::endl;
+ for (std::size_t i = 0; i < intervals_in_dimension_1.size(); i++)
+ std::cout << "intervals_in_dimension_1[" << i << "] = [" << intervals_in_dimension_1[i].first << "," <<
+ intervals_in_dimension_1[i].second << "]" << std::endl;
+ BOOST_CHECK(intervals_in_dimension_1.size() == 1);
+ BOOST_CHECK(intervals_in_dimension_1[0].first == 4);
+ BOOST_CHECK(intervals_in_dimension_1[0].second == std::numeric_limits<Mini_simplex_tree::Filtration_value>::infinity());
+
+ auto intervals_in_dimension_2 = pcoh.intervals_in_dimension(2);
+ std::cout << "intervals_in_dimension_2.size() = " << intervals_in_dimension_2.size() << std::endl;
+ BOOST_CHECK(intervals_in_dimension_2.size() == 0);
+}
diff --git a/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp b/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp
new file mode 100644
index 00000000..a1c106d5
--- /dev/null
+++ b/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp
@@ -0,0 +1,212 @@
+#include <iostream>
+#include <string>
+#include <algorithm>
+#include <utility> // std::pair, std::make_pair
+#include <cmath> // float comparison
+#include <limits>
+#include <cstdint> // for std::uint8_t
+
+#define BOOST_TEST_DYN_LINK
+#define BOOST_TEST_MODULE "persistent_cohomology"
+#include <boost/test/unit_test.hpp>
+
+#include <gudhi/graph_simplicial_complex.h>
+#include <gudhi/reader_utils.h>
+#include <gudhi/Simplex_tree.h>
+#include <gudhi/Persistent_cohomology.h>
+
+using namespace Gudhi;
+using namespace Gudhi::persistent_cohomology;
+using namespace boost::unit_test;
+
+typedef Simplex_tree<> typeST;
+
+std::string test_rips_persistence(int coefficient, int min_persistence) {
+ // file is copied in CMakeLists.txt
+ std::ifstream simplex_tree_stream;
+ simplex_tree_stream.open("simplex_tree_file_for_unit_test.txt");
+ typeST st;
+ simplex_tree_stream >> st;
+ simplex_tree_stream.close();
+
+ // Display the Simplex_tree
+ std::cout << "The complex contains " << st.num_simplices() << " simplices" << " - dimension= " << st.dimension()
+ << std::endl;
+
+ // Check
+ BOOST_CHECK(st.num_simplices() == 98);
+ BOOST_CHECK(st.dimension() == 3);
+
+ // Sort the simplices in the order of the filtration
+ st.initialize_filtration();
+
+ // Compute the persistence diagram of the complex
+ Persistent_cohomology<Simplex_tree<>, Field_Zp> pcoh(st);
+
+ pcoh.init_coefficients( coefficient ); // initializes the coefficient field for homology
+ // Check infinite rips
+ pcoh.compute_persistent_cohomology( min_persistence ); // Minimal lifetime of homology feature to be recorded.
+ std::ostringstream ossInfinite;
+
+ pcoh.output_diagram(ossInfinite);
+ std::string strInfinite = ossInfinite.str();
+ return strInfinite;
+}
+
+void test_rips_persistence_in_dimension(int dimension) {
+ std::string value0(" 0 0.02 1.12");
+ std::string value1(" 0 0.03 1.13");
+ std::string value2(" 0 0.04 1.14");
+ std::string value3(" 0 0.05 1.15");
+ std::string value4(" 0 0.06 1.16");
+ std::string value5(" 0 0.07 1.17");
+ std::string value6(" 0 0.08 1.18");
+ std::string value7(" 0 0.09 1.19");
+ std::string value8(" 0 0 inf" );
+ std::string value9(" 0 0.01 inf" );
+
+ value0.insert(0,std::to_string(dimension));
+ value1.insert(0,std::to_string(dimension));
+ value2.insert(0,std::to_string(dimension));
+ value3.insert(0,std::to_string(dimension));
+ value4.insert(0,std::to_string(dimension));
+ value5.insert(0,std::to_string(dimension));
+ value6.insert(0,std::to_string(dimension));
+ value7.insert(0,std::to_string(dimension));
+ value8.insert(0,std::to_string(dimension));
+ value9.insert(0,std::to_string(dimension));
+
+ std::cout << "********************************************************************" << std::endl;
+ std::cout << "TEST OF RIPS_PERSISTENT_COHOMOLOGY_SINGLE_FIELD DIM=" << dimension << " MIN_PERS=0" << std::endl;
+
+ std::string str_rips_persistence = test_rips_persistence(dimension, 0);
+ std::cout << str_rips_persistence << std::endl;
+
+ BOOST_CHECK(str_rips_persistence.find(value0) != std::string::npos); // Check found
+ BOOST_CHECK(str_rips_persistence.find(value1) != std::string::npos); // Check found
+ BOOST_CHECK(str_rips_persistence.find(value2) != std::string::npos); // Check found
+ BOOST_CHECK(str_rips_persistence.find(value3) != std::string::npos); // Check found
+ BOOST_CHECK(str_rips_persistence.find(value4) != std::string::npos); // Check found
+ BOOST_CHECK(str_rips_persistence.find(value5) != std::string::npos); // Check found
+ BOOST_CHECK(str_rips_persistence.find(value6) != std::string::npos); // Check found
+ BOOST_CHECK(str_rips_persistence.find(value7) != std::string::npos); // Check found
+ BOOST_CHECK(str_rips_persistence.find(value8) != std::string::npos); // Check found
+ BOOST_CHECK(str_rips_persistence.find(value9) != std::string::npos); // Check found
+ std::cout << "str_rips_persistence=" << str_rips_persistence << std::endl;
+
+ std::cout << "********************************************************************" << std::endl;
+ std::cout << "TEST OF RIPS_PERSISTENT_COHOMOLOGY_SINGLE_FIELD DIM=" << dimension << " MIN_PERS=1" << std::endl;
+
+ str_rips_persistence = test_rips_persistence(dimension, 1);
+
+ BOOST_CHECK(str_rips_persistence.find(value0) != std::string::npos); // Check found
+ BOOST_CHECK(str_rips_persistence.find(value1) != std::string::npos); // Check found
+ BOOST_CHECK(str_rips_persistence.find(value2) != std::string::npos); // Check found
+ BOOST_CHECK(str_rips_persistence.find(value3) != std::string::npos); // Check found
+ BOOST_CHECK(str_rips_persistence.find(value4) != std::string::npos); // Check found
+ BOOST_CHECK(str_rips_persistence.find(value5) != std::string::npos); // Check found
+ BOOST_CHECK(str_rips_persistence.find(value6) != std::string::npos); // Check found
+ BOOST_CHECK(str_rips_persistence.find(value7) != std::string::npos); // Check found
+ BOOST_CHECK(str_rips_persistence.find(value8) != std::string::npos); // Check found
+ BOOST_CHECK(str_rips_persistence.find(value9) != std::string::npos); // Check found
+ std::cout << "str_rips_persistence=" << str_rips_persistence << std::endl;
+
+ std::cout << "********************************************************************" << std::endl;
+ std::cout << "TEST OF RIPS_PERSISTENT_COHOMOLOGY_SINGLE_FIELD DIM=" << dimension << " MIN_PERS=2" << std::endl;
+
+ str_rips_persistence = test_rips_persistence(dimension, 2);
+
+ BOOST_CHECK(str_rips_persistence.find(value0) == std::string::npos); // Check not found
+ BOOST_CHECK(str_rips_persistence.find(value1) == std::string::npos); // Check not found
+ BOOST_CHECK(str_rips_persistence.find(value2) == std::string::npos); // Check not found
+ BOOST_CHECK(str_rips_persistence.find(value3) == std::string::npos); // Check not found
+ BOOST_CHECK(str_rips_persistence.find(value4) == std::string::npos); // Check not found
+ BOOST_CHECK(str_rips_persistence.find(value5) == std::string::npos); // Check not found
+ BOOST_CHECK(str_rips_persistence.find(value6) == std::string::npos); // Check not found
+ BOOST_CHECK(str_rips_persistence.find(value7) == std::string::npos); // Check not found
+ BOOST_CHECK(str_rips_persistence.find(value8) != std::string::npos); // Check found
+ BOOST_CHECK(str_rips_persistence.find(value9) != std::string::npos); // Check found
+ std::cout << "str_rips_persistence=" << str_rips_persistence << std::endl;
+
+ std::cout << "********************************************************************" << std::endl;
+ std::cout << "TEST OF RIPS_PERSISTENT_COHOMOLOGY_SINGLE_FIELD DIM=" << dimension << " MIN_PERS=Inf" << std::endl;
+
+ str_rips_persistence = test_rips_persistence(dimension, (std::numeric_limits<int>::max)());
+
+ BOOST_CHECK(str_rips_persistence.find(value0) == std::string::npos); // Check not found
+ BOOST_CHECK(str_rips_persistence.find(value1) == std::string::npos); // Check not found
+ BOOST_CHECK(str_rips_persistence.find(value2) == std::string::npos); // Check not found
+ BOOST_CHECK(str_rips_persistence.find(value3) == std::string::npos); // Check not found
+ BOOST_CHECK(str_rips_persistence.find(value4) == std::string::npos); // Check not found
+ BOOST_CHECK(str_rips_persistence.find(value5) == std::string::npos); // Check not found
+ BOOST_CHECK(str_rips_persistence.find(value6) == std::string::npos); // Check not found
+ BOOST_CHECK(str_rips_persistence.find(value7) == std::string::npos); // Check not found
+ BOOST_CHECK(str_rips_persistence.find(value8) != std::string::npos); // Check found
+ BOOST_CHECK(str_rips_persistence.find(value9) != std::string::npos); // Check found
+ std::cout << "str_rips_persistence=" << str_rips_persistence << std::endl;
+}
+
+BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_dim_1 )
+{
+ test_rips_persistence_in_dimension(1);
+}
+
+BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_dim_2 )
+{
+ test_rips_persistence_in_dimension(2);
+}
+
+BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_dim_3 )
+{
+ test_rips_persistence_in_dimension(3);
+}
+
+BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_dim_5 )
+{
+ test_rips_persistence_in_dimension(5);
+}
+
+// TODO(VR): not working from 6
+// std::string str_rips_persistence = test_rips_persistence(6, 0);
+// TODO(VR): division by zero
+// std::string str_rips_persistence = test_rips_persistence(0, 0);
+
+/** SimplexTree minimal options to test the limits.
+ *
+ * Maximum number of simplices to compute persistence is <CODE>std::numeric_limits<std::uint8_t>::max()<\CODE> = 256.*/
+struct MiniSTOptions {
+ typedef linear_indexing_tag Indexing_tag;
+ typedef short Vertex_handle;
+ typedef double Filtration_value;
+ // Maximum number of simplices to compute persistence is 2^8 - 1 = 255. One is reserved for null_key
+ typedef std::uint8_t Simplex_key;
+ static const bool store_key = true;
+ static const bool store_filtration = false;
+ static const bool contiguous_vertices = false;
+};
+
+using Mini_simplex_tree = Gudhi::Simplex_tree<MiniSTOptions>;
+using Mini_st_persistence =
+ Gudhi::persistent_cohomology::Persistent_cohomology<Mini_simplex_tree, Gudhi::persistent_cohomology::Field_Zp>;
+
+BOOST_AUTO_TEST_CASE( persistence_constructor_exception )
+{
+ Mini_simplex_tree st;
+
+ // 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);
+
+ // Sort the simplices in the order of the filtration
+ st.initialize_filtration();
+
+ BOOST_CHECK(st.num_simplices() <= std::numeric_limits<MiniSTOptions::Simplex_key>::max());
+ // Class for homology computation
+ BOOST_CHECK_NO_THROW(Mini_st_persistence pcoh(st));
+
+ st.insert_simplex({8});
+ BOOST_CHECK(st.num_simplices() > std::numeric_limits<MiniSTOptions::Simplex_key>::max());
+ // Class for homology computation
+ BOOST_CHECK_THROW(Mini_st_persistence pcoh2(st), std::out_of_range);
+
+}
diff --git a/src/Persistent_cohomology/test/persistent_cohomology_unit_test_multi_field.cpp b/src/Persistent_cohomology/test/persistent_cohomology_unit_test_multi_field.cpp
new file mode 100644
index 00000000..9e767943
--- /dev/null
+++ b/src/Persistent_cohomology/test/persistent_cohomology_unit_test_multi_field.cpp
@@ -0,0 +1,115 @@
+#include <iostream>
+#include <string>
+#include <algorithm>
+#include <utility> // std::pair, std::make_pair
+#include <cmath> // float comparison
+#include <limits>
+
+#define BOOST_TEST_DYN_LINK
+#define BOOST_TEST_MODULE "persistent_cohomology_multi_field"
+#include <boost/test/unit_test.hpp>
+
+#include <gudhi/graph_simplicial_complex.h>
+#include <gudhi/reader_utils.h>
+#include <gudhi/Simplex_tree.h>
+#include <gudhi/Persistent_cohomology.h>
+#include <gudhi/Persistent_cohomology/Multi_field.h>
+
+using namespace Gudhi;
+using namespace Gudhi::persistent_cohomology;
+using namespace boost::unit_test;
+
+typedef Simplex_tree<> typeST;
+
+std::string test_rips_persistence(int min_coefficient, int max_coefficient, double min_persistence) {
+ // file is copied in CMakeLists.txt
+ std::ifstream simplex_tree_stream;
+ simplex_tree_stream.open("simplex_tree_file_for_multi_field_unit_test.txt");
+ typeST st;
+ simplex_tree_stream >> st;
+ simplex_tree_stream.close();
+
+ // Display the Simplex_tree
+ std::cout << "The complex contains " << st.num_simplices() << " simplices" << " - dimension= " << st.dimension()
+ << std::endl;
+
+ // Check
+ BOOST_CHECK(st.num_simplices() == 58);
+ BOOST_CHECK(st.dimension() == 3);
+
+ // Sort the simplices in the order of the filtration
+ st.initialize_filtration();
+
+ // Compute the persistence diagram of the complex
+ Persistent_cohomology<Simplex_tree<>, Multi_field> pcoh(st);
+
+ pcoh.init_coefficients(min_coefficient, max_coefficient); // initializes the coefficient field for homology
+ // Check infinite rips
+ pcoh.compute_persistent_cohomology(min_persistence); // Minimal lifetime of homology feature to be recorded.
+
+ std::ostringstream ossRips;
+ pcoh.output_diagram(ossRips);
+
+ std::string strRips = ossRips.str();
+ return strRips;
+}
+
+void test_rips_persistence_in_dimension(int min_dimension, int max_dimension) {
+ // there are 2 discontinued ensembles
+ std::string value0(" 0 0.25 inf");
+ std::string value1(" 1 0.4 inf");
+ // And a big hole - cut in 2 pieces after 0.3
+ std::string value2(" 0 0.2 0.3");
+
+ // For dim <= 1 =>
+ std::string value3(" 1 0.25 inf");
+ std::string value4(" 2 0.25 inf");
+ std::string value5(" 1 0.3 inf");
+ std::string value6(" 2 0.3 inf");
+ std::string value7(" 2 0.4 inf");
+
+ std::cout << "********************************************************************" << std::endl;
+ std::cout << "TEST OF RIPS_PERSISTENT_COHOMOLOGY_MULTI_FIELD MIN_DIM=" << min_dimension << " MAX_DIM=" << max_dimension << " MIN_PERS=0" << std::endl;
+
+ std::string str_rips_persistence = test_rips_persistence(min_dimension, max_dimension, 0.0);
+ std::cout << "str_rips_persistence=" << str_rips_persistence << std::endl;
+
+ BOOST_CHECK(str_rips_persistence.find(value0) != std::string::npos); // Check found
+ BOOST_CHECK(str_rips_persistence.find(value1) != std::string::npos); // Check found
+ BOOST_CHECK(str_rips_persistence.find(value2) != std::string::npos); // Check found
+
+ if ((min_dimension < 2) && (max_dimension < 2)) {
+ BOOST_CHECK(str_rips_persistence.find(value3) != std::string::npos); // Check found
+ BOOST_CHECK(str_rips_persistence.find(value4) != std::string::npos); // Check found
+ BOOST_CHECK(str_rips_persistence.find(value5) != std::string::npos); // Check found
+ BOOST_CHECK(str_rips_persistence.find(value6) != std::string::npos); // Check found
+ BOOST_CHECK(str_rips_persistence.find(value7) != std::string::npos); // Check found
+ } else {
+ BOOST_CHECK(str_rips_persistence.find(value3) == std::string::npos); // Check not found
+ BOOST_CHECK(str_rips_persistence.find(value4) == std::string::npos); // Check not found
+ BOOST_CHECK(str_rips_persistence.find(value5) == std::string::npos); // Check not found
+ BOOST_CHECK(str_rips_persistence.find(value6) == std::string::npos); // Check not found
+ BOOST_CHECK(str_rips_persistence.find(value7) == std::string::npos); // Check not found
+ }
+
+}
+
+BOOST_AUTO_TEST_CASE(rips_persistent_cohomology_multi_field_dim_1_2) {
+ test_rips_persistence_in_dimension(0, 1);
+}
+
+BOOST_AUTO_TEST_CASE(rips_persistent_cohomology_multi_field_dim_2_3) {
+ test_rips_persistence_in_dimension(1, 3);
+}
+
+BOOST_AUTO_TEST_CASE(rips_persistent_cohomology_multi_field_dim_1_5) {
+ test_rips_persistence_in_dimension(1, 5);
+}
+
+// TODO(VR): not working from 6
+// std::string str_rips_persistence = test_rips_persistence(6, 0);
+// TODO(VR): division by zero
+// std::string str_rips_persistence = test_rips_persistence(0, 0);
+// TODO(VR): is result OK of :
+// test_rips_persistence_in_dimension(3, 4);
+
diff --git a/src/Persistent_cohomology/test/simplex_tree_file_for_multi_field_unit_test.txt b/src/Persistent_cohomology/test/simplex_tree_file_for_multi_field_unit_test.txt
new file mode 100644
index 00000000..ed2c0c3d
--- /dev/null
+++ b/src/Persistent_cohomology/test/simplex_tree_file_for_multi_field_unit_test.txt
@@ -0,0 +1,58 @@
+0 0 0.2
+0 3 0.2
+1 3 0 0.2
+0 6 0.2
+0 11 0.2
+1 11 6 0.2
+0 13 0.25
+0 14 0.25
+1 14 13 0.25
+0 15 0.25
+1 15 13 0.25
+1 15 14 0.25
+2 15 14 13 0.25
+0 1 0.3
+1 1 0 0.3
+0 2 0.3
+1 2 0 0.3
+1 2 1 0.3
+2 2 1 0 0.3
+0 4 0.3
+1 4 3 0.3
+0 5 0.3
+1 5 3 0.3
+1 5 4 0.3
+2 5 4 3 0.3
+0 9 0.3
+0 10 0.3
+1 10 2 0.3
+1 10 9 0.3
+1 11 9 0.3
+1 11 10 0.3
+2 11 10 9 0.3
+0 12 0.3
+1 12 2 0.3
+1 12 10 0.3
+2 12 10 2 0.3
+1 6 0 0.4
+1 6 1 0.4
+2 6 1 0 0.4
+0 7 0.4
+1 7 0 0.4
+1 7 1 0.4
+2 7 1 0 0.4
+1 7 6 0.4
+2 7 6 0 0.4
+2 7 6 1 0.4
+3 7 6 1 0 0.4
+0 8 0.4
+1 8 4 0.4
+1 8 5 0.4
+2 8 5 4 0.4
+1 9 4 0.4
+1 9 5 0.4
+2 9 5 4 0.4
+1 9 8 0.4
+2 9 8 4 0.4
+2 9 8 5 0.4
+3 9 8 5 4 0.4
diff --git a/src/Persistent_cohomology/test/simplex_tree_file_for_unit_test.txt b/src/Persistent_cohomology/test/simplex_tree_file_for_unit_test.txt
new file mode 100644
index 00000000..90756ce0
--- /dev/null
+++ b/src/Persistent_cohomology/test/simplex_tree_file_for_unit_test.txt
@@ -0,0 +1,98 @@
+0 0 0
+0 1 0.01
+0 2 0.02
+0 3 0.03
+0 4 0.04
+0 5 0.05
+0 6 0.06
+0 7 0.07
+0 8 0.08
+0 9 0.09
+1 2 1 1.12
+1 3 1 1.13
+1 4 1 1.14
+1 5 1 1.15
+1 6 1 1.16
+1 7 1 1.17
+1 8 1 1.18
+1 9 1 1.19
+1 3 2 1.23
+2 3 2 1 1.23
+1 6 2 1.26
+2 6 2 1 1.26
+1 8 2 1.28
+2 8 2 1 1.28
+1 9 2 1.29
+2 9 2 1 1.29
+1 6 3 1.36
+2 6 3 1 1.36
+2 6 3 2 1.36
+3 6 3 2 1 1.36
+1 7 3 1.37
+2 7 3 1 1.37
+1 8 3 1.38
+2 8 3 1 1.38
+2 8 3 2 1.38
+3 8 3 2 1 1.38
+1 5 4 1.45
+2 5 4 1 1.45
+1 6 4 1.46
+2 6 4 1 1.46
+1 8 4 1.48
+2 8 4 1 1.48
+1 6 5 1.56
+2 6 5 1 1.56
+2 6 5 4 1.56
+3 6 5 4 1 1.56
+1 7 5 1.57
+2 7 5 1 1.57
+1 8 5 1.58
+2 8 5 1 1.58
+2 8 5 4 1.58
+3 8 5 4 1 1.58
+1 9 5 1.59
+2 9 5 1 1.59
+1 7 6 1.67
+2 7 6 1 1.67
+2 7 6 3 1.67
+3 7 6 3 1 1.67
+2 7 6 5 1.67
+3 7 6 5 1 1.67
+1 8 6 1.68
+2 8 6 1 1.68
+2 8 6 2 1.68
+3 8 6 2 1 1.68
+2 8 6 3 1.68
+3 8 6 3 1 1.68
+3 8 6 3 2 1.68
+2 8 6 4 1.68
+3 8 6 4 1 1.68
+2 8 6 5 1.68
+3 8 6 5 1 1.68
+3 8 6 5 4 1.68
+1 9 6 1.69
+2 9 6 1 1.69
+2 9 6 2 1.69
+3 9 6 2 1 1.69
+2 9 6 5 1.69
+3 9 6 5 1 1.69
+1 8 7 1.78
+2 8 7 1 1.78
+2 8 7 3 1.78
+3 8 7 3 1 1.78
+2 8 7 5 1.78
+3 8 7 5 1 1.78
+2 8 7 6 1.78
+3 8 7 6 1 1.78
+3 8 7 6 3 1.78
+3 8 7 6 5 1.78
+1 9 8 1.89
+2 9 8 1 1.89
+2 9 8 2 1.89
+3 9 8 2 1 1.89
+2 9 8 5 1.89
+3 9 8 5 1 1.89
+2 9 8 6 1.89
+3 9 8 6 1 1.89
+3 9 8 6 2 1.89
+3 9 8 6 5 1.89