summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Bottleneck_distance/example/bottleneck_read_file_example.cpp4
-rw-r--r--src/Persistent_cohomology/example/rips_distance_matrix_persistence.cpp2
-rw-r--r--src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h13
-rw-r--r--src/Rips_complex/example/example_rips_complex_from_csv_distance_matrix_file.cpp2
-rw-r--r--src/Rips_complex/test/test_rips_complex.cpp2
-rw-r--r--src/cmake/modules/GUDHI_third_party_libraries.cmake4
-rw-r--r--src/common/doc/file_formats.h6
-rw-r--r--src/common/include/gudhi/reader_utils.h4
-rw-r--r--src/common/test/test_distance_matrix_reader.cpp4
-rw-r--r--src/common/test/test_persistence_intervals_reader.cpp37
-rw-r--r--src/cython/CMakeLists.txt17
-rwxr-xr-xsrc/cython/cython/persistence_graphical_tools.py76
-rw-r--r--src/cython/cython/reader_utils.pyx95
-rw-r--r--src/cython/cython/simplex_tree.pyx22
-rw-r--r--src/cython/doc/_templates/layout.html1
-rw-r--r--src/cython/doc/fileformats.rst33
-rw-r--r--src/cython/doc/persistence_graphical_tools_user.rst22
-rwxr-xr-xsrc/cython/doc/pyplots/barcode_persistence.py5
-rwxr-xr-xsrc/cython/doc/pyplots/diagram_persistence.py8
-rwxr-xr-xsrc/cython/doc/pyplots/show_palette_values.py3
-rwxr-xr-xsrc/cython/doc/python3-sphinx-build.in (renamed from src/cython/doc/python3-sphinx-build)2
-rw-r--r--src/cython/doc/reader_utils_ref.rst11
-rwxr-xr-xsrc/cython/example/alpha_complex_diagram_persistence_from_off_file_example.py4
-rwxr-xr-xsrc/cython/example/euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py5
-rwxr-xr-xsrc/cython/example/euclidean_witness_complex_diagram_persistence_from_off_file_example.py5
-rwxr-xr-xsrc/cython/example/gudhi_graphical_tools_example.py9
-rwxr-xr-xsrc/cython/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py4
-rwxr-xr-xsrc/cython/example/rips_complex_diagram_persistence_from_off_file_example.py4
-rwxr-xr-xsrc/cython/example/rips_persistence_diagram.py3
-rwxr-xr-xsrc/cython/example/tangential_complex_plain_homology_from_off_file_example.py4
-rw-r--r--src/cython/gudhi.pyx.in1
-rw-r--r--src/cython/include/Reader_utils_interface.h54
-rw-r--r--src/cython/include/Rips_complex_interface.h2
-rwxr-xr-xsrc/cython/test/test_reader_utils.py88
34 files changed, 475 insertions, 81 deletions
diff --git a/src/Bottleneck_distance/example/bottleneck_read_file_example.cpp b/src/Bottleneck_distance/example/bottleneck_read_file_example.cpp
index 238d99ad..1408681a 100644
--- a/src/Bottleneck_distance/example/bottleneck_read_file_example.cpp
+++ b/src/Bottleneck_distance/example/bottleneck_read_file_example.cpp
@@ -36,8 +36,8 @@ int main(int argc, char** argv) {
" distance (set by default to zero). The program will now terminate \n";
return -1;
}
- std::vector<std::pair<double, double>> diag1 = read_persistence_intervals_in_dimension(argv[1]);
- std::vector<std::pair<double, double>> diag2 = read_persistence_intervals_in_dimension(argv[2]);
+ std::vector<std::pair<double, double>> diag1 = Gudhi::read_persistence_intervals_in_dimension(argv[1]);
+ std::vector<std::pair<double, double>> diag2 = Gudhi::read_persistence_intervals_in_dimension(argv[2]);
double tolerance = 0.;
if (argc == 4) {
diff --git a/src/Persistent_cohomology/example/rips_distance_matrix_persistence.cpp b/src/Persistent_cohomology/example/rips_distance_matrix_persistence.cpp
index 8517e7f6..d38808c7 100644
--- a/src/Persistent_cohomology/example/rips_distance_matrix_persistence.cpp
+++ b/src/Persistent_cohomology/example/rips_distance_matrix_persistence.cpp
@@ -57,7 +57,7 @@ int main(int argc, char * argv[]) {
program_options(argc, argv, csv_matrix_file, filediag, threshold, dim_max, p, min_persistence);
- Distance_matrix distances = read_lower_triangular_matrix_from_csv_file<Filtration_value>(csv_matrix_file);
+ Distance_matrix distances = Gudhi::read_lower_triangular_matrix_from_csv_file<Filtration_value>(csv_matrix_file);
Rips_complex rips_complex_from_file(distances, threshold);
// Construct the Rips complex in a Simplex Tree
diff --git a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h
index 672fda48..e0a147b3 100644
--- a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h
+++ b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h
@@ -591,10 +591,17 @@ class Persistent_cohomology {
std::ofstream diagram_out(diagram_name.c_str());
cmp_intervals_by_length cmp(cpx_);
std::sort(std::begin(persistent_pairs_), std::end(persistent_pairs_), cmp);
+ bool has_infinity = std::numeric_limits<Filtration_value>::has_infinity;
for (auto pair : persistent_pairs_) {
- diagram_out << cpx_->dimension(get<0>(pair)) << " "
- << cpx_->filtration(get<0>(pair)) << " "
- << cpx_->filtration(get<1>(pair)) << std::endl;
+ // Special case on windows, inf is "1.#INF"
+ if (has_infinity && cpx_->filtration(get<1>(pair)) == std::numeric_limits<Filtration_value>::infinity()) {
+ diagram_out << cpx_->dimension(get<0>(pair)) << " "
+ << cpx_->filtration(get<0>(pair)) << " inf" << std::endl;
+ } else {
+ diagram_out << cpx_->dimension(get<0>(pair)) << " "
+ << cpx_->filtration(get<0>(pair)) << " "
+ << cpx_->filtration(get<1>(pair)) << std::endl;
+ }
}
}
diff --git a/src/Rips_complex/example/example_rips_complex_from_csv_distance_matrix_file.cpp b/src/Rips_complex/example/example_rips_complex_from_csv_distance_matrix_file.cpp
index 7ae8126f..9e182f1e 100644
--- a/src/Rips_complex/example/example_rips_complex_from_csv_distance_matrix_file.cpp
+++ b/src/Rips_complex/example/example_rips_complex_from_csv_distance_matrix_file.cpp
@@ -32,7 +32,7 @@ int main(int argc, char **argv) {
// Init of a Rips complex from a distance matrix in a csv file
// Default separator is ';'
// ----------------------------------------------------------------------------
- Distance_matrix distances = read_lower_triangular_matrix_from_csv_file<Filtration_value>(csv_file_name);
+ Distance_matrix distances = Gudhi::read_lower_triangular_matrix_from_csv_file<Filtration_value>(csv_file_name);
Rips_complex rips_complex_from_file(distances, threshold);
std::streambuf* streambufffer;
diff --git a/src/Rips_complex/test/test_rips_complex.cpp b/src/Rips_complex/test/test_rips_complex.cpp
index fc2179f2..fc83f5f7 100644
--- a/src/Rips_complex/test/test_rips_complex.cpp
+++ b/src/Rips_complex/test/test_rips_complex.cpp
@@ -244,7 +244,7 @@ BOOST_AUTO_TEST_CASE(Rips_doc_csv_file) {
std::cout << "========== CSV FILE NAME = " << csv_file_name << " - Rips threshold=" <<
rips_threshold << "==========" << std::endl;
- Distance_matrix distances = read_lower_triangular_matrix_from_csv_file<Filtration_value>(csv_file_name);
+ Distance_matrix distances = Gudhi::read_lower_triangular_matrix_from_csv_file<Filtration_value>(csv_file_name);
Rips_complex rips_complex_from_file(distances, rips_threshold);
const int DIMENSION_1 = 1;
diff --git a/src/cmake/modules/GUDHI_third_party_libraries.cmake b/src/cmake/modules/GUDHI_third_party_libraries.cmake
index 8f486118..dbf2106a 100644
--- a/src/cmake/modules/GUDHI_third_party_libraries.cmake
+++ b/src/cmake/modules/GUDHI_third_party_libraries.cmake
@@ -117,15 +117,13 @@ if(NOT GUDHI_CYTHON_PATH)
endif(NOT GUDHI_CYTHON_PATH)
if(PYTHONINTERP_FOUND AND CYTHON_FOUND)
- # Unitary tests are available through py.test
- find_program( PYTEST_PATH py.test )
# Default found version 2
if(PYTHON_VERSION_MAJOR EQUAL 2)
# Documentation generation is available through sphinx
find_program( SPHINX_PATH sphinx-build )
elseif(PYTHON_VERSION_MAJOR EQUAL 3)
# No sphinx-build in Pyton3, just hack it
- set(SPHINX_PATH "${CMAKE_SOURCE_DIR}/${GUDHI_CYTHON_PATH}/doc/python3-sphinx-build")
+ set(SPHINX_PATH "${CMAKE_CURRENT_BINARY_DIR}/${GUDHI_CYTHON_PATH}/doc/python3-sphinx-build")
else()
message(FATAL_ERROR "ERROR: Try to compile the Cython interface. Python version ${PYTHON_VERSION_STRING} is not valid.")
endif(PYTHON_VERSION_MAJOR EQUAL 2)
diff --git a/src/common/doc/file_formats.h b/src/common/doc/file_formats.h
index 9d0415b1..d715aa4d 100644
--- a/src/common/doc/file_formats.h
+++ b/src/common/doc/file_formats.h
@@ -26,7 +26,7 @@
namespace Gudhi {
/*! \page fileformats File formats
-
+
\tableofcontents
\section FileFormatsPers Persistence Diagram
@@ -49,6 +49,10 @@ namespace Gudhi {
\endverbatim
Other sample files can be found in the `data/persistence_diagram` folder.
+
+ Such files can be generated with `Gudhi::persistent_cohomology::Persistent_cohomology::output_diagram()` and read with
+ `Gudhi::read_persistence_intervals_and_dimension()`, `Gudhi::read_persistence_intervals_grouped_by_dimension()` or
+ `Gudhi::read_persistence_intervals_in_dimension()`.
*/
} // namespace Gudhi
diff --git a/src/common/include/gudhi/reader_utils.h b/src/common/include/gudhi/reader_utils.h
index bda93f4f..90be4fc7 100644
--- a/src/common/include/gudhi/reader_utils.h
+++ b/src/common/include/gudhi/reader_utils.h
@@ -38,6 +38,8 @@
#include <utility> // for pair
#include <tuple> // for std::make_tuple
+namespace Gudhi {
+
// Keep this file tag for Doxygen to parse the code, otherwise, functions are not documented.
// It is required for global functions and variables.
@@ -362,4 +364,6 @@ inline std::vector<std::pair<double, double>> read_persistence_intervals_in_dime
return ret;
}
+} // namespace Gudhi
+
#endif // READER_UTILS_H_
diff --git a/src/common/test/test_distance_matrix_reader.cpp b/src/common/test/test_distance_matrix_reader.cpp
index 95a73bd9..656e6f2e 100644
--- a/src/common/test/test_distance_matrix_reader.cpp
+++ b/src/common/test/test_distance_matrix_reader.cpp
@@ -36,7 +36,7 @@ BOOST_AUTO_TEST_CASE( lower_triangular_distance_matrix )
{
Distance_matrix from_lower_triangular;
// Read lower_triangular_distance_matrix.csv file where the separator is a ','
- from_lower_triangular = read_lower_triangular_matrix_from_csv_file<double>("lower_triangular_distance_matrix.csv",
+ from_lower_triangular = Gudhi::read_lower_triangular_matrix_from_csv_file<double>("lower_triangular_distance_matrix.csv",
',');
for (auto& i : from_lower_triangular) {
for (auto j : i) {
@@ -69,7 +69,7 @@ BOOST_AUTO_TEST_CASE( full_square_distance_matrix )
{
Distance_matrix from_full_square;
// Read full_square_distance_matrix.csv file where the separator is the default one ';'
- from_full_square = read_lower_triangular_matrix_from_csv_file<double>("full_square_distance_matrix.csv");
+ from_full_square = Gudhi::read_lower_triangular_matrix_from_csv_file<double>("full_square_distance_matrix.csv");
for (auto& i : from_full_square) {
for (auto j : i) {
std::cout << j << " ";
diff --git a/src/common/test/test_persistence_intervals_reader.cpp b/src/common/test/test_persistence_intervals_reader.cpp
index a06fff1e..be299376 100644
--- a/src/common/test/test_persistence_intervals_reader.cpp
+++ b/src/common/test/test_persistence_intervals_reader.cpp
@@ -27,6 +27,7 @@
#include <utility> // for pair
#include <tuple>
#include <limits> // for inf
+#include <map>
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE "persistence_intervals_reader"
@@ -44,7 +45,7 @@ BOOST_AUTO_TEST_CASE( persistence_intervals_without_dimension )
expected_intervals_by_dimension[-1].push_back(std::make_pair(3., std::numeric_limits<double>::infinity()));
Persistence_intervals_by_dimension persistence_intervals_by_dimension =
- read_persistence_intervals_grouped_by_dimension("persistence_intervals_without_dimension.pers");
+ Gudhi::read_persistence_intervals_grouped_by_dimension("persistence_intervals_without_dimension.pers");
std::cout << "\nread_persistence_intervals_grouped_by_dimension - expected\n";
for (auto map_iter : expected_intervals_by_dimension) {
@@ -69,7 +70,7 @@ BOOST_AUTO_TEST_CASE( persistence_intervals_without_dimension )
expected_intervals_in_dimension.push_back(std::make_pair(3., std::numeric_limits<double>::infinity()));
Persistence_intervals persistence_intervals_in_dimension =
- read_persistence_intervals_in_dimension("persistence_intervals_without_dimension.pers");
+ Gudhi::read_persistence_intervals_in_dimension("persistence_intervals_without_dimension.pers");
std::cout << "\nread_persistence_intervals_in_dimension - expected\n";
for (auto vec_iter : expected_intervals_in_dimension)
@@ -83,22 +84,22 @@ BOOST_AUTO_TEST_CASE( persistence_intervals_without_dimension )
expected_intervals_in_dimension.clear();
persistence_intervals_in_dimension =
- read_persistence_intervals_in_dimension("persistence_intervals_without_dimension.pers", 0);
+ Gudhi::read_persistence_intervals_in_dimension("persistence_intervals_without_dimension.pers", 0);
BOOST_CHECK(persistence_intervals_in_dimension == expected_intervals_in_dimension);
expected_intervals_in_dimension.clear();
persistence_intervals_in_dimension =
- read_persistence_intervals_in_dimension("persistence_intervals_without_dimension.pers", 1);
+ Gudhi::read_persistence_intervals_in_dimension("persistence_intervals_without_dimension.pers", 1);
BOOST_CHECK(persistence_intervals_in_dimension == expected_intervals_in_dimension);
expected_intervals_in_dimension.clear();
persistence_intervals_in_dimension =
- read_persistence_intervals_in_dimension("persistence_intervals_without_dimension.pers", 2);
+ Gudhi::read_persistence_intervals_in_dimension("persistence_intervals_without_dimension.pers", 2);
BOOST_CHECK(persistence_intervals_in_dimension == expected_intervals_in_dimension);
expected_intervals_in_dimension.clear();
persistence_intervals_in_dimension =
- read_persistence_intervals_in_dimension("persistence_intervals_without_dimension.pers", 3);
+ Gudhi::read_persistence_intervals_in_dimension("persistence_intervals_without_dimension.pers", 3);
BOOST_CHECK(persistence_intervals_in_dimension == expected_intervals_in_dimension);
}
@@ -112,7 +113,7 @@ BOOST_AUTO_TEST_CASE( persistence_intervals_with_dimension )
expected_intervals_by_dimension[1].push_back(std::make_pair(3., std::numeric_limits<double>::infinity()));
Persistence_intervals_by_dimension persistence_intervals_by_dimension =
- read_persistence_intervals_grouped_by_dimension("persistence_intervals_with_dimension.pers");
+ Gudhi::read_persistence_intervals_grouped_by_dimension("persistence_intervals_with_dimension.pers");
std::cout << "\nread_persistence_intervals_grouped_by_dimension - expected\n";
for (auto map_iter : expected_intervals_by_dimension) {
@@ -137,7 +138,7 @@ BOOST_AUTO_TEST_CASE( persistence_intervals_with_dimension )
expected_intervals_in_dimension.push_back(std::make_pair(3., std::numeric_limits<double>::infinity()));
Persistence_intervals persistence_intervals_in_dimension =
- read_persistence_intervals_in_dimension("persistence_intervals_with_dimension.pers");
+ Gudhi::read_persistence_intervals_in_dimension("persistence_intervals_with_dimension.pers");
std::cout << "\nread_persistence_intervals_in_dimension - expected\n";
for (auto vec_iter : expected_intervals_in_dimension)
@@ -152,7 +153,7 @@ BOOST_AUTO_TEST_CASE( persistence_intervals_with_dimension )
expected_intervals_in_dimension.clear();
expected_intervals_in_dimension.push_back(std::make_pair(2.7, 3.7));
persistence_intervals_in_dimension =
- read_persistence_intervals_in_dimension("persistence_intervals_with_dimension.pers", 0);
+ Gudhi::read_persistence_intervals_in_dimension("persistence_intervals_with_dimension.pers", 0);
std::cout << "\nread_persistence_intervals_in_dimension 0 - expected\n";
for (auto vec_iter : expected_intervals_in_dimension)
@@ -168,7 +169,7 @@ BOOST_AUTO_TEST_CASE( persistence_intervals_with_dimension )
expected_intervals_in_dimension.push_back(std::make_pair(9.6, 14.));
expected_intervals_in_dimension.push_back(std::make_pair(3., std::numeric_limits<double>::infinity()));
persistence_intervals_in_dimension =
- read_persistence_intervals_in_dimension("persistence_intervals_with_dimension.pers", 1);
+ Gudhi::read_persistence_intervals_in_dimension("persistence_intervals_with_dimension.pers", 1);
std::cout << "\nread_persistence_intervals_in_dimension 1 - expected\n";
for (auto vec_iter : expected_intervals_in_dimension)
@@ -182,7 +183,7 @@ BOOST_AUTO_TEST_CASE( persistence_intervals_with_dimension )
expected_intervals_in_dimension.clear();
persistence_intervals_in_dimension =
- read_persistence_intervals_in_dimension("persistence_intervals_with_dimension.pers", 2);
+ Gudhi::read_persistence_intervals_in_dimension("persistence_intervals_with_dimension.pers", 2);
std::cout << "\nread_persistence_intervals_in_dimension 2 - expected\n";
for (auto vec_iter : expected_intervals_in_dimension)
@@ -197,7 +198,7 @@ BOOST_AUTO_TEST_CASE( persistence_intervals_with_dimension )
expected_intervals_in_dimension.clear();
expected_intervals_in_dimension.push_back(std::make_pair(34.2, 34.974));
persistence_intervals_in_dimension =
- read_persistence_intervals_in_dimension("persistence_intervals_with_dimension.pers", 3);
+ Gudhi::read_persistence_intervals_in_dimension("persistence_intervals_with_dimension.pers", 3);
std::cout << "\nread_persistence_intervals_in_dimension 3 - expected\n";
for (auto vec_iter : expected_intervals_in_dimension)
@@ -221,7 +222,7 @@ BOOST_AUTO_TEST_CASE( persistence_intervals_with_field )
expected_intervals_by_dimension[1].push_back(std::make_pair(3., std::numeric_limits<double>::infinity()));
Persistence_intervals_by_dimension persistence_intervals_by_dimension =
- read_persistence_intervals_grouped_by_dimension("persistence_intervals_with_field.pers");
+ Gudhi::read_persistence_intervals_grouped_by_dimension("persistence_intervals_with_field.pers");
std::cout << "\nread_persistence_intervals_grouped_by_dimension - expected\n";
for (auto map_iter : expected_intervals_by_dimension) {
@@ -246,7 +247,7 @@ BOOST_AUTO_TEST_CASE( persistence_intervals_with_field )
expected_intervals_in_dimension.push_back(std::make_pair(3., std::numeric_limits<double>::infinity()));
Persistence_intervals persistence_intervals_in_dimension =
- read_persistence_intervals_in_dimension("persistence_intervals_with_field.pers");
+ Gudhi::read_persistence_intervals_in_dimension("persistence_intervals_with_field.pers");
std::cout << "\nread_persistence_intervals_in_dimension - expected\n";
for (auto vec_iter : expected_intervals_in_dimension)
@@ -261,7 +262,7 @@ BOOST_AUTO_TEST_CASE( persistence_intervals_with_field )
expected_intervals_in_dimension.clear();
expected_intervals_in_dimension.push_back(std::make_pair(2.7, 3.7));
persistence_intervals_in_dimension =
- read_persistence_intervals_in_dimension("persistence_intervals_with_field.pers", 0);
+ Gudhi::read_persistence_intervals_in_dimension("persistence_intervals_with_field.pers", 0);
std::cout << "\nread_persistence_intervals_in_dimension 0 - expected\n";
for (auto vec_iter : expected_intervals_in_dimension)
@@ -277,7 +278,7 @@ BOOST_AUTO_TEST_CASE( persistence_intervals_with_field )
expected_intervals_in_dimension.push_back(std::make_pair(9.6, 14.));
expected_intervals_in_dimension.push_back(std::make_pair(3., std::numeric_limits<double>::infinity()));
persistence_intervals_in_dimension =
- read_persistence_intervals_in_dimension("persistence_intervals_with_field.pers", 1);
+ Gudhi::read_persistence_intervals_in_dimension("persistence_intervals_with_field.pers", 1);
std::cout << "\nread_persistence_intervals_in_dimension 1 - expected\n";
for (auto vec_iter : expected_intervals_in_dimension)
@@ -291,7 +292,7 @@ BOOST_AUTO_TEST_CASE( persistence_intervals_with_field )
expected_intervals_in_dimension.clear();
persistence_intervals_in_dimension =
- read_persistence_intervals_in_dimension("persistence_intervals_with_field.pers", 2);
+ Gudhi::read_persistence_intervals_in_dimension("persistence_intervals_with_field.pers", 2);
std::cout << "\nread_persistence_intervals_in_dimension 2 - expected\n";
for (auto vec_iter : expected_intervals_in_dimension)
@@ -306,7 +307,7 @@ BOOST_AUTO_TEST_CASE( persistence_intervals_with_field )
expected_intervals_in_dimension.clear();
expected_intervals_in_dimension.push_back(std::make_pair(34.2, 34.974));
persistence_intervals_in_dimension =
- read_persistence_intervals_in_dimension("persistence_intervals_with_field.pers", 3);
+ Gudhi::read_persistence_intervals_in_dimension("persistence_intervals_with_field.pers", 3);
std::cout << "\nread_persistence_intervals_in_dimension 3 - expected\n";
for (auto vec_iter : expected_intervals_in_dimension)
diff --git a/src/cython/CMakeLists.txt b/src/cython/CMakeLists.txt
index 99badffb..ab5ea9ef 100644
--- a/src/cython/CMakeLists.txt
+++ b/src/cython/CMakeLists.txt
@@ -16,7 +16,7 @@ function( add_gudhi_cython_lib THE_LIB )
endfunction( add_gudhi_cython_lib )
if(CYTHON_FOUND)
- message("++ ${PYTHON_EXECUTABLE} v.${PYTHON_VERSION_STRING} - Cython is ${CYTHON_EXECUTABLE} - py.test is ${PYTEST_PATH} - Sphinx is ${SPHINX_PATH}")
+ message("++ ${PYTHON_EXECUTABLE} v.${PYTHON_VERSION_STRING} - Cython is ${CYTHON_EXECUTABLE} - Sphinx is ${SPHINX_PATH}")
set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DBOOST_RESULT_OF_USE_DECLTYPE', ")
set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DBOOST_ALL_NO_LIB', ")
@@ -100,7 +100,7 @@ if(CYTHON_FOUND)
file(COPY "${CMAKE_SOURCE_DIR}/data/distance_matrix/full_square_distance_matrix.csv" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc/")
# Persistence graphical tools examples
file(COPY "${CMAKE_SOURCE_DIR}/data/bitmap/3d_torus.txt" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc/")
- file(COPY "${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc/")
+ file(COPY "${CMAKE_SOURCE_DIR}/data/points/tore3D_1307.off" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc/")
if (NOT CGAL_VERSION VERSION_LESS 4.8.1)
# If CGAL_VERSION >= 4.8.1, include subsampling
@@ -194,6 +194,7 @@ if(CYTHON_FOUND)
endif(UNIX)
# set sphinx-build in make files
+ configure_file(doc/python3-sphinx-build.in "${CMAKE_CURRENT_BINARY_DIR}/doc/python3-sphinx-build" @ONLY)
configure_file(doc/Makefile.in "${CMAKE_CURRENT_BINARY_DIR}/doc/Makefile" @ONLY)
configure_file(doc/make.bat.in "${CMAKE_CURRENT_BINARY_DIR}/doc/make.bat" @ONLY)
@@ -305,13 +306,11 @@ if(CYTHON_FOUND)
set_tests_properties(witness_complex_from_nearest_landmark_table_py_test PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}")
# Unitary tests are available through py.test
- if(PYTEST_PATH)
- add_test(
- NAME gudhi_cython_py_test
- WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
- COMMAND ${PYTHON_EXECUTABLE} "${PYTEST_PATH}")
- set_tests_properties(gudhi_cython_py_test PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}")
- endif(PYTEST_PATH)
+ add_test(
+ NAME gudhi_cython_py_test
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMAND ${PYTHON_EXECUTABLE} -m pytest)
+ set_tests_properties(gudhi_cython_py_test PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}")
# Documentation generation is available through sphinx
if(SPHINX_PATH)
diff --git a/src/cython/cython/persistence_graphical_tools.py b/src/cython/cython/persistence_graphical_tools.py
index a984633e..fb837e29 100755
--- a/src/cython/cython/persistence_graphical_tools.py
+++ b/src/cython/cython/persistence_graphical_tools.py
@@ -1,11 +1,12 @@
import matplotlib.pyplot as plt
import numpy as np
+import os
"""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
+ Author(s): Vincent Rouvreau, Bertrand Michel
Copyright (C) 2016 INRIA
@@ -23,15 +24,17 @@ import numpy as np
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
-__author__ = "Vincent Rouvreau"
+__author__ = "Vincent Rouvreau, Bertrand Michel"
__copyright__ = "Copyright (C) 2016 INRIA"
__license__ = "GPL v3"
-def __min_birth_max_death(persistence):
+def __min_birth_max_death(persistence, band_boot=0.):
"""This function returns (min_birth, max_death) from the persistence.
:param persistence: The persistence to plot.
:type persistence: list of tuples(dimension, tuple(birth, death)).
+ :param band_boot: bootstrap band
+ :type band_boot: float.
:returns: (float, float) -- (min_birth, max_death).
"""
# Look for minimum birth date and maximum death date for plot optimisation
@@ -45,6 +48,8 @@ def __min_birth_max_death(persistence):
max_death = float(interval[1][0])
if float(interval[1][0]) < min_birth:
min_birth = float(interval[1][0])
+ if band_boot > 0.:
+ max_death += band_boot
return (min_birth, max_death)
"""
@@ -59,7 +64,7 @@ def show_palette_values(alpha=0.6):
:param alpha: alpha value in [0.0, 1.0] for horizontal bars (default is 0.6).
:type alpha: float.
- :returns: plot -- An horizontal bar plot of dimensions color.
+ :returns: plot the dimension palette values.
"""
colors = []
for color in palette:
@@ -70,18 +75,38 @@ def show_palette_values(alpha=0.6):
plt.barh(y_pos, y_pos + 1, align='center', alpha=alpha, color=colors)
plt.ylabel('Dimension')
plt.title('Dimension palette values')
+ return plt
- plt.show()
-
-def plot_persistence_barcode(persistence, alpha=0.6):
+def plot_persistence_barcode(persistence=[], persistence_file='', alpha=0.6, max_barcodes=0):
"""This function plots the persistence bar code.
:param persistence: The persistence to plot.
:type persistence: list of tuples(dimension, tuple(birth, death)).
+ :param persistence_file: A persistence file style name (reset persistence if both are set).
+ :type persistence_file: string
:param alpha: alpha value in [0.0, 1.0] for horizontal bars (default is 0.6).
:type alpha: float.
+ :param max_barcodes: number of maximal barcodes to be displayed
+ (persistence will be sorted by life time if max_barcodes is set)
+ :type max_barcodes: int.
:returns: plot -- An horizontal bar plot of persistence.
"""
+ if persistence_file is not '':
+ if os.path.isfile(persistence_file):
+ # Reset persistence
+ persistence = []
+ diag = read_persistence_intervals_grouped_by_dimension(persistence_file=persistence_file)
+ for key in diag.keys():
+ for persistence_interval in diag[key]:
+ persistence.append((key, persistence_interval))
+ else:
+ print("file " + persistence_file + " not found.")
+ return None
+
+ if max_barcodes > 0 and max_barcodes < len(persistence):
+ # Sort by life time, then takes only the max_plots elements
+ persistence = sorted(persistence, key=lambda life_time: life_time[1][1]-life_time[1][0], reverse=True)[:max_barcodes]
+
(min_birth, max_death) = __min_birth_max_death(persistence)
ind = 0
delta = ((max_death - min_birth) / 10.0)
@@ -106,18 +131,40 @@ def plot_persistence_barcode(persistence, alpha=0.6):
plt.title('Persistence barcode')
# Ends plot on infinity value and starts a little bit before min_birth
plt.axis([axis_start, infinity, 0, ind])
- plt.show()
+ return plt
-def plot_persistence_diagram(persistence, alpha=0.6):
- """This function plots the persistence diagram.
+def plot_persistence_diagram(persistence=[], persistence_file='', alpha=0.6, band_boot=0., max_plots=0):
+ """This function plots the persistence diagram with an optional confidence band.
:param persistence: The persistence to plot.
:type persistence: list of tuples(dimension, tuple(birth, death)).
+ :param persistence_file: A persistence file style name (reset persistence if both are set).
+ :type persistence_file: string
:param alpha: alpha value in [0.0, 1.0] for points and horizontal infinity line (default is 0.6).
:type alpha: float.
- :returns: plot -- An diagram plot of persistence.
+ :param band_boot: bootstrap band (not displayed if :math:`\leq` 0.)
+ :type band_boot: float.
+ :param max_plots: number of maximal plots to be displayed
+ :type max_plots: int.
+ :returns: plot -- A diagram plot of persistence.
"""
- (min_birth, max_death) = __min_birth_max_death(persistence)
+ if persistence_file is not '':
+ if os.path.isfile(persistence_file):
+ # Reset persistence
+ persistence = []
+ diag = read_persistence_intervals_grouped_by_dimension(persistence_file=persistence_file)
+ for key in diag.keys():
+ for persistence_interval in diag[key]:
+ persistence.append((key, persistence_interval))
+ else:
+ print("file " + persistence_file + " not found.")
+ return None
+
+ if max_plots > 0 and max_plots < len(persistence):
+ # Sort by life time, then takes only the max_plots elements
+ persistence = sorted(persistence, key=lambda life_time: life_time[1][1]-life_time[1][0], reverse=True)[:max_plots]
+
+ (min_birth, max_death) = __min_birth_max_death(persistence, band_boot)
ind = 0
delta = ((max_death - min_birth) / 10.0)
# Replace infinity values with max_death + delta for diagram to be more
@@ -131,6 +178,9 @@ def plot_persistence_diagram(persistence, alpha=0.6):
plt.plot(x, x, color='k', linewidth=1.0)
plt.plot(x, [infinity] * len(x), linewidth=1.0, color='k', alpha=alpha)
plt.text(axis_start, infinity, r'$\infty$', color='k', alpha=alpha)
+ # bootstrap band
+ if band_boot > 0.:
+ plt.fill_between(x, x, x+band_boot, alpha=alpha, facecolor='red')
# Draw points in loop
for interval in reversed(persistence):
@@ -149,4 +199,4 @@ def plot_persistence_diagram(persistence, alpha=0.6):
plt.ylabel('Death')
# Ends plot on infinity value and starts a little bit before min_birth
plt.axis([axis_start, infinity, axis_start, infinity + delta])
- plt.show()
+ return plt
diff --git a/src/cython/cython/reader_utils.pyx b/src/cython/cython/reader_utils.pyx
new file mode 100644
index 00000000..3a17c5a0
--- /dev/null
+++ b/src/cython/cython/reader_utils.pyx
@@ -0,0 +1,95 @@
+from cython cimport numeric
+from libcpp.vector cimport vector
+from libcpp.string cimport string
+from libcpp.map cimport map
+from libcpp.pair cimport pair
+import os
+
+"""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) 2017 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/>.
+"""
+
+__author__ = "Vincent Rouvreau"
+__copyright__ = "Copyright (C) 2017 INRIA"
+__license__ = "GPL v3"
+
+cdef extern from "Reader_utils_interface.h" namespace "Gudhi":
+ vector[vector[double]] read_matrix_from_csv_file(string off_file, char separator)
+ map[int, vector[pair[double, double]]] read_pers_intervals_grouped_by_dimension(string filename)
+ vector[pair[double, double]] read_pers_intervals_in_dimension(string filename, int only_this_dim)
+
+def read_lower_triangular_matrix_from_csv_file(csv_file='', separator=';'):
+ """Read lower triangular matrix from a CSV style file.
+
+ :param csv_file: A CSV file style name.
+ :type csv_file: string
+ :param separator: The value separator in the CSV file. Default value is ';'
+ :type separator: char
+
+ :returns: The lower triangular matrix.
+ :rtype: vector[vector[double]]
+ """
+ if csv_file is not '':
+ if os.path.isfile(csv_file):
+ return read_matrix_from_csv_file(str.encode(csv_file), ord(separator[0]))
+ print("file " + csv_file + " not set or not found.")
+ return []
+
+def read_persistence_intervals_grouped_by_dimension(persistence_file=''):
+ """Reads a file containing persistence intervals.
+ Each line might contain 2, 3 or 4 values: [[field] dimension] birth death
+ The return value is an `map[dim, vector[pair[birth, death]]]`
+ where `dim` is an `int`, `birth` a `double`, and `death` a `double`.
+ Note: the function does not check that birth <= death.
+
+ :param persistence_file: A persistence file style name.
+ :type persistence_file: string
+
+ :returns: The persistence pairs grouped by dimension.
+ :rtype: map[int, vector[pair[double, double]]]
+ """
+ if persistence_file is not '':
+ if os.path.isfile(persistence_file):
+ return read_pers_intervals_grouped_by_dimension(str.encode(persistence_file))
+ print("file " + persistence_file + " not set or not found.")
+ return []
+
+def read_persistence_intervals_in_dimension(persistence_file='', only_this_dim=-1):
+ """Reads a file containing persistence intervals.
+ Each line might contain 2, 3 or 4 values: [[field] dimension] birth death
+ If `only_this_dim` = -1, dimension is ignored and all lines are returned.
+ If `only_this_dim` is >= 0, only the lines where dimension = `only_this_dim`
+ (or where dimension is not specified) are returned.
+ The return value is an `vector[pair[birth, death]]`
+ where `birth` a `double`, and `death` a `double`.
+ Note: the function does not check that birth <= death.
+
+ :param persistence_file: A persistence file style name.
+ :type persistence_file: string
+
+ :returns: The persistence pairs grouped by dimension.
+ :rtype: map[int, vector[pair[double, double]]]
+ """
+ if persistence_file is not '':
+ if os.path.isfile(persistence_file):
+ return read_pers_intervals_in_dimension(str.encode(persistence_file), only_this_dim)
+ print("file " + persistence_file + " not set or not found.")
+ return []
diff --git a/src/cython/cython/simplex_tree.pyx b/src/cython/cython/simplex_tree.pyx
index 2acdac3c..9e3b2345 100644
--- a/src/cython/cython/simplex_tree.pyx
+++ b/src/cython/cython/simplex_tree.pyx
@@ -61,6 +61,7 @@ cdef extern from "Persistent_cohomology_interface.h" namespace "Gudhi":
vector[int] betti_numbers()
vector[int] persistent_betti_numbers(double from_value, double to_value)
vector[pair[double,double]] intervals_in_dimension(int dimension)
+ void write_output_diagram(string diagram_file_name)
# SimplexTree python interface
cdef class SimplexTree:
@@ -385,7 +386,7 @@ cdef class SimplexTree:
complex in a specific dimension.
:param dimension: The specific dimension.
- :type from_value: int.
+ :type dimension: int.
:returns: The persistence intervals.
:rtype: list of pair of float
@@ -399,3 +400,22 @@ cdef class SimplexTree:
print("intervals_in_dim function requires persistence function"
" to be launched first.")
return intervals_result
+
+ def write_persistence_diagram(self, persistence_file=''):
+ """This function writes the persistence intervals of the simplicial
+ complex in a user given file name.
+
+ :param persistence_file: The specific dimension.
+ :type persistence_file: string.
+
+ :note: intervals_in_dim function requires persistence function to be
+ launched first.
+ """
+ if self.pcohptr != NULL:
+ if persistence_file != '':
+ self.pcohptr.write_output_diagram(str.encode(persistence_file))
+ else:
+ print("persistence_file must be specified")
+ else:
+ print("intervals_in_dim function requires persistence function"
+ " to be launched first.")
diff --git a/src/cython/doc/_templates/layout.html b/src/cython/doc/_templates/layout.html
index b11c1236..243f33c6 100644
--- a/src/cython/doc/_templates/layout.html
+++ b/src/cython/doc/_templates/layout.html
@@ -65,6 +65,7 @@
{#- old style sidebars: using blocks -- should be deprecated #}
{%- block sidebartoc %}
<h2><a href="index.html">GUDHI</a></h2>
+<h2><a href="fileformats.html">File formats</a></h2>
<h2><a href="installation.html">GUDHI installation</a></h2>
<h2><a href="citation.html">Acknowledging the GUDHI library</a></h2>
<h2><a href="genindex.html">Index</a></h2>
diff --git a/src/cython/doc/fileformats.rst b/src/cython/doc/fileformats.rst
new file mode 100644
index 00000000..156ef4e4
--- /dev/null
+++ b/src/cython/doc/fileformats.rst
@@ -0,0 +1,33 @@
+File formats
+############
+
+Persistence Diagram
+*******************
+
+Such a file, whose extension is usually ``.pers``, contains a list of
+persistence intervals.
+
+Lines starting with ``#`` are ignored (comments).
+
+Other lines might contain 2, 3 or 4 values (the number of values on each line
+must be the same for all lines)::
+
+ [[field] dimension] birth death
+
+Here is a simple sample file::
+
+ # Persistence diagram example
+ 2 2.7 3.7
+ 2 9.6 14.
+ # Some comments
+ 3 34.2 34.974
+ 4 3. inf
+
+Other sample files can be found in the data/persistence_diagram folder.
+
+Such files can be generated with
+:meth:`gudhi.SimplexTree.write_persistence_diagram`, read with
+:meth:`gudhi.read_persistence_intervals_grouped_by_dimension`, or
+:meth:`gudhi.read_persistence_intervals_in_dimension` and displayed with
+:meth:`gudhi.plot_persistence_barcode` or
+:meth:`gudhi.plot_persistence_diagram`.
diff --git a/src/cython/doc/persistence_graphical_tools_user.rst b/src/cython/doc/persistence_graphical_tools_user.rst
index cae18323..13198162 100644
--- a/src/cython/doc/persistence_graphical_tools_user.rst
+++ b/src/cython/doc/persistence_graphical_tools_user.rst
@@ -14,12 +14,14 @@ This function is useful to show the color palette values of dimension:
.. testcode::
import gudhi
- gudhi.show_palette_values(alpha=1.0)
+ plt = gudhi.show_palette_values(alpha=1.0)
+ plt.show()
.. plot::
import gudhi
- gudhi.show_palette_values(alpha=1.0)
+ plt = gudhi.show_palette_values(alpha=1.0)
+ plt.show()
Show persistence as a barcode
-----------------------------
@@ -32,7 +34,8 @@ This function can display the persistence result as a barcode:
periodic_cc = gudhi.PeriodicCubicalComplex(perseus_file='3d_torus.txt')
diag = periodic_cc.persistence()
- gudhi.plot_persistence_barcode(diag)
+ plt = gudhi.plot_persistence_barcode(diag)
+ plt.show()
.. plot::
@@ -40,7 +43,8 @@ This function can display the persistence result as a barcode:
periodic_cc = gudhi.PeriodicCubicalComplex(perseus_file='3d_torus.txt')
diag = periodic_cc.persistence()
- gudhi.plot_persistence_barcode(diag)
+ plt = gudhi.plot_persistence_barcode(diag)
+ plt.show()
Show persistence as a diagram
-----------------------------
@@ -51,16 +55,18 @@ This function can display the persistence result as a diagram:
import gudhi
- rips_complex = gudhi.RipsComplex(off_file='tore3D_300.off', max_edge_length=2.0)
+ rips_complex = gudhi.RipsComplex(off_file='tore3D_1307.off', max_edge_length=0.2)
simplex_tree = rips_complex.create_simplex_tree(max_dimension=3)
diag = simplex_tree.persistence()
- gudhi.plot_persistence_diagram(diag)
+ plt = gudhi.plot_persistence_diagram(diag, band_boot=0.13)
+ plt.show()
.. plot::
import gudhi
- rips_complex = gudhi.RipsComplex(off_file='tore3D_300.off', max_edge_length=2.0)
+ rips_complex = gudhi.RipsComplex(off_file='tore3D_1307.off', max_edge_length=0.2)
simplex_tree = rips_complex.create_simplex_tree(max_dimension=3)
diag = simplex_tree.persistence()
- gudhi.plot_persistence_diagram(diag)
+ plt = gudhi.plot_persistence_diagram(diag, band_boot=0.13)
+ plt.show()
diff --git a/src/cython/doc/pyplots/barcode_persistence.py b/src/cython/doc/pyplots/barcode_persistence.py
index c06ac5a7..9cd3149d 100755
--- a/src/cython/doc/pyplots/barcode_persistence.py
+++ b/src/cython/doc/pyplots/barcode_persistence.py
@@ -1,5 +1,6 @@
import gudhi
-periodic_cc = gudhi.PeriodicCubicalComplex(perseus_file='../3d_torus.txt')
+periodic_cc = gudhi.PeriodicCubicalComplex(perseus_file='3d_torus.txt')
diag = periodic_cc.persistence()
-gudhi.plot_persistence_barcode(diag)
+plt = gudhi.plot_persistence_barcode(diag)
+plt.show()
diff --git a/src/cython/doc/pyplots/diagram_persistence.py b/src/cython/doc/pyplots/diagram_persistence.py
index b4714fe3..30661965 100755
--- a/src/cython/doc/pyplots/diagram_persistence.py
+++ b/src/cython/doc/pyplots/diagram_persistence.py
@@ -1,5 +1,7 @@
import gudhi
-alpha_complex = gudhi.AlphaComplex(off_file='../tore3D_300.off')
-diag = alpha_complex.persistence()
-gudhi.plot_persistence_diagram(diag)
+rips_complex = gudhi.RipsComplex(off_file='tore3D_1307.off', max_edge_length=0.2)
+simplex_tree = rips_complex.create_simplex_tree(max_dimension=3)
+diag = simplex_tree.persistence()
+plt = gudhi.plot_persistence_diagram(diag, band_boot=0.13)
+plt.show()
diff --git a/src/cython/doc/pyplots/show_palette_values.py b/src/cython/doc/pyplots/show_palette_values.py
index e72a55fd..fdf9645f 100755
--- a/src/cython/doc/pyplots/show_palette_values.py
+++ b/src/cython/doc/pyplots/show_palette_values.py
@@ -1,2 +1,3 @@
import gudhi
-gudhi.show_palette_values(alpha=1.0)
+plt = gudhi.show_palette_values(alpha=1.0)
+plt.show()
diff --git a/src/cython/doc/python3-sphinx-build b/src/cython/doc/python3-sphinx-build.in
index 44b94169..c97965f5 100755
--- a/src/cython/doc/python3-sphinx-build
+++ b/src/cython/doc/python3-sphinx-build.in
@@ -1,4 +1,4 @@
-#!/usr/bin/python3
+#!@PYTHON_EXECUTABLE@
"""
Emulate sphinx-build for python3
diff --git a/src/cython/doc/reader_utils_ref.rst b/src/cython/doc/reader_utils_ref.rst
new file mode 100644
index 00000000..9c1ea6fc
--- /dev/null
+++ b/src/cython/doc/reader_utils_ref.rst
@@ -0,0 +1,11 @@
+=============================
+Reader utils reference manual
+=============================
+
+.. autofunction:: gudhi.read_off
+
+.. autofunction:: gudhi.read_lower_triangular_matrix_from_csv_file
+
+.. autofunction:: gudhi.read_persistence_intervals_grouped_by_dimension
+
+.. autofunction:: gudhi.read_persistence_intervals_in_dimension
diff --git a/src/cython/example/alpha_complex_diagram_persistence_from_off_file_example.py b/src/cython/example/alpha_complex_diagram_persistence_from_off_file_example.py
index adedc7d2..b4487be4 100755
--- a/src/cython/example/alpha_complex_diagram_persistence_from_off_file_example.py
+++ b/src/cython/example/alpha_complex_diagram_persistence_from_off_file_example.py
@@ -38,6 +38,7 @@ parser = argparse.ArgumentParser(description='AlphaComplex creation from '
'points from the given OFF file.')
parser.add_argument("-f", "--file", type=str, required=True)
parser.add_argument("-a", "--max_alpha_square", type=float, default=0.5)
+parser.add_argument("-b", "--band_boot", type=float, default=0.)
parser.add_argument('--no-diagram', default=False, action='store_true' , help='Flag for not to display the diagrams')
args = parser.parse_args()
@@ -63,7 +64,8 @@ with open(args.file, 'r') as f:
print(simplex_tree.betti_numbers())
if args.no_diagram == False:
- gudhi.plot_persistence_diagram(diag)
+ pplot = gudhi.plot_persistence_diagram(diag, band_boot=args.band_boot)
+ pplot.show()
else:
print(args.file, "is not a valid OFF file")
diff --git a/src/cython/example/euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py b/src/cython/example/euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py
index 2371c36c..e3f362dc 100755
--- a/src/cython/example/euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py
+++ b/src/cython/example/euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py
@@ -40,6 +40,7 @@ parser.add_argument("-f", "--file", type=str, required=True)
parser.add_argument("-a", "--max_alpha_square", type=float, required=True)
parser.add_argument("-n", "--number_of_landmarks", type=int, required=True)
parser.add_argument("-d", "--limit_dimension", type=int, required=True)
+parser.add_argument("-b", "--band_boot", type=float, default=0.)
parser.add_argument('--no-diagram', default=False, action='store_true' , help='Flag for not to display the diagrams')
args = parser.parse_args()
@@ -70,8 +71,8 @@ with open(args.file, 'r') as f:
print(simplex_tree.betti_numbers())
if args.no_diagram == False:
- gudhi.plot_persistence_diagram(diag)
-
+ pplot = gudhi.plot_persistence_diagram(diag, band_boot=args.band_boot)
+ pplot.show()
else:
print(args.file, "is not a valid OFF file")
diff --git a/src/cython/example/euclidean_witness_complex_diagram_persistence_from_off_file_example.py b/src/cython/example/euclidean_witness_complex_diagram_persistence_from_off_file_example.py
index 5748aa8a..c236d992 100755
--- a/src/cython/example/euclidean_witness_complex_diagram_persistence_from_off_file_example.py
+++ b/src/cython/example/euclidean_witness_complex_diagram_persistence_from_off_file_example.py
@@ -40,6 +40,7 @@ parser.add_argument("-f", "--file", type=str, required=True)
parser.add_argument("-a", "--max_alpha_square", type=float, required=True)
parser.add_argument("-n", "--number_of_landmarks", type=int, required=True)
parser.add_argument("-d", "--limit_dimension", type=int, required=True)
+parser.add_argument("-b", "--band_boot", type=float, default=0.)
parser.add_argument('--no-diagram', default=False, action='store_true' , help='Flag for not to display the diagrams')
args = parser.parse_args()
@@ -70,8 +71,8 @@ with open(args.file, 'r') as f:
print(simplex_tree.betti_numbers())
if args.no_diagram == False:
- gudhi.plot_persistence_diagram(diag)
-
+ pplot = gudhi.plot_persistence_diagram(diag, band_boot=args.band_boot)
+ pplot.show()
else:
print(args.file, "is not a valid OFF file")
diff --git a/src/cython/example/gudhi_graphical_tools_example.py b/src/cython/example/gudhi_graphical_tools_example.py
index bc3b16ec..ed87806b 100755
--- a/src/cython/example/gudhi_graphical_tools_example.py
+++ b/src/cython/example/gudhi_graphical_tools_example.py
@@ -44,4 +44,11 @@ gudhi.plot_persistence_barcode(persistence)
print("#####################################################################")
print("Show diagram persistence example")
-gudhi.plot_persistence_diagram(persistence)
+pplot = gudhi.plot_persistence_diagram(persistence)
+pplot.show()
+
+print("#####################################################################")
+print("Show diagram persistence example with a confidence band")
+
+pplot = gudhi.plot_persistence_diagram(persistence, band_boot=0.2)
+pplot.show()
diff --git a/src/cython/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py b/src/cython/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py
index 984dbf1b..3baebd17 100755
--- a/src/cython/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py
+++ b/src/cython/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py
@@ -39,6 +39,7 @@ parser = argparse.ArgumentParser(description='RipsComplex creation from '
parser.add_argument("-f", "--file", type=str, required=True)
parser.add_argument("-e", "--max_edge_length", type=float, default=0.5)
parser.add_argument("-d", "--max_dimension", type=int, default=1)
+parser.add_argument("-b", "--band_boot", type=float, default=0.)
parser.add_argument('--no-diagram', default=False, action='store_true' , help='Flag for not to display the diagrams')
args = parser.parse_args()
@@ -61,4 +62,5 @@ print("betti_numbers()=")
print(simplex_tree.betti_numbers())
if args.no_diagram == False:
- gudhi.plot_persistence_diagram(diag)
+ pplot = gudhi.plot_persistence_diagram(diag, band_boot=args.band_boot)
+ pplot.show()
diff --git a/src/cython/example/rips_complex_diagram_persistence_from_off_file_example.py b/src/cython/example/rips_complex_diagram_persistence_from_off_file_example.py
index 4c21b98e..5951eedf 100755
--- a/src/cython/example/rips_complex_diagram_persistence_from_off_file_example.py
+++ b/src/cython/example/rips_complex_diagram_persistence_from_off_file_example.py
@@ -39,6 +39,7 @@ parser = argparse.ArgumentParser(description='RipsComplex creation from '
parser.add_argument("-f", "--file", type=str, required=True)
parser.add_argument("-e", "--max_edge_length", type=float, default=0.5)
parser.add_argument("-d", "--max_dimension", type=int, default=1)
+parser.add_argument("-b", "--band_boot", type=float, default=0.)
parser.add_argument('--no-diagram', default=False, action='store_true' , help='Flag for not to display the diagrams')
args = parser.parse_args()
@@ -64,7 +65,8 @@ with open(args.file, 'r') as f:
print(simplex_tree.betti_numbers())
if args.no_diagram == False:
- gudhi.plot_persistence_diagram(diag)
+ pplot = gudhi.plot_persistence_diagram(diag, band_boot=args.band_boot)
+ pplot.show()
else:
print(args.file, "is not a valid OFF file")
diff --git a/src/cython/example/rips_persistence_diagram.py b/src/cython/example/rips_persistence_diagram.py
index 4e5cd2c8..9bfea41c 100755
--- a/src/cython/example/rips_persistence_diagram.py
+++ b/src/cython/example/rips_persistence_diagram.py
@@ -39,4 +39,5 @@ simplex_tree = rips.create_simplex_tree(max_dimension=1)
diag = simplex_tree.persistence(homology_coeff_field=2, min_persistence=0)
print("diag=", diag)
-gudhi.plot_persistence_diagram(diag)
+pplot = gudhi.plot_persistence_diagram(diag)
+pplot.show()
diff --git a/src/cython/example/tangential_complex_plain_homology_from_off_file_example.py b/src/cython/example/tangential_complex_plain_homology_from_off_file_example.py
index 4845eb47..6145e7f2 100755
--- a/src/cython/example/tangential_complex_plain_homology_from_off_file_example.py
+++ b/src/cython/example/tangential_complex_plain_homology_from_off_file_example.py
@@ -37,6 +37,7 @@ parser = argparse.ArgumentParser(description='TangentialComplex creation from '
'- Constructs a tangential complex with the '
'points from the given OFF file')
parser.add_argument("-f", "--file", type=str, required=True)
+parser.add_argument("-b", "--band_boot", type=float, default=0.)
parser.add_argument('--no-diagram', default=False, action='store_true' , help='Flag for not to display the diagrams')
args = parser.parse_args()
@@ -59,7 +60,8 @@ with open(args.file, 'r') as f:
print(st.betti_numbers())
if args.no_diagram == False:
- gudhi.plot_persistence_diagram(diag)
+ pplot = gudhi.plot_persistence_diagram(diag, band_boot=args.band_boot)
+ pplot.show()
else:
print(args.file, "is not a valid OFF file")
diff --git a/src/cython/gudhi.pyx.in b/src/cython/gudhi.pyx.in
index 34d7c3b5..ed2d28cc 100644
--- a/src/cython/gudhi.pyx.in
+++ b/src/cython/gudhi.pyx.in
@@ -30,6 +30,7 @@ include "cython/rips_complex.pyx"
include "cython/cubical_complex.pyx"
include "cython/periodic_cubical_complex.pyx"
include "cython/persistence_graphical_tools.py"
+include "cython/reader_utils.pyx"
include "cython/witness_complex.pyx"
include "cython/strong_witness_complex.pyx"
@GUDHI_CYTHON_ALPHA_COMPLEX@
diff --git a/src/cython/include/Reader_utils_interface.h b/src/cython/include/Reader_utils_interface.h
new file mode 100644
index 00000000..b87b6cca
--- /dev/null
+++ b/src/cython/include/Reader_utils_interface.h
@@ -0,0 +1,54 @@
+/* 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) 2017 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/>.
+ */
+
+#ifndef INCLUDE_READER_UTILS_INTERFACE_H_
+#define INCLUDE_READER_UTILS_INTERFACE_H_
+
+#include <gudhi/reader_utils.h>
+
+#include <iostream>
+#include <vector>
+#include <string>
+
+namespace Gudhi {
+
+// Redefine functions with a different name in order the original name can be used in the Python version.
+std::vector<std::vector<double>> read_matrix_from_csv_file(const std::string& filename,
+ const char separator = ';') {
+ return read_lower_triangular_matrix_from_csv_file<double>(filename, separator);
+}
+
+inline std::map<int, std::vector<std::pair<double, double>>>
+ read_pers_intervals_grouped_by_dimension(std::string const& filename) {
+ return read_persistence_intervals_grouped_by_dimension(filename);
+}
+
+inline std::vector<std::pair<double, double>>
+ read_pers_intervals_in_dimension(std::string const& filename, int only_this_dim = -1) {
+ return read_persistence_intervals_in_dimension(filename, only_this_dim);
+}
+
+
+} // namespace Gudhi
+
+
+#endif // INCLUDE_READER_UTILS_INTERFACE_H_
diff --git a/src/cython/include/Rips_complex_interface.h b/src/cython/include/Rips_complex_interface.h
index 6d813f4a..d06ee4bd 100644
--- a/src/cython/include/Rips_complex_interface.h
+++ b/src/cython/include/Rips_complex_interface.h
@@ -66,7 +66,7 @@ class Rips_complex_interface {
} else {
// Rips construction where values is a distance matrix
Distance_matrix distances =
- read_lower_triangular_matrix_from_csv_file<Simplex_tree_interface<>::Filtration_value>(file_name);
+ Gudhi::read_lower_triangular_matrix_from_csv_file<Simplex_tree_interface<>::Filtration_value>(file_name);
rips_complex_ = new Rips_complex<Simplex_tree_interface<>::Filtration_value>(distances, threshold);
}
}
diff --git a/src/cython/test/test_reader_utils.py b/src/cython/test/test_reader_utils.py
new file mode 100755
index 00000000..25591fb3
--- /dev/null
+++ b/src/cython/test/test_reader_utils.py
@@ -0,0 +1,88 @@
+import gudhi
+
+"""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) 2017 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/>.
+"""
+
+__author__ = "Vincent Rouvreau"
+__copyright__ = "Copyright (C) 2017 INRIA"
+__license__ = "GPL v3"
+
+
+def test_non_existing_csv_file():
+ # Try to open a non existing file
+ matrix = gudhi.read_lower_triangular_matrix_from_csv_file(csv_file='pouetpouettralala.toubiloubabdou')
+ assert matrix == []
+
+def test_full_square_distance_matrix_csv_file():
+ # Create test file
+ test_file = open('full_square_distance_matrix.csv', 'w')
+ test_file.write('0;1;2;3;\n1;0;4;5;\n2;4;0;6;\n3;5;6;0;')
+ test_file.close()
+ matrix = gudhi.read_lower_triangular_matrix_from_csv_file(csv_file="full_square_distance_matrix.csv")
+ assert matrix == [[], [1.0], [2.0, 4.0], [3.0, 5.0, 6.0]]
+
+def test_lower_triangular_distance_matrix_csv_file():
+ # Create test file
+ test_file = open('lower_triangular_distance_matrix.csv', 'w')
+ test_file.write('\n1,\n2,3,\n4,5,6,\n7,8,9,10,')
+ test_file.close()
+ matrix = gudhi.read_lower_triangular_matrix_from_csv_file(csv_file="lower_triangular_distance_matrix.csv", separator=",")
+ assert matrix == [[], [1.0], [2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0, 10.0]]
+
+def test_non_existing_persistence_file():
+ # Try to open a non existing file
+ persistence = gudhi.read_persistence_intervals_grouped_by_dimension(persistence_file='pouetpouettralala.toubiloubabdou')
+ assert persistence == []
+ persistence = gudhi.read_persistence_intervals_in_dimension(persistence_file='pouetpouettralala.toubiloubabdou', only_this_dim=1)
+ assert persistence == []
+
+def test_read_persistence_intervals_without_dimension():
+ # Create test file
+ test_file = open('persistence_intervals_without_dimension.pers', 'w')
+ test_file.write('# Simple persistence diagram without dimension\n2.7 3.7\n9.6 14.\n34.2 34.974\n3. inf')
+ test_file.close()
+ persistence = gudhi.read_persistence_intervals_in_dimension(persistence_file='persistence_intervals_without_dimension.pers')
+ assert persistence == [(2.7, 3.7), (9.6, 14.), (34.2, 34.974), (3., float('Inf'))]
+ persistence = gudhi.read_persistence_intervals_in_dimension(persistence_file='persistence_intervals_without_dimension.pers', only_this_dim=0)
+ assert persistence == []
+ persistence = gudhi.read_persistence_intervals_in_dimension(persistence_file='persistence_intervals_without_dimension.pers', only_this_dim=1)
+ assert persistence == []
+ persistence = gudhi.read_persistence_intervals_grouped_by_dimension(persistence_file='persistence_intervals_without_dimension.pers')
+ assert persistence == {-1: [(2.7, 3.7), (9.6, 14.0), (34.2, 34.974), (3.0, float('Inf'))]}
+
+def test_read_persistence_intervals_with_dimension():
+ # Create test file
+ test_file = open('persistence_intervals_with_dimension.pers', 'w')
+ test_file.write('# Simple persistence diagram with dimension\n0 2.7 3.7\n1 9.6 14.\n3 34.2 34.974\n1 3. inf')
+ test_file.close()
+ persistence = gudhi.read_persistence_intervals_in_dimension(persistence_file='persistence_intervals_with_dimension.pers')
+ assert persistence == [(2.7, 3.7), (9.6, 14.), (34.2, 34.974), (3., float('Inf'))]
+ persistence = gudhi.read_persistence_intervals_in_dimension(persistence_file='persistence_intervals_with_dimension.pers', only_this_dim=0)
+ assert persistence == [(2.7, 3.7)]
+ persistence = gudhi.read_persistence_intervals_in_dimension(persistence_file='persistence_intervals_with_dimension.pers', only_this_dim=1)
+ assert persistence == [(9.6, 14.), (3., float('Inf'))]
+ persistence = gudhi.read_persistence_intervals_in_dimension(persistence_file='persistence_intervals_with_dimension.pers', only_this_dim=2)
+ assert persistence == []
+ persistence = gudhi.read_persistence_intervals_in_dimension(persistence_file='persistence_intervals_with_dimension.pers', only_this_dim=3)
+ assert persistence == [(34.2, 34.974)]
+ persistence = gudhi.read_persistence_intervals_grouped_by_dimension(persistence_file='persistence_intervals_with_dimension.pers')
+ assert persistence == {0: [(2.7, 3.7)], 1: [(9.6, 14.0), (3.0, float('Inf'))], 3: [(34.2, 34.974)]}