From 9fc45aafa4588b86ccd903b9173a8cdf48db68a1 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Thu, 5 Dec 2019 16:01:45 +0100 Subject: Add MPFR dependency for python module. Use Epeck_d by default for Alpha complex. Add boolean exact version mechanism --- src/cmake/modules/FindMPFR.cmake | 51 ++++++++++++++++++ .../modules/GUDHI_third_party_libraries.cmake | 2 + src/python/CMakeLists.txt | 61 +++++++++++++--------- src/python/gudhi/alpha_complex.pyx | 13 +++-- src/python/include/Alpha_complex_interface.h | 9 ++-- 5 files changed, 102 insertions(+), 34 deletions(-) create mode 100644 src/cmake/modules/FindMPFR.cmake diff --git a/src/cmake/modules/FindMPFR.cmake b/src/cmake/modules/FindMPFR.cmake new file mode 100644 index 00000000..6c963272 --- /dev/null +++ b/src/cmake/modules/FindMPFR.cmake @@ -0,0 +1,51 @@ +# Try to find the MPFR libraries +# MPFR_FOUND - system has MPFR lib +# MPFR_INCLUDE_DIR - the MPFR include directory +# MPFR_LIBRARIES_DIR - Directory where the MPFR libraries are located +# MPFR_LIBRARIES - the MPFR libraries + +# TODO: support MacOSX + +include(FindPackageHandleStandardArgs) + +if(MPFR_INCLUDE_DIR) + set(MPFR_in_cache TRUE) +else() + set(MPFR_in_cache FALSE) +endif() +if(NOT MPFR_LIBRARIES) + set(MPFR_in_cache FALSE) +endif() + +# Is it already configured? +if (MPFR_in_cache) + set(MPFR_FOUND TRUE) +else() + find_path(MPFR_INCLUDE_DIR + NAMES mpfr.h + HINTS ENV MPFR_INC_DIR + ENV MPFR_DIR + ${CGAL_INSTALLATION_PACKAGE_DIR}/auxiliary/gmp/include + PATH_SUFFIXES include + DOC "The directory containing the MPFR header files" + ) + + find_library(MPFR_LIBRARIES NAMES mpfr libmpfr-4 libmpfr-1 + HINTS ENV MPFR_LIB_DIR + ENV MPFR_DIR + ${CGAL_INSTALLATION_PACKAGE_DIR}/auxiliary/gmp/lib + PATH_SUFFIXES lib + DOC "Path to the MPFR library" + ) + + if ( MPFR_LIBRARIES ) + get_filename_component(MPFR_LIBRARIES_DIR ${MPFR_LIBRARIES} PATH CACHE ) + endif() + + # Attempt to load a user-defined configuration for MPFR if couldn't be found + if ( NOT MPFR_INCLUDE_DIR OR NOT MPFR_LIBRARIES_DIR ) + include( MPFRConfig OPTIONAL ) + endif() + + find_package_handle_standard_args(MPFR "DEFAULT_MSG" MPFR_LIBRARIES MPFR_INCLUDE_DIR) +endif() diff --git a/src/cmake/modules/GUDHI_third_party_libraries.cmake b/src/cmake/modules/GUDHI_third_party_libraries.cmake index 24a34150..d8c7a428 100644 --- a/src/cmake/modules/GUDHI_third_party_libraries.cmake +++ b/src/cmake/modules/GUDHI_third_party_libraries.cmake @@ -6,6 +6,8 @@ if(NOT Boost_FOUND) message(FATAL_ERROR "NOTICE: This program requires Boost and will not be compiled.") endif(NOT Boost_FOUND) +find_package(MPFR) + find_package(GMP) if(GMP_FOUND) INCLUDE_DIRECTORIES(${GMP_INCLUDE_DIR}) diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index 9af85eac..13a8a909 100644 --- a/src/python/CMakeLists.txt +++ b/src/python/CMakeLists.txt @@ -114,9 +114,9 @@ if(PYTHONINTERP_FOUND) set(GUDHI_PYTHON_MODULES_TO_COMPILE "${GUDHI_PYTHON_MODULES_TO_COMPILE}'nerve_gic', ") endif () if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.11.0) + set(GUDHI_PYTHON_MODULES_TO_COMPILE "${GUDHI_PYTHON_MODULES_TO_COMPILE}'alpha_complex', ") set(GUDHI_PYTHON_MODULES_TO_COMPILE "${GUDHI_PYTHON_MODULES_TO_COMPILE}'subsampling', ") set(GUDHI_PYTHON_MODULES_TO_COMPILE "${GUDHI_PYTHON_MODULES_TO_COMPILE}'tangential_complex', ") - set(GUDHI_PYTHON_MODULES_TO_COMPILE "${GUDHI_PYTHON_MODULES_TO_COMPILE}'alpha_complex', ") set(GUDHI_PYTHON_MODULES_TO_COMPILE "${GUDHI_PYTHON_MODULES_TO_COMPILE}'euclidean_witness_complex', ") set(GUDHI_PYTHON_MODULES_TO_COMPILE "${GUDHI_PYTHON_MODULES_TO_COMPILE}'euclidean_strong_witness_complex', ") endif () @@ -162,10 +162,17 @@ if(PYTHONINTERP_FOUND) set(GUDHI_PYTHON_EXTRA_COMPILE_ARGS "${GUDHI_PYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_USE_GMPXX', ") add_GUDHI_PYTHON_lib("${GMPXX_LIBRARIES}") set(GUDHI_PYTHON_LIBRARY_DIRS "${GUDHI_PYTHON_LIBRARY_DIRS}'${GMPXX_LIBRARIES_DIR}', ") - message("** Add gmpxx ${GMPXX_LIBRARIES_DIR}") + message("** Add gmpxx ${GMPXX_LIBRARIES_DIR}") endif(GMPXX_FOUND) endif(GMP_FOUND) - endif(CGAL_FOUND) + if(MPFR_FOUND) + add_gudhi_debug_info("MPFR_LIBRARIES = ${MPFR_LIBRARIES}") + set(GUDHI_PYTHON_EXTRA_COMPILE_ARGS "${GUDHI_PYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_USE_MPFR', ") + add_GUDHI_PYTHON_lib("${MPFR_LIBRARIES}") + set(GUDHI_PYTHON_LIBRARY_DIRS "${GUDHI_PYTHON_LIBRARY_DIRS}'${MPFR_LIBRARIES_DIR}', ") + message("** Add mpfr ${MPFR_LIBRARIES}") + endif(MPFR_FOUND) +endif(CGAL_FOUND) # Specific for Mac if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") @@ -223,13 +230,14 @@ if(PYTHONINTERP_FOUND) # Test examples if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.11.0) - # Bottleneck and Alpha - add_test(NAME alpha_rips_persistence_bottleneck_distance_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/alpha_rips_persistence_bottleneck_distance.py" - -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -t 0.15 -d 3) - + if (MPFR_FOUND) + # Bottleneck and Alpha + add_test(NAME alpha_rips_persistence_bottleneck_distance_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/alpha_rips_persistence_bottleneck_distance.py" + -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -t 0.15 -d 3) + endif(MPFR_FOUND) if(MATPLOTLIB_FOUND AND NUMPY_FOUND) # Tangential add_test(NAME tangential_complex_plain_homology_from_off_file_example_py_test @@ -300,22 +308,23 @@ if(PYTHONINTERP_FOUND) endif (NOT CGAL_VERSION VERSION_LESS 4.11.0) if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.11.0) - # Alpha - add_test(NAME alpha_complex_from_points_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/alpha_complex_from_points_example.py") - - if(MATPLOTLIB_FOUND AND NUMPY_FOUND) - add_test(NAME alpha_complex_diagram_persistence_from_off_file_example_py_test - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/alpha_complex_diagram_persistence_from_off_file_example.py" - --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -a 0.6) - endif() - - add_gudhi_py_test(test_alpha_complex) - + if (MPFR_FOUND) + # Alpha + add_test(NAME alpha_complex_from_points_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/alpha_complex_from_points_example.py") + + if(MATPLOTLIB_FOUND AND NUMPY_FOUND) + add_test(NAME alpha_complex_diagram_persistence_from_off_file_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/alpha_complex_diagram_persistence_from_off_file_example.py" + --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -a 0.6) + endif() + + add_gudhi_py_test(test_alpha_complex) + endif(MPFR_FOUND) endif (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.11.0) if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.11.0) diff --git a/src/python/gudhi/alpha_complex.pyx b/src/python/gudhi/alpha_complex.pyx index 8f2c98d5..abac6e7b 100644 --- a/src/python/gudhi/alpha_complex.pyx +++ b/src/python/gudhi/alpha_complex.pyx @@ -28,7 +28,7 @@ cdef extern from "Alpha_complex_interface.h" namespace "Gudhi": # bool from_file is a workaround for cython to find the correct signature Alpha_complex_interface(string off_file, bool from_file) vector[double] get_point(int vertex) - void create_simplex_tree(Simplex_tree_interface_full_featured* simplex_tree, double max_alpha_square) + void create_simplex_tree(Simplex_tree_interface_full_featured* simplex_tree, double max_alpha_square, bool exact_version) # AlphaComplex python interface cdef class AlphaComplex: @@ -66,7 +66,7 @@ cdef class AlphaComplex: """ # The real cython constructor - def __cinit__(self, points=None, off_file=''): + def __cinit__(self, points = None, off_file = ''): if off_file: if os.path.isfile(off_file): self.thisptr = new Alpha_complex_interface(str.encode(off_file), True) @@ -99,17 +99,22 @@ cdef class AlphaComplex: cdef vector[double] point = self.thisptr.get_point(vertex) return point - def create_simplex_tree(self, max_alpha_square=float('inf')): + def create_simplex_tree(self, max_alpha_square = float('inf'), + exact_version = False): """ :param max_alpha_square: The maximum alpha square threshold the simplices shall not exceed. Default is set to infinity, and there is very little point using anything else since it does not save time. :type max_alpha_square: float + :param exact_version: Exact computation version. Default is false + which means Safe version is used. + :type exact_version: bool :returns: A simplex tree created from the Delaunay Triangulation. :rtype: SimplexTree """ stree = SimplexTree() cdef intptr_t stree_int_ptr=stree.thisptr - self.thisptr.create_simplex_tree(stree_int_ptr, max_alpha_square) + self.thisptr.create_simplex_tree(stree_int_ptr, + max_alpha_square, exact_version) return stree diff --git a/src/python/include/Alpha_complex_interface.h b/src/python/include/Alpha_complex_interface.h index 96353cc4..a7621f2b 100644 --- a/src/python/include/Alpha_complex_interface.h +++ b/src/python/include/Alpha_complex_interface.h @@ -13,6 +13,7 @@ #include #include +#include #include #include @@ -28,7 +29,7 @@ namespace Gudhi { namespace alpha_complex { class Alpha_complex_interface { - using Dynamic_kernel = CGAL::Epick_d< CGAL::Dynamic_dimension_tag >; + using Dynamic_kernel = CGAL::Epeck_d< CGAL::Dynamic_dimension_tag >; using Point_d = Dynamic_kernel::Point_d; public: @@ -51,7 +52,7 @@ class Alpha_complex_interface { std::vector vd; try { Point_d const& ph = alpha_complex_->get_point(vh); - for (auto coord = ph.cartesian_begin(); coord < ph.cartesian_end(); coord++) + for (auto coord = ph.cartesian_begin(); coord != ph.cartesian_end(); coord++) vd.push_back(CGAL::to_double(*coord)); } catch (std::out_of_range const&) { // std::out_of_range is thrown in case not found. Other exceptions must be re-thrown @@ -59,8 +60,8 @@ class Alpha_complex_interface { return vd; } - void create_simplex_tree(Simplex_tree_interface<>* simplex_tree, double max_alpha_square) { - alpha_complex_->create_complex(*simplex_tree, max_alpha_square); + void create_simplex_tree(Simplex_tree_interface<>* simplex_tree, double max_alpha_square, bool exact_version) { + alpha_complex_->create_complex(*simplex_tree, max_alpha_square, exact_version); simplex_tree->initialize_filtration(); } -- cgit v1.2.3 From 3757fedbf7ad387cdc06870a1db9532bbee4bab9 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Thu, 5 Dec 2019 17:05:19 +0100 Subject: Add a test that fixes #107 --- src/python/test/test_alpha_complex.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/python/test/test_alpha_complex.py b/src/python/test/test_alpha_complex.py index 24f8bf53..ab84daaa 100755 --- a/src/python/test/test_alpha_complex.py +++ b/src/python/test/test_alpha_complex.py @@ -1,4 +1,8 @@ from gudhi import AlphaComplex, SimplexTree +import math +import numpy as np +import itertools +import pytest """ This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. @@ -88,3 +92,34 @@ def test_filtered_alpha(): ] assert simplex_tree.get_star([0]) == [([0], 0.0), ([0, 1], 0.25), ([0, 2], 0.25)] assert simplex_tree.get_cofaces([0], 1) == [([0, 1], 0.25), ([0, 2], 0.25)] + +def alpha_persistence_comparison(exact_version): + #generate periodic signal + time = np.arange(0, 10, 1) + signal = [math.sin(x) for x in time] + delta = math.pi + delayed = [math.sin(x + delta) for x in time] + + #construct embedding + embedding1 = [[signal[i], -signal[i]] for i in range(len(time))] + embedding2 = [[signal[i], delayed[i]] for i in range(len(time))] + + #build alpha complex and simplex tree + alpha_complex1 = AlphaComplex(points=embedding1) + simplex_tree1 = alpha_complex1.create_simplex_tree(exact_version = exact_version) + + alpha_complex2 = AlphaComplex(points=embedding2) + simplex_tree2 = alpha_complex2.create_simplex_tree(exact_version = exact_version) + + diag1 = simplex_tree1.persistence() + diag2 = simplex_tree2.persistence() + + for (first_p, second_p) in itertools.zip_longest(diag1, diag2): + assert first_p[0] == pytest.approx(second_p[0]) + assert first_p[1] == pytest.approx(second_p[1]) + +def test_exact_alpha_version(): + alpha_persistence_comparison(exact_version = True) + +def test_safe_alpha_version(): + alpha_persistence_comparison(exact_version = False) -- cgit v1.2.3 From 6142e146e92801cafe1438bf487f3ecafa502177 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Thu, 5 Dec 2019 17:57:19 +0100 Subject: nicer doc presentation --- src/python/gudhi/alpha_complex.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/python/gudhi/alpha_complex.pyx b/src/python/gudhi/alpha_complex.pyx index abac6e7b..bfb9783a 100644 --- a/src/python/gudhi/alpha_complex.pyx +++ b/src/python/gudhi/alpha_complex.pyx @@ -107,8 +107,8 @@ cdef class AlphaComplex: there is very little point using anything else since it does not save time. :type max_alpha_square: float - :param exact_version: Exact computation version. Default is false - which means Safe version is used. + :param exact_version: :code:`EXACT` computation version if set. + Default is false which means :code:`SAFE` version is used. :type exact_version: bool :returns: A simplex tree created from the Delaunay Triangulation. :rtype: SimplexTree -- cgit v1.2.3 From 0474f6a62622608b96eac3a553a081e148cbcabc Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Tue, 10 Dec 2019 22:51:08 +0100 Subject: Remove FindMPFR mechanism as the job is already done by CGAL --- src/cmake/modules/FindMPFR.cmake | 51 ---------------------- .../modules/GUDHI_third_party_libraries.cmake | 2 - src/python/CMakeLists.txt | 44 ++++++++----------- 3 files changed, 19 insertions(+), 78 deletions(-) delete mode 100644 src/cmake/modules/FindMPFR.cmake diff --git a/src/cmake/modules/FindMPFR.cmake b/src/cmake/modules/FindMPFR.cmake deleted file mode 100644 index 6c963272..00000000 --- a/src/cmake/modules/FindMPFR.cmake +++ /dev/null @@ -1,51 +0,0 @@ -# Try to find the MPFR libraries -# MPFR_FOUND - system has MPFR lib -# MPFR_INCLUDE_DIR - the MPFR include directory -# MPFR_LIBRARIES_DIR - Directory where the MPFR libraries are located -# MPFR_LIBRARIES - the MPFR libraries - -# TODO: support MacOSX - -include(FindPackageHandleStandardArgs) - -if(MPFR_INCLUDE_DIR) - set(MPFR_in_cache TRUE) -else() - set(MPFR_in_cache FALSE) -endif() -if(NOT MPFR_LIBRARIES) - set(MPFR_in_cache FALSE) -endif() - -# Is it already configured? -if (MPFR_in_cache) - set(MPFR_FOUND TRUE) -else() - find_path(MPFR_INCLUDE_DIR - NAMES mpfr.h - HINTS ENV MPFR_INC_DIR - ENV MPFR_DIR - ${CGAL_INSTALLATION_PACKAGE_DIR}/auxiliary/gmp/include - PATH_SUFFIXES include - DOC "The directory containing the MPFR header files" - ) - - find_library(MPFR_LIBRARIES NAMES mpfr libmpfr-4 libmpfr-1 - HINTS ENV MPFR_LIB_DIR - ENV MPFR_DIR - ${CGAL_INSTALLATION_PACKAGE_DIR}/auxiliary/gmp/lib - PATH_SUFFIXES lib - DOC "Path to the MPFR library" - ) - - if ( MPFR_LIBRARIES ) - get_filename_component(MPFR_LIBRARIES_DIR ${MPFR_LIBRARIES} PATH CACHE ) - endif() - - # Attempt to load a user-defined configuration for MPFR if couldn't be found - if ( NOT MPFR_INCLUDE_DIR OR NOT MPFR_LIBRARIES_DIR ) - include( MPFRConfig OPTIONAL ) - endif() - - find_package_handle_standard_args(MPFR "DEFAULT_MSG" MPFR_LIBRARIES MPFR_INCLUDE_DIR) -endif() diff --git a/src/cmake/modules/GUDHI_third_party_libraries.cmake b/src/cmake/modules/GUDHI_third_party_libraries.cmake index d8c7a428..24a34150 100644 --- a/src/cmake/modules/GUDHI_third_party_libraries.cmake +++ b/src/cmake/modules/GUDHI_third_party_libraries.cmake @@ -6,8 +6,6 @@ if(NOT Boost_FOUND) message(FATAL_ERROR "NOTICE: This program requires Boost and will not be compiled.") endif(NOT Boost_FOUND) -find_package(MPFR) - find_package(GMP) if(GMP_FOUND) INCLUDE_DIRECTORIES(${GMP_INCLUDE_DIR}) diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index 13a8a909..1704f491 100644 --- a/src/python/CMakeLists.txt +++ b/src/python/CMakeLists.txt @@ -230,14 +230,12 @@ endif(CGAL_FOUND) # Test examples if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.11.0) - if (MPFR_FOUND) - # Bottleneck and Alpha - add_test(NAME alpha_rips_persistence_bottleneck_distance_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/alpha_rips_persistence_bottleneck_distance.py" - -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -t 0.15 -d 3) - endif(MPFR_FOUND) + # Bottleneck and Alpha + add_test(NAME alpha_rips_persistence_bottleneck_distance_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/alpha_rips_persistence_bottleneck_distance.py" + -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -t 0.15 -d 3) if(MATPLOTLIB_FOUND AND NUMPY_FOUND) # Tangential add_test(NAME tangential_complex_plain_homology_from_off_file_example_py_test @@ -308,23 +306,19 @@ endif(CGAL_FOUND) endif (NOT CGAL_VERSION VERSION_LESS 4.11.0) if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.11.0) - if (MPFR_FOUND) - # Alpha - add_test(NAME alpha_complex_from_points_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/alpha_complex_from_points_example.py") - - if(MATPLOTLIB_FOUND AND NUMPY_FOUND) - add_test(NAME alpha_complex_diagram_persistence_from_off_file_example_py_test - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/alpha_complex_diagram_persistence_from_off_file_example.py" - --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -a 0.6) - endif() - - add_gudhi_py_test(test_alpha_complex) - endif(MPFR_FOUND) + # Alpha + add_test(NAME alpha_complex_from_points_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/alpha_complex_from_points_example.py") + if(MATPLOTLIB_FOUND AND NUMPY_FOUND) + add_test(NAME alpha_complex_diagram_persistence_from_off_file_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/alpha_complex_diagram_persistence_from_off_file_example.py" + --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -a 0.6) + endif() + add_gudhi_py_test(test_alpha_complex) endif (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.11.0) if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.11.0) -- cgit v1.2.3 From 7b2ac5ccd53ec8988854e5ac2c3c20176e0c24ed Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Mon, 16 Dec 2019 10:47:34 +0100 Subject: Fix MPFR when CGAL is not header only --- src/python/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index 1704f491..b558d4c4 100644 --- a/src/python/CMakeLists.txt +++ b/src/python/CMakeLists.txt @@ -169,6 +169,10 @@ if(PYTHONINTERP_FOUND) add_gudhi_debug_info("MPFR_LIBRARIES = ${MPFR_LIBRARIES}") set(GUDHI_PYTHON_EXTRA_COMPILE_ARGS "${GUDHI_PYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_USE_MPFR', ") add_GUDHI_PYTHON_lib("${MPFR_LIBRARIES}") + # In case CGAL is not header only, all MPFR variables are set except MPFR_LIBRARIES_DIR - Just set it + if(NOT MPFR_LIBRARIES_DIR) + get_filename_component(MPFR_LIBRARIES_DIR ${MPFR_LIBRARIES} PATH) + endif(NOT MPFR_LIBRARIES_DIR) set(GUDHI_PYTHON_LIBRARY_DIRS "${GUDHI_PYTHON_LIBRARY_DIRS}'${MPFR_LIBRARIES_DIR}', ") message("** Add mpfr ${MPFR_LIBRARIES}") endif(MPFR_FOUND) -- cgit v1.2.3 From 490a5774601e344bb732de5eab2a8cf6d5a7e81f Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Mon, 16 Dec 2019 13:38:58 +0100 Subject: Rollback exact version mechanism --- src/python/gudhi/alpha_complex.pyx | 11 +++-------- src/python/include/Alpha_complex_interface.h | 4 ++-- src/python/test/test_alpha_complex.py | 12 +++--------- 3 files changed, 8 insertions(+), 19 deletions(-) diff --git a/src/python/gudhi/alpha_complex.pyx b/src/python/gudhi/alpha_complex.pyx index bfb9783a..24e36bea 100644 --- a/src/python/gudhi/alpha_complex.pyx +++ b/src/python/gudhi/alpha_complex.pyx @@ -28,7 +28,7 @@ cdef extern from "Alpha_complex_interface.h" namespace "Gudhi": # bool from_file is a workaround for cython to find the correct signature Alpha_complex_interface(string off_file, bool from_file) vector[double] get_point(int vertex) - void create_simplex_tree(Simplex_tree_interface_full_featured* simplex_tree, double max_alpha_square, bool exact_version) + void create_simplex_tree(Simplex_tree_interface_full_featured* simplex_tree, double max_alpha_square) # AlphaComplex python interface cdef class AlphaComplex: @@ -99,22 +99,17 @@ cdef class AlphaComplex: cdef vector[double] point = self.thisptr.get_point(vertex) return point - def create_simplex_tree(self, max_alpha_square = float('inf'), - exact_version = False): + def create_simplex_tree(self, max_alpha_square = float('inf')): """ :param max_alpha_square: The maximum alpha square threshold the simplices shall not exceed. Default is set to infinity, and there is very little point using anything else since it does not save time. :type max_alpha_square: float - :param exact_version: :code:`EXACT` computation version if set. - Default is false which means :code:`SAFE` version is used. - :type exact_version: bool :returns: A simplex tree created from the Delaunay Triangulation. :rtype: SimplexTree """ stree = SimplexTree() cdef intptr_t stree_int_ptr=stree.thisptr - self.thisptr.create_simplex_tree(stree_int_ptr, - max_alpha_square, exact_version) + self.thisptr.create_simplex_tree(stree_int_ptr, max_alpha_square) return stree diff --git a/src/python/include/Alpha_complex_interface.h b/src/python/include/Alpha_complex_interface.h index a7621f2b..e9bbadb0 100644 --- a/src/python/include/Alpha_complex_interface.h +++ b/src/python/include/Alpha_complex_interface.h @@ -60,8 +60,8 @@ class Alpha_complex_interface { return vd; } - void create_simplex_tree(Simplex_tree_interface<>* simplex_tree, double max_alpha_square, bool exact_version) { - alpha_complex_->create_complex(*simplex_tree, max_alpha_square, exact_version); + void create_simplex_tree(Simplex_tree_interface<>* simplex_tree, double max_alpha_square) { + alpha_complex_->create_complex(*simplex_tree, max_alpha_square); simplex_tree->initialize_filtration(); } diff --git a/src/python/test/test_alpha_complex.py b/src/python/test/test_alpha_complex.py index ab84daaa..9b27fff2 100755 --- a/src/python/test/test_alpha_complex.py +++ b/src/python/test/test_alpha_complex.py @@ -93,7 +93,7 @@ def test_filtered_alpha(): assert simplex_tree.get_star([0]) == [([0], 0.0), ([0, 1], 0.25), ([0, 2], 0.25)] assert simplex_tree.get_cofaces([0], 1) == [([0, 1], 0.25), ([0, 2], 0.25)] -def alpha_persistence_comparison(exact_version): +def test_safe_alpha_persistence_comparison(): #generate periodic signal time = np.arange(0, 10, 1) signal = [math.sin(x) for x in time] @@ -106,10 +106,10 @@ def alpha_persistence_comparison(exact_version): #build alpha complex and simplex tree alpha_complex1 = AlphaComplex(points=embedding1) - simplex_tree1 = alpha_complex1.create_simplex_tree(exact_version = exact_version) + simplex_tree1 = alpha_complex1.create_simplex_tree() alpha_complex2 = AlphaComplex(points=embedding2) - simplex_tree2 = alpha_complex2.create_simplex_tree(exact_version = exact_version) + simplex_tree2 = alpha_complex2.create_simplex_tree() diag1 = simplex_tree1.persistence() diag2 = simplex_tree2.persistence() @@ -117,9 +117,3 @@ def alpha_persistence_comparison(exact_version): for (first_p, second_p) in itertools.zip_longest(diag1, diag2): assert first_p[0] == pytest.approx(second_p[0]) assert first_p[1] == pytest.approx(second_p[1]) - -def test_exact_alpha_version(): - alpha_persistence_comparison(exact_version = True) - -def test_safe_alpha_version(): - alpha_persistence_comparison(exact_version = False) -- cgit v1.2.3