diff options
Diffstat (limited to 'src/cython')
71 files changed, 840 insertions, 3064 deletions
diff --git a/src/cython/CMakeLists.txt b/src/cython/CMakeLists.txt index 99badffb..afca9d60 100644 --- a/src/cython/CMakeLists.txt +++ b/src/cython/CMakeLists.txt @@ -15,8 +15,18 @@ function( add_gudhi_cython_lib THE_LIB ) endif(EXISTS ${THE_LIB}) endfunction( add_gudhi_cython_lib ) +# THE_TEST is the python test file name (without .py extension) containing tests functions +function( add_gudhi_py_test THE_TEST ) + # use ${PYTHON_EXECUTABLE} -B, otherwise a __pycache__ directory is created in sources by python + # use py.test no cache provider, otherwise a .cache file is created in sources by py.test + add_test(NAME ${THE_TEST}_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${PYTHON_EXECUTABLE} -B -m pytest -p no:cacheprovider ${CMAKE_CURRENT_SOURCE_DIR}/test/${THE_TEST}.py) +endfunction( add_gudhi_py_test ) + + 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', ") @@ -73,76 +83,20 @@ if(CYTHON_FOUND) set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_EIGEN3_ENABLED', ") endif (EIGEN3_FOUND) - # Copy recursively include, cython, example, doc and test repositories before packages finding - # Some tests and doc files are removed in case some packages are not found - file(COPY include DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) - file(COPY cython DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) - file(COPY example DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) - file(COPY test DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) - file(COPY doc DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) - # Developper version for doc images - file(GLOB GUDHI_DEV_DOC_IMAGES "${CMAKE_SOURCE_DIR}/src/*/doc/*.png") - file(COPY ${GUDHI_DEV_DOC_IMAGES} DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc/img") - file(GLOB GUDHI_DEV_DOC_IMAGES "${CMAKE_SOURCE_DIR}/src/*/doc/*.svg") - file(COPY ${GUDHI_DEV_DOC_IMAGES} DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc/img") - # User version for doc images - file(GLOB GUDHI_USER_DOC_IMAGES "${CMAKE_SOURCE_DIR}/doc/*/*.png") - file(COPY ${GUDHI_USER_DOC_IMAGES} DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc/img") - file(GLOB GUDHI_USER_DOC_IMAGES "${CMAKE_SOURCE_DIR}/doc/*/*.svg") - file(COPY ${GUDHI_USER_DOC_IMAGES} DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc/img") - # Biblio - file(GLOB GUDHI_BIB_FILES "${CMAKE_SOURCE_DIR}/biblio/*.bib") - file(COPY ${GUDHI_BIB_FILES} DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc/") - # Cubical complex perseus doc example - file(GLOB GUDHI_CUBICAL_PERSEUS_FILES "${CMAKE_SOURCE_DIR}/data/bitmap/*cubicalcomplexdoc.txt") - file(COPY ${GUDHI_CUBICAL_PERSEUS_FILES} DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc/") - file(COPY "${CMAKE_SOURCE_DIR}/data/points/alphacomplexdoc.off" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc/") - 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/") - if (NOT CGAL_VERSION VERSION_LESS 4.8.1) - # If CGAL_VERSION >= 4.8.1, include subsampling - set(GUDHI_CYTHON_SUBSAMPLING "include 'cython/subsampling.pyx'") - set(GUDHI_CYTHON_TANGENTIAL_COMPLEX "include 'cython/tangential_complex.pyx'") - set(GUDHI_CYTHON_BOTTLENECK_DISTANCE "include 'cython/bottleneck_distance.pyx'") - else (NOT CGAL_VERSION VERSION_LESS 4.8.1) - # Remove subsampling unitary tests - file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/test/test_subsampling.py) - file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/subsampling_ref.rst") - file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/subsampling_sum.rst") - file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/subsampling_user.rst") - # Remove tangential complex and bottleneck unitary tests - file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/test/test_tangential_complex.py) - file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/test/test_bottleneck_distance.py) - file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/bottleneck_distance_ref.rst") - file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/bottleneck_distance_sum.rst") - file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/bottleneck_distance_user.rst") - file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/tangential_complex_ref.rst") - file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/tangential_complex_sum.rst") - file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/tangential_complex_user.rst") + set(GUDHI_CYTHON_BOTTLENECK_DISTANCE "include '${CMAKE_CURRENT_SOURCE_DIR}/cython/bottleneck_distance.pyx'") endif (NOT CGAL_VERSION VERSION_LESS 4.8.1) - if (NOT CGAL_VERSION VERSION_LESS 4.7.0) - # If CGAL_VERSION >= 4.7.0, include alpha - set(GUDHI_CYTHON_ALPHA_COMPLEX "include 'cython/alpha_complex.pyx'") - else (NOT CGAL_VERSION VERSION_LESS 4.7.0) - # Remove alpha complex unitary tests - file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/test/test_alpha_complex.py) - file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/alpha_complex_ref.rst") - file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/alpha_complex_sum.rst") - file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/alpha_complex_user.rst") - endif (NOT CGAL_VERSION VERSION_LESS 4.7.0) - if (NOT CGAL_VERSION VERSION_LESS 4.6.0) - # If CGAL_VERSION >= 4.6.0, include euclidean versions of witness complex + if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) + set(GUDHI_CYTHON_SUBSAMPLING "include '${CMAKE_CURRENT_SOURCE_DIR}/cython/subsampling.pyx'") + set(GUDHI_CYTHON_TANGENTIAL_COMPLEX "include '${CMAKE_CURRENT_SOURCE_DIR}/cython/tangential_complex.pyx'") + endif (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) + if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.7.0) + set(GUDHI_CYTHON_ALPHA_COMPLEX "include '${CMAKE_CURRENT_SOURCE_DIR}/cython/alpha_complex.pyx'") + endif (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.7.0) + if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.6.0) set(GUDHI_CYTHON_EUCLIDEAN_WITNESS_COMPLEX - "include 'cython/euclidean_witness_complex.pyx'\ninclude 'cython/euclidean_strong_witness_complex.pyx'\n") - else (NOT CGAL_VERSION VERSION_LESS 4.6.0) - # Remove alpha complex unitary tests - file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/test/test_euclidean_witness_complex.py) - file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/euclidean_witness_complex_ref.rst") - file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/euclidean_strong_witness_complex_ref.rst") - endif (NOT CGAL_VERSION VERSION_LESS 4.6.0) + "include '${CMAKE_CURRENT_SOURCE_DIR}/cython/euclidean_witness_complex.pyx'\ninclude '${CMAKE_CURRENT_SOURCE_DIR}/cython/euclidean_strong_witness_complex.pyx'\n") + endif (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.6.0) if(CGAL_FOUND) # Add CGAL compilation args @@ -193,10 +147,6 @@ if(CYTHON_FOUND) set( GUDHI_CYTHON_RUNTIME_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}") endif(UNIX) - # set sphinx-build in make files - 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) - # Generate setup.py file to cythonize Gudhi - This file must be named setup.py by convention configure_file(setup.py.in "${CMAKE_CURRENT_BINARY_DIR}/setup.py" @ONLY) # Generate gudhi.pyx - Gudhi cython file @@ -218,112 +168,147 @@ if(CYTHON_FOUND) PATTERN "*.pyd") # Test examples - if (NOT CGAL_VERSION VERSION_LESS 4.8.1) + if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) + # Bottleneck and Alpha add_test(NAME alpha_rips_persistence_bottleneck_distance_py_test WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/example/alpha_rips_persistence_bottleneck_distance.py" + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/alpha_rips_persistence_bottleneck_distance.py" -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -t 0.15 -d 3) - set_tests_properties(alpha_rips_persistence_bottleneck_distance_py_test PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}") - - add_test(NAME bottleneck_basic_example_py_test - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/example/bottleneck_basic_example.py") - set_tests_properties(bottleneck_basic_example_py_test PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}") + # Tangential add_test(NAME tangential_complex_plain_homology_from_off_file_example_py_test WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/example/tangential_complex_plain_homology_from_off_file_example.py" + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/tangential_complex_plain_homology_from_off_file_example.py" --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off) - set_tests_properties(tangential_complex_plain_homology_from_off_file_example_py_test PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}") + 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 ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/example/euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py" + 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) - set_tests_properties(euclidean_strong_witness_complex_diagram_persistence_from_off_file_example_py_test PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}") add_test(NAME euclidean_witness_complex_diagram_persistence_from_off_file_example_py_test WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/example/euclidean_witness_complex_diagram_persistence_from_off_file_example.py" + 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) - set_tests_properties(euclidean_witness_complex_diagram_persistence_from_off_file_example_py_test PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}") + + # Subsampling + add_gudhi_py_test(test_subsampling) + + endif (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) + if (NOT CGAL_VERSION VERSION_LESS 4.8.1) + # Bottleneck + add_test(NAME bottleneck_basic_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/bottleneck_basic_example.py") + + add_gudhi_py_test(test_bottleneck_distance) endif (NOT CGAL_VERSION VERSION_LESS 4.8.1) - if (NOT CGAL_VERSION VERSION_LESS 4.7.0) + if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.7.0) + # Alpha add_test(NAME alpha_complex_from_points_example_py_test WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/example/alpha_complex_from_points_example.py") - set_tests_properties(alpha_complex_from_points_example_py_test PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}") + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/alpha_complex_from_points_example.py") add_test(NAME alpha_complex_diagram_persistence_from_off_file_example_py_test WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/example/alpha_complex_diagram_persistence_from_off_file_example.py" + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/alpha_complex_diagram_persistence_from_off_file_example.py" --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -a 0.6) - set_tests_properties(alpha_complex_diagram_persistence_from_off_file_example_py_test PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}") - endif (NOT CGAL_VERSION VERSION_LESS 4.7.0) - if (NOT CGAL_VERSION VERSION_LESS 4.6.0) - endif (NOT CGAL_VERSION VERSION_LESS 4.6.0) + add_gudhi_py_test(test_alpha_complex) + + endif (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.7.0) + + if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.6.0) + # Euclidean witness + add_gudhi_py_test(test_euclidean_witness_complex) + endif (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.6.0) + + # Cubical add_test(NAME periodic_cubical_complex_barcode_persistence_from_perseus_file_example_py_test WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/example/periodic_cubical_complex_barcode_persistence_from_perseus_file_example.py" + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/periodic_cubical_complex_barcode_persistence_from_perseus_file_example.py" --no-barcode -f ${CMAKE_SOURCE_DIR}/data/bitmap/CubicalTwoSphere.txt) - set_tests_properties(periodic_cubical_complex_barcode_persistence_from_perseus_file_example_py_test PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}") add_test(NAME random_cubical_complex_persistence_example_py_test WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/example/random_cubical_complex_persistence_example.py" + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/random_cubical_complex_persistence_example.py" 10 10 10) - set_tests_properties(random_cubical_complex_persistence_example_py_test PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}") + add_gudhi_py_test(test_cubical_complex) + + # Rips add_test(NAME rips_complex_diagram_persistence_from_distance_matrix_file_example_py_test WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py" + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py" --no-diagram -f ${CMAKE_SOURCE_DIR}/data/distance_matrix/lower_triangular_distance_matrix.csv -e 12.0 -d 3) - set_tests_properties(rips_complex_diagram_persistence_from_distance_matrix_file_example_py_test PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}") add_test(NAME rips_complex_diagram_persistence_from_off_file_example_py_test WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/example/rips_complex_diagram_persistence_from_off_file_example.py + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example/rips_complex_diagram_persistence_from_off_file_example.py --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -e 0.25 -d 3) - set_tests_properties(rips_complex_diagram_persistence_from_off_file_example_py_test PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}") add_test(NAME rips_complex_from_points_example_py_test WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/example/rips_complex_from_points_example.py) - set_tests_properties(rips_complex_from_points_example_py_test PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}") + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example/rips_complex_from_points_example.py) + + add_gudhi_py_test(test_rips_complex) + # Simplex tree add_test(NAME simplex_tree_example_py_test WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/example/simplex_tree_example.py) - set_tests_properties(simplex_tree_example_py_test PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}") + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example/simplex_tree_example.py) + add_gudhi_py_test(test_simplex_tree) + + # Witness add_test(NAME witness_complex_from_nearest_landmark_table_py_test WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/example/witness_complex_from_nearest_landmark_table.py) - 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) - - # Documentation generation is available through sphinx - if(SPHINX_PATH) - if (UNIX) - add_custom_target(sphinx - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/gudhi.so" - COMMAND make html doctest) - else (UNIX) - add_custom_target(sphinx - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc - COMMAND make.bat html doctest) - endif (UNIX) - endif(SPHINX_PATH) + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example/witness_complex_from_nearest_landmark_table.py) + + add_gudhi_py_test(test_witness_complex) + + # Reader utils + add_gudhi_py_test(test_reader_utils) + + # Documentation generation is available through sphinx - requires all modules + if(SPHINX_PATH AND NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) + set (GUDHI_SPHINX_MESSAGE "Generating API documentation with Sphinx in ${CMAKE_CURRENT_BINARY_DIR}/sphinx/") + # User warning - Sphinx is a static pages generator, and configured to work fine with user_version + # Images and biblio warnings because not found on developper version + if (GUDHI_CYTHON_PATH STREQUAL "src/cython") + set (GUDHI_SPHINX_MESSAGE "${GUDHI_SPHINX_MESSAGE} \n WARNING : Sphinx is configured for user version, you run it on developper version. Images and biblio will miss") + endif() + # sphinx target requires gudhi.so, because conf.py reads gudhi version from it + add_custom_target(sphinx + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/doc + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${SPHINX_PATH} -b html ${CMAKE_CURRENT_SOURCE_DIR}/doc ${CMAKE_CURRENT_BINARY_DIR}/sphinx + DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/gudhi.so" + COMMENT "${GUDHI_SPHINX_MESSAGE}" VERBATIM) + + add_test(NAME sphinx_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${SPHINX_PATH} -b doctest ${CMAKE_CURRENT_SOURCE_DIR}/doc ${CMAKE_CURRENT_BINARY_DIR}/doctest) + + endif(SPHINX_PATH AND NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) endif(CYTHON_FOUND) diff --git a/src/cython/cython/periodic_cubical_complex.pyx b/src/cython/cython/periodic_cubical_complex.pyx index 581c7b69..3025f125 100644 --- a/src/cython/cython/periodic_cubical_complex.pyx +++ b/src/cython/cython/periodic_cubical_complex.pyx @@ -33,7 +33,7 @@ __license__ = "GPL v3" cdef extern from "Cubical_complex_interface.h" namespace "Gudhi": cdef cppclass Periodic_cubical_complex_base_interface "Gudhi::Cubical_complex::Cubical_complex_interface<Gudhi::cubical_complex::Bitmap_cubical_complex_periodic_boundary_conditions_base<double>>": - Periodic_cubical_complex_base_interface(vector[unsigned] dimensions, vector[double] top_dimensional_cells) + Periodic_cubical_complex_base_interface(vector[unsigned] dimensions, vector[double] top_dimensional_cells, vector[bool] periodic_dimensions) Periodic_cubical_complex_base_interface(string perseus_file) int num_simplices() int dimension() @@ -58,7 +58,7 @@ cdef class PeriodicCubicalComplex: # Fake constructor that does nothing but documenting the constructor def __init__(self, dimensions=None, top_dimensional_cells=None, - perseus_file=''): + periodic_dimensions=None, perseus_file=''): """PeriodicCubicalComplex constructor from dimensions and top_dimensional_cells or from a Perseus-style file name. @@ -66,6 +66,8 @@ cdef class PeriodicCubicalComplex: :type dimensions: list of int :param top_dimensional_cells: A list of cells filtration values. :type top_dimensional_cells: list of double + :param periodic_dimensions: A list of top dimensional cells periodicity value. + :type periodic_dimensions: list of boolean Or @@ -75,10 +77,10 @@ cdef class PeriodicCubicalComplex: # The real cython constructor def __cinit__(self, dimensions=None, top_dimensional_cells=None, - perseus_file=''): - if (dimensions is not None) and (top_dimensional_cells is not None) and (perseus_file is ''): - self.thisptr = new Periodic_cubical_complex_base_interface(dimensions, top_dimensional_cells) - elif (dimensions is None) and (top_dimensional_cells is None) and (perseus_file is not ''): + periodic_dimensions=None, perseus_file=''): + if (dimensions is not None) and (top_dimensional_cells is not None) and (periodic_dimensions is not None) and (perseus_file is ''): + self.thisptr = new Periodic_cubical_complex_base_interface(dimensions, top_dimensional_cells, periodic_dimensions) + elif (dimensions is None) and (top_dimensional_cells is None) and (periodic_dimensions is None) and (perseus_file is not ''): if os.path.isfile(perseus_file): self.thisptr = new Periodic_cubical_complex_base_interface(str.encode(perseus_file)) else: 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/persistence_representations_intervals.pyx b/src/cython/cython/persistence_representations_intervals.pyx deleted file mode 100644 index c1cc347d..00000000 --- a/src/cython/cython/persistence_representations_intervals.pyx +++ /dev/null @@ -1,318 +0,0 @@ -from cython cimport numeric -from libcpp.vector cimport vector -from libcpp.utility cimport pair -from libcpp cimport bool -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): Pawel Dlotko - - Copyright (C) 2017 Swansea University - - 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__ = "Pawel Dlotko" -__copyright__ = "Copyright (C) 2017 Swansea University" -__license__ = "GPL v3" - - -""" -This is a promisse that there will be a class in this file with the following -function signature. Something like C++ predeclaration. -According to Vincent, most of the tutorials in cython suggest to -separate pre-declaration below with the definition of the method. -Hovewer it seems to create problems, that is why we keep them both here. -""" - - - - -cdef extern from "Persistence_intervals_interface.h" namespace "Gudhi::Persistence_representations": - cdef cppclass Persistence_intervals_interface "Gudhi::Persistence_representations::Persistence_intervals_interface": - Persistence_intervals_interface(const char*, unsigned) - Persistence_intervals_interface(const vector[pair[double, double]] intervals) - pair[double, double] get_x_range() const - pair[double, double] get_y_range() const - vector[double] length_of_dominant_intervals(size_t where_to_cut)const - vector[pair[double, double]] dominant_intervals(size_t where_to_cut) const - vector[size_t] histogram_of_lengths(size_t number_of_bins) const - vector[size_t] cumulative_histogram_of_lengths(size_t number_of_bins) const - vector[double] characteristic_function_of_diagram(double x_min, double x_max, size_t number_of_bins)const - vector[double] cumulative_characteristic_function_of_diagram(double x_min, double x_max, size_t number_of_bins)const - vector[pair[double, size_t]] compute_persistent_betti_numbers()const - double project_to_R(int number_of_function) const - size_t number_of_projections_to_R() const - vector[double] vectorize(int number_of_function) const - size_t number_of_vectorize_functions() const - -""" -make sure that here we call the functions from the intermediate .h file, -with dummy names, so that later below we can use the same names of the -functions as in C++ version. -Over here I need to list all the functions that will be used in the file. -So there should be a list of constructors, methors, etc. -to separate the function, use newline. Put there only C++ signature -""" - - -#convention for python class is PersistenceIntervals instead of -#Persistence_intervals for methods it is def num_simplices(self). -cdef class PersistenceIntervals: - """ - Persistence intrvals is a standard representation of persistent homology. This file provide implementation of a number of operations on persistence diagrams. - """ - cdef Persistence_intervals_interface * thisptr - - #do we need a fake constructor here, as in case of bitmaps?? - #We do need it so that we have a doc for python because the - #documentation only read from __init__, it do not read from - #__cinit__, where __ means private memeber - def __init__(self, vector_of_intervals=None, dimension=None, - file_with_intervals=''): - """Persistence interals is a standard representation of - persistent homology. This file provide implementation of a - number of operations on persistence diagrams. - - :param dimensions: A vector of birth-death pairs. - - Or - - :param Gudhi style file togethr with a dimension of birth-death - pairs to consider. - """ - - #The real cython constructor - def __cinit__(self, vector_of_intervals=None, dimension=None, - file_with_intervals=''): - """ - This is a constructor of a class Persistence_intervals. - It either take text file and a positive integer, or a vector - of pairs. In case of file, each line of the input file is - supposed to contain two numbers of a type double - (or convertible to double) representing the birth and the death - of the persistence interval. If the pairs are not sorted so that - birth <= death, then the constructor will sort then that way. - In case of vector of pairs, it simply accept vector of pair of - doubles. - :param vector_of_intervals -- vector of pairs of doubles with - birth-death pairs. None if we construct it from file. - :type vector of pairs of doubles or None - :param dimension -- diension of intervals to be extracted from file - :type nonnegative integer or None - :param file_with_intervals - a path to Gudhi style file with - persistence interfals. - :type string of None. - """ - if (vector_of_intervals is None) and (file_with_intervals is not ''): - if (dimension is not None): - if os.path.isfile(file_with_intervals): - self.thisptr = new Persistence_intervals_interface(file_with_intervals, dimension) - else: - print("file " + file_with_intervals + " not found.") - else: - self.thisptr = new Persistence_intervals_interface(file_with_intervals) - elif (file_with_intervals is '') and (vector_of_intervals is not None): - self.thisptr = new Persistence_intervals_interface(vector_of_intervals) - else: - print("Persistence interals can be constructed from vector of birth-death pairs, vector_of_intervals or a Gudhi-style file.") - - def __dealloc__(self): - """ - destructor - """ - if self.thisptr != NULL: - del self.thisptr - - #from here on this is my try. Do we need to specify the returned type?? - #no, we do not. - def get_x_range(self): - """ - This procedure returns x-range of a given persistence diagram. - """ - if self.thisptr != NULL: - return self.thisptr.get_x_range() - - def get_y_range(self): - """ - This procedure returns y-range of a given persistence diagram. - """ - if self.thisptr != NULL: - return self.thisptr.get_y_range() - - def length_of_dominant_intervals(self, where_to_cut): - """ - Procedure that compute the vector of lengths of the dominant - (i.e. the longest) persistence intervals. The list is - truncated at the parameter of the call where_to_cut - (set by default to 100). - :param where_to_cut -- number of domiannt intervals to be returned. - :type positive integer. - """ - if (self.thisptr != NULL) and (where_to_cut is not None): - return self.thisptr.length_of_dominant_intervals(where_to_cut) - else: - if (self.thisptr != NULL): - return self.thisptr.dominant_intervals(100) - - def dominant_intervals(self, where_to_cut): - """ - Procedure that compute the vector of the dominant (i.e. the longest) - persistence intervals. The parameter of the procedure (set by default - to 100) is the number of dominant intervals returned by the procedure. - :param where_to_cut -- number of lengths of domiannt intervals to - be returned. - :type positive integer. - """ - if (self.thisptr != NULL) and (where_to_cut is not None): - return self.thisptr.dominant_intervals(where_to_cut) - else: - if (self.thisptr != NULL): - return self.thisptr.dominant_intervals(100) - - def histogram_of_lengths(self, number_of_bins): - """ - Procedure to compute a histogram of interval's length. - A histogram is a block plot. The number of blocks is - determined by the first parameter of the function - (set by default to 10). - For the sake of argument let us assume that the length of the - longest interval is 1 and the number of bins is - 10. In this case the i-th block correspond to a range between - i-1/10 and i10. The vale of a block supported at the interval is - the number of persistence intervals of a length between x_0 - and x_1. - :param where_to_cut -- number of bins in the histogram. - :type positive integer. - """ - if (self.thisptr != NULL) and (number_of_bins is not None): - return self.thisptr.histogram_of_lengths(number_of_bins) - else: - if (self.thisptr != NULL): - return self.thisptr.dominant_intervals(100) - - def cumulative_histogram_of_lengths(self, number_of_bins): - """ - Based on a histogram of intervals lengths computed by the - function histogram_of_lengths H the procedure below - computes the cumulative histogram. The i-th position - of the resulting histogram - is the sum of values of H for the positions from 0 to i. - :param where_to_cut -- number of bins in the histogram. - :type positive integer. - """ - if (self.thisptr != NULL) and (number_of_bins is not None): - return self.thisptr.cumulative_histogram_of_lengths(number_of_bins) - else: - if (self.thisptr != NULL): - return self.thisptr.cumulative_histogram_of_lengths(10) - - def characteristic_function_of_diagram(self, x_min, x_max, number_of_bins): - """ - In this procedure we assume that each barcode is a characteristic - function of a hight equal to its length. The persistence diagram - is a sum of such a functions. The procedure below construct a - function being a sum of the characteristic functions of - persistence intervals. The first two parameters are the range in - which the function is to be computed and the last parameter is - the number of bins in the discretization of the interval - [_min,_max] - :param x_min -- Begin of range of function. - :type real number - :param x_max -- End of range of function. - :type real number - :param number_of_bins -- Number of bins in characteristic function. - :type positive integer - """ - if (self.thisptr != NULL) and (x_min is not None) and (x_max is not None) and (number_of_bins is not None): - return self.thisptr.characteristic_function_of_diagram(x_min, x_max , number_of_bins) - else: - if (self.thisptr != NULL) and (x_min is not None) and (x_max is not None): - return self.thisptr.characteristic_function_of_diagram(x_min, x_max, 10) - - def cumulative_characteristic_function_of_diagram(self, x_min, x_max, number_of_bins): - """ - Cumulative version of the function characteristic_function_of_diagram. - :param x_min -- Begin of range of function. - :type real number - :param x_max -- End of range of function. - :type real number - :param number_of_bins -- Number of bins in characteristic function. - :type positive integer - """ - if (self.thisptr != NULL) and (x_min is not None) and (x_max is not None) and (number_of_bins is not None): - return self.thisptr.cumulative_characteristic_function_of_diagram(x_min, x_max, number_of_bins) - else: - if (self.thisptr != NULL) and (x_min is not None) and (x_max is not None): - return self.thisptr.cumulative_characteristic_function_of_diagram(x_min, x_max, 10) - - def compute_persistent_betti_numbers(self): - """ - Compute the function of persistence Betti numbers. The returned - value is a vector of pair. First element of each - pair is a place where persistence Betti numbers change. - Second element of each pair is the value of Persistence Betti - numbers at that point. - """ - if self.thisptr != NULL: - return self.thisptr.compute_persistent_betti_numbers() - - def project_to_R(self, number_of_function): - """ - This is a simple function projecting the persistence intervals - to a real number. The function we use here is a sum - of squared lengths of intervals. It can be naturally interpreted as - sum of step function, where the step hight it equal to the length - of the interval. At the moment this function is not tested, since - it is quite likely to be changed in the future. Given this, when - using it, keep in mind that it - will be most likely changed in the next versions. - :param number of projection - :type positive integer. - """ - if (self.thisptr != NULL) and (number_of_function is not None): - return self.thisptr.project_to_R(number_of_function) - - def number_of_projections_to_R(self): - """ - The function gives the number of possible projections to R. - This function is required by the - Real_valued_topological_data concept. - """ - if self.thisptr != NULL: - return self.thisptr.number_of_projections_to_R() - - def vectorize(self, number_of_function): - """ - Return a family of vectors obtained from the persistence diagram. - The i-th vector consist of the length of i - dominant persistence intervals. - :param number of function to vectorizes - :type positive integer. - """ - if (self.thisptr != NULL) and (number_of_function is not None): - return self.thisptr.vectorize(number_of_function) - - def number_of_vectorize_functions(self): - """ - This function return the number of functions that allows - vectorization of a persistence diagram. It is required - in a concept Vectorized_topological_data - """ - if (self.thisptr != NULL): - return self.thisptr.number_of_vectorize_functions() diff --git a/src/cython/cython/persistence_representations_landscapes.pyx b/src/cython/cython/persistence_representations_landscapes.pyx deleted file mode 100644 index 39b62439..00000000 --- a/src/cython/cython/persistence_representations_landscapes.pyx +++ /dev/null @@ -1,378 +0,0 @@ -from cython cimport numeric -from libcpp.vector cimport vector -from libcpp.utility cimport pair -from libcpp cimport bool -from cython.operator cimport dereference as deref -import os -import sys - -"""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): Pawel Dlotko - - Copyright (C) 2017 Swansea University - - 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__ = "Pawel Dlotko" -__copyright__ = "Copyright (C) 2017 Swansea University" -__license__ = "GPL v3" - - - -cdef extern from "Persistence_landscape_interface.h" namespace "Gudhi::Persistence_representations": - cdef cppclass Persistence_landscape_interface "Gudhi::Persistence_representations::Persistence_landscape_interface": - Persistence_landscape_interface() - #Persistence_landscape_interface(vector[pair[double, double]], bool, size_t) - #Persistence_landscape_interface(const char*, size_t , size_t) - void load_landscape_from_file(const char*) - void print_to_file(const char*)const - double compute_integral_of_landscape()const - double compute_integral_of_a_level_of_a_landscape(size_t)const - double compute_integral_of_landscape(double)const - double compute_value_at_a_given_point(unsigned , double)const - double compute_maximum()const - double compute_minimum()const - double compute_norm_of_landscape(double) - Persistence_landscape_interface* new_abs_interface() - size_t size()const - double find_max(unsigned)const - double project_to_R(int)const - size_t number_of_projections_to_R()const - vector[double] vectorize(int)const - size_t number_of_vectorize_functions()const - void compute_average(const vector[Persistence_landscape_interface*]&) - void new_compute_average(const vector[Persistence_landscape_interface*]&) - double distance(const Persistence_landscape_interface&, double) - double compute_scalar_product(const Persistence_landscape_interface&)const - pair[double, double] get_y_range(size_t)const - #************** - #static methods - @staticmethod - Persistence_landscape_interface* construct_from_file( const char*, size_t, size_t) - @staticmethod - Persistence_landscape_interface* construct_from_vector_of_pairs( const vector[pair[double, double]], size_t) - #*************** - - - - -#convention for python class is PersistenceIntervals instead of Persistence_intervals -#for methods it is def num_simplices(self). -cdef class PersistenceLandscapes: - - cdef Persistence_landscape_interface* thisptr - - - -#Can we have only one constructor, or can we have more - def __init__(self, vector_of_intervals=None, dimension=None, file_with_intervals='',number_of_levels=sys.maxsize): - """ - This is a class implementing persistence landscapes data structures. - For theoretical description, please consult <i>Statistical topological - data analysis using persistence landscapes</i>\cite bubenik_landscapes_2015, - and for details of algorithms, A persistence landscapes toolbox for - topological statistics</i>\cite bubenik_dlotko_landscapes_2016. - - Persistence landscapes allow vectorization, computations of distances, - computations of projections to Real, computations of averages and - scalar products. Therefore they implement suitable interfaces. It - implements the following concepts: Vectorized_topological_data, - Topological_data_with_distances, Real_valued_topological_data, - Topological_data_with_averages, Topological_data_with_scalar_product - - Note that at the moment, due to rounding errors during the construction - of persistence landscapes, elements which are different by 0.000005 are - considered the same. If the scale in your persistence diagrams is - comparable to this value, please rescale them before use this code. - """ - - - - def __cinit__(self, vector_of_intervals=None, dimension=None, file_with_intervals='',number_of_levels=sys.maxsize): - """ - This is a constructor of a class PersistenceLandscapes. - It either take text file and a positive integer, or a vector - of pairs. The last optional parameter is the nunmer of levels of - the landscapes to be generated. If not set, all the levels will - be generated. In case of file, each line of the input file is, - supposed to contain two numbers of a type double - (or convertible to double) representing the birth and the death - of the persistence interval. If the pairs are not sorted so that - birth <= death, then the constructor will sort then that way. - In case of vector of pairs, it simply accept vector of pair of - doubles. - :param vector_of_intervals -- vector of pairs of doubles with - birth-death pairs. None if we construct it from file. - :type vector of pairs of doubles or None - :param dimension -- diension of intervals to be extracted from file - :type nonnegative integer or None - :param file_with_intervals - a path to Gudhi style file with - persistence interfals. - :type string of None. - :param number_of_levels - number of levels of landscape to be - generated (if not set, all of the are generated). - :type positive integer - """ - if (vector_of_intervals is None) and (file_with_intervals is not ''): - if (dimension is not None): - if os.path.isfile(file_with_intervals): - #self.thisptr = new Persistence_landscape_interface(file_with_intervals, dimension, number_of_levels) - self.thisptr = Persistence_landscape_interface.construct_from_file(file_with_intervals, dimension, number_of_levels) - else: - print("file " + file_with_intervals + " not found.") - else: - #self.thisptr = new Persistence_landscape_interface(file_with_intervals, number_of_levels) - self.thisptr = Persistence_landscape_interface.construct_from_file(file_with_intervals,0, number_of_levels) - elif (file_with_intervals is '') and (vector_of_intervals is not None): - #self.thisptr = new Persistence_landscape_interface(vector_of_intervals, true, number_of_levels) - self.thisptr = Persistence_landscape_interface.construct_from_vector_of_pairs(vector_of_intervals, number_of_levels) - else: - print("Persistence interals can be constructed from vector of birth-death pairs, vector_of_intervals or a Gudhi-style file.") - self.thisptr = new Persistence_landscape_interface() - - def __dealloc__(self): - """ - destructor - """ - if self.thisptr != NULL: - del self.thisptr - - def load_landscape_from_file(self,filename): - """ - This procedure loads a landscape from file. It erase all the data - that was previously stored in this landscape. - :param Name of the file. - :type String - """ - if ( self.thisptr != NULL ) and ( filename is not None ): - self.thisptr.load_landscape_from_file(filename) - - def print_to_file(self,filename) : - """ - The procedure stores a landscape to a file. The file can be later - used by a procedure load_landscape_from_file. - :param Name of the file. - :type String - """ - if ( self.thisptr != NULL ) and ( filename is not None ): - self.thisptr.print_to_file(filename) - - def compute_integral_of_landscape(self): - """ - This function compute integral of the landscape (defined formally as - sum of integrals on R of all landscape functions) - """ - if ( self.thisptr != NULL ): - return self.thisptr.compute_integral_of_landscape() - - def compute_integral_of_a_level_of_a_landscape(self,level): - """ - This function compute integral of the 'level'-level of a landscape. - :param Level of the landscape, n, so that the integral of lambda_n is - computed - :type nonnegative integer. - """ - if ( self.thisptr != NULL ) and ( level is not None ): - return self.thisptr.compute_integral_of_landscape(level) - - def compute_integral_of_landscape(self,p): - """ - This function compute integral of the landscape p-th power of a - landscape (defined formally as sum of integrals on R of p-th powers - of all landscape functions) - :param An positive real p such that the integral of p-th power of - landscape is computed. - :type Real value - """ - if ( self.thisptr != NULL ) and ( p is not None ): - return self.thisptr.compute_integral_of_landscape(p) - - def compute_value_at_a_given_point(self, level, x): - """ - A function that computes the value of a landscape at a given point. - The parameters of the function are: unsigned - level and double x. - The procedure will compute the value of the level-landscape at the - point x. - param: level n of lanscape (positive integer) and real number x. - The value \lambda_n(x) is - type: nonnegative integer - :param A real number x. The value \lambda_n(x) is computed. - :type real - """ - if ( self.thisptr != NULL ) and ( level is not None ) and ( x is not None ): - return self.thisptr.compute_value_at_a_given_point(level,x) - - def compute_maximum( self ): - """ - Computations of maximum (y) value of landscape. - """ - if ( self.thisptr != NULL ): - return self.thisptr.compute_maximum() - - def compute_minimum( self ): - """ - Computations of minimum (y) value of landscape. - """ - if ( self.thisptr != NULL ): - return self.thisptr.compute_minimum() - - def compute_norm_of_landscape(self,i): - """ - Computations of a \f$L^i\f$ norm of landscape, where i is the input parameter. - :type integer. - :param i - """ - if ( self.thisptr != NULL ) and ( i is not None ): - return self.thisptr.compute_norm_of_landscape(i) - - def abs( self ): - """ - Function to compute absolute value of a PL function. The representation - of persistence landscapes allow to store - general PL-function. When computing distance between two landscapes, - we compute difference between - them. In this case, a general PL-function with negative value can - appear as a result. Then in order to compute - distance, we need to take its absolute value. This is the purpose of - this procedure. - """ - if ( self.thisptr != NULL ): - abs_ = PersistenceLandscapes() - abs_.thisptr = self.thisptr.new_abs_interface() - return abs_ - - - def size( self ): - """ - Computes the number of landscape functions. - """ - if ( self.thisptr != NULL ): - return self.thisptr.size() - - def find_max(self, lambda_): - """ - Compute maximal value of lambda-level landscape. - :param level of landscape - :type nonnegative integer - """ - if ( self.thisptr != NULL ) and ( lambda_ is not None ): - return self.thisptr.find_max(lambda_) - - def project_to_R(self, number_of_function): - """ - The number of projections to R is defined to the number of nonzero - landscape functions. I-th projection is an - integral of i-th landscape function over whole R. - This function is required by the Real_valued_topological_data concept. - At the moment this function is not tested, since it is quite likely - to be changed in the future. Given this, when - using it, keep in mind that it - will be most likely changed in the next versions. - :param number of function - :type nonnegative integer - """ - if ( self.thisptr != NULL ) and ( number_of_function is not None ): - return self.thisptr.project_to_R(number_of_function) - - def number_of_projections_to_R(self): - """ - The function gives the number of possible projections to R. This - function is required by the - Real_valued_topological_data concept - """ - if ( self.thisptr != NULL ): - return self.thisptr.number_of_projections_to_R() - - def vectorize(self, number_of_function): - """ - This function produce a vector of doubles based on a landscape. It - is required in a concept - Vectorized_topological_data - :param number of function - :type nonnegative intege - """ - if ( self.thisptr != NULL ) and ( number_of_function is not None ): - return self.thisptr.vectorize(number_of_function) - - def number_of_vectorize_functions(self): - """ - The number of projections to R is defined to the number of nonzero - landscape functions. I-th projection is an - integral of i-th landscape function over whole R. - This function is required by the Real_valued_topological_data concept. - At the moment this function is not tested, since it is quite likely - to be changed in the future. Given this, when - using it, keep in mind that it - will be most likely changed in the next versions - """ - if ( self.thisptr != NULL ): - return self.thisptr.number_of_vectorize_functions() - - def compute_average( self,to_average=[] ): - """ - A function to compute averaged persistence landscape, based on vector - of persistence landscapes. - This function is required by Topological_data_with_averages concept. - :param vector of persistence landscapes to average - :type vectors of references to persistence landscapes - """ - #TODO -- add a check if all objects in the to_average are of the same type. - cdef vector[Persistence_landscape_interface*] cpp_list - if ( self.thisptr != NULL ) and ( to_average is not None ): - for elt in to_average: - cpp_list.push_back((<PersistenceLandscapes>elt).thisptr) - self.thisptr.new_compute_average( cpp_list ) - - - - def distance(self, PersistenceLandscapes second, power): - """ - A function to compute distance between persistence landscape. - The parameter of this function is a Persistence_landscape. - This function is required in Topological_data_with_distances concept. - For max norm distance, set power to std::numeric_limits<double>::max() - :param the landascape to compute distance to - :type PersistenceLandscape - """ - if ( self.thisptr != NULL ) and ( second is not None ) and ( power is not None ): - return self.thisptr.distance( deref(second.thisptr), power) - - def compute_scalar_product(self, PersistenceLandscapes second): - """ - A function to compute scalar product of persistence landscapes. - The parameter of this function is a Persistence_landscape. - This function is required in Topological_data_with_scalar_product concept. - :param the landascape to compute scalar product with - :type PersistenceLandscape - """ - if ( self.thisptr != NULL ) and ( second is not None ): - return self.thisptr.compute_scalar_product( deref(second.thisptr) ) - - def get_y_range(self, level): - """ - This procedure returns y-range of a given level persistence landscape. - If a default value is used, the y-range - of 0th level landscape is given (and this range contains the ranges - of all other landscapes). - :param The level of lrandscape - :type nonnegative integer - """ - if ( self.thisptr != NULL ): - return self.thisptr.get_y_range(level) - diff --git a/src/cython/cython/persistence_representations_landscapes_on_grid.pyx b/src/cython/cython/persistence_representations_landscapes_on_grid.pyx deleted file mode 100644 index f69496cd..00000000 --- a/src/cython/cython/persistence_representations_landscapes_on_grid.pyx +++ /dev/null @@ -1,388 +0,0 @@ -from cython cimport numeric -from libcpp.vector cimport vector -from libcpp.utility cimport pair -from libcpp cimport bool -from cython.operator cimport dereference as deref -import os -import sys - -"""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): Pawel Dlotko - - Copyright (C) 2017 Swansea University - - 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__ = "Pawel Dlotko" -__copyright__ = "Copyright (C) 2017 Swansea University" -__license__ = "GPL v3" - - - -cdef extern from "Persistence_landscape_on_grid_interface.h" namespace "Gudhi::Persistence_representations": - cdef cppclass Persistence_landscape_on_grid_interface "Gudhi::Persistence_representations::Persistence_landscape_on_grid_interface": - Persistence_landscape_on_grid_interface() - Persistence_landscape_on_grid_interface(vector[pair[double, double]], double grid_min_, double grid_max_, size_t number_of_points_) - Persistence_landscape_on_grid_interface(vector[pair[double, double]], double grid_min_, double grid_max_, size_t number_of_points_, unsigned number_of_levels_of_landscape) - Persistence_landscape_on_grid_interface(const char* filename, double grid_min_, double grid_max_, size_t number_of_points_, - unsigned number_of_levels_of_landscape, unsigned) - Persistence_landscape_on_grid_interface(const char* filename, double grid_min_, double grid_max_, size_t number_of_points_, - unsigned dimension_) - Persistence_landscape_on_grid_interface(const char* filename, size_t number_of_points, unsigned number_of_levels_of_landscape, unsigned dimension) - Persistence_landscape_on_grid_interface(const char* filename, size_t number_of_points, unsigned dimension) - void load_landscape_from_file(const char*) - void print_to_file(const char*)const - double compute_integral_of_landscape()const - double compute_integral_of_a_level_of_a_landscape(size_t)const - double compute_integral_of_landscape(double)const - double compute_value_at_a_given_point(unsigned , double)const - double compute_maximum()const - double compute_minimum()const - double compute_norm_of_landscape(double) - Persistence_landscape_on_grid_interface* new_abs_interface() - size_t size()const - double find_max(unsigned)const - double project_to_R(int)const - size_t number_of_projections_to_R()const - vector[double] vectorize(int)const - size_t number_of_vectorize_functions()const - void compute_average(const vector[Persistence_landscape_on_grid_interface*]&) - void new_compute_average(const vector[Persistence_landscape_on_grid_interface*]&) - double distance(Persistence_landscape_on_grid_interface&, double) - double compute_scalar_product(const Persistence_landscape_on_grid_interface&)const - pair[double, double] get_y_range(size_t)const - - - - -#convention for python class is PersistenceIntervals instead of Persistence_intervals -#for methods it is def num_simplices(self). -cdef class PersistenceLandscapesOnGrid: - - cdef Persistence_landscape_on_grid_interface* thisptr - -#Can we have only one constructor, or can we have more - def __init__(self, grid_min_, grid_max_,number_of_points_, file_with_intervals='', - vector_of_intervals=None, dimension=None,number_of_levels=sys.maxsize): - """ - This is a class implementing persistence landscapes data structures. - For theoretical description, please consult <i>Statistical topological - data analysis using persistence landscapes</i>\cite bubenik_landscapes_2015, - and for details of algorithms, A persistence landscapes toolbox for - topological statistics</i>\cite bubenik_dlotko_landscapes_2016. - - Persistence landscapes allow vectorization, computations of distances, - computations of projections to Real, computations of averages and - scalar products. Therefore they implement suitable interfaces. It - implements the following concepts: Vectorized_topological_data, - Topological_data_with_distances, Real_valued_topological_data, - Topological_data_with_averages, Topological_data_with_scalar_product - - Note that at the moment, due to rounding errors during the construction - of persistence landscapes, elements which are different by 0.000005 are - considered the same. If the scale in your persistence diagrams is - comparable to this value, please rescale them before use this code. - """ - - - - def __cinit__(self, grid_min_, grid_max_,number_of_points_, file_with_intervals='', - vector_of_intervals=None, dimension=None,number_of_levels=sys.maxsize): - """ - This is a constructor of a class PersistenceLandscapes. - It either take text file and a positive integer, or a vector - of pairs. The last optional parameter is the nunmer of levels of - the landscapes to be generated. If not set, all the levels will - be generated. In case of file, each line of the input file is, - supposed to contain two numbers of a type double - (or convertible to double) representing the birth and the death - of the persistence interval. If the pairs are not sorted so that - birth <= death, then the constructor will sort then that way. - In case of vector of pairs, it simply accept vector of pair of - doubles. - :param vector_of_intervals -- vector of pairs of doubles with - birth-death pairs. None if we construct it from file. - :type vector of pairs of doubles or None - :param dimension -- diension of intervals to be extracted from file - :type nonnegative integer or None - :param file_with_intervals - a path to Gudhi style file with - persistence interfals. - :type string of None. - :param grid_min_ - minumum of the grid to be cosntructed. - :type double - :param grid_max_ - maximum of the grid to be cosntructed. - :type double - :param number_of_points_ - number of points in the grid. - :type positive integer - :param number_of_levels - number of levels of landscape to be - generated (if not set, all of the are generated). - :type positive integer - """ - if ( (grid_min_ is None) or ( grid_max_ is None ) or ( number_of_points_ is None ) ): - print "Please provide parameters of the grid in order to construct the persistence landscape on a grid." - else: - if (vector_of_intervals is None) and (file_with_intervals is not ''): - if (dimension is not None): - if os.path.isfile(file_with_intervals): - self.thisptr = new Persistence_landscape_on_grid_interface(file_with_intervals, dimension, grid_min_, grid_max_,number_of_points_, number_of_levels) - else: - print("file " + file_with_intervals + " not found.") - else: - self.thisptr = new Persistence_landscape_on_grid_interface(file_with_intervals,0, grid_min_, grid_max_,number_of_points_, number_of_levels) - else: - if (file_with_intervals is '') and (vector_of_intervals is not None): - self.thisptr = new Persistence_landscape_on_grid_interface(vector_of_intervals, grid_min_, grid_max_, number_of_points_,number_of_levels) - #Persistence_landscape_on_grid_interface(vector_of_intervals, grid_min_, grid_max_,number_of_points_, number_of_levels) - else: - print("Persistence interals can be constructed from vector of birth-death pairs, vector_of_intervals or a Gudhi-style file.") - - -#Persistence_landscape_on_grid_interface(const vector[pair[double, double]], double grid_min_, double grid_max_, size_t number_of_points_, unsigned number_of_levels_of_landscape) - - - - def __dealloc__(self): - """ - destructor - """ - if self.thisptr != NULL: - del self.thisptr - - def load_landscape_from_file(self,filename): - """ - This procedure loads a landscape from file. It erase all the data - that was previously stored in this landscape. - :param Name of the file. - :type String - """ - if ( self.thisptr != NULL ) and ( filename is not None ): - self.thisptr.load_landscape_from_file(filename) - - def print_to_file(self,filename) : - """ - The procedure stores a landscape to a file. The file can be later - used by a procedure load_landscape_from_file. - :param Name of the file. - :type String - """ - if ( self.thisptr != NULL ) and ( filename is not None ): - self.thisptr.print_to_file(filename) - - def compute_integral_of_landscape(self): - """ - This function compute integral of the landscape (defined formally as - sum of integrals on R of all landscape functions) - """ - if ( self.thisptr != NULL ): - return self.thisptr.compute_integral_of_landscape() - - def compute_integral_of_a_level_of_a_landscape(self,level): - """ - This function compute integral of the 'level'-level of a landscape. - :param Level of the landscape, n, so that the integral of lambda_n is - computed - :type nonnegative integer. - """ - if ( self.thisptr != NULL ) and ( level is not None ): - return self.thisptr.compute_integral_of_landscape(level) - - def compute_integral_of_landscape(self,p): - """ - This function compute integral of the landscape p-th power of a - landscape (defined formally as sum of integrals on R of p-th powers - of all landscape functions) - :param An positive real p such that the integral of p-th power of - landscape is computed. - :type Real value - """ - if ( self.thisptr != NULL ) and ( p is not None ): - return self.thisptr.compute_integral_of_landscape(p) - - def compute_value_at_a_given_point(self, level, x): - """ - A function that computes the value of a landscape at a given point. - The parameters of the function are: unsigned - level and double x. - The procedure will compute the value of the level-landscape at the - point x. - param: level n of lanscape (positive integer) and real number x. - The value \lambda_n(x) is - type: nonnegative integer - :param A real number x. The value \lambda_n(x) is computed. - :type real - """ - if ( self.thisptr != NULL ) and ( level is not None ) and ( x is not None ): - return self.thisptr.compute_value_at_a_given_point(level,x) - - def compute_maximum( self ): - """ - Computations of maximum (y) value of landscape. - """ - if ( self.thisptr != NULL ): - return self.thisptr.compute_maximum() - - def compute_minimum( self ): - """ - Computations of minimum (y) value of landscape. - """ - if ( self.thisptr != NULL ): - return self.thisptr.compute_minimum() - - def compute_norm_of_landscape(self,i): - """ - Computations of a \f$L^i\f$ norm of landscape, where i is the input parameter. - :type integer. - :param i - """ - if ( self.thisptr != NULL ) and ( i is not None ): - return self.thisptr.compute_norm_of_landscape(i) - - def abs( self ): - """ - Function to compute absolute value of a PL function. The representation - of persistence landscapes allow to store - general PL-function. When computing distance between two landscapes, - we compute difference between - them. In this case, a general PL-function with negative value can - appear as a result. Then in order to compute - distance, we need to take its absolute value. This is the purpose of - this procedure. - """ - if ( self.thisptr != NULL ): - abs_ = PersistenceLandscapesOnGrid() - abs_.thisptr = self.thisptr.new_abs_interface() - return abs_ - - - def size( self ): - """ - Computes the number of landscape functions. - """ - if ( self.thisptr != NULL ): - return self.thisptr.size() - - def find_max(self, lambda_): - """ - Compute maximal value of lambda-level landscape. - :param level of landscape - :type nonnegative integer - """ - if ( self.thisptr != NULL ) and ( lambda_ is not None ): - return self.thisptr.find_max(lambda_) - - def project_to_R(self, number_of_function): - """ - The number of projections to R is defined to the number of nonzero - landscape functions. I-th projection is an - integral of i-th landscape function over whole R. - This function is required by the Real_valued_topological_data concept. - At the moment this function is not tested, since it is quite likely - to be changed in the future. Given this, when - using it, keep in mind that it - will be most likely changed in the next versions. - :param number of function - :type nonnegative integer - """ - if ( self.thisptr != NULL ) and ( number_of_function is not None ): - return self.thisptr.project_to_R(number_of_function) - - def number_of_projections_to_R(self): - """ - The function gives the number of possible projections to R. This - function is required by the - Real_valued_topological_data concept - """ - if ( self.thisptr != NULL ): - return self.thisptr.number_of_projections_to_R() - - def vectorize(self, number_of_function): - """ - This function produce a vector of doubles based on a landscape. It - is required in a concept - Vectorized_topological_data - :param number of function - :type nonnegative intege - """ - if ( self.thisptr != NULL ) and ( number_of_function is not None ): - return self.thisptr.vectorize(number_of_function) - - def number_of_vectorize_functions(self): - """ - The number of projections to R is defined to the number of nonzero - landscape functions. I-th projection is an - integral of i-th landscape function over whole R. - This function is required by the Real_valued_topological_data concept. - At the moment this function is not tested, since it is quite likely - to be changed in the future. Given this, when - using it, keep in mind that it - will be most likely changed in the next versions - """ - if ( self.thisptr != NULL ): - return self.thisptr.number_of_vectorize_functions() - - def compute_average( self,to_average=[] ): - """ - A function to compute averaged persistence landscape, based on vector - of persistence landscapes. - This function is required by Topological_data_with_averages concept. - :param vector of persistence landscapes to average - :type vectors of references to persistence landscapes - """ - cdef vector[Persistence_landscape_on_grid_interface*] cpp_list - if ( self.thisptr != NULL ) and ( to_average is not None ): - for elt in to_average: - cpp_list.push_back((<PersistenceLandscapesOnGrid>elt).thisptr) - self.thisptr.new_compute_average( cpp_list ) - - - - def distance(self, PersistenceLandscapesOnGrid second, power): - """ - A function to compute distance between persistence landscape. - The parameter of this function is a Persistence_landscape. - This function is required in Topological_data_with_distances concept. - For max norm distance, set power to numeric_limits<double>::max() - :param the landascape to compute distance to - :type PersistenceLandscape - """ - if ( self.thisptr != NULL ) and ( second is not None ) and ( power is not None ): - return self.thisptr.distance(deref(second.thisptr), power) - - def compute_scalar_product(self, PersistenceLandscapesOnGrid second): - """ - A function to compute scalar product of persistence landscapes. - The parameter of this function is a Persistence_landscape. - This function is required in Topological_data_with_scalar_product concept. - :param the landascape to compute scalar product with - :type PersistenceLandscape - """ - if ( self.thisptr != NULL ) and ( second is not None ): - return self.thisptr.compute_scalar_product( deref(second.thisptr) ) - - def get_y_range(self, level): - """ - This procedure returns y-range of a given level persistence landscape. - If a default value is used, the y-range - of 0th level landscape is given (and this range contains the ranges - of all other landscapes). - :param The level of lrandscape - :type nonnegative integer - """ - if ( self.thisptr != NULL ): - return self.thisptr.get_y_range(level) - 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..8a436619 100644 --- a/src/cython/cython/simplex_tree.pyx +++ b/src/cython/cython/simplex_tree.pyx @@ -2,6 +2,7 @@ from cython cimport numeric from libcpp.vector cimport vector from libcpp.utility cimport pair from libcpp cimport bool +from libcpp.string cimport string """This file is part of the Gudhi Library. The Gudhi library (Geometric Understanding in Higher Dimensions) is a generic C++ @@ -35,14 +36,14 @@ cdef extern from "Simplex_tree_interface.h" namespace "Gudhi": cdef cppclass Simplex_tree_interface_full_featured "Gudhi::Simplex_tree_interface<Gudhi::Simplex_tree_options_full_featured>": Simplex_tree() - double filtration() double simplex_filtration(vector[int] simplex) - void set_filtration(double filtration) + void assign_simplex_filtration(vector[int] simplex, double filtration) void initialize_filtration() int num_vertices() int num_simplices() void set_dimension(int dimension) int dimension() + int upper_bound_dimension() bint find_simplex(vector[int] simplex) bint insert_simplex_and_subfaces(vector[int] simplex, double filtration) @@ -51,8 +52,9 @@ cdef extern from "Simplex_tree_interface.h" namespace "Gudhi": vector[pair[vector[int], double]] get_star(vector[int] simplex) vector[pair[vector[int], double]] get_cofaces(vector[int] simplex, int dimension) - void remove_maximal_simplex(vector[int] simplex) void expansion(int max_dim) + void remove_maximal_simplex(vector[int] simplex) + bool prune_above_filtration(double filtration) cdef extern from "Persistent_cohomology_interface.h" namespace "Gudhi": cdef cppclass Simplex_tree_persistence_interface "Gudhi::Persistent_cohomology_interface<Gudhi::Simplex_tree<Gudhi::Simplex_tree_options_full_featured>>": @@ -61,6 +63,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: @@ -113,13 +116,16 @@ cdef class SimplexTree: """ return self.thisptr.simplex_filtration(simplex) - def set_filtration(self, filtration): - """This function sets the main simplicial complex filtration value. + def assign_filtration(self, simplex, filtration): + """This function assigns the simplicial complex filtration value for a + given N-simplex. - :param filtration: The filtration value. - :type filtration: float. + :param simplex: The N-simplex, represented by a list of vertex. + :type simplex: list of int. + :param filtration: The simplicial complex filtration value. + :type filtration: float """ - self.thisptr.set_filtration(<double> filtration) + self.thisptr.assign_simplex_filtration(simplex, filtration) def initialize_filtration(self): """This function initializes and sorts the simplicial complex @@ -127,9 +133,14 @@ cdef class SimplexTree: .. note:: - This function must be launched before persistence, betti_numbers, - persistent_betti_numbers or get_filtration after inserting or - removing simplices. + This function must be launched before + :func:`persistence()<gudhi.SimplexTree.persistence>`, + :func:`betti_numbers()<gudhi.SimplexTree.betti_numbers>`, + :func:`persistent_betti_numbers()<gudhi.SimplexTree.persistent_betti_numbers>`, + or :func:`get_filtration()<gudhi.SimplexTree.get_filtration>` + after :func:`inserting<gudhi.SimplexTree.insert>` or + :func:`removing<gudhi.SimplexTree.remove_maximal_simplex>` + simplices. """ self.thisptr.initialize_filtration() @@ -156,21 +167,42 @@ cdef class SimplexTree: :returns: the simplicial complex dimension. :rtype: int + + .. note:: + + This function is not constant time because it can recompute + dimension if required (can be triggered by + :func:`remove_maximal_simplex()<gudhi.SimplexTree.remove_maximal_simplex>` + or + :func:`prune_above_filtration()<gudhi.SimplexTree.prune_above_filtration>` + methods). """ return self.thisptr.dimension() - def set_dimension(self, dimension): - """This function sets the dimension of the simplicial complex. + def upper_bound_dimension(self): + """This function returns a valid dimension upper bound of the + simplicial complex. - insert and remove_maximal_simplex functions do not update dimension - value of the `SimplexTree`. + :returns: an upper bound on the dimension of the simplicial complex. + :rtype: int + """ + return self.thisptr.upper_bound_dimension() - `AlphaComplex`, `RipsComplex`, `TangentialComplex` and `WitnessComplex` - automatically sets the correct dimension in their `create_simplex_tree` - functions. + def set_dimension(self, dimension): + """This function sets the dimension of the simplicial complex. :param dimension: The new dimension value. :type dimension: int. + + .. note:: + + This function must be used with caution because it disables + dimension recomputation when required + (this recomputation can be triggered by + :func:`remove_maximal_simplex()<gudhi.SimplexTree.remove_maximal_simplex>` + or + :func:`prune_above_filtration()<gudhi.SimplexTree.prune_above_filtration>` + ). """ self.thisptr.set_dimension(<int>dimension) @@ -294,9 +326,57 @@ cdef class SimplexTree: :param simplex: The N-simplex, represented by a list of vertex. :type simplex: list of int. + + .. note:: + + Be aware that removing is shifting data in a flat_map + (:func:`initialize_filtration()<gudhi.SimplexTree.initialize_filtration>` to be done). + + .. note:: + + The dimension of the simplicial complex may be lower after calling + remove_maximal_simplex than it was before. However, + :func:`upper_bound_dimension()<gudhi.SimplexTree.upper_bound_dimension>` + method will return the old value, which + remains a valid upper bound. If you care, you can call + :func:`dimension()<gudhi.SimplexTree.dimension>` + to recompute the exact dimension. """ self.thisptr.remove_maximal_simplex(simplex) + def prune_above_filtration(self, filtration): + """Prune above filtration value given as parameter. + + :param filtration: Maximum threshold value. + :type filtration: float. + :returns: The filtration modification information. + :rtype: bint + + + .. note:: + + Some simplex tree functions require the filtration to be valid. + prune_above_filtration function is not launching + :func:`initialize_filtration()<gudhi.SimplexTree.initialize_filtration>` + but returns the filtration modification + information. If the complex has changed , please call + :func:`initialize_filtration()<gudhi.SimplexTree.initialize_filtration>` + to recompute it. + + .. note:: + + Note that the dimension of the simplicial complex may be lower + after calling + :func:`prune_above_filtration()<gudhi.SimplexTree.prune_above_filtration>` + than it was before. However, + :func:`upper_bound_dimension()<gudhi.SimplexTree.upper_bound_dimension>` + will return the old value, which remains a + valid upper bound. If you care, you can call + :func:`dimension()<gudhi.SimplexTree.dimension>` + method to recompute the exact dimension. + """ + return self.thisptr.prune_above_filtration(filtration) + def expansion(self, max_dim): """Expands the Simplex_tree containing only its one skeleton until dimension max_dim. @@ -320,7 +400,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 @@ -344,8 +424,9 @@ cdef class SimplexTree: :returns: The Betti numbers ([B0, B1, ..., Bn]). :rtype: list of int - :note: betti_numbers function requires persistence function to be - launched first. + :note: betti_numbers function requires + :func:`persistence()<gudhi.SimplexTree.persistence>` + function to be launched first. """ cdef vector[int] bn_result if self.pcohptr != NULL: @@ -369,7 +450,8 @@ cdef class SimplexTree: :returns: The persistent Betti numbers ([B0, B1, ..., Bn]). :rtype: list of int - :note: persistent_betti_numbers function requires persistence + :note: persistent_betti_numbers function requires + :func:`persistence()<gudhi.SimplexTree.persistence>` function to be launched first. """ cdef vector[int] pbn_result @@ -385,12 +467,13 @@ 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 - :note: intervals_in_dim function requires persistence function to be - launched first. + :note: intervals_in_dim function requires + :func:`persistence()<gudhi.SimplexTree.persistence>` + function to be launched first. """ cdef vector[pair[double,double]] intervals_result if self.pcohptr != NULL: @@ -399,3 +482,23 @@ 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 + :func:`persistence()<gudhi.SimplexTree.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/Makefile.in b/src/cython/doc/Makefile.in deleted file mode 100644 index 526350b3..00000000 --- a/src/cython/doc/Makefile.in +++ /dev/null @@ -1,44 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = @SPHINX_PATH@ -PAPER = -BUILDDIR = _build - -# User-friendly check for sphinx-build -ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) -$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) -endif - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext - -help: - @echo "Please use \`make <target>' where <target> is one of" - @echo " html to make standalone HTML files" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - -clean: - rm -f examples.inc - rm -rf $(BUILDDIR)/* - -# GUDHI specific : Examples.inc is generated with generate_examples.py (and deleted on clean) - -html: - ./generate_examples.py - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." 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/alpha_complex_sum.rst b/src/cython/doc/alpha_complex_sum.rst index a5f6420a..1680a712 100644 --- a/src/cython/doc/alpha_complex_sum.rst +++ b/src/cython/doc/alpha_complex_sum.rst @@ -5,7 +5,7 @@ +----------------------------------------------------------------+------------------------------------------------------------------------+ | .. figure:: | Alpha_complex is a simplicial complex constructed from the finite | -| img/alpha_complex_representation.png | cells of a Delaunay Triangulation. | +| ../../doc/Alpha_complex/alpha_complex_representation.png | cells of a Delaunay Triangulation. | | :alt: Alpha complex representation | | | :figclass: align-center | The filtration value of each simplex is computed as the square of the | | | circumradius of the simplex if the circumsphere is empty (the simplex | diff --git a/src/cython/doc/alpha_complex_user.rst b/src/cython/doc/alpha_complex_user.rst index e8268ef1..db7edd6f 100644 --- a/src/cython/doc/alpha_complex_user.rst +++ b/src/cython/doc/alpha_complex_user.rst @@ -75,7 +75,7 @@ In order to build the alpha complex, first, a Simplex tree is built from the cel (The filtration value is set to NaN, which stands for unknown value): .. figure:: - img/alpha_complex_doc.png + ../../doc/Alpha_complex/alpha_complex_doc.png :figclass: align-center :alt: Simplex tree structure construction example @@ -112,7 +112,7 @@ computes the filtration value of the triangle, and then propagates the filtratio here: .. figure:: - img/alpha_complex_doc_420.png + ../../doc/Alpha_complex/alpha_complex_doc_420.png :figclass: align-center :alt: Filtration value propagation example @@ -142,7 +142,7 @@ Prune above given filtration value ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The simplex tree is pruned from the given maximum alpha squared value (cf. `Simplex_tree::prune_above_filtration()` -int he `C++ version <http://gudhi.gforge.inria.fr/doc/latest/index.html>`_). +in the `C++ version <http://gudhi.gforge.inria.fr/doc/latest/index.html>`_). In the following example, the value is given by the user as argument of the program. @@ -158,7 +158,8 @@ Then, it is asked to display information about the alpha complex: .. testcode:: import gudhi - alpha_complex = gudhi.AlphaComplex(off_file='alphacomplexdoc.off') + alpha_complex = gudhi.AlphaComplex(off_file=gudhi.__root_source_dir__ + \ + '/data/points/alphacomplexdoc.off') simplex_tree = alpha_complex.create_simplex_tree(max_alpha_square=59.0) result_str = 'Alpha complex is of dimension ' + repr(simplex_tree.dimension()) + ' - ' + \ repr(simplex_tree.num_simplices()) + ' simplices - ' + \ @@ -200,6 +201,6 @@ the program output is: CGAL citations ============== -.. bibliography:: how_to_cite_cgal.bib +.. bibliography:: ../../biblio/how_to_cite_cgal.bib :filter: docnames :style: unsrt diff --git a/src/cython/doc/bottleneck_distance_sum.rst b/src/cython/doc/bottleneck_distance_sum.rst index 5c475d0d..030fad9e 100644 --- a/src/cython/doc/bottleneck_distance_sum.rst +++ b/src/cython/doc/bottleneck_distance_sum.rst @@ -5,7 +5,7 @@ +-----------------------------------------------------------------+----------------------------------------------------------------------+ | .. figure:: | Bottleneck distance measures the similarity between two persistence | -| img/perturb_pd.png | diagrams. It's the shortest distance b for which there exists a | +| ../../doc/Bottleneck_distance/perturb_pd.png | diagrams. It's the shortest distance b for which there exists a | | :figclass: align-center | perfect matching between the points of the two diagrams (+ all the | | | diagonal points) such that any couple of matched points are at | | Bottleneck distance is the length of | distance at most b. | diff --git a/src/cython/doc/bottleneck_distance_user.rst b/src/cython/doc/bottleneck_distance_user.rst index 0066992f..7692dce2 100644 --- a/src/cython/doc/bottleneck_distance_user.rst +++ b/src/cython/doc/bottleneck_distance_user.rst @@ -25,7 +25,7 @@ This example computes the bottleneck distance from 2 persistence diagrams: message = "Bottleneck distance approximation=" + '%.2f' % gudhi.bottleneck_distance(diag1, diag2, 0.1) print(message) - message = "Bottleneck distance exact value=" + '%.2f' % gudhi.bottleneck_distance(diag1, diag2, 0) + message = "Bottleneck distance value=" + '%.2f' % gudhi.bottleneck_distance(diag1, diag2) print(message) The output is: @@ -33,4 +33,4 @@ The output is: .. testoutput:: Bottleneck distance approximation=0.81 - Bottleneck distance exact value=0.75 + Bottleneck distance value=0.75 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/conf.py b/src/cython/doc/conf.py index 42bfd59c..19a880d4 100755 --- a/src/cython/doc/conf.py +++ b/src/cython/doc/conf.py @@ -21,7 +21,7 @@ import os #sys.path.insert(0, os.path.abspath('.')) # Path to Gudhi.so from source path -sys.path.insert(0, os.path.abspath('..')) +sys.path.insert(0, os.path.abspath('.')) # -- General configuration ------------------------------------------------ @@ -58,18 +58,20 @@ source_suffix = '.rst' # The master toctree document. master_doc = 'index' +import gudhi + # General information about the project. -project = u'GUDHI' -copyright = u'2016, GUDHI Editorial Board' +project = gudhi.__name__ +copyright = gudhi.__copyright__ # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -version = '2.0' +version = gudhi.__version__ # The full version, including alpha/beta/rc tags. -release = '2.0.0' +#release = '2.0.1-rc1' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -198,81 +200,3 @@ html_static_path = ['_static'] # Output file base name for HTML help builder. htmlhelp_basename = 'GUDHIdoc' - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -#'preamble': '', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - ('index', 'GUDHI.tex', u'GUDHI Documentation', - u'Vincent Rouvreau', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -#latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# If true, show page references after internal links. -#latex_show_pagerefs = False - -# If true, show URL addresses after external links. -#latex_show_urls = False - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_domain_indices = True - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ('index', 'gudhi', u'GUDHI Documentation', - [u'Vincent Rouvreau'], 1) -] - -# If true, show URL addresses after external links. -#man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - ('index', 'GUDHI', u'GUDHI Documentation', - u'Vincent Rouvreau', 'GUDHI', 'One line description of project.', - 'Miscellaneous'), -] - -# Documents to append as an appendix to all manuals. -#texinfo_appendices = [] - -# If false, no module index is generated. -#texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' - -# If true, do not generate a @detailmenu in the "Top" node's menu. -#texinfo_no_detailmenu = False diff --git a/src/cython/doc/cubical_complex_sum.rst b/src/cython/doc/cubical_complex_sum.rst index 3ddf6375..280ad0e0 100644 --- a/src/cython/doc/cubical_complex_sum.rst +++ b/src/cython/doc/cubical_complex_sum.rst @@ -2,14 +2,14 @@ :Author: Pawel Dlotko :Introduced in: GUDHI 2.0.0 :Copyright: GPL v3 ================================================================= =================================== =================================== -+-----------------------------------------------------------------+----------------------------------------------------------------------+ -| .. figure:: | The cubical complex is an example of a structured complex useful in | -| img/Cubical_complex_representation.png | computational mathematics (specially rigorous numerics) and image | -| :alt: Cubical complex representation | analysis. | -| :figclass: align-center | | -| | | -| Cubical complex representation | | -+-----------------------------------------------------------------+----------------------------------------------------------------------+ -| :doc:`cubical_complex_user` | * :doc:`cubical_complex_ref` | -| | * :doc:`periodic_cubical_complex_ref` | -+-----------------------------------------------------------------+----------------------------------------------------------------------+ ++--------------------------------------------------------------------------+----------------------------------------------------------------------+ +| .. figure:: | The cubical complex is an example of a structured complex useful in | +| ../../doc/Bitmap_cubical_complex/Cubical_complex_representation.png | computational mathematics (specially rigorous numerics) and image | +| :alt: Cubical complex representation | analysis. | +| :figclass: align-center | | +| | | +| Cubical complex representation | | ++--------------------------------------------------------------------------+----------------------------------------------------------------------+ +| :doc:`cubical_complex_user` | * :doc:`cubical_complex_ref` | +| | * :doc:`periodic_cubical_complex_ref` | ++--------------------------------------------------------------------------+----------------------------------------------------------------------+ diff --git a/src/cython/doc/cubical_complex_user.rst b/src/cython/doc/cubical_complex_user.rst index 344b9554..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,14 +95,15 @@ 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:: cubicalcomplexdoc.txt +.. centered:: ../../data/bitmap/cubicalcomplexdoc.txt .. testcode:: import gudhi - cubical_complex = gudhi.CubicalComplex(perseus_file='cubicalcomplexdoc.txt') + cubical_complex = gudhi.CubicalComplex(perseus_file=gudhi.__root_source_dir__ + \ + '/data/bitmap/cubicalcomplexdoc.txt') result_str = 'Cubical complex is of dimension ' + repr(cubical_complex.dimension()) + ' - ' + \ repr(cubical_complex.num_simplices()) + ' simplices.' print(result_str) @@ -127,16 +128,17 @@ 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:: 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. .. testcode:: import gudhi - periodic_cc = gudhi.PeriodicCubicalComplex(perseus_file='periodiccubicalcomplexdoc.txt') + periodic_cc = gudhi.PeriodicCubicalComplex(perseus_file=gudhi.__root_source_dir__ + \ + '/data/bitmap/periodiccubicalcomplexdoc.txt') result_str = 'Periodic cubical complex is of dimension ' + repr(periodic_cc.dimension()) + ' - ' + \ repr(periodic_cc.num_simplices()) + ' simplices.' print(result_str) @@ -155,6 +157,6 @@ End user programs are available in cython/example/ folder. Bibliography ============ -.. bibliography:: bibliography.bib +.. bibliography:: ../../bibliography.bib :filter: docnames :style: unsrt diff --git a/src/cython/doc/examples.rst b/src/cython/doc/examples.rst index a89e0596..1e596e18 100644 --- a/src/cython/doc/examples.rst +++ b/src/cython/doc/examples.rst @@ -1,4 +1,21 @@ Examples ######## -.. include:: examples.inc +.. only:: builder_html + + * :download:`rips_complex_from_points_example.py <../example/rips_complex_from_points_example.py>` + * :download:`alpha_complex_from_points_example.py <../example/alpha_complex_from_points_example.py>` + * :download:`simplex_tree_example.py <../example/simplex_tree_example.py>` + * :download:`alpha_rips_persistence_bottleneck_distance.py <../example/alpha_rips_persistence_bottleneck_distance.py>` + * :download:`tangential_complex_plain_homology_from_off_file_example.py <../example/tangential_complex_plain_homology_from_off_file_example.py>` + * :download:`alpha_complex_diagram_persistence_from_off_file_example.py <../example/alpha_complex_diagram_persistence_from_off_file_example.py>` + * :download:`periodic_cubical_complex_barcode_persistence_from_perseus_file_example.py <../example/periodic_cubical_complex_barcode_persistence_from_perseus_file_example.py>` + * :download:`bottleneck_basic_example.py <../example/bottleneck_basic_example.py>` + * :download:`gudhi_graphical_tools_example.py <../example/gudhi_graphical_tools_example.py>` + * :download:`witness_complex_from_nearest_landmark_table.py <../example/witness_complex_from_nearest_landmark_table.py>` + * :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>` + * :download:`rips_complex_diagram_persistence_from_off_file_example.py <../example/rips_complex_diagram_persistence_from_off_file_example.py>` + * :download:`rips_complex_diagram_persistence_from_distance_matrix_file_example.py <../example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py>` + * :download:`rips_persistence_diagram.py <../example/rips_persistence_diagram.py>` + * :download:`random_cubical_complex_persistence_example.py <../example/random_cubical_complex_persistence_example.py>` 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/generate_examples.py b/src/cython/doc/generate_examples.py deleted file mode 100755 index d64d506c..00000000 --- a/src/cython/doc/generate_examples.py +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env python - -from os import listdir - -"""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" - -""" -generate_examples.py generates examples.inc to be included in examples.rst. -Refer to Makefile and make.bat to see if it is correctly launched. -""" - -output_file = open('examples.inc','w') - -output_file.write('.. only:: builder_html\n\n') - -for file in listdir('../example/'): - output_file.write(" * :download:`" + file + " <../example/" + file + ">`\n") - -output_file.close() diff --git a/src/cython/doc/index.rst b/src/cython/doc/index.rst index f6d10567..3945d72a 100644 --- a/src/cython/doc/index.rst +++ b/src/cython/doc/index.rst @@ -1,8 +1,10 @@ GUDHI Python module documentation ################################# -.. image:: img/Gudhi_banner.png - :align: center +.. figure:: + ../../doc/common/Gudhi_banner.png + :alt: Gudhi banner + :figclass: align-center Introduction ************ @@ -81,6 +83,6 @@ Persistence graphical tools Bibliography ************ -.. bibliography:: bibliography.bib +.. bibliography:: ../../biblio/bibliography.bib :filter: docnames :style: unsrt 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/doc/make.bat.in b/src/cython/doc/make.bat.in deleted file mode 100644 index ff1a6d56..00000000 --- a/src/cython/doc/make.bat.in +++ /dev/null @@ -1,67 +0,0 @@ -@ECHO OFF
-
-REM Command file for Sphinx documentation
-
-if "%SPHINXBUILD%" == "" (
- set SPHINXBUILD=@SPHINX_PATH@
-)
-set BUILDDIR=_build
-set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
-set I18NSPHINXOPTS=%SPHINXOPTS% .
-if NOT "%PAPER%" == "" (
- set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
- set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
-)
-
-if "%1" == "" goto help
-
-if "%1" == "help" (
- :help
- echo.Please use `make ^<target^>` where ^<target^> is one of
- echo. html to make standalone HTML files
- echo. doctest to run all doctests embedded in the documentation if enabled
- goto end
-)
-
-if "%1" == "clean" (
- del examples.inc
- for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
- del /q /s %BUILDDIR%\*
- goto end
-)
-
-
-%SPHINXBUILD% 2> nul
-if errorlevel 9009 (
- echo.
- echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
- echo.installed, then set the SPHINXBUILD environment variable to point
- echo.to the full path of the 'sphinx-build' executable. Alternatively you
- echo.may add the Sphinx directory to PATH.
- echo.
- echo.If you don't have Sphinx installed, grab it from
- echo.http://sphinx-doc.org/
- exit /b 1
-)
-
-:: GUDHI specific : Examples.inc is generated with generate_examples.py (and deleted on clean)
-
-if "%1" == "html" (
- generate_examples.py
- %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The HTML pages are in %BUILDDIR%/html.
- goto end
-)
-
-if "%1" == "doctest" (
- %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
- if errorlevel 1 exit /b 1
- echo.
- echo.Testing of doctests in the sources finished, look at the ^
-results in %BUILDDIR%/doctest/output.txt.
- goto end
-)
-
-:end
diff --git a/src/cython/doc/persistence_graphical_tools_user.rst b/src/cython/doc/persistence_graphical_tools_user.rst index cae18323..9033331f 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 ----------------------------- @@ -30,17 +32,22 @@ This function can display the persistence result as a barcode: import gudhi - periodic_cc = gudhi.PeriodicCubicalComplex(perseus_file='3d_torus.txt') + periodic_cc = gudhi.PeriodicCubicalComplex(perseus_file=gudhi.__root_source_dir__ + \ + '/data/bitmap/3d_torus.txt') diag = periodic_cc.persistence() - gudhi.plot_persistence_barcode(diag) + plt = gudhi.plot_persistence_barcode(diag) + plt.show() .. plot:: import gudhi - periodic_cc = gudhi.PeriodicCubicalComplex(perseus_file='3d_torus.txt') + periodic_cc = gudhi.PeriodicCubicalComplex(perseus_file=gudhi.__root_source_dir__ + \ + '/data/bitmap/3d_torus.txt') diag = periodic_cc.persistence() - gudhi.plot_persistence_barcode(diag) + print("diag = ", diag) + plt = gudhi.plot_persistence_barcode(diag) + plt.show() Show persistence as a diagram ----------------------------- @@ -51,16 +58,20 @@ 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=gudhi.__root_source_dir__ + \ + '/data/points/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=gudhi.__root_source_dir__ + \ + '/data/points/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/persistent_cohomology_sum.rst b/src/cython/doc/persistent_cohomology_sum.rst index d1f79cb4..a26df1dc 100644 --- a/src/cython/doc/persistent_cohomology_sum.rst +++ b/src/cython/doc/persistent_cohomology_sum.rst @@ -4,7 +4,7 @@ +-----------------------------------------------------------------+-----------------------------------------------------------------------+ | .. figure:: | The theory of homology consists in attaching to a topological space | -| img/3DTorus_poch.png | a sequence of (homology) groups, capturing global topological | +| ../../doc/Persistent_cohomology/3DTorus_poch.png | a sequence of (homology) groups, capturing global topological | | :figclass: align-center | features like connected components, holes, cavities, etc. Persistent | | | homology studies the evolution -- birth, life and death -- of these | | Rips Persistent Cohomology on a 3D | features when the topological space is changing. Consequently, the | diff --git a/src/cython/doc/persistent_cohomology_user.rst b/src/cython/doc/persistent_cohomology_user.rst index 72f1a7f7..bf90c163 100644 --- a/src/cython/doc/persistent_cohomology_user.rst +++ b/src/cython/doc/persistent_cohomology_user.rst @@ -109,6 +109,6 @@ We provide several example files: run these examples with -h for details on thei Bibliography ============ -.. bibliography:: bibliography.bib +.. bibliography:: ../../biblio/bibliography.bib :filter: docnames :style: unsrt diff --git a/src/cython/doc/pyplots/barcode_persistence.py b/src/cython/doc/pyplots/barcode_persistence.py index c06ac5a7..de33d506 100755 --- a/src/cython/doc/pyplots/barcode_persistence.py +++ b/src/cython/doc/pyplots/barcode_persistence.py @@ -1,5 +1,7 @@ import gudhi -periodic_cc = gudhi.PeriodicCubicalComplex(perseus_file='../3d_torus.txt') +periodic_cc = gudhi.PeriodicCubicalComplex(perseus_file=gudhi.__root_source_dir__ + \ + '/data/bitmap/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..c2fbf801 100755 --- a/src/cython/doc/pyplots/diagram_persistence.py +++ b/src/cython/doc/pyplots/diagram_persistence.py @@ -1,5 +1,8 @@ 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=gudhi.__root_source_dir__ + \ + '/data/points/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.py index 44b94169..84d158cf 100755 --- a/src/cython/doc/python3-sphinx-build +++ b/src/cython/doc/python3-sphinx-build.py @@ -1,4 +1,4 @@ -#!/usr/bin/python3 +#!/usr/bin/env python3 """ 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/doc/rips_complex_sum.rst b/src/cython/doc/rips_complex_sum.rst index 2b65fc19..5616bfa9 100644 --- a/src/cython/doc/rips_complex_sum.rst +++ b/src/cython/doc/rips_complex_sum.rst @@ -4,7 +4,7 @@ +----------------------------------------------------------------+------------------------------------------------------------------------+ | .. figure:: | Rips complex is a simplicial complex constructed from a one skeleton | -| img/rips_complex_representation.png | graph. | +| ../../doc/Rips_complex/rips_complex_representation.png | graph. | | :figclass: align-center | | | | The filtration value of each edge is computed from a user-given | | Rips complex representation | distance function and is inserted until a user-given threshold | diff --git a/src/cython/doc/rips_complex_user.rst b/src/cython/doc/rips_complex_user.rst index f9760976..96ba9944 100644 --- a/src/cython/doc/rips_complex_user.rst +++ b/src/cython/doc/rips_complex_user.rst @@ -26,7 +26,7 @@ structure, and then expands the simplicial complex when required. Vertex name correspond to the index of the point in the given range (aka. the point cloud). .. figure:: - img/rips_complex_representation.png + ../../doc/Rips_complex/rips_complex_representation.png :align: center Rips-complex one skeleton graph representation @@ -101,7 +101,8 @@ Finally, it is asked to display information about the Rips complex. .. testcode:: import gudhi - rips_complex = gudhi.RipsComplex(off_file='alphacomplexdoc.off', max_edge_length=12.0) + rips_complex = gudhi.RipsComplex(off_file=gudhi.__root_source_dir__ + \ + '/data/points/alphacomplexdoc.off', max_edge_length=12.0) simplex_tree = rips_complex.create_simplex_tree(max_dimension=1) result_str = 'Rips complex is of dimension ' + repr(simplex_tree.dimension()) + ' - ' + \ repr(simplex_tree.num_simplices()) + ' simplices - ' + \ @@ -205,7 +206,8 @@ Finally, it is asked to display information about the Rips complex. .. testcode:: import gudhi - rips_complex = gudhi.RipsComplex(csv_file='full_square_distance_matrix.csv', max_edge_length=12.0) + rips_complex = gudhi.RipsComplex(csv_file=gudhi.__root_source_dir__ + \ + '/data/distance_matrix/full_square_distance_matrix.csv', max_edge_length=12.0) simplex_tree = rips_complex.create_simplex_tree(max_dimension=1) result_str = 'Rips complex is of dimension ' + repr(simplex_tree.dimension()) + ' - ' + \ repr(simplex_tree.num_simplices()) + ' simplices - ' + \ diff --git a/src/cython/doc/simplex_tree_sum.rst b/src/cython/doc/simplex_tree_sum.rst index 3174fb62..fb0e54c1 100644 --- a/src/cython/doc/simplex_tree_sum.rst +++ b/src/cython/doc/simplex_tree_sum.rst @@ -4,7 +4,7 @@ +----------------------------------------------------------------+------------------------------------------------------------------------+ | .. figure:: | The simplex tree is an efficient and flexible data structure for | -| img/Simplex_tree_representation.png | representing general (filtered) simplicial complexes. | +| ../../doc/Simplex_tree/Simplex_tree_representation.png | representing general (filtered) simplicial complexes. | | :alt: Simplex tree representation | | | :figclass: align-center | The data structure is described in | | | :cite:`boissonnatmariasimplextreealgorithmica` | diff --git a/src/cython/doc/tangential_complex_sum.rst b/src/cython/doc/tangential_complex_sum.rst index 2b05bc10..72b4d7ba 100644 --- a/src/cython/doc/tangential_complex_sum.rst +++ b/src/cython/doc/tangential_complex_sum.rst @@ -5,10 +5,10 @@ +----------------------------------------------------------------+------------------------------------------------------------------------+ | .. figure:: | A Tangential Delaunay complex is a simplicial complex designed to | -| img/tc_examples.png | reconstruct a :math:`k`-dimensional manifold embedded in :math:`d`- | +| ../../doc/Tangential_complex/tc_examples.png | reconstruct a :math:`k`-dimensional manifold embedded in :math:`d`- | | :figclass: align-center | dimensional Euclidean space. The input is a point sample coming from | | | an unknown manifold. The running time depends only linearly on the | -| **Tangential complex representation** | extrinsic dimension :math:`d` and exponentially on the intrinsic | +| Tangential complex representation | extrinsic dimension :math:`d` and exponentially on the intrinsic | | | dimension :math:`k`. | +----------------------------------------------------------------+------------------------------------------------------------------------+ | :doc:`tangential_complex_user` | :doc:`tangential_complex_ref` | diff --git a/src/cython/doc/tangential_complex_user.rst b/src/cython/doc/tangential_complex_user.rst index 03f9fea6..efa6d7ce 100644 --- a/src/cython/doc/tangential_complex_user.rst +++ b/src/cython/doc/tangential_complex_user.rst @@ -22,7 +22,7 @@ Let us start with the description of the Tangential complex of a simple example, with :math:`k = 1` and :math:`d = 2`. The input data is 4 points :math:`P` located on a curve embedded in 2D. -.. figure:: img/tc_example_01.png +.. figure:: ../../doc/Tangential_complex/tc_example_01.png :alt: The input :figclass: align-center @@ -31,7 +31,7 @@ example, with :math:`k = 1` and :math:`d = 2`. The input data is 4 points For each point :math:`p`, estimate its tangent subspace :math:`T_p` (e.g. using PCA). -.. figure:: img/tc_example_02.png +.. figure:: ../../doc/Tangential_complex/tc_example_02.png :alt: The estimated normals :figclass: align-center @@ -42,7 +42,7 @@ Let us add the Voronoi diagram of the points in orange. For each point :math:`p`, construct its star in the Delaunay triangulation of :math:`P` restricted to :math:`T_p`. -.. figure:: img/tc_example_03.png +.. figure:: ../../doc/Tangential_complex/tc_example_03.png :alt: The Voronoi diagram :figclass: align-center @@ -62,7 +62,7 @@ simplex is not in the star of all its vertices. Let us take the same example. -.. figure:: img/tc_example_07_before.png +.. figure:: ../../doc/Tangential_complex/tc_example_07_before.png :alt: Before :figclass: align-center @@ -70,7 +70,7 @@ Let us take the same example. Let us slightly move the tangent subspace :math:`T_q` -.. figure:: img/tc_example_07_after.png +.. figure:: ../../doc/Tangential_complex/tc_example_07_after.png :alt: After :figclass: align-center @@ -79,7 +79,7 @@ Let us slightly move the tangent subspace :math:`T_q` Now, the star of :math:`Q` contains :math:`QP`, but the star of :math:`P` does not contain :math:`QP`. We have an inconsistency. -.. figure:: img/tc_example_08.png +.. figure:: ../../doc/Tangential_complex/tc_example_08.png :alt: After :figclass: align-center @@ -122,7 +122,8 @@ This example builds the Tangential complex of point set read in an OFF file. .. testcode:: import gudhi - tc = gudhi.TangentialComplex(off_file='alphacomplexdoc.off') + tc = gudhi.TangentialComplex(off_file=gudhi.__root_source_dir__ + \ + '/data/points/alphacomplexdoc.off') result_str = 'Tangential contains ' + repr(tc.num_simplices()) + \ ' simplices - ' + repr(tc.num_vertices()) + ' vertices.' print(result_str) @@ -190,6 +191,6 @@ The output is: Bibliography ============ -.. bibliography:: bibliography.bib +.. bibliography:: ../../biblio/bibliography.bib :filter: docnames :style: unsrt diff --git a/src/cython/doc/witness_complex_sum.rst b/src/cython/doc/witness_complex_sum.rst index b65522ba..a8a126a0 100644 --- a/src/cython/doc/witness_complex_sum.rst +++ b/src/cython/doc/witness_complex_sum.rst @@ -3,15 +3,17 @@ :Euclidean version requires: CGAL :math:`\geq` 4.6.0 Eigen3 ================================================================= =================================== =================================== -+-----------------------------------------------------------------+----------------------------------------------------------------------+ -| .. image:: | Witness complex :math:`Wit(W,L)` is a simplicial complex defined on | -| img/Witness_complex_representation.png | two sets of points in :math:`\mathbb{R}^D`. | -| | | -| | The data structure is described in | -| | :cite:`boissonnatmariasimplextreealgorithmica`. | -+-----------------------------------------------------------------+----------------------------------------------------------------------+ -| :doc:`witness_complex_user` | * :doc:`witness_complex_ref` | -| | * :doc:`strong_witness_complex_ref` | -| | * :doc:`euclidean_witness_complex_ref` | -| | * :doc:`euclidean_strong_witness_complex_ref` | -+-----------------------------------------------------------------+----------------------------------------------------------------------+ ++-------------------------------------------------------------------+----------------------------------------------------------------------+ +| .. figure:: | Witness complex :math:`Wit(W,L)` is a simplicial complex defined on | +| ../../doc/Witness_complex/Witness_complex_representation.png | two sets of points in :math:`\mathbb{R}^D`. | +| :alt: Witness complex representation | | +| :figclass: align-center | The data structure is described in | +| | :cite:`boissonnatmariasimplextreealgorithmica`. | +| | | +| Witness complex representation | | ++-------------------------------------------------------------------+----------------------------------------------------------------------+ +| :doc:`witness_complex_user` | * :doc:`witness_complex_ref` | +| | * :doc:`strong_witness_complex_ref` | +| | * :doc:`euclidean_witness_complex_ref` | +| | * :doc:`euclidean_strong_witness_complex_ref` | ++-------------------------------------------------------------------+----------------------------------------------------------------------+ diff --git a/src/cython/doc/witness_complex_user.rst b/src/cython/doc/witness_complex_user.rst index aa9cbb2c..29413269 100644 --- a/src/cython/doc/witness_complex_user.rst +++ b/src/cython/doc/witness_complex_user.rst @@ -33,7 +33,7 @@ Both definitions can be relaxed by a real value :math:`\alpha`: which leads to definitions of **weak relaxed witness complex** (or just relaxed witness complex for short) and **strong relaxed witness complex** respectively. -.. figure:: img/swit.svg +.. figure:: ../../doc/Witness_complex/swit.svg :alt: Strongly witnessed simplex :figclass: align-center @@ -126,6 +126,6 @@ Here is an example of constructing a strong witness complex filtration and compu Bibliography ============ -.. bibliography:: bibliography.bib +.. bibliography:: ../../biblio/bibliography.bib :filter: docnames :style: unsrt 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/persistence_representations_diagrams_example.py b/src/cython/example/persistence_representations_diagrams_example.py deleted file mode 100755 index bd7452a0..00000000 --- a/src/cython/example/persistence_representations_diagrams_example.py +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env python - -import gudhi -import argparse - -"""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): Pawel Dlotko - - Copyright (C) 2017 Swansea University - - 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__ = "Pawel Dlotko" -__copyright__ = "Copyright (C) 2017 Swansea University" -__license__ = "GPL v3" - -print("#####################################################################") -print("Persistence representations diagrams example") - - -parser = argparse.ArgumentParser(description='Statistics of persistence diagrams from file ', - epilog='Example: ' - 'example/persistence_representations_diagrams_example.py ' - '-f file_with_diagram -d 1') -parser.add_argument("-f", "--file", type=str, required=True) -parser.add_argument("-d", "--dimension", type=int, default=0) - -args = parser.parse_args() - -print "Here are the parameters of the program: ",args.file," , " ,args.dimension - -p = gudhi.PersistenceIntervals(None,args.dimension,args.file); -min_max_ = p.get_x_range(); -print "Birth-death range : ", min_max_ - -dominant_ten_intervals_length = p.length_of_dominant_intervals(10) -print "Length of ten dominant intervals : ", dominant_ten_intervals_length - -ten_dominant_intervals = p.dominant_intervals(10); -print "Here are the dominant intervals : " , ten_dominant_intervals - -histogram = p.histogram_of_lengths(10); -print "Here is the histogram of barcode's length : ", histogram - -cumulative_histogram = p.cumulative_histogram_of_lengths(10) -print "Cumulative histogram : " ,cumulative_histogram - -char_funct_diag = p.characteristic_function_of_diagram(min_max_[0], min_max_[1],None) -print "Characteristic function of diagram : ",char_funct_diag - -cumul_char_funct_diag = p.cumulative_characteristic_function_of_diagram(min_max_[0], min_max_[1],None) -print "Cumulative characteristic function of diagram : ",cumul_char_funct_diag - -pbns = p.compute_persistent_betti_numbers() -print "Persistence Betti numbers ", pbns diff --git a/src/cython/example/persistence_representations_landscapes_example.py b/src/cython/example/persistence_representations_landscapes_example.py deleted file mode 100755 index 94b68225..00000000 --- a/src/cython/example/persistence_representations_landscapes_example.py +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env python - -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): Pawel Dlotko - - Copyright (C) 2017 Swansea University - - 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__ = "Pawel Dlotko" -__copyright__ = "Copyright (C) 2017 Swansea University" -__license__ = "GPL v3" - -print("#####################################################################") -print("Persistence representations landscapes example") - -persistence1 = [(1,2),(6,8),(0,4),(3,8)] -persistence2 = [(2,9),(1,6),(3,5),(6,10)] - - -#create two persistence landscapes based on persistence1 and persistence2: -l1 = gudhi.PersistenceLandscapes(vector_of_intervals=persistence1, dimension=3) -l2 = gudhi.PersistenceLandscapes(vector_of_intervals=persistence2) - -#This is how to compute integral of landscapes: -print "Integral of the first landscape : ", l1.compute_integral_of_landscape() -print "Integral of the second landscape : ", l2.compute_integral_of_landscape() - -#here are the maxima of the functions: -print "Maximum of l1 : ", l1.compute_maximum() -print "Maximum of l2 : ", l2.compute_maximum() - -#here are the norms of landscapes: -print "L^1 Norm of l1 : ", l1.compute_norm_of_landscape(1.) -print "L^1 Norm of l2 : ", l2.compute_norm_of_landscape(1.) - -#here is the average of landscapes: -average = gudhi.PersistenceLandscapes() -average.compute_average(to_average=[l1, l2]) - -#here is the distance of landscapes: -print "Distance : ", l1.distance(average,1) - -#here is the scalar product of landscapes: -print "Scalar product : ", l1.compute_scalar_product(l2) diff --git a/src/cython/example/persistence_representations_landscapes_on_grid_example.py b/src/cython/example/persistence_representations_landscapes_on_grid_example.py deleted file mode 100755 index 60b0e873..00000000 --- a/src/cython/example/persistence_representations_landscapes_on_grid_example.py +++ /dev/null @@ -1,110 +0,0 @@ -#!/usr/bin/env python - -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): Pawel Dlotko - - Copyright (C) 2017 Swansea University - - 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__ = "Pawel Dlotko" -__copyright__ = "Copyright (C) 2017 Swansea University" -__license__ = "GPL v3" - -print("#####################################################################") -print("Persistence representations landscapes on a grid example") - -persistence1 = [(1, 2),(6, 8),(0, 4),(3, 8)] -persistence2 = [(2, 9),(1, 6),(3, 5),(6, 10)] - -#create two persistence landscapes based on persistence1 and persistence2: -l1 = PersistenceLandscapeOnGrid(persistence1, 0, 11, 20) -l2 = PersistenceLandscapeOnGrid(persistence2, 0, 11, 20) - -#This is how to compute integral of landscapes: -print "Integral of the first landscape : " , l1.compute_integral_of_landscape() -print "Integral of the second landscape : " , l2.compute_integral_of_landscape() - -#here are the maxima of the functions: -print "Maximum of l1 : " , l1.compute_maximum() -print "Maximum of l2 : " , l2.compute_maximum() - -#here are the norms of landscapes: -print "L^1 Norm of l1 : " , l1.compute_norm_of_landscape(1.) -print "L^1 Norm of l2 : " , l2.compute_norm_of_landscape(1.) - -#here is the average of landscapes: -average = PersistenceLandscapeOnGrid(); -average.compute_average(to_average=[l1, l2]); - - -#here is the distance of landscapes: -print "Distance : " , l1.distance(l2) - -#here is the scalar product of landscapes: -print "Scalar product : " , l1.compute_scalar_product(l2) - - - - - - - - - - - - - - - - - - -persistence1 = [(1,2),(6,8),(0,4),(3,8)] -persistence2 = [(2,9),(1,6),(3,5),(6,10)] - - -#create two persistence landscapes based on persistence1 and persistence2: -l1 = gudhi.PersistenceLandscapes(vector_of_intervals=persistence1, dimension=3) -l2 = gudhi.PersistenceLandscapes(vector_of_intervals=persistence2) - -#This is how to compute integral of landscapes: -print "Integral of the first landscape : ", l1.compute_integral_of_landscape() -print "Integral of the second landscape : ", l2.compute_integral_of_landscape() - -#here are the maxima of the functions: -print "Maximum of l1 : ", l1.compute_maximum() -print "Maximum of l2 : ", l2.compute_maximum() - -#here are the norms of landscapes: -print "L^1 Norm of l1 : ", l1.compute_norm_of_landscape(1.) -print "L^1 Norm of l2 : ", l2.compute_norm_of_landscape(1.) - -#here is the average of landscapes: -average = gudhi.PersistenceLandscapes() -average.compute_average(to_average=[l1, l2]) - -#here is the distance of landscapes: -print "Distance : ", l1.distance(average,1) - -#here is the scalar product of landscapes: -print "Scalar product : ", l1.compute_scalar_product(l2) 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/simplex_tree_example.py b/src/cython/example/simplex_tree_example.py index 3af20fcf..51a60e73 100755 --- a/src/cython/example/simplex_tree_example.py +++ b/src/cython/example/simplex_tree_example.py @@ -48,11 +48,8 @@ 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.set_filtration(4.0) st.initialize_filtration() print("filtration=", st.get_filtration()) print("filtration[1, 2]=", st.filtration([1, 2])) 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 53f09c4b..a8dd9f80 100644 --- a/src/cython/gudhi.pyx.in +++ b/src/cython/gudhi.pyx.in @@ -23,18 +23,19 @@ __author__ = "Vincent Rouvreau" __copyright__ = "Copyright (C) 2016 INRIA" __license__ = "GPL v3" +__version__ = "@GUDHI_VERSION@" +# This variable is used by doctest to find files +__root_source_dir__ = "@CMAKE_SOURCE_DIR@" -include "cython/off_reader.pyx" -include "cython/simplex_tree.pyx" -include "cython/rips_complex.pyx" -include "cython/cubical_complex.pyx" -include "cython/periodic_cubical_complex.pyx" -include "cython/persistence_graphical_tools.py" -include "cython/witness_complex.pyx" -include "cython/strong_witness_complex.pyx" -include "cython/persistence_representations_intervals.pyx" -include "cython/persistence_representations_landscapes.pyx" -#include "cython/persistence_representations_landscapes_on_grid.pyx" +include '@CMAKE_CURRENT_SOURCE_DIR@/cython/off_reader.pyx' +include '@CMAKE_CURRENT_SOURCE_DIR@/cython/simplex_tree.pyx' +include '@CMAKE_CURRENT_SOURCE_DIR@/cython/rips_complex.pyx' +include '@CMAKE_CURRENT_SOURCE_DIR@/cython/cubical_complex.pyx' +include '@CMAKE_CURRENT_SOURCE_DIR@/cython/periodic_cubical_complex.pyx' +include '@CMAKE_CURRENT_SOURCE_DIR@/cython/persistence_graphical_tools.py' +include '@CMAKE_CURRENT_SOURCE_DIR@/cython/reader_utils.pyx' +include '@CMAKE_CURRENT_SOURCE_DIR@/cython/witness_complex.pyx' +include '@CMAKE_CURRENT_SOURCE_DIR@/cython/strong_witness_complex.pyx' @GUDHI_CYTHON_ALPHA_COMPLEX@ @GUDHI_CYTHON_EUCLIDEAN_WITNESS_COMPLEX@ @GUDHI_CYTHON_SUBSAMPLING@ diff --git a/src/cython/include/Cubical_complex_interface.h b/src/cython/include/Cubical_complex_interface.h index 7c0148f1..fad92c2c 100644 --- a/src/cython/include/Cubical_complex_interface.h +++ b/src/cython/include/Cubical_complex_interface.h @@ -43,6 +43,12 @@ class Cubical_complex_interface : public Bitmap_cubical_complex<CubicalComplexOp : Bitmap_cubical_complex<CubicalComplexOptions>(dimensions, top_dimensional_cells) { } + Cubical_complex_interface(const std::vector<unsigned>& dimensions, + const std::vector<double>& top_dimensional_cells, + const std::vector<bool>& periodic_dimensions) + : Bitmap_cubical_complex<CubicalComplexOptions>(dimensions, top_dimensional_cells, periodic_dimensions) { + } + Cubical_complex_interface(const std::string& perseus_file) : Bitmap_cubical_complex<CubicalComplexOptions>(perseus_file.c_str()) { } diff --git a/src/cython/include/PSSK_interface.h b/src/cython/include/PSSK_interface.h deleted file mode 100644 index 3b2d336a..00000000 --- a/src/cython/include/PSSK_interface.h +++ /dev/null @@ -1,63 +0,0 @@ -/* 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): Pawel Dlotko - * - * Copyright (C) 2017 Swansea University - * - * 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 PSSK_INTERFACE_H_ -#define PSSK_INTERFACE__H_ - - -#include <gudhi/PSSK.h> - - -namespace Gudhi { -namespace Persistence_representations { - -/** -* This is a version of a representation presented in https://arxiv.org/abs/1412.6821 -* In that paper the authors are using the representation just to compute kernel. Over here, we extend the usability by -*far. -* Note that the version presented here is not exact, since we are discretizing the kernel. -* The only difference with respect to the original class is the method of creation. We have full (square) image, and for -*every point (p,q), we add a kernel at (p,q) and the negative kernel -* at (q,p) -**/ - -class PSSK_interface : public PSSK { - public: - PSSK_interface(){} - - PSSK_interface(const std::vector<std::pair<double, double> >& interval, - std::vector<std::vector<double> > filter = create_Gaussian_filter(5, 1), size_t number_of_pixels = 1000, - double min_ = -1, double max_ = -1) - : - PSSK(interval,filter,number_of_pixels,min_,max_){} - - PSSK_interface(const char* filename, std::vector<std::vector<double> > filter = create_Gaussian_filter(5, 1), - size_t number_of_pixels = 1000, double min_ = -1, double max_ = -1, - unsigned dimension = std::numeric_limits<unsigned>::max()) - :PSSK(filename,filter,number_of_pixels,min_,max_,dimension){} - -}; - -} // namespace Persistence_representations -} // namespace Gudhi - -#endif // PSSK_INTERFACE__H_ diff --git a/src/cython/include/Persistence_heat_maps_interface.h b/src/cython/include/Persistence_heat_maps_interface.h deleted file mode 100644 index fe565313..00000000 --- a/src/cython/include/Persistence_heat_maps_interface.h +++ /dev/null @@ -1,156 +0,0 @@ -/* 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): Pawel Dlotko - * - * Copyright (C) 2016 INRIA (France) - * - * 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 PERSISTENCE_HEAT_MAPS_INTERFACE_H_ -#define PERSISTENCE_HEAT_MAPS_INTERFACE_H_ - -// gudhi include -#include <gudhi/read_persistence_from_file.h> -#include <gudhi/common_persistence_representations.h> - -// standard include -#include <vector> -#include <sstream> -#include <iostream> -#include <cmath> -#include <limits> -#include <algorithm> -#include <utility> -#include <string> -#include <functional> - -namespace Gudhi { -namespace Persistence_representations { - -class Persistence_heat_maps_interface : public Persistence_heat_maps { - public: - - Persistence_heat_maps_interface():Persistence_heat_maps(){} - - - Persistence_heat_maps_interface(const std::vector<std::pair<double, double> >& interval, - std::vector<std::vector<double> > filter = create_Gaussian_filter(5, 1), - bool erase_below_diagonal = false, size_t number_of_pixels = 1000, - double min_ = std::numeric_limits<double>::max(), - double max_ = std::numeric_limits<double>::max()): - Persistence_heat_maps(interval,filter,erase_below_diagonal,number_of_pixels,min_max_){} - - - Persistence_heat_maps_interface(const char* filename, std::vector<std::vector<double> > filter = create_Gaussian_filter(5, 1), - bool erase_below_diagonal = false, size_t number_of_pixels = 1000, - double min_ = std::numeric_limits<double>::max(), - double max_ = std::numeric_limits<double>::max(), - unsigned dimension = std::numeric_limits<unsigned>::max()): - Persistence_heat_maps(filename,filter,erase_below_diagonal,number_of_pixels,min_,max_,dimension){} - - void compute_mean_interface(const std::vector<Persistence_heat_maps*>& maps) - { - this->compute_mean(maps); - } - - void compute_median_interface(const std::vector<Persistence_heat_maps*>& maps) - { - this->compute_median(maps); - } - - void compute_percentage_of_active_interface(const std::vector<Persistence_heat_maps*>& maps, size_t cutoff = 1) - { - this->compute_percentage_of_active(maps,cutoff); - } - - void print_to_file_interface(const char* filename) const - { - this->print_to_file(filename); - } - - void load_from_file_interface(const char* filename) - { - this->load_from_file( filename ); - } - - inline bool check_if_the_same_interface(const Persistence_heat_maps& second) const - { - return this->check_if_the_same( second ); - } - - inline double get_min_interface() const - { - return this->get_min(); - } - - inline double get_max_interface() const - { - return this->get_max(); - } - - std::vector<double> vectorize_interface(int number_of_function) const - { - return this->vectorize(number_of_function); - } - - size_t number_of_vectorize_functions_interface() const - { - return this->number_of_vectorize_functions(); - } - - double project_to_R_interface(int number_of_function) const - { - return this->project_to_R( number_of_function ); - } - - size_t number_of_projections_to_R_interface() const - { - return this->number_of_projections_to_R(); - } - - double distance_interface(const Persistence_heat_maps& second_, double power = 1) const - { - return this->distance( second, power ); - } - - void compute_average_interface(const std::vector<Persistence_heat_maps*>& to_average) - { - this->compute_average( to_average ); - } - - double compute_scalar_product_interface(const Persistence_heat_maps& second_) const - { - return this->compute_scalar_product( second_ ); - } - - std::pair<double, double> get_x_range_interface() const - { - return this->get_x_range(); - } - - std::pair<double, double> get_y_range_interface() const - { - return this->get_y_range(); - } - -}; - - -} // namespace Persistence_representations -} // namespace Gudhi - -#endif // PERSISTENCE_HEAT_MAPS_INTERFACE_H_ diff --git a/src/cython/include/Persistence_intervals_interface.h b/src/cython/include/Persistence_intervals_interface.h deleted file mode 100644 index c3a3dde7..00000000 --- a/src/cython/include/Persistence_intervals_interface.h +++ /dev/null @@ -1,59 +0,0 @@ -/* 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): Pawel Dlotko - * - * Copyright (C) 2017 Swansea University - * - * 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_PERSISTENCE_REPRESENTATIONS_INTERVALS_ -#define INCLUDE_PERSISTENCE_REPRESENTATIONS_INTERVALS_ - -#include <gudhi/Persistence_intervals.h> - -#include <iostream> -#include <vector> -#include <string> - -namespace Gudhi { - -//But if we want to have the same names of classes in C++ and cyton side we ned this interface, because othervise we will have a name conflict. And we want to have the same names on the -//C++ and python side for various reasonc (clarity, documentantions etc.). -//If the C++ class we inherid from are template class, we are inherid from concretization, for instance Persistence_intervals<double>. -//Also in this class, we create an interface functions that will be used in the python side. That will allow to have the same name of the functions in the C++ and python side. - -namespace Persistence_representations { - -class Persistence_intervals_interface : public Persistence_intervals -{ - public: - Persistence_intervals_interface(const char* filename, unsigned dimension = std::numeric_limits<unsigned>::max()) - : Persistence_intervals(filename, dimension) { - } - - Persistence_intervals_interface(const std::vector<std::pair<double, double> >& intervals) - : Persistence_intervals(intervals) { - } - -}; - -} // namespace Persistence_representations - -} // namespace Gudhi - -#endif // INCLUDE_PERSISTENCE_REPRESENTATIONS_DIAGRAMS_ - diff --git a/src/cython/include/Persistence_intervals_with_distances_interface.h b/src/cython/include/Persistence_intervals_with_distances_interface.h deleted file mode 100644 index 05caa14a..00000000 --- a/src/cython/include/Persistence_intervals_with_distances_interface.h +++ /dev/null @@ -1,43 +0,0 @@ -/* This file is part of the Gudhi hiLibrary. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * - * Author(s): Pawel Dlotko - * - * Copyright (C) 2017 Swansea University - * - * 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 PERSISTENCE_INTERVALS_WITH_DISTANCES_INTERFACE_H_ -#define PERSISTENCE_INTERVALS_WITH_DISTANCES_INTERFACE_H_ - -#include <gudhi/Persistence_intervals_with_distances.h> - -namespace Gudhi { -namespace Persistence_representations { - -class Persistence_intervals_with_distances_interface : public Persistence_intervals_with_distances { - public: - double distance_interface(const Persistence_intervals_with_distances& second, double power = std::numeric_limits<double>::max(), - double tolerance = 0) const - { - return this->distance( second, power, tolerance ); - } -}; - -} // namespace Persistence_representations -} // namespace Gudhi - -#endif // PERSISTENCE_INTERVALS_WITH_DISTANCES_INTERFACE_H_ diff --git a/src/cython/include/Persistence_landscape_interface.h b/src/cython/include/Persistence_landscape_interface.h deleted file mode 100644 index 339031d4..00000000 --- a/src/cython/include/Persistence_landscape_interface.h +++ /dev/null @@ -1,200 +0,0 @@ -/* 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): Pawel Dlotko - * - * Copyright (C) 2017 Swansea University - * - * 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 PERSISTENCE_LANDSCAPE_INTERFACE_H_ -#define PERSISTENCE_LANDSCAPE_INTERFACE_H_ - -#include <gudhi/Persistence_landscape.h> - -namespace Gudhi { -namespace Persistence_representations { - - -class Persistence_landscape_interface : public Persistence_landscape -{ - public: - Persistence_landscape_interface():Persistence_landscape(){} - - Persistence_landscape_interface(const std::vector<std::pair<double, double> >& p, size_t number_of_levels = std::numeric_limits<size_t>::max() ):Persistence_landscape(p,number_of_levels){} - - Persistence_landscape_interface(const char* filename, size_t dimension = std::numeric_limits<unsigned>::max() , size_t number_of_levels = std::numeric_limits<size_t>::max() ):Persistence_landscape(filename,dimension,number_of_levels){} - - //**************** - static Persistence_landscape_interface* construct_from_file( const char* filename, size_t dimension = std::numeric_limits<unsigned>::max() , size_t number_of_levels = std::numeric_limits<size_t>::max() ) - { - Persistence_landscape_interface* result = new Persistence_landscape_interface(filename,dimension,number_of_levels); - return result; - } - static Persistence_landscape_interface* construct_from_vector_of_pairs( const std::vector<std::pair<double, double> >& p, size_t number_of_levels = std::numeric_limits<size_t>::max() ) - { - Persistence_landscape_interface* result = new Persistence_landscape_interface(p,number_of_levels); - return result; - } - - //**************** - - - Persistence_landscape_interface* new_abs_interface() - { - return (Persistence_landscape_interface*)this->new_abs(); - } - - void new_compute_average(const std::vector<Persistence_landscape_interface*>& to_average) - { - std::vector<Persistence_landscape*> to_average_new; - to_average_new.reserve( to_average.size() ); - for ( size_t i = 0 ; i != to_average.size() ; ++i ) - { - to_average_new.push_back( (Persistence_landscape*)to_average[i] ); - } - this->compute_average(to_average_new); - } - -/* - void load_landscape_from_file_interface(const char* filename) - { - this->load_landscape_from_file(filename); - } - - - void print_to_file_interface(const char* filename) const - { - this->print_to_file(filename); - } - - - double compute_integral_of_landscape_interface() const - { - return this->compute_integral_of_landscape(); - } - - - double compute_integral_of_a_level_of_a_landscape_interface(size_t level) const - { - return this->compute_integral_of_a_level_of_a_landscape(level); - } - - - double compute_integral_of_landscape_interface(double p) const - { - return this->compute_integral_of_landscape(p); - } - - - double compute_value_at_a_given_point_interface(unsigned level, double x) const - { - return this->compute_value_at_a_given_point(level,x); - } - - - double compute_maximum_interface() const - { - return this->compute_maximum(); - } - - - double compute_minimum_interface() const - { - return this->compute_minimum(); - } - - - - double compute_norm_of_landscape_interface(double i) - { - return this->compute_norm_of_landscape(i); - } - - - Persistence_landscape abs_interface() - { - return this->abs(); - } - - size_t size_interface() const - { - return this->size(); - } - - double find_max_interface(unsigned lambda) const - { - return this->find_max(); - } - - friend double compute_inner_product_interface(const Persistence_landscape& l1, const Persistence_landscape& l2) - { - return this->compute_inner_product(l1,l2); - } - - double project_to_R_interface(int number_of_function) const - { - return this->project_to_R(number_of_function); - } - - - size_t number_of_projections_to_R_interface() const - { - return this->number_of_projections_to_R(); - } - - - std::vector<double> vectorize_interface(int number_of_function) const - { - return this->vectorize( number_of_function ); - } - - - size_t number_of_vectorize_function_interface() const - { - return this->number_of_vectorize_function(); - } - - - void compute_average_interface(const std::vector<Persistence_landscape*>& to_average) - { - return this->compute_average(to_average); - } - - - double distance_interface(const Persistence_landscape& second, double power = 1) - { - return this->distance( second, power ); - } - - - double compute_scalar_product_interface(const Persistence_landscape& second) const - { - return this->compute_scalar_product( second ); - } - - - std::pair<double, double> get_y_range_interface(size_t level = 0) const - { - return this->get_y_range( level ); - } - */ -}; - -} // namespace Persistence_representations -} // namespace Gudhi - -#endif // PERSISTENCE_LANDSCAPE_INTERFACE_H_ diff --git a/src/cython/include/Persistence_landscape_on_grid_interface.h b/src/cython/include/Persistence_landscape_on_grid_interface.h deleted file mode 100644 index c8ba9f76..00000000 --- a/src/cython/include/Persistence_landscape_on_grid_interface.h +++ /dev/null @@ -1,207 +0,0 @@ -/* 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): Pawel Dlotko - * - * Copyright (C) 2017 Swansea University - * - * 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 PERSISTENCE_LANDSCAPE_ON_GRID_INTERFACE_H_ -#define PERSISTENCE_LANDSCAPE_ON_GRID_INTERFACE_H_ - -#include <gudhi/Persistence_landscape_on_grid.h> - -namespace Gudhi { -namespace Persistence_representations { - - -class Persistence_landscape_on_grid_interface : public Persistence_landscape_on_grid -{ - public: - Persistence_landscape_on_grid_interface():Persistence_landscape_on_grid(){} - - Persistence_landscape_on_grid_interface(const std::vector<std::pair<double, double> >& p, double grid_min_, double grid_max_, - size_t number_of_points_):Persistence_landscape_on_grid(p, grid_min_, grid_max_,number_of_points_){} - - - Persistence_landscape_on_grid_interface(const std::vector<std::pair<double, double> >& p, double grid_min_, double grid_max_, - size_t number_of_points_, unsigned number_of_levels_of_landscape): - Persistence_landscape_on_grid(p, grid_min_, grid_max_,number_of_points_, number_of_levels_of_landscape){} - - - Persistence_landscape_on_grid_interface(const char* filename, double grid_min_, double grid_max_, size_t number_of_points_, - unsigned number_of_levels_of_landscape, uint16_t dimension_ = std::numeric_limits<uint16_t>::max()): - Persistence_landscape_on_grid(filename, grid_min_, grid_max_, number_of_points_, number_of_levels_of_landscape, dimension_ ){} - - - Persistence_landscape_on_grid_interface(const char* filename, double grid_min_, double grid_max_, size_t number_of_points_, - uint16_t dimension_ = std::numeric_limits<uint16_t>::max()):Persistence_landscape_on_grid(filename,grid_min_,grid_max_,number_of_points_,dimension_ ){} - - - Persistence_landscape_on_grid_interface(const char* filename, size_t number_of_points, unsigned number_of_levels_of_landscape, uint16_t dimension = std::numeric_limits<uint16_t>::max()): - Persistence_landscape_on_grid(filename,number_of_points,number_of_levels_of_landscape,dimension){} - - - Persistence_landscape_on_grid_interface(const char* filename, size_t number_of_points, uint16_t dimension = std::numeric_limits<uint16_t>::max()): - Persistence_landscape_on_grid(filename,number_of_points,dimension){} - - - Persistence_landscape_on_grid_interface* new_abs_interface() - { - return (Persistence_landscape_on_grid_interface*)this->new_abs(); - } - - void new_compute_average(const std::vector<Persistence_landscape_on_grid_interface*>& to_average) - { - std::vector<Persistence_landscape_on_grid*> to_average_new; - to_average_new.reserve( to_average.size() ); - for ( size_t i = 0 ; i != to_average.size() ; ++i ) - { - to_average_new.push_back( (Persistence_landscape_on_grid*)to_average[i] ); - } - this->compute_average(to_average_new); - } - - -/* - void load_landscape_from_file_interface(const char* filename) - { - this->load_landscape_from_file(filename); - } - - - void print_to_file_interface(const char* filename) const - { - this->print_to_file(filename); - } - - - double compute_integral_of_landscape_interface() const - { - return this->compute_integral_of_landscape(); - } - - - double compute_integral_of_a_level_of_a_landscape_interface(size_t level) const - { - return this->compute_integral_of_a_level_of_a_landscape(level); - } - - - double compute_integral_of_landscape_interface(double p) const - { - return this->compute_integral_of_landscape(p); - } - - - double compute_value_at_a_given_point_interface(unsigned level, double x) const - { - return this->compute_value_at_a_given_point(level,x); - } - - - double compute_maximum_interface() const - { - return this->compute_maximum(); - } - - - double compute_minimum_interface() const - { - return this->compute_minimum(); - } - - - double compute_norm_of_landscape_interface(double i) - { - return this->compute_norm_of_landscape(i); - } - - - Persistence_landscape abs_interface() - { - return this->abs(); - } - - size_t size_interface() const - { - return this->size(); - } - - double find_max_interface(unsigned lambda) const - { - return this->find_max(); - } - - friend double compute_inner_product_interface(const Persistence_landscape& l1, const Persistence_landscape& l2) - { - return this->compute_inner_product(l1,l2); - } - - double project_to_R_interface(int number_of_function) const - { - return this->project_to_R(number_of_function); - } - - - size_t number_of_projections_to_R_interface() const - { - return this->number_of_projections_to_R(); - } - - - std::vector<double> vectorize_interface(int number_of_function) const - { - return this->vectorize( number_of_function ); - } - - - size_t number_of_vectorize_function_interface() const - { - return this->number_of_vectorize_function(); - } - - - void compute_average_interface(const std::vector<Persistence_landscape*>& to_average) - { - return this->compute_average(to_average); - } - - - double distance_interface(const Persistence_landscape& second, double power = 1) - { - return this->distance( second, power ); - } - - - double compute_scalar_product_interface(const Persistence_landscape& second) const - { - return this->compute_scalar_product( second ); - } - - - std::pair<double, double> get_y_range_interface(size_t level = 0) const - { - return this->get_y_range( level ); - } - */ -}; - -} // namespace Persistence_representations -} // namespace Gudhi - -#endif // PERSISTENCE_LANDSCAPE_ON_GRID_INTERFACE_H_ diff --git a/src/cython/include/Persistence_vectors_interface.h b/src/cython/include/Persistence_vectors_interface.h deleted file mode 100644 index 3fc482d7..00000000 --- a/src/cython/include/Persistence_vectors_interface.h +++ /dev/null @@ -1,121 +0,0 @@ -/* 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): Pawel Dlotko - * - * Copyright (C) 2016 INRIA (France) - * - * 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 PERSISTENCE_VECTORS_INTERFACE_H_ -#define PERSISTENCE_VECTORS_INTERFACE_H_ - -// gudhi include -#include <gudhi/persistence_vectors.h> -s -namespace Gudhi { -namespace Persistence_representations { - - - -template <typename F> -class Vector_distances_in_diagram_interface : Vector_distances_in_diagram<Euclidean_distance> { - public: - Vector_distances_in_diagram_interface():Vector_distances_in_diagram(){} - - Vector_distances_in_diagram_interface(const std::vector<std::pair<double, double> >& intervals, size_t where_to_cut): - Vector_distances_in_diagram(intervals,where_to_cut){} - - Vector_distances_in_diagram_interface(const char* filename, size_t where_to_cut, - unsigned dimension = std::numeric_limits<unsigned>::max()): - Vector_distances_in_diagram_interface(filename,where_to_cut,dimension){} - - inline double vector_in_position_interface(size_t position) const - { - return this->vector_in_position(position): - } - - inline size_t size_interface() const - { - return this->size(); - } - - void write_to_file_interface(const char* filename) const - { - this->write_to_file( filename ); - } - - void print_to_file_interface(const char* filename) const - { - this->print_to_file(filename); - } - - void load_from_file_interface(const char* filename) - { - this->load_from_file(filename); - } - - double project_to_R_interface(int number_of_function) const - { - return this->project_to_R(number_of_function); - } - - size_t number_of_projections_to_R_interface() const - { - return this->number_of_projections_to_R(); - } - - std::vector<double> vectorize_interface(int number_of_function) const - { - return this->vectorize(number_of_function); - } - - size_t number_of_vectorize_functions_interface() const - { - return this->number_of_vectorize_functions(); - } - - void compute_average_interface(const std::vector<Vector_distances_in_diagram*>& to_average) - { - this->compute_average(to_average); - } - - double distance_interface(const Vector_distances_in_diagram& second, double power = 1) const - { - return this->distance(second,power); - } - - double compute_scalar_product_interface(const Vector_distances_in_diagram& second) const - { - return this->compute_scalar_product(second); - } - - std::pair<double, double> get_x_range_interface() const - { - return this->get_x_range(); - } - - std::pair<double, double> get_y_range_interface() const - { - return this->get_y_range(); - } - -}; - -} // namespace Persistence_representations -} // namespace Gudhi - -#endif // PERSISTENCE_VECTORS_INTERFACE_H_ diff --git a/src/cython/include/Reader_utils_interface.h b/src/cython/include/Reader_utils_interface.h new file mode 100644 index 00000000..8ec34f61 --- /dev/null +++ b/src/cython/include/Reader_utils_interface.h @@ -0,0 +1,56 @@ +/* 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> +#include <map> +#include <utility> // for pair<> + +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..02985727 100644 --- a/src/cython/include/Rips_complex_interface.h +++ b/src/cython/include/Rips_complex_interface.h @@ -66,11 +66,15 @@ 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); } } + ~Rips_complex_interface() { + delete rips_complex_; + } + void create_simplex_tree(Simplex_tree_interface<>* simplex_tree, int dim_max) { rips_complex_->create_complex(*simplex_tree, dim_max); simplex_tree->initialize_filtration(); diff --git a/src/cython/include/Simplex_tree_interface.h b/src/cython/include/Simplex_tree_interface.h index 09e7e992..54a4f824 100644 --- a/src/cython/include/Simplex_tree_interface.h +++ b/src/cython/include/Simplex_tree_interface.h @@ -52,6 +52,10 @@ class Simplex_tree_interface : public Simplex_tree<SimplexTreeOptions> { return (Base::find(vh) != Base::null_simplex()); } + void assign_simplex_filtration(const Simplex& vh, Filtration_value filtration) { + Base::assign_filtration(Base::find(vh), filtration); + } + bool insert(const Simplex& simplex, Filtration_value filtration = 0) { Insertion_result result = Base::insert_simplex_and_subfaces(simplex, filtration); return (result.second); 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/setup.py.in b/src/cython/setup.py.in index c1a1717a..fefa36bb 100644 --- a/src/cython/setup.py.in +++ b/src/cython/setup.py.in @@ -29,7 +29,7 @@ __license__ = "GPL v3" gudhi = Extension( "gudhi", - sources = ['gudhi.pyx',], + sources = ['@CMAKE_CURRENT_BINARY_DIR@/gudhi.pyx',], language = 'c++', extra_compile_args=[@GUDHI_CYTHON_EXTRA_COMPILE_ARGS@], extra_link_args=[@GUDHI_CYTHON_EXTRA_LINK_ARGS@], 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_persistence_representations_intervals.py b/src/cython/test/test_persistence_representations_intervals.py deleted file mode 100755 index a8f3686e..00000000 --- a/src/cython/test/test_persistence_representations_intervals.py +++ /dev/null @@ -1,87 +0,0 @@ -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): Pawel Dlotko - - Copyright (C) 2017 Swansea University - - 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__ = "Pawel Dlotko" -__copyright__ = "Copyright (C) 2017 Swansea University" -__license__ = "GPL v3" - -epsilon = 0.0000005; - -def test_check_min_max_function(): - p = gudhi.PersistenceIntervals(None,None,"data/file_with_diagram") - min_max_ = p.get_x_range() - assert fabs(min_max_[0] - 0.0290362) <= epsilon - assert fabs(min_max_[1] - 0.994537) <= epsilon - -def test_check_length_of_dominant_intervals(): - p = gudhi.PersistenceIntervals(None,None,"data/file_with_diagram") - dominant_ten_intervals_length = p.length_of_dominant_intervals(10) - dominant_intervals_length_ = [0.862625,0.800893,0.762061,0.756501,0.729367,0.718177,0.708395,0.702844,0.700468,0.622177] - assert dominant_ten_intervals_length == dominant_intervals_length_ - - -def test_check_dominant_intervals(): - p = gudhi.PersistenceIntervals(None,None,"data/file_with_diagram"); - ten_dominant_intervals = p.dominant_intervals(10); - templ = [ (0.114718, 0.977343) , (0.133638, 0.93453) , (0.104599, 0.866659) , (0.149798, 0.906299), (0.247352, 0.976719) , (0.192675, 0.910852) , (0.191836, 0.900231) , (0.284998, 0.987842) , (0.294069, 0.994537), (0.267421, 0.889597)] - assert fabs(ten_dominant_intervals - templ) <= epsilon - - -def test_check_histogram_of_lengths(): - p = gudhi.PersistenceIntervals(None,None,"data/file_with_diagram") - histogram = p.histogram_of_lengths(10); - template_histogram = [10,5,3,4,4,3,6,1,7,1,1] - assert fabs(histogram - template_histogram) <= epsilon - - -def test_check_cumulative_histograms_of_lengths(): - p = gudhi.PersistenceIntervals(None,None,"data/file_with_diagram") - cumulative_histogram = p.cumulative_histogram_of_lengths(10) - template_cumulative_histogram = [10,15,18,22,26,29,35,36,43,44,45] - assert fabs(cumulative_histogram - template_cumulative_histogram) <= epsilon - - -def test_check_characteristic_function_of_diagram(): - p = gudhi.PersistenceIntervals(None,None,"data/file_with_diagram") - min_max_ = p.get_x_range(); - char_funct_diag = p.characteristic_function_of_diagram(min_max_[0], min_max_[1]); - template_char_funct_diag = [0.370665,0.84058,1.24649,1.3664,1.34032,1.31904,1.14076,0.991259,0.800714,0.0676303] - assert fabs(char_funct_diag - template_char_funct_diag) <= 0.0001 - - -def test_check_cumulative_characteristic_function_of_diagram(): - p = gudhi.PersistenceIntervals(None,None,"data/file_with_diagram") - min_max_ = p.get_x_range() - cumul_char_funct_diag = p.cumulative_characteristic_function_of_diagram(min_max_.first, min_max_.second,None); - template_char_funct_diag_cumul = [0.370665,1.21125,2.45774,3.82414,5.16446,6.4835,7.62426,8.61552,9.41623,9.48386] - assert fabs(cumul_char_funct_diag - template_char_funct_diag_cumul) <= 0.0001 - - -def test_check_compute_persistent_betti_numbers(): - p = gudhi.PersistenceIntervals(None,None,"data/file_with_diagram") - pbns = [(0.0290362, 1),(0.0307676, 2),(0.0366312, 3),(0.0544614, 4),(0.0920033, 5),(0.104599, 6),(0.114718, 7),(0.117379, 8),(0.123493, 9),(0.133638, 10)(0.137798, 9),(0.149798, 10),(0.155421, 11),(0.158443, 12)(0.176956, 13),(0.183234, 12),(0.191069, 13),(0.191333, 14),(0.191836, 15),(0.192675, 16),(0.208564, 17),(0.218425, 18),(0.219902, 17),(0.23233, 16),(0.234558, 17),(0.237166, 16),(0.247352, 17),(0.267421, 18),(0.268093, 19),(0.278734, 18),(0.284722, 19),(0.284998, 20),(0.294069, 21),(0.306293, 22),(0.322361, 21),(0.323152, 22),(0.371021, 23),(0.372395, 24),(0.387744, 25),(0.435537, 26),(0.462911, 25),(0.483569, 26),(0.489209, 25),(0.517115, 24),(0.522197, 23),(0.532665, 22),(0.545262, 23),(0.587227, 22),(0.593036, 23),(0.602647, 24),(0.605044, 25),(0.621962, 24),(0.629449, 23),(0.636719, 22),(0.64957, 21),(0.650781, 22),(0.654951, 23),(0.683489, 24),(0.687172, 23),(0.69703, 22),(0.701174, 21),(0.717623, 22),(0.722023, 21),(0.722298, 20),(0.725347, 19),(0.73071, 18),(0.758355, 17),(0.770913, 18),(0.790833, 17),(0.821211, 16),(0.849305, 17),(0.853669, 16),(0.866659, 15),(0.872896, 16),(0.889597, 15),(0.900231, 14),(0.903847, 13),(0.906299, 12),(0.910852, 11),(0.93453, 10),(0.944757, 9),(0.947812, 8),(0.959154, 7),(0.975654, 6),(0.976719, 5),(0.977343, 4),(0.980129, 3),(0.987842, 2),(0.990127, 1),(0.994537, 0)] - pbns_new = p.compute_persistent_betti_numbers(); - assert fabs(pbns - pbns_new) <= epsilon - - diff --git a/src/cython/test/test_persistence_representations_landscapes.py b/src/cython/test/test_persistence_representations_landscapes.py deleted file mode 100755 index f5e6f351..00000000 --- a/src/cython/test/test_persistence_representations_landscapes.py +++ /dev/null @@ -1,139 +0,0 @@ -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): Pawel Dlotko - - Copyright (C) 2017 Swansea University - - 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__ = "Pawel Dlotko" -__copyright__ = "Copyright (C) 2017 Swansea University" -__license__ = "GPL v3" - -epsilon = 0.0000005; - -def test_check_construction_of_landscape(): - p = gudhi.Persistence_landscape("data/file_with_diagram",0) - q = gudhi.Persistence_landscape() - q.load_landscape_from_file("data/file_with_landscape_from_file_with_diagram") - assert p == q - - -def test_check_construction_of_landscape_form_gudhi_style_file(): - p = gudhi.Persistence_landscape("data/persistence_file_with_four_entries_per_line", 1) - q = gudhi.Persistence_landscape() - q.load_landscape_from_file("data/persistence_file_with_four_entries_per_line_landscape"); - assert p == q; - -def test_check_computations_of_integrals(): - p = gudhi.Persistence_landscape("data/file_with_diagram",0) - integral = p.compute_integral_of_landscape() - assert fabs(integral - 2.34992) <= 0.00001 - - -def test_check_computations_of_integrals_for_each_level_separatelly(): - diag = read_persistence_intervals_in_one_dimension_from_file("data/file_with_diagram"); - p = gudhi.Persistence_landscape(diag) - integrals_for_different_levels = [0.216432,0.204763,0.188793,0.178856,0.163142,0.155015,0.143046,0.133765,0.123531,0.117393,0.111269,0.104283,0.0941308,0.0811208,0.0679001,0.0580801,0.0489647,0.0407936,0.0342599,0.02896,0.0239881,0.0171792,0.0071511,0.00462067,0.00229033,0.000195296] - for lv in range(0, len(integrals_for_different_levels)): - integral = p.compute_integral_of_a_level_of_a_landscape(lv); - assert fabs(integral - integrals_fir_different_levels[lv]) <= 0.00001 - -def test_check_computations_of_integrals_of_powers_of_landscape(): - diag = read_persistence_intervals_in_one_dimension_from_file("data/file_with_diagram") - p = gudhi.Persistence_landscape(diag) - integrals_fir_different_powers = [17.1692,2.34992,0.49857,0.126405,0.0355235] - for power in range(0,5): - integral = p.compute_integral_of_landscape(power) - assert fabs(integral - integrals_fir_different_powers[power]) <= 0.00005 - - -def test_check_computations_of_values_on_different_points(): - diag = read_persistence_intervals_in_one_dimension_from_file("data/file_with_diagram") - p = gudhi.Persistence_landscape(diag); - assert fabs(p.compute_value_at_a_given_point(1, 0.0)) <= 0.00001 - assert fabs(p.compute_value_at_a_given_point(1, 0.1) - 0.0692324) <= 0.00001 - assert fabs(p.compute_value_at_a_given_point(1, 0.2) - 0.163369) <= 0.00001 - assert fabs(p.compute_value_at_a_given_point(1, 0.3) - 0.217115) <= 0.00001 - assert fabs(p.compute_value_at_a_given_point(2, 0.0)) <= 0.00001 - assert fabs(p.compute_value_at_a_given_point(2, 0.1) - 0.0633688) <= 0.00001 - assert fabs(p.compute_value_at_a_given_point(2, 0.2) - 0.122361) <= 0.00001 - assert fabs(p.compute_value_at_a_given_point(2, 0.3) - 0.195401) <= 0.00001 - assert fabs(p.compute_value_at_a_given_point(3, 0.0)) <= 0.00001 - assert fabs(p.compute_value_at_a_given_point(3, 0.1) - 0.0455386) <= 0.00001 - assert fabs(p.compute_value_at_a_given_point(3, 0.2) - 0.0954012) <= 0.00001 - assert fabs(p.compute_value_at_a_given_point(3, 0.3) - 0.185282) <= 0.00001 - - -def test_check_computations_of_maxima_and_norms(): - diag = read_persistence_intervals_in_one_dimension_from_file("data/file_with_diagram") - p = gudhi.Persistence_landscape(diag) - second = gudhi.Persistence_landscape() - second.load_landscape_from_file("data/file_with_landscape_from_file_with_diagram_1") - sum_ = gudhi.Persistence_landscape() - sum_ = p + second; - assert fabs(p.compute_maximum() - 0.431313) <= 0.00001 - assert fabs(p.compute_norm_of_landscape(1) - 2.34992) <= 0.00001 - assert fabs(p.compute_norm_of_landscape(2) - 0.706095) <= 0.00001 - assert fabs(p.compute_norm_of_landscape(3) - 0.501867) <= 0.00001 - assert fabs(compute_distance_of_landscapes(p, sum_, 1) - 27.9323) <= 0.00005 - assert fabs(compute_distance_of_landscapes(p, sum_, 2) - 2.35199) <= 0.00001 - - - -def test_check_default_parameters_of_distances(): - diag = read_persistence_intervals_in_one_dimension_from_file("data/file_with_diagram") - p = gudhi.Persistence_landscape(diag) - diag1 = read_persistence_intervals_in_one_dimension_from_file("data/file_with_diagram_1") - q = gudhi.Persistence_landscape(diag1) - dist_numeric_limit_max = p.distance(q, sys.float_info.max); - dist_infinity = p.distance(q, sys.float_info.max); - assert dist_numeric_limit_max == dist_infinity - - -def test_check_computations_of_averages(): - diag = read_persistence_intervals_in_one_dimension_from_file("data/file_with_diagram") - p = gudhi.Persistence_landscape(diag) - diag2 = read_persistence_intervals_in_one_dimension_from_file("data/file_with_diagram_1") - q = gudhi.Persistence_landscape(diag2) - av = gudhi.Persistence_landscape() - av.compute_average({p, q}) - template_average = Persistence_landscape() - template_averagetemplate_average.load_landscape_from_file("data/average") - assert template_average == av - - -def test_check_computations_of_distances(): - diag = read_persistence_intervals_in_one_dimension_from_file("data/file_with_diagram") - p = gudhi.Persistence_landscape(diag) - diag2 = read_persistence_intervals_in_one_dimension_from_file("data/file_with_diagram_1") - q = Persistence_landscape(diag2) - assert fabs(p.distance(q) - 25.5824) <= 0.00005 - assert fabs(p.distance(q, 2) - 2.12636) <= 0.00001 - assert fabs(p.distance(q, sys.float_info.max) - 0.359068) <= 0.00001 - - -def test_check_computations_of_scalar_product(): - diag = read_persistence_intervals_in_one_dimension_from_file("data/file_with_diagram") - p = gudhi.Persistence_landscape(diag) - diag2 = read_persistence_intervals_in_one_dimension_from_file("data/file_with_diagram_1") - q = Persistence_landscape(diag2) - assert fabs(p.compute_scalar_product(q) - 0.754498) <= 0.00001 - diff --git a/src/cython/test/test_persistence_representations_landscapes_on_grid.py b/src/cython/test/test_persistence_representations_landscapes_on_grid.py deleted file mode 100755 index 7a1f2b49..00000000 --- a/src/cython/test/test_persistence_representations_landscapes_on_grid.py +++ /dev/null @@ -1,120 +0,0 @@ -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): Pawel Dlotko - - Copyright (C) 2017 Swansea University - - 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__ = "Pawel Dlotko" -__copyright__ = "Copyright (C) 2017 Swansea University" -__license__ = "GPL v3" - -epsilon = 0.0000005; - - - -def test_check_construction_of_landscape: - l = gudhi.PersistenceLandscapeOnGrid("data/file_with_diagram_1", 100,sys.maxsize) - l.print_to_file("landscape_from_file_with_diagram_1") - g = gudhi.PersistenceLandscapeOnGrid() - g.load_landscape_from_file("landscape_from_file_with_diagram_1") - assert l == g - - -def test_check_construction_of_landscape_using_only_ten_levels: - number = 10 - l = gudhi.PersistenceLandscapeOnGrid("data/file_with_diagram_1", 100, number) - g = gudhi.PersistenceLandscapeOnGrid("data/file_with_diagram_1", 100, sys.maxsize) - for level in range(0,number): - v1 = l.vectorize(level) - v2 = g.vectorize(level) - assert v1 == v2 - -def test_check_computations_of_integrals: - p = gudhi.PersistenceLandscapeOnGrid("data/file_with_diagram_1", 100, sys.maxsize) - integral = p.compute_integral_of_landscape() - assert fabs(integral - 27.343) <= 0.00005 - -def test_check_computations_of_integrals_for_each_level_separatelly: - p = gudhi.PersistenceLandscapeOnGrid("data/file_with_diagram_1", 100, sys.maxsize) - integrals_fir_different_levels = [0.241168,0.239276,0.237882,0.235193,0.230115,0.227626,0.226132.0.223643,0.221651,0.220556,0.21727,0.215976,0.213685,0.211993,0.2102,0.208707,0.207014,0.205122,0.204226,0.202633] - for level in range(0,len(integrals_fir_different_levels)) - integral = p.compute_integral_of_landscape(level); - assert fabs(integral - integrals_fir_different_levels[level]) <= 0.00005 - -def test_check_computations_of_integrals_of_powers_of_landscape: - p = gudhi.PersistenceLandscapeOnGrid("data/file_with_diagram_1", 100, sys.maxsize) - integrals_fir_different_powers = [0.241168,0.239276,0.237882,0.235193,0.23011] - for power in range(0:5): - integral = p.compute_integral_of_landscape(power) - assert fabs(integral - integrals_fir_different_powers[power]) <= 0.00001 - -def test_check_computations_of_values_on_different_points: - p = gudhi.PersistenceLandscapeOnGrid("data/file_with_diagram_1", 100, sys.maxsize) - results_level_0 = [0.00997867,0.0521921,0.104312,0.156432,0.208552,0.260672,0.312792,0.364912,0.417032,0.429237] - results_level_10 = [7.21433e-05,0.0422135,0.0943335,0.146453,0.198573,0.240715,0.272877,0.324997,0.359232,0.379344] - double x = 0.0012321; - double dx = 0.05212; - for i in range(0,10): - assert almost_equal(p.compute_value_at_a_given_point(0, x), results_level_0[i])); - assert almost_equal(p.compute_value_at_a_given_point(10, x), results_level_10[i])); - x += dx; - -def test_check_computations_of_maxima_and_norms: - p = gudhi.PersistenceLandscapeOnGrid("data/file_with_diagram_1", 0., 1., 100) - second = gudhi.PersistenceLandscapeOnGrid("data/file_with_diagram_2", 0., 1., 100) - assert fabs(p.compute_maximum() - 0.46) <= 0.00001 - assert fabs(p.compute_norm_of_landscape(1) - 27.3373) <= 0.00001 - assert fabs(p.compute_norm_of_landscape(2) - 1.84143) <= 0.00001 - assert fabs(p.compute_norm_of_landscape(3) - 0.927067) <= 0.00001 - -def test_check_default_parameters_of_distances: - diag = read_persistence_intervals_in_dimension("data/file_with_diagram") - p = gudhi.PersistenceLandscapeOnGrid(diag, 0., 1., 100) - diag1 = read_persistence_intervals_in_dimension("data/file_with_diagram_1") - q = gudhi.PersistenceLandscapeOnGrid(diag1, 0., 1., 100) - dist_numeric_limit_max = p.distance(q, sys.maxsize); - dist_infinity = p.distance(q, sys.maxsize); - assert dist_numeric_limit_max == dist_infinity - -def test_check_computations_of_averages: - p = gudhi.PersistenceLandscapeOnGrid("data/file_with_diagram", 0., 1., 100) - q = gudhi.PersistenceLandscapeOnGrid("data/file_with_diagram_1", 0., 1., 100) - av = gudhi.PersistenceLandscapeOnGrid() - av.compute_average({&p, &q) - - template_average = gudhi.PersistenceLandscapeOnGrid() - template_average.load_landscape_from_file("data/average_on_a_grid") - assert template_average == av - - -def test_check_computations_of_distances: - p = gudhi.PersistenceLandscapeOnGrid("data/file_with_diagram", 0., 1., 10000) - q = gudhi.PersistenceLandscapeOnGrid("data/file_with_diagram_1", 0., 1., 10000) - assert fabs(p.distance(q) - 25.5779) <= 0.00005 - assert fabs(p.distance(q, 2) - 2.04891) <= 0.00001 - assert fabs(p.distance(q, sys.maxsize) - 0.359) <= 0.00001 - - -def test_check_computations_of_scalar_product: - p = gudhi.PersistenceLandscapeOnGrid("data/file_with_diagram", 0., 1., 10000) - q = gudhi.PersistenceLandscapeOnGrid("data/file_with_diagram_1", 0., 1., 10000) - assert almost_equal(p.compute_scalar_product(q), 0.754367) 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)]} diff --git a/src/cython/test/test_simplex_tree.py b/src/cython/test/test_simplex_tree.py index 3ae537e3..6dec5d94 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 @@ -53,7 +57,6 @@ def test_insertion(): assert st.find([2, 3]) == False # filtration test - st.set_filtration(5.0) st.initialize_filtration() assert st.filtration([0, 1, 2]) == 4.0 assert st.filtration([0, 2]) == 4.0 @@ -87,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] @@ -130,3 +134,30 @@ def test_expansion(): ([1, 2], 0.5), ([0, 1, 2], 0.5), ([1, 2, 3], 0.5), ([5], 0.6), ([6], 0.6), ([5, 6], 0.6), ([4], 0.7), ([2, 4], 0.7), ([0, 3], 0.8), ([0, 1, 3], 0.8), ([0, 2, 3], 0.8), ([0, 1, 2, 3], 0.8), ([4, 6], 0.9), ([3, 6], 1.0)] + +def test_automatic_dimension(): + st = SimplexTree() + assert st.__is_defined() == True + assert st.__is_persistence_defined() == False + + # insert test + assert st.insert([0,1,3], filtration=0.5) == True + assert st.insert([0,1,2], filtration=1.) == True + + assert st.num_vertices() == 4 + assert st.num_simplices() == 11 + + assert st.dimension() == 2 + assert st.upper_bound_dimension() == 2 + + assert st.prune_above_filtration(0.6) == True + assert st.dimension() == 2 + assert st.upper_bound_dimension() == 2 + + st.assign_filtration([0, 1, 3], 0.7) + assert st.filtration([0, 1, 3]) == 0.7 + + st.remove_maximal_simplex([0, 1, 3]) + assert st.upper_bound_dimension() == 2 + assert st.dimension() == 1 + assert st.upper_bound_dimension() == 1 |