From 8c30016a3c56522014254dc571ed4fe81f31e02b Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Wed, 25 Dec 2019 22:18:20 +0100 Subject: Add Hera as a submodule --- .gitmodules | 3 +++ ext/hera | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 ext/hera diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..6e8b3ab1 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "ext/hera"] + path = ext/hera + url = https://bitbucket.org/grey_narn/hera.git diff --git a/ext/hera b/ext/hera new file mode 160000 index 00000000..5a59cfad --- /dev/null +++ b/ext/hera @@ -0,0 +1 @@ +Subproject commit 5a59cfad45c155f8af89c2c6d82db2848d52a953 -- cgit v1.2.3 From 15f222eecf3b427c59f09ec3bec17983377d96a2 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Wed, 25 Dec 2019 22:27:52 +0100 Subject: Copy hera headers in user_version --- src/cmake/modules/GUDHI_user_version_target.cmake | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cmake/modules/GUDHI_user_version_target.cmake b/src/cmake/modules/GUDHI_user_version_target.cmake index 4fa74330..2527dee9 100644 --- a/src/cmake/modules/GUDHI_user_version_target.cmake +++ b/src/cmake/modules/GUDHI_user_version_target.cmake @@ -56,6 +56,9 @@ add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/src/GudhUI ${GUDHI_USER_VERSION_DIR}/GudhUI) +add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E + copy_directory ${CMAKE_SOURCE_DIR}/ext/hera/geom_matching/wasserstein/include ${GUDHI_USER_VERSION_DIR}/hera/wasserstein) + set(GUDHI_DIRECTORIES "doc;example;concept;utilities") set(GUDHI_INCLUDE_DIRECTORIES "include/gudhi") @@ -95,4 +98,4 @@ foreach(GUDHI_MODULE ${GUDHI_MODULES_FULL_LIST}) endforeach() endforeach(GUDHI_INCLUDE_DIRECTORY ${GUDHI_INCLUDE_DIRECTORIES}) -endforeach(GUDHI_MODULE ${GUDHI_MODULES_FULL_LIST}) \ No newline at end of file +endforeach(GUDHI_MODULE ${GUDHI_MODULES_FULL_LIST}) -- cgit v1.2.3 From c2e22942c35e894d5c1ddc429eb32687c61538c8 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Thu, 26 Dec 2019 10:22:47 +0100 Subject: Basic binding for wasserstein_distance --- src/cmake/modules/GUDHI_user_version_target.cmake | 2 +- src/python/gudhi/hera.cc | 48 +++++++++++++++++++++++ src/python/setup.py.in | 26 +++++++++++- 3 files changed, 73 insertions(+), 3 deletions(-) create mode 100644 src/python/gudhi/hera.cc diff --git a/src/cmake/modules/GUDHI_user_version_target.cmake b/src/cmake/modules/GUDHI_user_version_target.cmake index 2527dee9..9a05386f 100644 --- a/src/cmake/modules/GUDHI_user_version_target.cmake +++ b/src/cmake/modules/GUDHI_user_version_target.cmake @@ -57,7 +57,7 @@ add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/src/GudhUI ${GUDHI_USER_VERSION_DIR}/GudhUI) add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E - copy_directory ${CMAKE_SOURCE_DIR}/ext/hera/geom_matching/wasserstein/include ${GUDHI_USER_VERSION_DIR}/hera/wasserstein) + copy_directory ${CMAKE_SOURCE_DIR}/ext/hera/geom_matching/wasserstein/include ${GUDHI_USER_VERSION_DIR}/ext/hera/geom_matching/wasserstein/include) set(GUDHI_DIRECTORIES "doc;example;concept;utilities") diff --git a/src/python/gudhi/hera.cc b/src/python/gudhi/hera.cc new file mode 100644 index 00000000..7cef9425 --- /dev/null +++ b/src/python/gudhi/hera.cc @@ -0,0 +1,48 @@ +#include +#include + +#include + +#include + +#include + +namespace py = pybind11; +typedef py::array_t Dgm; + +namespace hera { +template <> struct DiagramTraits{ + //using Container = void; + using PointType = std::array; + using RealType = double; + + static RealType get_x(const PointType& p) { return std::get<0>(p); } + static RealType get_y(const PointType& p) { return std::get<1>(p); } +}; +} + +double wasserstein_distance( + Dgm d1, + Dgm d2) +{ + py::buffer_info buf1 = d1.request(); + py::buffer_info buf2 = d2.request(); + if(buf1.ndim!=2 || buf1.shape[1]!=2) + throw std::runtime_error("Diagram 1 must be an array of size n x 2"); + if(buf2.ndim!=2 || buf2.shape[1]!=2) + throw std::runtime_error("Diagram 1 must be an array of size n x 2"); + typedef hera::DiagramTraits::PointType Point; + auto p1 = (Point*)buf1.ptr; + auto p2 = (Point*)buf2.ptr; + auto diag1 = boost::make_iterator_range(p1, p1+buf1.shape[0]); + auto diag2 = boost::make_iterator_range(p2, p2+buf2.shape[0]); + + hera::AuctionParams params; + return hera::wasserstein_dist(diag1, diag2, params); +} + +PYBIND11_MODULE(hera, m) { + m.def("wasserstein_distance", &wasserstein_distance, R"pbdoc( + Compute the Wasserstein distance between two diagrams + )pbdoc"); +} diff --git a/src/python/setup.py.in b/src/python/setup.py.in index 3f1d4424..f7ffd146 100644 --- a/src/python/setup.py.in +++ b/src/python/setup.py.in @@ -26,6 +26,19 @@ library_dirs=[@GUDHI_PYTHON_LIBRARY_DIRS@] include_dirs = [numpy_get_include(), '@CMAKE_CURRENT_SOURCE_DIR@/gudhi/', @GUDHI_PYTHON_INCLUDE_DIRS@] runtime_library_dirs=[@GUDHI_PYTHON_RUNTIME_LIBRARY_DIRS@] +class get_pybind_include(object): + """Helper class to determine the pybind11 include path + The purpose of this class is to postpone importing pybind11 + until it is actually installed, so that the ``get_include()`` + method can be invoked. """ + + def __init__(self, user=False): + self.user = user + + def __str__(self): + import pybind11 + return pybind11.get_include(self.user) + # Create ext_modules list from module list ext_modules = [] for module in modules: @@ -39,6 +52,15 @@ for module in modules: library_dirs=library_dirs, include_dirs=include_dirs, runtime_library_dirs=runtime_library_dirs,)) +ext_modules.append(Extension( + 'gudhi.hera', + sources = [source_dir + 'hera.cc'], + language = 'c++', + extra_compile_args=extra_compile_args + ['-fvisibility=hidden'], # FIXME + include_dirs = include_dirs + + ['@CMAKE_SOURCE_DIR@/ext/hera/geom_matching/wasserstein/include', + get_pybind_include(False), get_pybind_include(True)] + )) setup( name = 'gudhi', @@ -48,6 +70,6 @@ setup( version='@GUDHI_VERSION@', url='http://gudhi.gforge.inria.fr/', ext_modules = cythonize(ext_modules), - install_requires = ['cython','numpy >= 1.9',], - setup_requires = ['numpy >= 1.9',], + install_requires = ['cython','numpy >= 1.9','pybind11',], + setup_requires = ['numpy >= 1.9','pybind11',], ) -- cgit v1.2.3 From 56cee2efaa26e734c9555b5b0bb9dfbbc4baaed8 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Thu, 26 Dec 2019 17:33:51 +0100 Subject: Fix compilation --- src/python/CMakeLists.txt | 1 + src/python/setup.py.in | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index b558d4c4..bec38305 100644 --- a/src/python/CMakeLists.txt +++ b/src/python/CMakeLists.txt @@ -86,6 +86,7 @@ if(PYTHONINTERP_FOUND) endif(MSVC) if(CMAKE_COMPILER_IS_GNUCXX) set(GUDHI_PYTHON_EXTRA_COMPILE_ARGS "${GUDHI_PYTHON_EXTRA_COMPILE_ARGS}'-frounding-math', ") + set(GUDHI_PYBIND11_EXTRA_COMPILE_ARGS "${GUDHI_PYBIND11_EXTRA_COMPILE_ARGS}'-fvisibility=hidden', ") endif(CMAKE_COMPILER_IS_GNUCXX) if (CMAKE_CXX_COMPILER_ID MATCHES Intel) set(GUDHI_PYTHON_EXTRA_COMPILE_ARGS "${GUDHI_PYTHON_EXTRA_COMPILE_ARGS}'-fp-model strict', ") diff --git a/src/python/setup.py.in b/src/python/setup.py.in index f7ffd146..2d96c57b 100644 --- a/src/python/setup.py.in +++ b/src/python/setup.py.in @@ -26,6 +26,7 @@ library_dirs=[@GUDHI_PYTHON_LIBRARY_DIRS@] include_dirs = [numpy_get_include(), '@CMAKE_CURRENT_SOURCE_DIR@/gudhi/', @GUDHI_PYTHON_INCLUDE_DIRS@] runtime_library_dirs=[@GUDHI_PYTHON_RUNTIME_LIBRARY_DIRS@] +# Copied from https://github.com/pybind/python_example/blob/master/setup.py class get_pybind_include(object): """Helper class to determine the pybind11 include path The purpose of this class is to postpone importing pybind11 @@ -52,14 +53,16 @@ for module in modules: library_dirs=library_dirs, include_dirs=include_dirs, runtime_library_dirs=runtime_library_dirs,)) +ext_modules = cythonize(ext_modules) + ext_modules.append(Extension( 'gudhi.hera', sources = [source_dir + 'hera.cc'], language = 'c++', - extra_compile_args=extra_compile_args + ['-fvisibility=hidden'], # FIXME include_dirs = include_dirs + ['@CMAKE_SOURCE_DIR@/ext/hera/geom_matching/wasserstein/include', - get_pybind_include(False), get_pybind_include(True)] + get_pybind_include(False), get_pybind_include(True)], + extra_compile_args=extra_compile_args + [@GUDHI_PYBIND11_EXTRA_COMPILE_ARGS@], )) setup( @@ -69,7 +72,7 @@ setup( author_email='gudhi-contact@lists.gforge.inria.fr', version='@GUDHI_VERSION@', url='http://gudhi.gforge.inria.fr/', - ext_modules = cythonize(ext_modules), + ext_modules = ext_modules, install_requires = ['cython','numpy >= 1.9','pybind11',], setup_requires = ['numpy >= 1.9','pybind11',], ) -- cgit v1.2.3 From 4922f305b7601d9e5d7eb39c73a88ee53bf1ca87 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Thu, 26 Dec 2019 18:31:47 +0100 Subject: Update doc --- src/python/doc/wasserstein_distance_user.rst | 14 +++++++++++--- src/python/gudhi/hera.cc | 8 +++++++- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/python/doc/wasserstein_distance_user.rst b/src/python/doc/wasserstein_distance_user.rst index a049cfb5..13f6f1af 100644 --- a/src/python/doc/wasserstein_distance_user.rst +++ b/src/python/doc/wasserstein_distance_user.rst @@ -9,12 +9,20 @@ Definition .. include:: wasserstein_distance_sum.inc -This implementation is based on ideas from "Large Scale Computation of Means and Cluster for Persistence Diagrams via Optimal Transport". +Functions +--------- +This implementation is based on ideas from "Large Scale Computation of Means +and Cluster for Persistence Diagrams via Optimal Transport". -Function --------- .. autofunction:: gudhi.wasserstein.wasserstein_distance +This other implementation comes from `Hera +`_ and is based on `"Geometry +Helps to Compare Persistence Diagrams." +`_ by Michael Kerber, Dmitriy +Morozov, and Arnur Nigmetov, at ALENEX 2016. + +.. autofunction:: gudhi.hera.wasserstein_distance Basic example ------------- diff --git a/src/python/gudhi/hera.cc b/src/python/gudhi/hera.cc index 7cef9425..04f5990f 100644 --- a/src/python/gudhi/hera.cc +++ b/src/python/gudhi/hera.cc @@ -42,7 +42,13 @@ double wasserstein_distance( } PYBIND11_MODULE(hera, m) { - m.def("wasserstein_distance", &wasserstein_distance, R"pbdoc( + m.def("wasserstein_distance", &wasserstein_distance, + py::arg("X"), py::arg("Y"), + R"pbdoc( Compute the Wasserstein distance between two diagrams + + Parameters: + X (n x 2 numpy array): First diagram + Y (n x 2 numpy array): Second diagram )pbdoc"); } -- cgit v1.2.3 From 003b33403ab92e25cab2b9e51b36528d5cc6112c Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Thu, 26 Dec 2019 19:30:04 +0100 Subject: Check for pybind11 --- .appveyor.yml | 2 +- .travis.yml | 2 +- .../modules/GUDHI_third_party_libraries.cmake | 1 + src/python/CMakeLists.txt | 51 ++++++++++++---------- 4 files changed, 31 insertions(+), 25 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 4a76ea0a..3a33ed62 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -48,7 +48,7 @@ install: - pip --version - python -m pip install --upgrade pip - pip install -U setuptools numpy matplotlib scipy Cython pytest - - pip install -U POT + - pip install -U POT pybind11 build_script: - mkdir build diff --git a/.travis.yml b/.travis.yml index d6c82e70..4b4c7068 100644 --- a/.travis.yml +++ b/.travis.yml @@ -59,7 +59,7 @@ before_cache: install: - python3 -m pip install --upgrade pip setuptools wheel - python3 -m pip install --user pytest Cython sphinx sphinxcontrib-bibtex sphinx-paramlinks matplotlib numpy scipy scikit-learn - - python3 -m pip install --user POT + - python3 -m pip install --user POT pybind11 script: - rm -rf build diff --git a/src/cmake/modules/GUDHI_third_party_libraries.cmake b/src/cmake/modules/GUDHI_third_party_libraries.cmake index 24a34150..cb9f9033 100644 --- a/src/cmake/modules/GUDHI_third_party_libraries.cmake +++ b/src/cmake/modules/GUDHI_third_party_libraries.cmake @@ -127,6 +127,7 @@ if( PYTHONINTERP_FOUND ) find_python_module("sphinx") find_python_module("sklearn") find_python_module("ot") + find_python_module("pybind11") endif() if(NOT GUDHI_PYTHON_PATH) diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index bec38305..edb1ba02 100644 --- a/src/python/CMakeLists.txt +++ b/src/python/CMakeLists.txt @@ -407,32 +407,37 @@ endif(CGAL_FOUND) if(SCIPY_FOUND) if(SKLEARN_FOUND) if(OT_FOUND) - if(NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.11.0) - 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_PYTHON_PATH STREQUAL "src/python") - 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) + if(PYBIND11_FOUND) + if(NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.11.0) + 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_PYTHON_PATH STREQUAL "src/python") + 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) + 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) - # Set missing or not modules - set(GUDHI_MODULES ${GUDHI_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MODULES") - else(NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.11.0) - message("++ Python documentation module will not be compiled because it requires a Eigen3 and CGAL version >= 4.11.0") + # Set missing or not modules + set(GUDHI_MODULES ${GUDHI_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MODULES") + else(NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.11.0) + message("++ Python documentation module will not be compiled because it requires a Eigen3 and CGAL version >= 4.11.0") + set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MISSING_MODULES") + endif(NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.11.0) + else(PYBIND11_FOUND) + message("++ Python documentation module will not be compiled because pybind11 was not found") set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MISSING_MODULES") - endif(NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.11.0) + endif(PYBIND11_FOUND) else(OT_FOUND) message("++ Python documentation module will not be compiled because POT was not found") set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MISSING_MODULES") -- cgit v1.2.3 From 7568b34c56e6a6102507df1be0029a0259f2afa7 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Thu, 26 Dec 2019 20:37:19 +0100 Subject: Checkout submodules in circleci --- .circleci/config.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5e45bc14..51b6c019 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -50,6 +50,8 @@ jobs: - run: name: Build and test python module. Generates and tests the python documentation command: | + git submodule init + git submodule update mkdir build; cd build; cmake -DUSER_VERSION_DIR=version ..; @@ -74,6 +76,8 @@ jobs: - run: name: Generates the C++ documentation with doxygen command: | + git submodule init + git submodule update mkdir build; cd build; cmake -DCMAKE_BUILD_TYPE=Release -DWITH_GUDHI_EXAMPLE=OFF -DWITH_GUDHI_TEST=OFF -DWITH_GUDHI_UTILITIES=OFF -DWITH_GUDHI_PYTHON=OFF -DUSER_VERSION_DIR=version ..; @@ -93,4 +97,4 @@ workflows: - tests - utils - python - - doxygen \ No newline at end of file + - doxygen -- cgit v1.2.3 From b8701d847db37b80a58770e00b91494889df00e8 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Fri, 27 Dec 2019 00:56:08 +0100 Subject: Expose more options --- src/python/doc/wasserstein_distance_user.rst | 4 ++-- src/python/gudhi/hera.cc | 31 +++++++++++++++++++++------- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/python/doc/wasserstein_distance_user.rst b/src/python/doc/wasserstein_distance_user.rst index 13f6f1af..6cd7f3a0 100644 --- a/src/python/doc/wasserstein_distance_user.rst +++ b/src/python/doc/wasserstein_distance_user.rst @@ -17,8 +17,8 @@ and Cluster for Persistence Diagrams via Optimal Transport". .. autofunction:: gudhi.wasserstein.wasserstein_distance This other implementation comes from `Hera -`_ and is based on `"Geometry -Helps to Compare Persistence Diagrams." +`_ (BSD-3-Clause) and is +based on `"Geometry Helps to Compare Persistence Diagrams." `_ by Michael Kerber, Dmitriy Morozov, and Arnur Nigmetov, at ALENEX 2016. diff --git a/src/python/gudhi/hera.cc b/src/python/gudhi/hera.cc index 04f5990f..898040fb 100644 --- a/src/python/gudhi/hera.cc +++ b/src/python/gudhi/hera.cc @@ -12,7 +12,6 @@ typedef py::array_t Dgm; namespace hera { template <> struct DiagramTraits{ - //using Container = void; using PointType = std::array; using RealType = double; @@ -22,15 +21,17 @@ template <> struct DiagramTraits{ } double wasserstein_distance( - Dgm d1, - Dgm d2) + Dgm d1, Dgm d2, + double wasserstein_power, double internal_p, + double delta) { py::buffer_info buf1 = d1.request(); py::buffer_info buf2 = d2.request(); - if(buf1.ndim!=2 || buf1.shape[1]!=2) - throw std::runtime_error("Diagram 1 must be an array of size n x 2"); - if(buf2.ndim!=2 || buf2.shape[1]!=2) + // shape (n,2) or (0) for empty + if((buf1.ndim!=2 || buf1.shape[1]!=2) && (buf1.ndim!=1 || buf1.shape[0]!=0)) throw std::runtime_error("Diagram 1 must be an array of size n x 2"); + if((buf2.ndim!=2 || buf2.shape[1]!=2) && (buf2.ndim!=1 || buf2.shape[0]!=0)) + throw std::runtime_error("Diagram 2 must be an array of size n x 2"); typedef hera::DiagramTraits::PointType Point; auto p1 = (Point*)buf1.ptr; auto p2 = (Point*)buf2.ptr; @@ -38,17 +39,33 @@ double wasserstein_distance( auto diag2 = boost::make_iterator_range(p2, p2+buf2.shape[0]); hera::AuctionParams params; + params.wasserstein_power = wasserstein_power; + // hera encodes infinity as -1... + if(std::isinf(internal_p)) internal_p = hera::get_infinity(); + params.internal_p = internal_p; + params.delta = delta; + // The extra parameters are purposedly not exposed for now. return hera::wasserstein_dist(diag1, diag2, params); } PYBIND11_MODULE(hera, m) { m.def("wasserstein_distance", &wasserstein_distance, py::arg("X"), py::arg("Y"), + // Should we name those q, p and d instead? + py::arg("wasserstein_power") = 1, + py::arg("internal_p") = std::numeric_limits::infinity(), + py::arg("delta") = .01, R"pbdoc( - Compute the Wasserstein distance between two diagrams + Compute the Wasserstein distance between two diagrams. Points at infinity are supported. Parameters: X (n x 2 numpy array): First diagram Y (n x 2 numpy array): Second diagram + wasserstein_power (float): Wasserstein degree W_q + internal_p (float): Internal Minkowski norm L^p in R^2 + delta (float): Relative error 1+delta + + Returns: + float: Approximate Wasserstein distance W_q(X,Y) )pbdoc"); } -- cgit v1.2.3 From ec8b343dafdb70acc4a948ef737d83a3cc4d9f7b Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Fri, 27 Dec 2019 12:43:03 +0100 Subject: Handle submodules in appveyor --- .appveyor.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.appveyor.yml b/.appveyor.yml index 3a33ed62..34f42dea 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -39,6 +39,7 @@ init: install: + - git submodule update --init - vcpkg install tbb:x64-windows boost-disjoint-sets:x64-windows boost-serialization:x64-windows boost-date-time:x64-windows boost-system:x64-windows boost-filesystem:x64-windows boost-units:x64-windows boost-thread:x64-windows boost-program-options:x64-windows eigen3:x64-windows mpfr:x64-windows mpir:x64-windows cgal:x64-windows - SET PATH=c:\Tools\vcpkg\installed\x64-windows\bin;%PATH% - SET PATH=%PYTHON%;%PYTHON%\Scripts;%PYTHON%\Library\bin;%PATH% -- cgit v1.2.3 From ef4a688e07e070b190caf267a64fedd607830ee7 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Thu, 2 Jan 2020 20:25:04 +0100 Subject: Update Hera --- ext/hera | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/hera b/ext/hera index 5a59cfad..9a899718 160000 --- a/ext/hera +++ b/ext/hera @@ -1 +1 @@ -Subproject commit 5a59cfad45c155f8af89c2c6d82db2848d52a953 +Subproject commit 9a89971855acefe39dce0e2adadf53b88ca8f683 -- cgit v1.2.3 From a7f3167ffb465bd6d1e3b9e40bc6f1c35daf87fc Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Mon, 20 Jan 2020 16:43:37 +0100 Subject: Simplify the pybind11 code --- src/python/doc/wasserstein_distance_user.rst | 5 +++-- src/python/gudhi/hera.cc | 19 +++++-------------- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/src/python/doc/wasserstein_distance_user.rst b/src/python/doc/wasserstein_distance_user.rst index 6cd7f3a0..355ad247 100644 --- a/src/python/doc/wasserstein_distance_user.rst +++ b/src/python/doc/wasserstein_distance_user.rst @@ -11,8 +11,9 @@ Definition Functions --------- -This implementation is based on ideas from "Large Scale Computation of Means -and Cluster for Persistence Diagrams via Optimal Transport". +This implementation uses the Python Optimal Transport library and is based on +ideas from "Large Scale Computation of Means and Cluster for Persistence +Diagrams via Optimal Transport". .. autofunction:: gudhi.wasserstein.wasserstein_distance diff --git a/src/python/gudhi/hera.cc b/src/python/gudhi/hera.cc index 898040fb..61f0da10 100644 --- a/src/python/gudhi/hera.cc +++ b/src/python/gudhi/hera.cc @@ -10,16 +10,6 @@ namespace py = pybind11; typedef py::array_t Dgm; -namespace hera { -template <> struct DiagramTraits{ - using PointType = std::array; - using RealType = double; - - static RealType get_x(const PointType& p) { return std::get<0>(p); } - static RealType get_y(const PointType& p) { return std::get<1>(p); } -}; -} - double wasserstein_distance( Dgm d1, Dgm d2, double wasserstein_power, double internal_p, @@ -32,7 +22,7 @@ double wasserstein_distance( throw std::runtime_error("Diagram 1 must be an array of size n x 2"); if((buf2.ndim!=2 || buf2.shape[1]!=2) && (buf2.ndim!=1 || buf2.shape[0]!=0)) throw std::runtime_error("Diagram 2 must be an array of size n x 2"); - typedef hera::DiagramTraits::PointType Point; + typedef std::array Point; auto p1 = (Point*)buf1.ptr; auto p2 = (Point*)buf2.ptr; auto diag1 = boost::make_iterator_range(p1, p1+buf1.shape[0]); @@ -52,16 +42,17 @@ PYBIND11_MODULE(hera, m) { m.def("wasserstein_distance", &wasserstein_distance, py::arg("X"), py::arg("Y"), // Should we name those q, p and d instead? - py::arg("wasserstein_power") = 1, + py::arg("order") = 1, py::arg("internal_p") = std::numeric_limits::infinity(), py::arg("delta") = .01, R"pbdoc( - Compute the Wasserstein distance between two diagrams. Points at infinity are supported. + Compute the Wasserstein distance between two diagrams. + Points at infinity are supported. Parameters: X (n x 2 numpy array): First diagram Y (n x 2 numpy array): Second diagram - wasserstein_power (float): Wasserstein degree W_q + order (float): Wasserstein exponent W_q internal_p (float): Internal Minkowski norm L^p in R^2 delta (float): Relative error 1+delta -- cgit v1.2.3 From 1783c047302414bbcd6ff4f7c73dcc5a6501fd81 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Mon, 20 Jan 2020 17:51:28 +0100 Subject: Share tests for wasserstein_distance --- src/python/test/test_wasserstein_distance.py | 59 ++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 17 deletions(-) diff --git a/src/python/test/test_wasserstein_distance.py b/src/python/test/test_wasserstein_distance.py index 43dda77e..46a7079f 100755 --- a/src/python/test/test_wasserstein_distance.py +++ b/src/python/test/test_wasserstein_distance.py @@ -8,41 +8,66 @@ - YYYY/MM Author: Description of the modification """ -from gudhi.wasserstein import wasserstein_distance +from gudhi.wasserstein import wasserstein_distance as pot +from gudhi.hera import wasserstein_distance as hera import numpy as np __author__ = "Theo Lacombe" __copyright__ = "Copyright (C) 2019 Inria" __license__ = "MIT" - -def test_basic_wasserstein(): +def _basic_wasserstein(wasserstein_distance, delta, test_infinity=True): diag1 = np.array([[2.7, 3.7], [9.6, 14.0], [34.2, 34.974]]) diag2 = np.array([[2.8, 4.45], [9.5, 14.1]]) diag3 = np.array([[0, 2], [4, 6]]) diag4 = np.array([[0, 3], [4, 8]]) - emptydiag = np.array([[]]) + emptydiag = np.array([]) + + # We just need to handle positive numbers here + def approx(a, b): + f = 1 + delta + return a <= b*f and b <= a*f assert wasserstein_distance(emptydiag, emptydiag, internal_p=2., order=1.) == 0. assert wasserstein_distance(emptydiag, emptydiag, internal_p=np.inf, order=1.) == 0. assert wasserstein_distance(emptydiag, emptydiag, internal_p=np.inf, order=2.) == 0. assert wasserstein_distance(emptydiag, emptydiag, internal_p=2., order=2.) == 0. - assert wasserstein_distance(diag3, emptydiag, internal_p=np.inf, order=1.) == 2. - assert wasserstein_distance(diag3, emptydiag, internal_p=1., order=1.) == 4. + assert approx(wasserstein_distance(diag3, emptydiag, internal_p=np.inf, order=1.), 2.) + assert approx(wasserstein_distance(diag3, emptydiag, internal_p=1., order=1.), 4.) + + assert approx(wasserstein_distance(diag4, emptydiag, internal_p=1., order=2.), 5.) # thank you Pythagorician triplets + assert approx(wasserstein_distance(diag4, emptydiag, internal_p=np.inf, order=2.), 2.5) + assert approx(wasserstein_distance(diag4, emptydiag, internal_p=2., order=2.), 3.5355339059327378) + + assert approx(wasserstein_distance(diag1, diag2, internal_p=2., order=1.) , 1.4453593023967701) + assert approx(wasserstein_distance(diag1, diag2, internal_p=2.35, order=1.74), 0.9772734057168739) + + assert approx(wasserstein_distance(diag1, emptydiag, internal_p=2.35, order=1.7863), 3.141592214572228) + + assert approx(wasserstein_distance(diag3, diag4, internal_p=1., order=1.), 3.) + assert approx(wasserstein_distance(diag3, diag4, internal_p=np.inf, order=1.), 3.) # no diag matching here + assert approx(wasserstein_distance(diag3, diag4, internal_p=np.inf, order=2.), np.sqrt(5)) + assert approx(wasserstein_distance(diag3, diag4, internal_p=1., order=2.), np.sqrt(5)) + assert approx(wasserstein_distance(diag3, diag4, internal_p=4.5, order=2.), np.sqrt(5)) + + if(not test_infinity): + return - assert wasserstein_distance(diag4, emptydiag, internal_p=1., order=2.) == 5. # thank you Pythagorician triplets - assert wasserstein_distance(diag4, emptydiag, internal_p=np.inf, order=2.) == 2.5 - assert wasserstein_distance(diag4, emptydiag, internal_p=2., order=2.) == 3.5355339059327378 + diag5 = np.array([[0, 3], [4, np.inf]]) + diag6 = np.array([[7, 8], [4, 6], [3, np.inf]]) - assert wasserstein_distance(diag1, diag2, internal_p=2., order=1.) == 1.4453593023967701 - assert wasserstein_distance(diag1, diag2, internal_p=2.35, order=1.74) == 0.9772734057168739 + assert wasserstein_distance(diag4, diag5) == np.inf + assert approx(wasserstein_distance(diag5, diag6, order=1, internal_p=np.inf), 4.) - assert wasserstein_distance(diag1, emptydiag, internal_p=2.35, order=1.7863) == 3.141592214572228 +def hera_wrap(delta): + def fun(*kargs,**kwargs): + return hera(*kargs,**kwargs,delta=delta) + return fun - assert wasserstein_distance(diag3, diag4, internal_p=1., order=1.) == 3. - assert wasserstein_distance(diag3, diag4, internal_p=np.inf, order=1.) == 3. # no diag matching here - assert wasserstein_distance(diag3, diag4, internal_p=np.inf, order=2.) == np.sqrt(5) - assert wasserstein_distance(diag3, diag4, internal_p=1., order=2.) == np.sqrt(5) - assert wasserstein_distance(diag3, diag4, internal_p=4.5, order=2.) == np.sqrt(5) +def test_wasserstein_distance_pot(): + _basic_wasserstein(pot, 1e-15, False) +def test_wasserstein_distance_hera(): + _basic_wasserstein(hera_wrap(1e-12), 1e-12) + _basic_wasserstein(hera_wrap(.1), .1) -- cgit v1.2.3 From a02397ba04d707dc79736ce2f598ebb74459bf90 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Mon, 20 Jan 2020 18:20:45 +0100 Subject: Mention submodules in README --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 167a38b3..f7e3d70c 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,15 @@ The GUDHI library is a generic open source C++ library, with a Python interface, for Topological Data Analysis (TDA) and Higher Dimensional Geometry Understanding. The library offers state-of-the-art data structures and algorithms to construct simplicial complexes and compute persistent homology. +# Source code + +We recommend that users get official releases from [the GUDHI website](https://gudhi.inria.fr/). + +For potential contributors, to fully checkout GUDHI, after cloning the git repository, you may also need to checkout its submodules using +```sh +git submodule update --init +``` + # Compilation and installation To install GUDHI, you can follow the [C++ compilation procedure](https://gudhi.inria.fr/doc/latest/installation.html), the [Python compilation procedure](https://gudhi.inria.fr/python/latest/installation.html), use our [conda-forge package](https://gudhi.inria.fr/conda/), or [go with Docker](https://gudhi.inria.fr/dockerfile/). -- cgit v1.2.3 From 4c8e4549818bb033b148632abba4eae9ae9407c3 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Mon, 20 Jan 2020 19:17:14 +0100 Subject: Add pybind11 to Dockerfile_gudhi_installation --- Dockerfile_gudhi_installation | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Dockerfile_gudhi_installation b/Dockerfile_gudhi_installation index 9fe20730..76b2628b 100644 --- a/Dockerfile_gudhi_installation +++ b/Dockerfile_gudhi_installation @@ -42,6 +42,7 @@ RUN apt-get install -y make \ python3-pip \ python3-pytest \ python3-tk \ + python3-pybind11 \ libfreetype6-dev \ pkg-config \ curl @@ -62,4 +63,4 @@ RUN curl -LO "https://github.com/GUDHI/gudhi-devel/releases/download/tags%2Fgudh && make all test install \ && cmake -DWITH_GUDHI_PYTHON=ON . \ && cd python \ -&& python3 setup.py install \ No newline at end of file +&& python3 setup.py install -- cgit v1.2.3 From 48952ee2ad76e2f4e5ada7f038ff88dee496272a Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Thu, 30 Jan 2020 11:58:52 +0100 Subject: Allow use of preinstalled Hera --- src/cmake/modules/GUDHI_third_party_libraries.cmake | 3 +++ src/python/setup.py.in | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cmake/modules/GUDHI_third_party_libraries.cmake b/src/cmake/modules/GUDHI_third_party_libraries.cmake index cb9f9033..359d1c12 100644 --- a/src/cmake/modules/GUDHI_third_party_libraries.cmake +++ b/src/cmake/modules/GUDHI_third_party_libraries.cmake @@ -35,6 +35,9 @@ if(CGAL_FOUND) include( ${CGAL_USE_FILE} ) endif() +# For those who dislike bundled dependencies, this indicates where to find a preinstalled Hera. +set(HERA_WASSERSTEIN_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/ext/hera/geom_matching/wasserstein/include CACHE PATH "Directory where one can find Hera's wasserstein.h") + option(WITH_GUDHI_USE_TBB "Build with Intel TBB parallelization" ON) # Find TBB package for parallel sort - not mandatory, just optional. diff --git a/src/python/setup.py.in b/src/python/setup.py.in index 08c46ced..851188bd 100644 --- a/src/python/setup.py.in +++ b/src/python/setup.py.in @@ -63,7 +63,7 @@ ext_modules.append(Extension( sources = [source_dir + 'hera.cc'], language = 'c++', include_dirs = include_dirs + - ['@CMAKE_SOURCE_DIR@/ext/hera/geom_matching/wasserstein/include', + ['@HERA_WASSERSTEIN_INCLUDE_DIR@', get_pybind_include(False), get_pybind_include(True)], extra_compile_args=extra_compile_args + [@GUDHI_PYBIND11_EXTRA_COMPILE_ARGS@], )) -- cgit v1.2.3 From 09cf8752c50f25acac0eb1a6369624399431b2ca Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Thu, 30 Jan 2020 12:14:20 +0100 Subject: Document dependency on pybind11 --- src/python/doc/installation.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/python/doc/installation.rst b/src/python/doc/installation.rst index 40f3f44b..f8456799 100644 --- a/src/python/doc/installation.rst +++ b/src/python/doc/installation.rst @@ -257,6 +257,14 @@ The :doc:`Wasserstein distance ` module requires `POT `_, a library that provides several solvers for optimization problems related to Optimal Transport. +Pybind11 +======== + +The :doc:`Wasserstein distance ` module requires +`pybind11 `_, a library that provides +interoperability between C++ and Python, for its interface to `Hera +`_. + Scikit-learn ============ -- cgit v1.2.3 From 09a0757357f89ff91fdafb535a0b250b937ee88b Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Thu, 6 Feb 2020 17:09:17 +0100 Subject: 3.1.1 release candidate 1 --- CMakeGUDHIVersion.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeGUDHIVersion.txt b/CMakeGUDHIVersion.txt index ed19ecfb..ec9794ce 100644 --- a/CMakeGUDHIVersion.txt +++ b/CMakeGUDHIVersion.txt @@ -1,6 +1,6 @@ set (GUDHI_MAJOR_VERSION 3) set (GUDHI_MINOR_VERSION 1) -set (GUDHI_PATCH_VERSION 0) +set (GUDHI_PATCH_VERSION 1.rc1) set(GUDHI_VERSION ${GUDHI_MAJOR_VERSION}.${GUDHI_MINOR_VERSION}.${GUDHI_PATCH_VERSION}) message(STATUS "GUDHI version : ${GUDHI_VERSION}") -- cgit v1.2.3 From 57eabeaa00f724fe60e1ee69b5db3c35a765e198 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Thu, 6 Feb 2020 17:16:08 +0100 Subject: Release note for version 3.1.1 --- next_release.md | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/next_release.md b/next_release.md index 26d4fca5..deb04085 100644 --- a/next_release.md +++ b/next_release.md @@ -1,20 +1,6 @@ -We are pleased to announce the release 3.X.X of the GUDHI library. - -As a major new feature, the GUDHI library now offers ... - -We are now using GitHub to develop the GUDHI library, do not hesitate to [fork the GUDHI project on GitHub](https://github.com/GUDHI/gudhi-devel). From a user point of view, we recommend to download GUDHI user version (gudhi.3.X.X.tar.gz). - -Below is a list of changes made since Gudhi 3.1.0: - -- [Module](link) - - ... - -- [Module](link) - - ... - -- Miscellaneous - - See the list of [bug fixes](https://github.com/GUDHI/gudhi-devel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A3.X.X+). +gudhi-3.1.1 is a bug-fix release. In particular, it fixes the installation of the Python representation module. +The [list of bugs that were solved since gudhi-3.1.0](https://github.com/GUDHI/gudhi-devel/issues?q=label%3A3.1.1+is%3Aclosed) is available on GitHub. All modules are distributed under the terms of the MIT license. However, there are still GPL dependencies for many modules. We invite you to check our [license dedicated web page](https://gudhi.inria.fr/licensing/) for further details. @@ -25,4 +11,4 @@ We provide [bibtex entries](https://gudhi.inria.fr/doc/latest/_citation.html) fo Feel free to [contact us](https://gudhi.inria.fr/contact/) in case you have any questions or remarks. -For further information about downloading and installing the library ([C++](https://gudhi.inria.fr/doc/3.1.0.rc1/installation.html) or [Python](https://gudhi.inria.fr/python/3.1.0.rc1/installation.html)), please visit the [GUDHI web site](https://gudhi.inria.fr/). +For further information about downloading and installing the library ([C++](https://gudhi.inria.fr/doc/3.1.1.rc1/installation.html) or [Python](https://gudhi.inria.fr/python/3.1.1.rc1/installation.html)), please visit the [GUDHI web site](https://gudhi.inria.fr/). -- cgit v1.2.3 From 00c46d21df80c51a0c83e412230f4583a5803fc9 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Thu, 6 Feb 2020 19:27:36 +0100 Subject: Print pybind11 version, protect test --- src/python/CMakeLists.txt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index edb1ba02..090a7446 100644 --- a/src/python/CMakeLists.txt +++ b/src/python/CMakeLists.txt @@ -32,6 +32,10 @@ function( add_gudhi_debug_info DEBUG_INFO ) endfunction( add_gudhi_debug_info ) if(PYTHONINTERP_FOUND) + if(PYBIND11_FOUND) + add_gudhi_debug_info("Pybind11 version ${PYBIND11_VERSION}") + set(GUDHI_PYTHON_MODULES_EXTRA "${GUDHI_PYTHON_MODULES_EXTRA}'hera', ") + endif() if(CYTHON_FOUND) set(GUDHI_PYTHON_MODULES "${GUDHI_PYTHON_MODULES}'off_reader', ") set(GUDHI_PYTHON_MODULES "${GUDHI_PYTHON_MODULES}'simplex_tree', ") @@ -391,9 +395,9 @@ endif(CGAL_FOUND) add_gudhi_py_test(test_reader_utils) # Wasserstein - if(OT_FOUND) + if(OT_FOUND AND PYBIND11_FOUND) add_gudhi_py_test(test_wasserstein_distance) - endif(OT_FOUND) + endif() # Representations if(SKLEARN_FOUND AND MATPLOTLIB_FOUND) -- cgit v1.2.3 From 08b82e8a606a7fcd1219e7074cc2f15340090e59 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Thu, 6 Feb 2020 21:20:17 +0100 Subject: Make pybind11 mandatory and simplify The use of install_requires and setup_requires looks strange, I would expect cython in setup_requires, not install_requires. But setup_requires doesn't seem to work so well anyway. --- src/python/doc/installation.rst | 13 +++---------- src/python/setup.py.in | 19 +++---------------- 2 files changed, 6 insertions(+), 26 deletions(-) diff --git a/src/python/doc/installation.rst b/src/python/doc/installation.rst index f8456799..d459145b 100644 --- a/src/python/doc/installation.rst +++ b/src/python/doc/installation.rst @@ -14,10 +14,11 @@ Compiling ********* The library uses c++14 and requires `Boost `_ ≥ 1.56.0, `CMake `_ ≥ 3.1 to generate makefiles, -`NumPy `_ and `Cython `_ to compile +`NumPy `_, `Cython `_ and +`pybind11 `_ to compile the GUDHI Python module. It is a multi-platform library and compiles on Linux, Mac OSX and Visual -Studio 2015. +Studio 2017. On `Windows `_ , only Python ≥ 3.5 are available because of the required Visual Studio version. @@ -257,14 +258,6 @@ The :doc:`Wasserstein distance ` module requires `POT `_, a library that provides several solvers for optimization problems related to Optimal Transport. -Pybind11 -======== - -The :doc:`Wasserstein distance ` module requires -`pybind11 `_, a library that provides -interoperability between C++ and Python, for its interface to `Hera -`_. - Scikit-learn ============ diff --git a/src/python/setup.py.in b/src/python/setup.py.in index 851188bd..d05e4675 100644 --- a/src/python/setup.py.in +++ b/src/python/setup.py.in @@ -12,6 +12,7 @@ from setuptools import setup, Extension from Cython.Build import cythonize from numpy import get_include as numpy_get_include import sys +import pybind11 __author__ = "Vincent Rouvreau" __copyright__ = "Copyright (C) 2016 Inria" @@ -27,20 +28,6 @@ library_dirs=[@GUDHI_PYTHON_LIBRARY_DIRS@] include_dirs = [numpy_get_include(), '@CMAKE_CURRENT_SOURCE_DIR@/gudhi/', @GUDHI_PYTHON_INCLUDE_DIRS@] runtime_library_dirs=[@GUDHI_PYTHON_RUNTIME_LIBRARY_DIRS@] -# Copied from https://github.com/pybind/python_example/blob/master/setup.py -class get_pybind_include(object): - """Helper class to determine the pybind11 include path - The purpose of this class is to postpone importing pybind11 - until it is actually installed, so that the ``get_include()`` - method can be invoked. """ - - def __init__(self, user=False): - self.user = user - - def __str__(self): - import pybind11 - return pybind11.get_include(self.user) - # Create ext_modules list from module list ext_modules = [] for module in modules: @@ -64,7 +51,7 @@ ext_modules.append(Extension( language = 'c++', include_dirs = include_dirs + ['@HERA_WASSERSTEIN_INCLUDE_DIR@', - get_pybind_include(False), get_pybind_include(True)], + pybind11.get_include(False), pybind11.get_include(True)], extra_compile_args=extra_compile_args + [@GUDHI_PYBIND11_EXTRA_COMPILE_ARGS@], )) @@ -76,6 +63,6 @@ setup( version='@GUDHI_VERSION@', url='http://gudhi.gforge.inria.fr/', ext_modules = ext_modules, - install_requires = ['cython','numpy >= 1.9','pybind11',], + install_requires = ['cython','numpy >= 1.9',], setup_requires = ['numpy >= 1.9','pybind11',], ) -- cgit v1.2.3 From 518c619d578dc6f168b6369417f15872e3cd0056 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Thu, 6 Feb 2020 21:54:44 +0100 Subject: use bibtex --- biblio/bibliography.bib | 12 ++++++++++++ src/python/doc/wasserstein_distance_user.rst | 10 +++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/biblio/bibliography.bib b/biblio/bibliography.bib index a1b951e0..3bbe7960 100644 --- a/biblio/bibliography.bib +++ b/biblio/bibliography.bib @@ -1180,3 +1180,15 @@ language={English} booktitle = {In Neural Information Processing Systems}, year = {2007} } +@inproceedings{10.5555/3327546.3327645, +author = {Lacombe, Th\'{e}o and Cuturi, Marco and Oudot, Steve}, +title = {Large Scale Computation of Means and Clusters for Persistence Diagrams Using Optimal Transport}, +year = {2018}, +publisher = {Curran Associates Inc.}, +address = {Red Hook, NY, USA}, +booktitle = {Proceedings of the 32nd International Conference on Neural Information Processing Systems}, +pages = {9792–9802}, +numpages = {11}, +location = {Montr\'{e}al, Canada}, +series = {NIPS’18} +} diff --git a/src/python/doc/wasserstein_distance_user.rst b/src/python/doc/wasserstein_distance_user.rst index 648cc568..99445b99 100644 --- a/src/python/doc/wasserstein_distance_user.rst +++ b/src/python/doc/wasserstein_distance_user.rst @@ -13,15 +13,15 @@ Functions --------- This implementation uses the Python Optimal Transport library and is based on ideas from "Large Scale Computation of Means and Cluster for Persistence -Diagrams via Optimal Transport". +Diagrams via Optimal Transport" :cite:`10.5555/3327546.3327645`. .. autofunction:: gudhi.wasserstein.wasserstein_distance This other implementation comes from `Hera -`_ (BSD-3-Clause) and is -based on `"Geometry Helps to Compare Persistence Diagrams." -`_ by Michael Kerber, Dmitriy -Morozov, and Arnur Nigmetov, at ALENEX 2016. +`_ (BSD-3-Clause) which is +based on "Geometry Helps to Compare Persistence Diagrams" +:cite:`Kerber:2017:GHC:3047249.3064175` by Michael Kerber, Dmitriy +Morozov, and Arnur Nigmetov. .. autofunction:: gudhi.hera.wasserstein_distance -- cgit v1.2.3 From e8c908469cb4ac547d4fd46ad8daf5ee21739f58 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Thu, 6 Feb 2020 22:14:08 +0100 Subject: pytest.approx --- src/python/test/test_wasserstein_distance.py | 34 ++++++++++++++-------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/python/test/test_wasserstein_distance.py b/src/python/test/test_wasserstein_distance.py index 46a7079f..6a14c50e 100755 --- a/src/python/test/test_wasserstein_distance.py +++ b/src/python/test/test_wasserstein_distance.py @@ -11,6 +11,7 @@ from gudhi.wasserstein import wasserstein_distance as pot from gudhi.hera import wasserstein_distance as hera import numpy as np +import pytest __author__ = "Theo Lacombe" __copyright__ = "Copyright (C) 2019 Inria" @@ -24,32 +25,31 @@ def _basic_wasserstein(wasserstein_distance, delta, test_infinity=True): emptydiag = np.array([]) # We just need to handle positive numbers here - def approx(a, b): - f = 1 + delta - return a <= b*f and b <= a*f + def approx(x): + return pytest.approx(x, rel=delta) assert wasserstein_distance(emptydiag, emptydiag, internal_p=2., order=1.) == 0. assert wasserstein_distance(emptydiag, emptydiag, internal_p=np.inf, order=1.) == 0. assert wasserstein_distance(emptydiag, emptydiag, internal_p=np.inf, order=2.) == 0. assert wasserstein_distance(emptydiag, emptydiag, internal_p=2., order=2.) == 0. - assert approx(wasserstein_distance(diag3, emptydiag, internal_p=np.inf, order=1.), 2.) - assert approx(wasserstein_distance(diag3, emptydiag, internal_p=1., order=1.), 4.) + assert wasserstein_distance(diag3, emptydiag, internal_p=np.inf, order=1.) == approx(2.) + assert wasserstein_distance(diag3, emptydiag, internal_p=1., order=1.) == approx(4.) - assert approx(wasserstein_distance(diag4, emptydiag, internal_p=1., order=2.), 5.) # thank you Pythagorician triplets - assert approx(wasserstein_distance(diag4, emptydiag, internal_p=np.inf, order=2.), 2.5) - assert approx(wasserstein_distance(diag4, emptydiag, internal_p=2., order=2.), 3.5355339059327378) + assert wasserstein_distance(diag4, emptydiag, internal_p=1., order=2.) == approx(5.) # thank you Pythagorician triplets + assert wasserstein_distance(diag4, emptydiag, internal_p=np.inf, order=2.) == approx(2.5) + assert wasserstein_distance(diag4, emptydiag, internal_p=2., order=2.) == approx(3.5355339059327378) - assert approx(wasserstein_distance(diag1, diag2, internal_p=2., order=1.) , 1.4453593023967701) - assert approx(wasserstein_distance(diag1, diag2, internal_p=2.35, order=1.74), 0.9772734057168739) + assert wasserstein_distance(diag1, diag2, internal_p=2., order=1.) == approx(1.4453593023967701) + assert wasserstein_distance(diag1, diag2, internal_p=2.35, order=1.74) == approx(0.9772734057168739) - assert approx(wasserstein_distance(diag1, emptydiag, internal_p=2.35, order=1.7863), 3.141592214572228) + assert wasserstein_distance(diag1, emptydiag, internal_p=2.35, order=1.7863) == approx(3.141592214572228) - assert approx(wasserstein_distance(diag3, diag4, internal_p=1., order=1.), 3.) - assert approx(wasserstein_distance(diag3, diag4, internal_p=np.inf, order=1.), 3.) # no diag matching here - assert approx(wasserstein_distance(diag3, diag4, internal_p=np.inf, order=2.), np.sqrt(5)) - assert approx(wasserstein_distance(diag3, diag4, internal_p=1., order=2.), np.sqrt(5)) - assert approx(wasserstein_distance(diag3, diag4, internal_p=4.5, order=2.), np.sqrt(5)) + assert wasserstein_distance(diag3, diag4, internal_p=1., order=1.) == approx(3.) + assert wasserstein_distance(diag3, diag4, internal_p=np.inf, order=1.) == approx(3.) # no diag matching here + assert wasserstein_distance(diag3, diag4, internal_p=np.inf, order=2.) == approx(np.sqrt(5)) + assert wasserstein_distance(diag3, diag4, internal_p=1., order=2.) == approx(np.sqrt(5)) + assert wasserstein_distance(diag3, diag4, internal_p=4.5, order=2.) == approx(np.sqrt(5)) if(not test_infinity): return @@ -58,7 +58,7 @@ def _basic_wasserstein(wasserstein_distance, delta, test_infinity=True): diag6 = np.array([[7, 8], [4, 6], [3, np.inf]]) assert wasserstein_distance(diag4, diag5) == np.inf - assert approx(wasserstein_distance(diag5, diag6, order=1, internal_p=np.inf), 4.) + assert wasserstein_distance(diag5, diag6, order=1, internal_p=np.inf) == approx(4.) def hera_wrap(delta): def fun(*kargs,**kwargs): -- cgit v1.2.3 From cbe3d0d2b16e19048928ae308851c4312cca42c8 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Fri, 7 Feb 2020 14:37:06 +0100 Subject: Release note and Version for 3.1.1 version --- CMakeGUDHIVersion.txt | 2 +- next_release.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeGUDHIVersion.txt b/CMakeGUDHIVersion.txt index ec9794ce..0f827b9e 100644 --- a/CMakeGUDHIVersion.txt +++ b/CMakeGUDHIVersion.txt @@ -1,6 +1,6 @@ set (GUDHI_MAJOR_VERSION 3) set (GUDHI_MINOR_VERSION 1) -set (GUDHI_PATCH_VERSION 1.rc1) +set (GUDHI_PATCH_VERSION 1) set(GUDHI_VERSION ${GUDHI_MAJOR_VERSION}.${GUDHI_MINOR_VERSION}.${GUDHI_PATCH_VERSION}) message(STATUS "GUDHI version : ${GUDHI_VERSION}") diff --git a/next_release.md b/next_release.md index deb04085..78270d15 100644 --- a/next_release.md +++ b/next_release.md @@ -11,4 +11,4 @@ We provide [bibtex entries](https://gudhi.inria.fr/doc/latest/_citation.html) fo Feel free to [contact us](https://gudhi.inria.fr/contact/) in case you have any questions or remarks. -For further information about downloading and installing the library ([C++](https://gudhi.inria.fr/doc/3.1.1.rc1/installation.html) or [Python](https://gudhi.inria.fr/python/3.1.1.rc1/installation.html)), please visit the [GUDHI web site](https://gudhi.inria.fr/). +For further information about downloading and installing the library ([C++](https://gudhi.inria.fr/doc/3.1.1/installation.html) or [Python](https://gudhi.inria.fr/python/3.1.1/installation.html)), please visit the [GUDHI web site](https://gudhi.inria.fr/). -- cgit v1.2.3 From 5c037fb06250e93ad04bb45bdbceb937701e03fa Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Fri, 7 Feb 2020 16:32:33 +0100 Subject: Bad link for last version --- src/common/doc/header.html | 2 +- src/python/doc/_templates/layout.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/doc/header.html b/src/common/doc/header.html index 9fdb2321..99ab6bb7 100644 --- a/src/common/doc/header.html +++ b/src/common/doc/header.html @@ -56,7 +56,7 @@ $extrastylesheet Download diff --git a/src/python/doc/_templates/layout.html b/src/python/doc/_templates/layout.html index 2f2d9c72..a672a281 100644 --- a/src/python/doc/_templates/layout.html +++ b/src/python/doc/_templates/layout.html @@ -201,7 +201,7 @@ Download -- cgit v1.2.3 From 7be3cfef278917dc0c1905588ae88314273909d4 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Fri, 7 Feb 2020 19:38:27 +0100 Subject: More uniform notations between the 2 wassersteins --- src/python/gudhi/wasserstein.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/python/gudhi/wasserstein.py b/src/python/gudhi/wasserstein.py index db5ddff2..b1cfd588 100644 --- a/src/python/gudhi/wasserstein.py +++ b/src/python/gudhi/wasserstein.py @@ -27,8 +27,8 @@ def _build_dist_matrix(X, Y, order=2., internal_p=2.): ''' :param X: (n x 2) numpy.array encoding the (points of the) first diagram. :param Y: (m x 2) numpy.array encoding the second diagram. - :param internal_p: Ground metric (i.e. norm l_p). :param order: exponent for the Wasserstein metric. + :param internal_p: Ground metric (i.e. norm L^p). :returns: (n+1) x (m+1) np.array encoding the cost matrix C. For 1 <= i <= n, 1 <= j <= m, C[i,j] encodes the distance between X[i] and Y[j], while C[i, m+1] (resp. C[n+1, j]) encodes the distance (to the p) between X[i] (resp Y[j]) and its orthogonal proj onto the diagonal. note also that C[n+1, m+1] = 0 (it costs nothing to move from the diagonal to the diagonal). @@ -54,8 +54,8 @@ def _build_dist_matrix(X, Y, order=2., internal_p=2.): def _perstot(X, order, internal_p): ''' :param X: (n x 2) numpy.array (points of a given diagram). - :param internal_p: Ground metric on the (upper-half) plane (i.e. norm l_p in R^2); Default value is 2 (Euclidean norm). :param order: exponent for Wasserstein. Default value is 2. + :param internal_p: Ground metric on the (upper-half) plane (i.e. norm L^p in R^2); Default value is 2 (Euclidean norm). :returns: float, the total persistence of the diagram (that is, its distance to the empty diagram). ''' Xdiag = _proj_on_diag(X) @@ -66,8 +66,8 @@ def wasserstein_distance(X, Y, order=2., internal_p=2.): ''' :param X: (n x 2) numpy.array encoding the (finite points of the) first diagram. Must not contain essential points (i.e. with infinite coordinate). :param Y: (m x 2) numpy.array encoding the second diagram. - :param internal_p: Ground metric on the (upper-half) plane (i.e. norm l_p in R^2); Default value is 2 (euclidean norm). :param order: exponent for Wasserstein; Default value is 2. + :param internal_p: Ground metric on the (upper-half) plane (i.e. norm L^p in R^2); Default value is 2 (euclidean norm). :returns: the Wasserstein distance of order q (1 <= q < infinity) between persistence diagrams with respect to the internal_p-norm as ground metric. :rtype: float ''' -- cgit v1.2.3 From 458ee3e95c752f09058d933349851c8a3a730cad Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Fri, 7 Feb 2020 19:41:38 +0100 Subject: Name argument MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Théo Lacombe --- src/python/test/test_wasserstein_distance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python/test/test_wasserstein_distance.py b/src/python/test/test_wasserstein_distance.py index 6a14c50e..4bc7114e 100755 --- a/src/python/test/test_wasserstein_distance.py +++ b/src/python/test/test_wasserstein_distance.py @@ -66,7 +66,7 @@ def hera_wrap(delta): return fun def test_wasserstein_distance_pot(): - _basic_wasserstein(pot, 1e-15, False) + _basic_wasserstein(pot, 1e-15, test_infinity=False) def test_wasserstein_distance_hera(): _basic_wasserstein(hera_wrap(1e-12), 1e-12) -- cgit v1.2.3 From b75123eeda446e7f778d4939da67a78e4c8c6abc Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Sat, 8 Feb 2020 17:39:05 +0100 Subject: Euclidean with a capital E --- src/Bottleneck_distance/include/gudhi/Persistence_graph.h | 2 +- src/python/doc/wasserstein_distance_user.rst | 2 +- src/python/gudhi/wasserstein.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Bottleneck_distance/include/gudhi/Persistence_graph.h b/src/Bottleneck_distance/include/gudhi/Persistence_graph.h index f791e37c..e1e3522e 100644 --- a/src/Bottleneck_distance/include/gudhi/Persistence_graph.h +++ b/src/Bottleneck_distance/include/gudhi/Persistence_graph.h @@ -25,7 +25,7 @@ namespace Gudhi { namespace persistence_diagram { -/** \internal \brief Structure representing an euclidean bipartite graph containing +/** \internal \brief Structure representing a Euclidean bipartite graph containing * the points from the two persistence diagrams (including the projections). * * \ingroup bottleneck_distance diff --git a/src/python/doc/wasserstein_distance_user.rst b/src/python/doc/wasserstein_distance_user.rst index 99445b99..94b454e2 100644 --- a/src/python/doc/wasserstein_distance_user.rst +++ b/src/python/doc/wasserstein_distance_user.rst @@ -28,7 +28,7 @@ Morozov, and Arnur Nigmetov. Basic example ------------- -This example computes the 1-Wasserstein distance from 2 persistence diagrams with euclidean ground metric. +This example computes the 1-Wasserstein distance from 2 persistence diagrams with Euclidean ground metric. Note that persistence diagrams must be submitted as (n x 2) numpy arrays and must not contain inf values. .. testcode:: diff --git a/src/python/gudhi/wasserstein.py b/src/python/gudhi/wasserstein.py index b1cfd588..13102094 100644 --- a/src/python/gudhi/wasserstein.py +++ b/src/python/gudhi/wasserstein.py @@ -67,7 +67,7 @@ def wasserstein_distance(X, Y, order=2., internal_p=2.): :param X: (n x 2) numpy.array encoding the (finite points of the) first diagram. Must not contain essential points (i.e. with infinite coordinate). :param Y: (m x 2) numpy.array encoding the second diagram. :param order: exponent for Wasserstein; Default value is 2. - :param internal_p: Ground metric on the (upper-half) plane (i.e. norm L^p in R^2); Default value is 2 (euclidean norm). + :param internal_p: Ground metric on the (upper-half) plane (i.e. norm L^p in R^2); Default value is 2 (Euclidean norm). :returns: the Wasserstein distance of order q (1 <= q < infinity) between persistence diagrams with respect to the internal_p-norm as ground metric. :rtype: float ''' -- cgit v1.2.3 From 486fc4b560c61e936e6aae83ce90994f318517df Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Sat, 8 Feb 2020 23:23:50 +0100 Subject: Add tensorflow to the circleci docker image Needed for perslay --- Dockerfile_for_circleci_image | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Dockerfile_for_circleci_image b/Dockerfile_for_circleci_image index b7d0dcca..ebd2f366 100644 --- a/Dockerfile_for_circleci_image +++ b/Dockerfile_for_circleci_image @@ -58,7 +58,8 @@ RUN pip3 install \ scikit-learn \ sphinx \ sphinx-paramlinks \ - sphinxcontrib-bibtex + sphinxcontrib-bibtex \ + tensorflow # apt clean up RUN apt autoremove && rm -rf /var/lib/apt/lists/* -- cgit v1.2.3 From f2c85ed1fd87f9ca50b1ed80135b6eea21d08c33 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Mon, 10 Feb 2020 11:05:40 +0100 Subject: Move next_release in for_dev directory. Add a for_dev/for_maintainer directory to explain how to create a GUDHI release --- CMakeLists.txt | 2 + code_conventions.md | 26 ------ for_dev/code_conventions.md | 26 ++++++ .../for_maintainers/new_gudhi_version_creation.md | 97 ++++++++++++++++++++++ for_dev/for_maintainers/next_release_template.md | 28 +++++++ for_dev/next_release.md | 28 +++++++ next_release.md | 14 ---- 7 files changed, 181 insertions(+), 40 deletions(-) delete mode 100644 code_conventions.md create mode 100644 for_dev/code_conventions.md create mode 100644 for_dev/for_maintainers/new_gudhi_version_creation.md create mode 100644 for_dev/for_maintainers/next_release_template.md create mode 100644 for_dev/next_release.md delete mode 100644 next_release.md diff --git a/CMakeLists.txt b/CMakeLists.txt index 5dcc6803..d9244dc0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,5 +65,7 @@ include(GUDHI_user_version_target) # For "make doxygen" - Requires GUDHI_USER_VERSION_DIR to be set - Done in GUDHI_user_version_target for dev version include(GUDHI_doxygen_target) +configure_file(${CMAKE_SOURCE_DIR}/for_dev/for_maintainers/new_gudhi_version_creation.md "${CMAKE_CURRENT_BINARY_DIR}/" @ONLY) + message("++ GUDHI_MODULES list is:\"${GUDHI_MODULES}\"") message("++ GUDHI_MISSING_MODULES list is:\"${GUDHI_MISSING_MODULES}\"") diff --git a/code_conventions.md b/code_conventions.md deleted file mode 100644 index 5882f78e..00000000 --- a/code_conventions.md +++ /dev/null @@ -1,26 +0,0 @@ -# Naming conventions - -## C++ - -### In the code: -* The classes and functions of a package should be in a sub-namespace of the `Gudhi` namespace. The sub-namespace names are in lowercase and use underscore separators. E.g. `Gudhi::package_name::` -* Concepts are named with camel case starting with uppercase. E.g. `PersistentHomology` for the concept of Persitence homology. -* Classes start with an uppercase letter and use underscore separators. E.g. `Skeleton_blocker_contractor`. -* Member functions and free functions are in lowercase and use underscore separators. E.g. `int num_vertices()`. -* Constants and macros are in uppercase. -* Macros should begin with the prefix `GUDHI_`. - -### File names: -* All headers are named *.h and all sources are named *.cpp. -* If a single class or function is provided in a file, its name (with the same letter case) should be used for the file name. -* If a file does not contain a single class, its name should not begin with a capital letter. -* Test files should be called `test_[what_is_tested].cpp`. E.g. `test_sparsify_point_set.cpp` -* Example files should be called `example_[what_it_is].cpp`. E.g. `example_sparsify_point_set.cpp` - -### In CMakeLists.txt files: -* The name of the "project" should be in this form: `Package_[tests|examples|…]`. E.g. `project(Simplex_tree_examples)`. -* The name if each "target" (first parameter of add_executable) should be in this form: `Package_{name of the cpp file without extension}`. E.g `add_executable(Subsampling_test_sparsify_point_set test_sparsify_point_set.cpp)`. - -## Python - -In progress... \ No newline at end of file diff --git a/for_dev/code_conventions.md b/for_dev/code_conventions.md new file mode 100644 index 00000000..5882f78e --- /dev/null +++ b/for_dev/code_conventions.md @@ -0,0 +1,26 @@ +# Naming conventions + +## C++ + +### In the code: +* The classes and functions of a package should be in a sub-namespace of the `Gudhi` namespace. The sub-namespace names are in lowercase and use underscore separators. E.g. `Gudhi::package_name::` +* Concepts are named with camel case starting with uppercase. E.g. `PersistentHomology` for the concept of Persitence homology. +* Classes start with an uppercase letter and use underscore separators. E.g. `Skeleton_blocker_contractor`. +* Member functions and free functions are in lowercase and use underscore separators. E.g. `int num_vertices()`. +* Constants and macros are in uppercase. +* Macros should begin with the prefix `GUDHI_`. + +### File names: +* All headers are named *.h and all sources are named *.cpp. +* If a single class or function is provided in a file, its name (with the same letter case) should be used for the file name. +* If a file does not contain a single class, its name should not begin with a capital letter. +* Test files should be called `test_[what_is_tested].cpp`. E.g. `test_sparsify_point_set.cpp` +* Example files should be called `example_[what_it_is].cpp`. E.g. `example_sparsify_point_set.cpp` + +### In CMakeLists.txt files: +* The name of the "project" should be in this form: `Package_[tests|examples|…]`. E.g. `project(Simplex_tree_examples)`. +* The name if each "target" (first parameter of add_executable) should be in this form: `Package_{name of the cpp file without extension}`. E.g `add_executable(Subsampling_test_sparsify_point_set test_sparsify_point_set.cpp)`. + +## Python + +In progress... \ No newline at end of file diff --git a/for_dev/for_maintainers/new_gudhi_version_creation.md b/for_dev/for_maintainers/new_gudhi_version_creation.md new file mode 100644 index 00000000..74d818f3 --- /dev/null +++ b/for_dev/for_maintainers/new_gudhi_version_creation.md @@ -0,0 +1,97 @@ +# Create a new GUDHI version + +We will consider that all operations will be performed in a brand new clone of the main project: +```bash +git clone https://github.com/GUDHI/gudhi-devel.git +cd gudhi-devel +``` + +## Version file modification + +**Edit the file CMakeGUDHIVersion.txt**, and increment major, minor, or patch version number, in function of the version new delivery. +```bash +# cf. .gitignore - ignore this if it is a fresh clone version +rm -rf data/points/COIL_database/lucky_cat.off_dist data/points/COIL_database/lucky_cat.off_sc.dot data/points/KleinBottle5D.off_dist data/points/KleinBottle5D.off_sc.dot data/points/human.off_dist data/points/human.off_sc.off data/points/human.off_sc.txt +``` + +Checkin the modifications, build and test the version: +```bash +mkdir build +cd build +cmake -DCGAL_DIR=/your/path/to/CGAL -DWITH_GUDHI_EXAMPLE=ON -DWITH_GUDHI_BENCHMARK=ON -DUSER_VERSION_DIR=gudhi.@GUDHI_VERSION@ -DPython_ADDITIONAL_VERSIONS=3 .. +make user_version +date +"%d-%m-%Y-%T" > gudhi.@GUDHI_VERSION@/timestamp.txt +tar -czvf gudhi.@GUDHI_VERSION@.tar.gz gudhi.@GUDHI_VERSION@ +md5sum gudhi.@GUDHI_VERSION@.tar.gz > md5sum.txt +sha256sum gudhi.@GUDHI_VERSION@.tar.gz > sha256sum.txt +sha512sum gudhi.@GUDHI_VERSION@.tar.gz > sha512sum.txt + +make -j all test +``` + +***[Check there are no error]*** + +## Create the documentation +```bash +mkdir gudhi.doc.@GUDHI_VERSION@ +make doxygen 2>&1 | tee dox.log && grep warning dox.log +``` + +***[Check there are no error and the warnings]*** + +```bash +cp -R gudhi.@GUDHI_VERSION@/doc/html gudhi.doc.@GUDHI_VERSION@/cpp +cd gudhi.@GUDHI_VERSION@ +rm -rf build; mkdir build; cd build; cmake -DCGAL_DIR=/your/path/to/CGAL -DWITH_GUDHI_EXAMPLE=ON -DPython_ADDITIONAL_VERSIONS=3 .. +export LC_ALL=en_US.UTF-8 # cf. bug +make sphinx +``` + +***[Check there are no error]*** + +```bash +cp -R python/sphinx ../../gudhi.doc.@GUDHI_VERSION@/python +cd ../.. +tar -czvf gudhi.doc.@GUDHI_VERSION@.tar.gz gudhi.doc.@GUDHI_VERSION@ + +cd gudhi.@GUDHI_VERSION@/build +make all test +``` + +***[Check there are no error]*** + +## Upload the documentation + +Upload by ftp the content of the directory gudhi.doc.@GUDHI_VERSION@/cpp in a new directory on ForgeLogin@scm.gforge.inria.fr:/home/groups/gudhi/htdocs/doc/@GUDHI_VERSION@ + +Upload by ftp the content of the directory gudhi.doc.@GUDHI_VERSION@/python in a new directory on ForgeLogin@scm.gforge.inria.fr:/home/groups/gudhi/htdocs/python/@GUDHI_VERSION@ + +Through ssh, make the **latest** link to your new version of the documentation: +```bash +ssh ForgeLogin@scm.gforge.inria.fr +cd /home/groups/gudhi/htdocs/doc +rm latest +ln -s @GUDHI_VERSION@ latest +cd /home/groups/gudhi/htdocs/python +rm latest +ln -s @GUDHI_VERSION@ latest +``` + +## Put a version label on files + +* Go on page https://github.com/GUDHI/gudhi-devel/releases/new +* Name the tag: tags/gudhi-release-@GUDHI_VERSION@ +* Name the release GUDHI @GUDHI_VERSION@ +* Write the release note +* Drag'n drop *gudhi.@GUDHI_VERSION@.tar.gz*, *md5sum.txt*, *sha256sum.txt*, *sha512sum.txt* files +* Tick the *This is a pre-release* check button if this is a release candidate (untick if this is an official version) +* Click the *Publish the release* button + +***[Where X, Y and Z corresponds respectively to the major, minor, and patch version number]*** + + +===Mail sending=== +Send version mail to the following lists : +gudhi-devel@lists.gforge.inria.fr +gudhi-users@lists.gforge.inria.fr (not for release candidate) + diff --git a/for_dev/for_maintainers/next_release_template.md b/for_dev/for_maintainers/next_release_template.md new file mode 100644 index 00000000..a2805a55 --- /dev/null +++ b/for_dev/for_maintainers/next_release_template.md @@ -0,0 +1,28 @@ +We are pleased to announce the release 3.X.X of the GUDHI library. + +As a major new feature, the GUDHI library now offers ... + +We are now using GitHub to develop the GUDHI library, do not hesitate to [fork the GUDHI project on GitHub](https://github.com/GUDHI/gudhi-devel). From a user point of view, we recommend to download GUDHI user version (gudhi.3.X.X.tar.gz). + +Below is a list of changes made since GUDHI 3.X-1.X-1: + +- [Module](link) + - ... + +- [Module](link) + - ... + +- Miscellaneous + - The [list of bugs that were solved since GUDHI-3.X-1.X-1](https://github.com/GUDHI/gudhi-devel/issues?q=label%3A3.1.1+is%3Aclosed) is available on GitHub. + +All modules are distributed under the terms of the MIT license. +However, there are still GPL dependencies for many modules. We invite you to check our [license dedicated web page](https://gudhi.inria.fr/licensing/) for further details. + +We kindly ask users to cite the GUDHI library as appropriately as possible in their papers, and to mention the use of the GUDHI library on the web pages of their projects using GUDHI and provide us with links to these web pages. + +We provide [bibtex entries](https://gudhi.inria.fr/doc/latest/_citation.html) for the modules of the User and Reference Manual, as well as for publications directly related to the GUDHI library. + +Feel free to [contact us](https://gudhi.inria.fr/contact/) in case you have any questions or remarks. + +For further information about downloading and installing the library ([C++](https://gudhi.inria.fr/doc/latest/installation.html) or [Python](https://gudhi.inria.fr/python/latest/installation.html)), please visit the [GUDHI web site](https://gudhi.inria.fr/). + diff --git a/for_dev/next_release.md b/for_dev/next_release.md new file mode 100644 index 00000000..a2805a55 --- /dev/null +++ b/for_dev/next_release.md @@ -0,0 +1,28 @@ +We are pleased to announce the release 3.X.X of the GUDHI library. + +As a major new feature, the GUDHI library now offers ... + +We are now using GitHub to develop the GUDHI library, do not hesitate to [fork the GUDHI project on GitHub](https://github.com/GUDHI/gudhi-devel). From a user point of view, we recommend to download GUDHI user version (gudhi.3.X.X.tar.gz). + +Below is a list of changes made since GUDHI 3.X-1.X-1: + +- [Module](link) + - ... + +- [Module](link) + - ... + +- Miscellaneous + - The [list of bugs that were solved since GUDHI-3.X-1.X-1](https://github.com/GUDHI/gudhi-devel/issues?q=label%3A3.1.1+is%3Aclosed) is available on GitHub. + +All modules are distributed under the terms of the MIT license. +However, there are still GPL dependencies for many modules. We invite you to check our [license dedicated web page](https://gudhi.inria.fr/licensing/) for further details. + +We kindly ask users to cite the GUDHI library as appropriately as possible in their papers, and to mention the use of the GUDHI library on the web pages of their projects using GUDHI and provide us with links to these web pages. + +We provide [bibtex entries](https://gudhi.inria.fr/doc/latest/_citation.html) for the modules of the User and Reference Manual, as well as for publications directly related to the GUDHI library. + +Feel free to [contact us](https://gudhi.inria.fr/contact/) in case you have any questions or remarks. + +For further information about downloading and installing the library ([C++](https://gudhi.inria.fr/doc/latest/installation.html) or [Python](https://gudhi.inria.fr/python/latest/installation.html)), please visit the [GUDHI web site](https://gudhi.inria.fr/). + diff --git a/next_release.md b/next_release.md deleted file mode 100644 index 78270d15..00000000 --- a/next_release.md +++ /dev/null @@ -1,14 +0,0 @@ -gudhi-3.1.1 is a bug-fix release. In particular, it fixes the installation of the Python representation module. - -The [list of bugs that were solved since gudhi-3.1.0](https://github.com/GUDHI/gudhi-devel/issues?q=label%3A3.1.1+is%3Aclosed) is available on GitHub. - -All modules are distributed under the terms of the MIT license. -However, there are still GPL dependencies for many modules. We invite you to check our [license dedicated web page](https://gudhi.inria.fr/licensing/) for further details. - -We kindly ask users to cite the GUDHI library as appropriately as possible in their papers, and to mention the use of the GUDHI library on the web pages of their projects using GUDHI and provide us with links to these web pages. - -We provide [bibtex entries](https://gudhi.inria.fr/doc/latest/_citation.html) for the modules of the User and Reference Manual, as well as for publications directly related to the GUDHI library. - -Feel free to [contact us](https://gudhi.inria.fr/contact/) in case you have any questions or remarks. - -For further information about downloading and installing the library ([C++](https://gudhi.inria.fr/doc/3.1.1/installation.html) or [Python](https://gudhi.inria.fr/python/3.1.1/installation.html)), please visit the [GUDHI web site](https://gudhi.inria.fr/). -- cgit v1.2.3 From f7317664c051dd1f49861c2e22c3bf3ca471052c Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Mon, 10 Feb 2020 13:21:01 +0100 Subject: Gudhi version 3.1.1 --- Dockerfile_gudhi_installation | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Dockerfile_gudhi_installation b/Dockerfile_gudhi_installation index d5d86338..33864d11 100644 --- a/Dockerfile_gudhi_installation +++ b/Dockerfile_gudhi_installation @@ -57,11 +57,11 @@ RUN pip3 install \ # apt clean up RUN apt autoremove && rm -rf /var/lib/apt/lists/* -RUN curl -LO "https://github.com/GUDHI/gudhi-devel/releases/download/tags%2Fgudhi-release-3.1.0/gudhi.3.1.0.tar.gz" \ -&& tar xf gudhi.3.1.0.tar.gz \ -&& cd gudhi.3.1.0 \ +RUN curl -LO "https://github.com/GUDHI/gudhi-devel/releases/download/tags%2Fgudhi-release-3.1.1/gudhi.3.1.1.tar.gz" \ +&& tar xf gudhi.3.1.1.tar.gz \ +&& cd gudhi.3.1.1 \ && mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Release -DWITH_GUDHI_PYTHON=OFF -DPython_ADDITIONAL_VERSIONS=3 .. \ && make all test install \ && cmake -DWITH_GUDHI_PYTHON=ON . \ && cd python \ -&& python3 setup.py install \ No newline at end of file +&& python3 setup.py install -- cgit v1.2.3 From a3b15cf6c7bcdcc815c3c9a4a1d6876a5b29873f Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau <10407034+VincentRouvreau@users.noreply.github.com> Date: Mon, 10 Feb 2020 14:14:47 +0100 Subject: Markdown was not correct --- for_dev/for_maintainers/new_gudhi_version_creation.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/for_dev/for_maintainers/new_gudhi_version_creation.md b/for_dev/for_maintainers/new_gudhi_version_creation.md index 74d818f3..4a40f373 100644 --- a/for_dev/for_maintainers/new_gudhi_version_creation.md +++ b/for_dev/for_maintainers/new_gudhi_version_creation.md @@ -90,8 +90,8 @@ ln -s @GUDHI_VERSION@ latest ***[Where X, Y and Z corresponds respectively to the major, minor, and patch version number]*** -===Mail sending=== +## Mail sending Send version mail to the following lists : -gudhi-devel@lists.gforge.inria.fr -gudhi-users@lists.gforge.inria.fr (not for release candidate) +* gudhi-devel@lists.gforge.inria.fr +* gudhi-users@lists.gforge.inria.fr (not for release candidate) -- cgit v1.2.3 From ee0f12f1df406c81c6ad860c494eed908021fad9 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Sat, 8 Feb 2020 19:54:46 +0100 Subject: Use setuptools.find_packages --- src/python/setup.py.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/python/setup.py.in b/src/python/setup.py.in index f993165c..bd7fb180 100644 --- a/src/python/setup.py.in +++ b/src/python/setup.py.in @@ -8,7 +8,7 @@ - YYYY/MM Author: Description of the modification """ -from setuptools import setup, Extension +from setuptools import setup, Extension, find_packages from Cython.Build import cythonize from numpy import get_include as numpy_get_include import sys @@ -44,7 +44,7 @@ for module in modules: setup( name = 'gudhi', - packages=["gudhi","gudhi.representations"], + packages=find_packages(), # find_namespace_packages(include=["gudhi*"]) author='GUDHI Editorial Board', author_email='gudhi-contact@lists.gforge.inria.fr', version='@GUDHI_VERSION@', -- cgit v1.2.3 From d6f3165831d20bf3a91f1ff7e9734a574eaa567a Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Tue, 11 Feb 2020 13:06:48 +0100 Subject: License and author --- src/python/gudhi/hera.cc | 13 +++++++++++-- src/python/test/test_wasserstein_distance.py | 2 +- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/python/gudhi/hera.cc b/src/python/gudhi/hera.cc index 61f0da10..0d562b4c 100644 --- a/src/python/gudhi/hera.cc +++ b/src/python/gudhi/hera.cc @@ -1,9 +1,19 @@ +/* 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. + * Author(s): Marc Glisse + * + * Copyright (C) 2020 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + #include #include #include -#include +#include // Hera #include @@ -41,7 +51,6 @@ double wasserstein_distance( PYBIND11_MODULE(hera, m) { m.def("wasserstein_distance", &wasserstein_distance, py::arg("X"), py::arg("Y"), - // Should we name those q, p and d instead? py::arg("order") = 1, py::arg("internal_p") = std::numeric_limits::infinity(), py::arg("delta") = .01, diff --git a/src/python/test/test_wasserstein_distance.py b/src/python/test/test_wasserstein_distance.py index 4bc7114e..6a6b217b 100755 --- a/src/python/test/test_wasserstein_distance.py +++ b/src/python/test/test_wasserstein_distance.py @@ -1,6 +1,6 @@ """ 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. - Author(s): Theo Lacombe + Author(s): Theo Lacombe, Marc Glisse Copyright (C) 2019 Inria -- cgit v1.2.3