diff options
Diffstat (limited to 'src/cython')
-rw-r--r-- | src/cython/CMakeLists.txt | 228 | ||||
-rw-r--r-- | src/cython/cython/alpha_complex.pyx | 49 | ||||
-rw-r--r-- | src/cython/cython/rips_complex.pyx | 24 | ||||
-rw-r--r-- | src/cython/doc/alpha_complex_sum.rst | 4 | ||||
-rwxr-xr-x | src/cython/doc/conf.py | 4 | ||||
-rw-r--r-- | src/cython/doc/cubical_complex_sum.rst | 2 | ||||
-rw-r--r-- | src/cython/doc/persistence_graphical_tools_ref.rst | 8 | ||||
-rw-r--r-- | src/cython/doc/persistence_graphical_tools_sum.rst | 13 | ||||
-rw-r--r-- | src/cython/doc/persistence_graphical_tools_user.rst | 46 | ||||
-rw-r--r-- | src/cython/doc/persistent_cohomology_sum.rst | 2 | ||||
-rwxr-xr-x | src/cython/doc/pyplots/diagram_persistence.py | 1 | ||||
-rw-r--r-- | src/cython/doc/simplex_tree_sum.rst | 2 | ||||
-rw-r--r-- | src/cython/doc/witness_complex_sum.rst | 2 | ||||
-rw-r--r-- | src/cython/include/Alpha_complex_interface.h | 120 | ||||
-rw-r--r-- | src/cython/include/Simplex_tree_interface.h | 16 | ||||
-rw-r--r-- | src/cython/include/Witness_complex_interface.h | 8 |
16 files changed, 337 insertions, 192 deletions
diff --git a/src/cython/CMakeLists.txt b/src/cython/CMakeLists.txt index 383dd08a..81fbe8fe 100644 --- a/src/cython/CMakeLists.txt +++ b/src/cython/CMakeLists.txt @@ -5,116 +5,128 @@ FIND_PROGRAM( PYTHON_PATH python ) FIND_PROGRAM( CYTHON_PATH cython ) if(PYTHON_PATH AND CYTHON_PATH) - # Gudhi and CGAL compilation option - if(MSVC) - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'/fp:strict', ") - else(MSVC) - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-std=c++11', ") - endif(MSVC) - if(CMAKE_COMPILER_IS_GNUCXX) - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-frounding-math', ") - endif(CMAKE_COMPILER_IS_GNUCXX) - if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-fp-model strict', ") - endif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") + find_package(Boost REQUIRED COMPONENTS system REQUIRED) - find_package(Eigen3 3.1.0) - - if (EIGEN3_FOUND) - # No problem, even if no CGAL found - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_EIGEN3_ENABLED', ") - set(GUDHI_CYTHON_INCLUDE_DIRS "${GUDHI_CYTHON_INCLUDE_DIRS}'${EIGEN3_INCLUDE_DIR}', ") - endif (EIGEN3_FOUND) - - # Copy recursively include, cython and test repositories before packages finding - # Some tests 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 test DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) - - if (CGAL_FOUND) - if (NOT CGAL_VERSION VERSION_LESS 4.7.0) - # If CGAL_VERSION >= 4.7.0, include alpha complex - set(GUDHI_CYTHON_LIBRARIES "${GUDHI_CYTHON_LIBRARIES}'CGAL', ") - set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${CGAL_LIBRARIES_DIR}', ") - # GMP and GMPXX are not required, but if present, CGAL will link with them. - if(GMP_FOUND) - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_USE_GMP', ") - set(GUDHI_CYTHON_LIBRARIES "${GUDHI_CYTHON_LIBRARIES}'gmp', ") - set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${GMP_LIBRARIES_DIR}', ") - if(GMPXX_FOUND) - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_USE_GMPXX', ") - set(GUDHI_CYTHON_LIBRARIES "${GUDHI_CYTHON_LIBRARIES}'gmpxx', ") - set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${GMPXX_LIBRARIES_DIR}', ") - endif(GMPXX_FOUND) - endif(GMP_FOUND) - - 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) - endif (NOT CGAL_VERSION VERSION_LESS 4.7.0) - endif (CGAL_FOUND) - - # Loop on INCLUDE_DIRECTORIES PROPERTY - get_property(GUDHI_INCLUDE_DIRECTORIES DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES) - foreach(GUDHI_INCLUDE_DIRECTORY ${GUDHI_INCLUDE_DIRECTORIES}) - set(GUDHI_CYTHON_INCLUDE_DIRS "${GUDHI_CYTHON_INCLUDE_DIRS}'${GUDHI_INCLUDE_DIRECTORY}', ") - endforeach() - set(GUDHI_CYTHON_INCLUDE_DIRS "${GUDHI_CYTHON_INCLUDE_DIRS}'${CMAKE_SOURCE_DIR}/${GUDHI_CYTHON_PATH}/include', ") + if(NOT Boost_FOUND) + message(FATAL_ERROR "NOTICE: This demo requires Boost and will not be compiled.") + else(NOT Boost_FOUND) + + 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', ") + set(GUDHI_CYTHON_INCLUDE_DIRS "${GUDHI_CYTHON_INCLUDE_DIRS}'${Boost_INCLUDE_DIRS}', ") + set(GUDHI_CYTHON_LIBRARIES "${GUDHI_CYTHON_LIBRARIES}'boost_system', ") + set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${Boost_LIBRARY_DIRS}', ") + + # Gudhi and CGAL compilation option + if(MSVC) + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'/fp:strict', ") + else(MSVC) + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-std=c++11', ") + endif(MSVC) + if(CMAKE_COMPILER_IS_GNUCXX) + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-frounding-math', ") + endif(CMAKE_COMPILER_IS_GNUCXX) + if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-fp-model strict', ") + endif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") - # Generate cythonize_gudhi.py file to cythonize Gudhi - configure_file(cythonize_gudhi.py.in "${CMAKE_CURRENT_BINARY_DIR}/cythonize_gudhi.py" @ONLY) - # Generate gudhi.pyx - Gudhi cython file - configure_file(gudhi.pyx.in "${CMAKE_CURRENT_BINARY_DIR}/gudhi.pyx" @ONLY) + find_package(Eigen3 3.1.0) + + if (EIGEN3_FOUND) + # No problem, even if no CGAL found + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_EIGEN3_ENABLED', ") + set(GUDHI_CYTHON_INCLUDE_DIRS "${GUDHI_CYTHON_INCLUDE_DIRS}'${EIGEN3_INCLUDE_DIR}', ") + endif (EIGEN3_FOUND) + + # Copy recursively include, cython and test repositories before packages finding + # Some tests 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 test DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) + + if (CGAL_FOUND) + if (NOT CGAL_VERSION VERSION_LESS 4.7.0) + # If CGAL_VERSION >= 4.7.0, include alpha complex + set(GUDHI_CYTHON_LIBRARIES "${GUDHI_CYTHON_LIBRARIES}'CGAL', ") + set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${CGAL_LIBRARIES_DIR}', ") + # GMP and GMPXX are not required, but if present, CGAL will link with them. + if(GMP_FOUND) + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_USE_GMP', ") + set(GUDHI_CYTHON_LIBRARIES "${GUDHI_CYTHON_LIBRARIES}'gmp', ") + set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${GMP_LIBRARIES_DIR}', ") + if(GMPXX_FOUND) + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_USE_GMPXX', ") + set(GUDHI_CYTHON_LIBRARIES "${GUDHI_CYTHON_LIBRARIES}'gmpxx', ") + set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${GMPXX_LIBRARIES_DIR}', ") + endif(GMPXX_FOUND) + endif(GMP_FOUND) + + 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) + endif (NOT CGAL_VERSION VERSION_LESS 4.7.0) + endif (CGAL_FOUND) + + # Loop on INCLUDE_DIRECTORIES PROPERTY + get_property(GUDHI_INCLUDE_DIRECTORIES DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES) + foreach(GUDHI_INCLUDE_DIRECTORY ${GUDHI_INCLUDE_DIRECTORIES}) + set(GUDHI_CYTHON_INCLUDE_DIRS "${GUDHI_CYTHON_INCLUDE_DIRS}'${GUDHI_INCLUDE_DIRECTORY}', ") + endforeach() + set(GUDHI_CYTHON_INCLUDE_DIRS "${GUDHI_CYTHON_INCLUDE_DIRS}'${CMAKE_SOURCE_DIR}/${GUDHI_CYTHON_PATH}/include', ") + + # Generate cythonize_gudhi.py file to cythonize Gudhi + configure_file(cythonize_gudhi.py.in "${CMAKE_CURRENT_BINARY_DIR}/cythonize_gudhi.py" @ONLY) + # Generate gudhi.pyx - Gudhi cython file + configure_file(gudhi.pyx.in "${CMAKE_CURRENT_BINARY_DIR}/gudhi.pyx" @ONLY) + + add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/gudhi.so" + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND python "${CMAKE_CURRENT_BINARY_DIR}/cythonize_gudhi.py" "build_ext" "--inplace") + + add_custom_target(cythonize_gudhi ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/gudhi.so" + COMMENT "Do not forget to add ${CMAKE_CURRENT_BINARY_DIR}/gudhi.so to your PYTHONPATH before using examples") - add_custom_command( - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/gudhi.so" - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND python "${CMAKE_CURRENT_BINARY_DIR}/cythonize_gudhi.py" "build_ext" "--inplace") + # Unitary tests are available through py.test + find_program( PYTEST_PATH py.test ) + if(PYTEST_PATH) + add_test( + NAME gudhi_cython_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${PYTEST_PATH}) + set_tests_properties(gudhi_cython_py_test PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}") + endif(PYTEST_PATH) - add_custom_target(cythonize_gudhi ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/gudhi.so" - COMMENT "Do not forget to add ${CMAKE_CURRENT_BINARY_DIR}/gudhi.so to your PYTHONPATH before using examples") - - # Unitary tests are available through py.test - find_program( PYTEST_PATH py.test ) - if(PYTEST_PATH) - add_test( - NAME gudhi_cython_py_test - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${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 - find_program( SPHINX_PATH sphinx-build ) - if(SPHINX_PATH) - file(COPY doc DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) - # Developper version - 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") - # User version - file(GLOB GUDHI_USER_DOC_IMAGES "${CMAKE_SOURCE_DIR}/doc/*/*.png") - 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/") - # 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 (UNIX) - add_custom_target(html - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc - COMMAND make html && make doctest) - else (UNIX) - add_custom_target(html - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc - COMMAND make.bat html) - endif (UNIX) - endif(SPHINX_PATH) - + # Documentation generation is available through sphinx + find_program( SPHINX_PATH sphinx-build ) + if(SPHINX_PATH) + file(COPY doc DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) + # Developper version + 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") + # User version + file(GLOB GUDHI_USER_DOC_IMAGES "${CMAKE_SOURCE_DIR}/doc/*/*.png") + 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/") + # 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 (UNIX) + add_custom_target(html + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc + COMMAND make html && make doctest) + else (UNIX) + add_custom_target(html + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc + COMMAND make.bat html) + endif (UNIX) + endif(SPHINX_PATH) + endif(NOT Boost_FOUND) endif(PYTHON_PATH AND CYTHON_PATH) diff --git a/src/cython/cython/alpha_complex.pyx b/src/cython/cython/alpha_complex.pyx index 44da8c9d..af609863 100644 --- a/src/cython/cython/alpha_complex.pyx +++ b/src/cython/cython/alpha_complex.pyx @@ -34,7 +34,7 @@ __license__ = "GPL v3" cdef extern from "Alpha_complex_interface.h" namespace "Gudhi": cdef cppclass Alpha_complex_interface "Gudhi::alphacomplex::Alpha_complex_interface": Alpha_complex_interface(vector[vector[double]] points, double max_alpha_square) - # bool from_file is a workaround fro cython to find the correct signature + # bool from_file is a workaround for cython to find the correct signature Alpha_complex_interface(string off_file, double max_alpha_square, bool from_file) double filtration() double simplex_filtration(vector[int] simplex) @@ -54,13 +54,9 @@ cdef extern from "Alpha_complex_interface.h" namespace "Gudhi": int dimension) void remove_maximal_simplex(vector[int] simplex) vector[double] get_point(int vertex) - -cdef extern from "Persistent_cohomology_interface.h" namespace "Gudhi": - cdef cppclass Alpha_complex_persistence_interface "Gudhi::Persistent_cohomology_interface<Gudhi::alphacomplex::Alpha_complex< CGAL::Epick_d< CGAL::Dynamic_dimension_tag > >>": - Alpha_complex_persistence_interface(Alpha_complex_interface * st) vector[pair[int, pair[double, double]]] get_persistence(int homology_coeff_field, double min_persistence) - vector[int] betti_numbers() - vector[int] persistent_betti_numbers(double from_value, double to_value) + vector[int] get_betti_numbers() + vector[int] get_persistent_betti_numbers(double from_value, double to_value) # AlphaComplex python interface cdef class AlphaComplex: @@ -84,8 +80,6 @@ cdef class AlphaComplex: cdef Alpha_complex_interface * thisptr - cdef Alpha_complex_persistence_interface * pcohptr - # Fake constructor that does nothing but documenting the constructor def __init__(self, points=None, off_file='', max_alpha_square=float('inf')): """AlphaComplex constructor. @@ -118,19 +112,12 @@ cdef class AlphaComplex: def __dealloc__(self): if self.thisptr != NULL: del self.thisptr - if self.pcohptr != NULL: - del self.pcohptr def __is_defined(self): """Returns true if AlphaComplex pointer is not NULL. """ return self.thisptr != NULL - def __is_persistence_defined(self): - """Returns true if Persistence pointer is not NULL. - """ - return self.pcohptr != NULL - def get_filtration(self): """This function returns the main simplicial complex filtration value. @@ -341,18 +328,10 @@ cdef class AlphaComplex: 0.0. Sets min_persistence to -1.0 to see all values. :type min_persistence: float. - :returns: list of tuples(dimension, tuple(birth, death)) -- the + :note: list of pairs(dimension, pair(birth, death)) -- the persistence of the simplicial complex. """ - if self.pcohptr != NULL: - del self.pcohptr - self.pcohptr = new Alpha_complex_persistence_interface(self.thisptr) - cdef vector[pair[int, pair[double, double]]] persistence_result - if self.pcohptr != NULL: - persistence_result \ - = self.pcohptr.get_persistence(homology_coeff_field, - min_persistence) - return persistence_result + return self.thisptr.get_persistence(homology_coeff_field, min_persistence) def betti_numbers(self): """This function returns the Betti numbers of the simplicial complex. @@ -362,13 +341,7 @@ cdef class AlphaComplex: :note: betti_numbers function requires persistence function to be launched first. """ - cdef vector[int] bn_result - if self.pcohptr != NULL: - bn_result = self.pcohptr.betti_numbers() - else: - print("betti_numbers function requires persistence function" - " to be launched first.") - return bn_result + return self.thisptr.get_betti_numbers() def persistent_betti_numbers(self, from_value, to_value): """This function returns the persistent Betti numbers of the @@ -387,12 +360,4 @@ cdef class AlphaComplex: :note: persistent_betti_numbers function requires persistence function to be launched first. """ - cdef vector[int] pbn_result - if self.pcohptr != NULL: - pbn_result \ - = self.pcohptr.persistent_betti_numbers(<double>from_value, - <double>to_value) - else: - print("persistent_betti_numbers function requires persistence " - "function to be launched first.") - return pbn_result + return self.thisptr.get_persistent_betti_numbers(from_value, to_value) diff --git a/src/cython/cython/rips_complex.pyx b/src/cython/cython/rips_complex.pyx index ee4c34b0..08bd2388 100644 --- a/src/cython/cython/rips_complex.pyx +++ b/src/cython/cython/rips_complex.pyx @@ -1,6 +1,8 @@ from cython cimport numeric from libcpp.vector cimport vector from libcpp.utility cimport pair +from libcpp.string cimport string +from libcpp cimport bool """This file is part of the Gudhi Library. The Gudhi library (Geometric Understanding in Higher Dimensions) is a generic C++ @@ -53,6 +55,8 @@ cdef extern from "Simplex_tree_interface.h" namespace "Gudhi": void remove_maximal_simplex(vector[int] simplex) void graph_expansion(vector[vector[double]] points, int max_dimension, double max_edge_length) + void graph_expansion(string off_file, int max_dimension, + double max_edge_length, bool from_file) cdef extern from "Persistent_cohomology_interface.h" namespace "Gudhi": cdef cppclass Rips_complex_persistence_interface "Gudhi::Persistent_cohomology_interface<Gudhi::Simplex_tree<Gudhi::Simplex_tree_options_full_featured>>": @@ -79,12 +83,18 @@ cdef class RipsComplex: cdef Rips_complex_persistence_interface * pcohptr # Fake constructor that does nothing but documenting the constructor - def __init__(self, points=[], max_dimension=3, - max_edge_length=float('inf')): + def __init__(self, points=[], off_file='', max_dimension=3, + max_edge_length=float('inf')): """RipsComplex constructor. :param points: A list of points in d-Dimension. :type points: list of list of double + + Or + + :param off_file: An OFF file style name. + :type off_file: string + :param max_dimension: Maximum dimension of the complex to be expanded. :type max_dimension: int :param max_edge_length: Maximum edge length value (rips radius). @@ -92,11 +102,17 @@ cdef class RipsComplex: """ # The real cython constructor - def __cinit__(self, points=[], max_dimension=3, + def __cinit__(self, points=[], off_file='', max_dimension=3, max_edge_length=float('inf')): self.thisptr = new Rips_complex_interface() # Constructor from graph expansion - if points is not None: + if off_file is not '': + if os.path.isfile(off_file): + self.thisptr.graph_expansion(off_file, max_dimension, + max_edge_length, True) + else: + print("file " + off_file + " not found.") + else: self.thisptr.graph_expansion(points, max_dimension, max_edge_length) diff --git a/src/cython/doc/alpha_complex_sum.rst b/src/cython/doc/alpha_complex_sum.rst index b608050e..b3689556 100644 --- a/src/cython/doc/alpha_complex_sum.rst +++ b/src/cython/doc/alpha_complex_sum.rst @@ -1,5 +1,7 @@ ===================================== ===================================== ===================================== -:Author: Vincent Rouvreau :Introduced in: GUDHI PYTHON 1.4.0 :Copyright: GPL v3 +:Author: Vincent Rouvreau :Introduced in: GUDHI 1.3.0 :Copyright: GPL v3 +===================================== ===================================== ===================================== +:Requires: CGAL &ge 4.7.0 Eigen3 ===================================== ===================================== ===================================== +-------------------------------------------+----------------------------------------------------------------------+ diff --git a/src/cython/doc/conf.py b/src/cython/doc/conf.py index 8d6483af..8b42ce37 100755 --- a/src/cython/doc/conf.py +++ b/src/cython/doc/conf.py @@ -67,9 +67,9 @@ copyright = u'2016, Vincent Rouvreau' # built documents. # # The short X.Y version. -version = '1.3.1' +version = '1.4.beta' # The full version, including alpha/beta/rc tags. -release = '1.3.1' +release = '1.4.beta' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/src/cython/doc/cubical_complex_sum.rst b/src/cython/doc/cubical_complex_sum.rst index 4008a1fd..98e23849 100644 --- a/src/cython/doc/cubical_complex_sum.rst +++ b/src/cython/doc/cubical_complex_sum.rst @@ -1,5 +1,5 @@ ===================================== ===================================== ===================================== -:Author: Pawel Dlotko :Introduced in: GUDHI PYTHON 1.4.0 :Copyright: GPL v3 +:Author: Pawel Dlotko :Introduced in: GUDHI 1.3.0 :Copyright: GPL v3 ===================================== ===================================== ===================================== +---------------------------------------------+----------------------------------------------------------------------+ diff --git a/src/cython/doc/persistence_graphical_tools_ref.rst b/src/cython/doc/persistence_graphical_tools_ref.rst new file mode 100644 index 00000000..aa214edf --- /dev/null +++ b/src/cython/doc/persistence_graphical_tools_ref.rst @@ -0,0 +1,8 @@ +============================================ +Persistence graphical tools reference manual +============================================ + +.. automethod:: gudhi.__min_birth_max_death +.. automethod:: gudhi.show_palette_values +.. automethod:: gudhi.barcode_persistence +.. automethod:: gudhi.diagram_persistence
\ No newline at end of file diff --git a/src/cython/doc/persistence_graphical_tools_sum.rst b/src/cython/doc/persistence_graphical_tools_sum.rst new file mode 100644 index 00000000..a6260032 --- /dev/null +++ b/src/cython/doc/persistence_graphical_tools_sum.rst @@ -0,0 +1,13 @@ +===================================== ===================================== ===================================== +:Author: Vincent Rouvreau :Introduced in: GUDHI 1.4.0 :Copyright: GPL v3 +===================================== ===================================== ===================================== +:Requires: Matplotlib Numpy +===================================== ===================================== ===================================== + ++---------------------------------------------+----------------------------------------------------------------------+ +| .. image:: | These graphical tools comes on top of persistence results and allows | +| img/graphical_tools_representation.png | the user to build easily barcode and persistence diagram. | +| | | ++---------------------------------------------+----------------------------------------------------------------------+ +| :doc:`persistence_graphical_tools_user` | * :doc:`persistence_graphical_tools_ref` | ++---------------------------------------------+----------------------------------------------------------------------+ diff --git a/src/cython/doc/persistence_graphical_tools_user.rst b/src/cython/doc/persistence_graphical_tools_user.rst new file mode 100644 index 00000000..0cb61cf1 --- /dev/null +++ b/src/cython/doc/persistence_graphical_tools_user.rst @@ -0,0 +1,46 @@ +======================================= +Persistence graphical tools user manual +======================================= +Definition +---------- +.. include:: persistence_graphical_tools_sum.rst + + +Show palette values +------------------- + +This function is useful to show the color palette values of dimension: + + +.. testcode:: + + import gudhi + gudhi.show_palette_values(alpha=1.0) + +Show persistence as a barcode +----------------------------- + +This function can display the persistence result as a barcode: + +.. testcode:: + + import gudhi + + periodic_cc = gudhi.PeriodicCubicalComplex(perseus_file='3d_torus.txt') + diag = periodic_cc.persistence() + gudhi.barcode_persistence(diag) + + +Show persistence as a diagram +----------------------------- + +This function can display the persistence result as a diagram: + +.. testcode:: + + import gudhi + + alpha_complex = gudhi.AlphaComplex(off_file='tore3D_300.off') + alpha_complex.initialize_filtration() + diag = alpha_complex.persistence() + gudhi.diagram_persistence(diag) diff --git a/src/cython/doc/persistent_cohomology_sum.rst b/src/cython/doc/persistent_cohomology_sum.rst index 081399a5..b306b3d4 100644 --- a/src/cython/doc/persistent_cohomology_sum.rst +++ b/src/cython/doc/persistent_cohomology_sum.rst @@ -1,5 +1,5 @@ ===================================== ===================================== ===================================== -:Author: Clément Maria :Introduced in: GUDHI PYTHON 1.4.0 :Copyright: GPL v3 +:Author: Clément Maria :Introduced in: GUDHI 1.0.0 :Copyright: GPL v3 ===================================== ===================================== ===================================== +---------------------------------------------+----------------------------------------------------------------------+ diff --git a/src/cython/doc/pyplots/diagram_persistence.py b/src/cython/doc/pyplots/diagram_persistence.py index ceeeceb3..b006b0bf 100755 --- a/src/cython/doc/pyplots/diagram_persistence.py +++ b/src/cython/doc/pyplots/diagram_persistence.py @@ -1,6 +1,5 @@ import gudhi alpha_complex = gudhi.AlphaComplex(off_file='../tore3D_300.off') -alpha_complex.initialize_filtration() diag = alpha_complex.persistence() gudhi.diagram_persistence(diag) diff --git a/src/cython/doc/simplex_tree_sum.rst b/src/cython/doc/simplex_tree_sum.rst index ffdb2cf4..0f34888a 100644 --- a/src/cython/doc/simplex_tree_sum.rst +++ b/src/cython/doc/simplex_tree_sum.rst @@ -1,5 +1,5 @@ ===================================== ===================================== ===================================== -:Author: Clément Maria :Introduced in: GUDHI PYTHON 1.4.0 :Copyright: GPL v3 +:Author: Clément Maria :Introduced in: GUDHI 1.0.0 :Copyright: GPL v3 ===================================== ===================================== ===================================== +-------------------------------------------+----------------------------------------------------------------------+ diff --git a/src/cython/doc/witness_complex_sum.rst b/src/cython/doc/witness_complex_sum.rst index 0d65d420..005a5a41 100644 --- a/src/cython/doc/witness_complex_sum.rst +++ b/src/cython/doc/witness_complex_sum.rst @@ -1,5 +1,5 @@ ===================================== ===================================== ===================================== -:Author: Siargey Kachanovich :Introduced in: GUDHI PYTHON 1.4.0 :Copyright: GPL v3 +:Author: Siargey Kachanovich :Introduced in: GUDHI 1.3.0 :Copyright: GPL v3 ===================================== ===================================== ===================================== +---------------------------------------------+----------------------------------------------------------------------+ diff --git a/src/cython/include/Alpha_complex_interface.h b/src/cython/include/Alpha_complex_interface.h index e2e6d100..13412994 100644 --- a/src/cython/include/Alpha_complex_interface.h +++ b/src/cython/include/Alpha_complex_interface.h @@ -23,9 +23,12 @@ #ifndef ALPHA_COMPLEX_INTERFACE_H #define ALPHA_COMPLEX_INTERFACE_H +#include <gudhi/Simplex_tree.h> #include <gudhi/Alpha_complex.h> #include <CGAL/Epick_d.h> +#include "Persistent_cohomology_interface.h" + #include <vector> #include <utility> // std::pair #include <iostream> @@ -34,51 +37,57 @@ namespace Gudhi { namespace alpha_complex { -class Alpha_complex_interface : public Alpha_complex< CGAL::Epick_d< CGAL::Dynamic_dimension_tag > > { - using Alpha_complex = Alpha_complex< CGAL::Epick_d< CGAL::Dynamic_dimension_tag > > ; - typedef typename Alpha_complex::Simplex_handle Simplex_handle; +class Alpha_complex_interface { + using Dynamic_kernel = CGAL::Epick_d< CGAL::Dynamic_dimension_tag >; + using Point_d = Dynamic_kernel::Point_d; + typedef typename Simplex_tree<>::Simplex_handle Simplex_handle; typedef typename std::pair<Simplex_handle, bool> Insertion_result; using Simplex = std::vector<Vertex_handle>; using Filtered_complex = std::pair<Simplex, Filtration_value>; using Complex_tree = std::vector<Filtered_complex>; - using Point_d = Alpha_complex::Point_d; - public: + typedef typename Simplex_tree<>::Simplex_key Simplex_key; + public: Alpha_complex_interface(std::vector<std::vector<double>>&points, double max_alpha_square) - : Alpha_complex(points, max_alpha_square) { + : pcoh_(nullptr) { + alpha_complex_ = new Alpha_complex<Dynamic_kernel>(points); + alpha_complex_->create_complex(simplex_tree_, max_alpha_square); + simplex_tree_.initialize_filtration(); } - // bool from_file is a workaround fro cython to find the correct signature - Alpha_complex_interface(const std::string& off_file, double max_alpha_square, bool from_file) - : Alpha_complex(off_file, max_alpha_square) { + Alpha_complex_interface(std::string off_file_name, double max_alpha_square, bool from_file = true) + : pcoh_(nullptr) { + alpha_complex_ = new Alpha_complex<Dynamic_kernel>(off_file_name); + alpha_complex_->create_complex(simplex_tree_, max_alpha_square); + simplex_tree_.initialize_filtration(); } bool find_simplex(const Simplex& vh) { - return (Alpha_complex::find(vh) != Alpha_complex::null_simplex()); + return (simplex_tree_.find(vh) != simplex_tree_.null_simplex()); } bool insert_simplex_and_subfaces(const Simplex& complex, Filtration_value filtration = 0) { - Insertion_result result = Alpha_complex::insert_simplex_and_subfaces(complex, filtration); + Insertion_result result = simplex_tree_.insert_simplex_and_subfaces(complex, filtration); return (result.second); } Filtration_value simplex_filtration(const Simplex& complex) { - return Alpha_complex::filtration(Alpha_complex::find(complex)); + return simplex_tree_.filtration(simplex_tree_.find(complex)); } void remove_maximal_simplex(const Simplex& complex) { - return Alpha_complex::remove_maximal_simplex(Alpha_complex::find(complex)); + return simplex_tree_.remove_maximal_simplex(simplex_tree_.find(complex)); } Complex_tree get_filtered_tree() { Complex_tree filtered_tree; - for (auto f_simplex : Alpha_complex::filtration_simplex_range()) { + for (auto f_simplex : simplex_tree_.filtration_simplex_range()) { Simplex simplex; - for (auto vertex : Alpha_complex::simplex_vertex_range(f_simplex)) { + for (auto vertex : simplex_tree_.simplex_vertex_range(f_simplex)) { simplex.insert(simplex.begin(), vertex); } - filtered_tree.push_back(std::make_pair(simplex, Alpha_complex::filtration(f_simplex))); + filtered_tree.push_back(std::make_pair(simplex, simplex_tree_.filtration(f_simplex))); } return filtered_tree; @@ -86,44 +95,73 @@ class Alpha_complex_interface : public Alpha_complex< CGAL::Epick_d< CGAL::Dynam Complex_tree get_skeleton_tree(int dimension) { Complex_tree skeleton_tree; - for (auto f_simplex : Alpha_complex::skeleton_simplex_range(dimension)) { + for (auto f_simplex : simplex_tree_.skeleton_simplex_range(dimension)) { Simplex simplex; - for (auto vertex : Alpha_complex::simplex_vertex_range(f_simplex)) { + for (auto vertex : simplex_tree_.simplex_vertex_range(f_simplex)) { simplex.insert(simplex.begin(), vertex); } - skeleton_tree.push_back(std::make_pair(simplex, Alpha_complex::filtration(f_simplex))); + skeleton_tree.push_back(std::make_pair(simplex, simplex_tree_.filtration(f_simplex))); } return skeleton_tree; } Complex_tree get_star_tree(const Simplex& complex) { Complex_tree star_tree; - for (auto f_simplex : Alpha_complex::star_simplex_range(Alpha_complex::find(complex))) { + for (auto f_simplex : simplex_tree_.star_simplex_range(simplex_tree_.find(complex))) { Simplex simplex; - for (auto vertex : Alpha_complex::simplex_vertex_range(f_simplex)) { + for (auto vertex : simplex_tree_.simplex_vertex_range(f_simplex)) { simplex.insert(simplex.begin(), vertex); } - star_tree.push_back(std::make_pair(simplex, Alpha_complex::filtration(f_simplex))); + star_tree.push_back(std::make_pair(simplex, simplex_tree_.filtration(f_simplex))); } return star_tree; } Complex_tree get_coface_tree(const Simplex& complex, int dimension) { Complex_tree coface_tree; - for (auto f_simplex : Alpha_complex::cofaces_simplex_range(Alpha_complex::find(complex), dimension)) { + for (auto f_simplex : simplex_tree_.cofaces_simplex_range(simplex_tree_.find(complex), dimension)) { Simplex simplex; - for (auto vertex : Alpha_complex::simplex_vertex_range(f_simplex)) { + for (auto vertex : simplex_tree_.simplex_vertex_range(f_simplex)) { simplex.insert(simplex.begin(), vertex); } - coface_tree.push_back(std::make_pair(simplex, Alpha_complex::filtration(f_simplex))); + coface_tree.push_back(std::make_pair(simplex, simplex_tree_.filtration(f_simplex))); } return coface_tree; } - + + // Specific to Witness complex because no inheritance + Filtration_value filtration() const { + return simplex_tree_.filtration(); + } + + void set_filtration(Filtration_value fil) { + simplex_tree_.set_filtration(fil); + } + + void initialize_filtration() { + simplex_tree_.initialize_filtration(); + } + + size_t num_vertices() const { + return simplex_tree_.num_vertices(); + } + + size_t num_simplices() { + return simplex_tree_.num_simplices(); + } + + int dimension() const { + return simplex_tree_.dimension(); + } + + void set_dimension(int dimension) { + simplex_tree_.set_dimension(dimension); + } + std::vector<double> get_point(int vh) { std::vector<double> vd; try { - Point_d ph = Alpha_complex::get_point(vh); + Point_d ph = alpha_complex_->get_point(vh); for (auto coord = ph.cartesian_begin(); coord < ph.cartesian_end(); coord++) vd.push_back(*coord); } catch (std::out_of_range outofrange) { @@ -132,6 +170,34 @@ class Alpha_complex_interface : public Alpha_complex< CGAL::Epick_d< CGAL::Dynam return vd; } + std::vector<std::pair<int, std::pair<double, double>>> get_persistence(int homology_coeff_field, double min_persistence) { + if (pcoh_ != nullptr) { + delete pcoh_; + } + pcoh_ = new Persistent_cohomology_interface<Simplex_tree<>>(&simplex_tree_); + return pcoh_->get_persistence(homology_coeff_field, min_persistence); + } + + std::vector<int> get_betti_numbers() const { + if (pcoh_ != nullptr) { + return pcoh_->betti_numbers(); + } + std::vector<int> betti_numbers; + return betti_numbers; + } + + std::vector<int> get_persistent_betti_numbers(Filtration_value from, Filtration_value to) const { + if (pcoh_ != nullptr) { + return pcoh_->persistent_betti_numbers(from, to); + } + std::vector<int> persistent_betti_numbers; + return persistent_betti_numbers; + } + + private: + Simplex_tree<> simplex_tree_; + Persistent_cohomology_interface<Simplex_tree<>>* pcoh_; + Alpha_complex<Dynamic_kernel>* alpha_complex_; }; } // namespace alpha_complex diff --git a/src/cython/include/Simplex_tree_interface.h b/src/cython/include/Simplex_tree_interface.h index 9aee630b..ad7be1a8 100644 --- a/src/cython/include/Simplex_tree_interface.h +++ b/src/cython/include/Simplex_tree_interface.h @@ -26,6 +26,7 @@ #include <gudhi/graph_simplicial_complex.h> #include <gudhi/distance_functions.h> #include <gudhi/Simplex_tree.h> +#include <gudhi/Points_off_io.h> #include <vector> #include <utility> // std::pair @@ -116,6 +117,21 @@ class Simplex_tree_interface : public Simplex_tree<SimplexTreeOptions> { Simplex_tree<SimplexTreeOptions>::initialize_filtration(); } + void graph_expansion(std::string& off_file_name, int max_dimension, double max_edge_length, bool from_file=true) { + Gudhi::Points_off_reader<std::vector <double>> off_reader(off_file_name); + // Check the read operation was correct + if (!off_reader.is_valid()) { + std::cerr << "Unable to read file " << off_file_name << std::endl; + } else { + std::vector<std::vector <double>> points = off_reader.get_point_cloud(); + Graph_t prox_graph = compute_proximity_graph(points, max_edge_length, + euclidean_distance<std::vector<double>>); + Simplex_tree<SimplexTreeOptions>::insert_graph(prox_graph); + Simplex_tree<SimplexTreeOptions>::expansion(max_dimension); + Simplex_tree<SimplexTreeOptions>::initialize_filtration(); + } + } + }; struct Simplex_tree_options_mini : Simplex_tree_options_full_featured { diff --git a/src/cython/include/Witness_complex_interface.h b/src/cython/include/Witness_complex_interface.h index bdfea91f..ab99adf5 100644 --- a/src/cython/include/Witness_complex_interface.h +++ b/src/cython/include/Witness_complex_interface.h @@ -25,7 +25,8 @@ #include <gudhi/Simplex_tree.h> #include <gudhi/Witness_complex.h> -#include <gudhi/Landmark_choice_by_furthest_point.h> +#include <gudhi/Construct_closest_landmark_table.h> +#include <gudhi/pick_n_random_points.h> #include "Persistent_cohomology_interface.h" @@ -48,10 +49,11 @@ class Witness_complex_interface { Witness_complex_interface(std::vector<std::vector<double>>&points, int number_of_landmarks) : pcoh_(nullptr) { std::vector<std::vector< int > > knn; + std::vector<std::vector<double>> landmarks; + Gudhi::subsampling::pick_n_random_points(points, number_of_landmarks, std::back_inserter(landmarks)); + Gudhi::witness_complex::construct_closest_landmark_table(points, landmarks, knn); - Gudhi::witness_complex::landmark_choice_by_furthest_point(points, number_of_landmarks, knn); Gudhi::witness_complex::witness_complex(knn, number_of_landmarks, points[0].size(), simplex_tree_); - } bool find_simplex(const Simplex& vh) { |