From 53818204ba2f914c89e21deb6bfe7cb4a0122718 Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau Date: Wed, 30 Mar 2022 09:22:09 +0200 Subject: Remove this useless line --- src/Alpha_complex/include/gudhi/Alpha_complex_3d.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Alpha_complex/include/gudhi/Alpha_complex_3d.h b/src/Alpha_complex/include/gudhi/Alpha_complex_3d.h index df5c630e..b3dbc9bb 100644 --- a/src/Alpha_complex/include/gudhi/Alpha_complex_3d.h +++ b/src/Alpha_complex/include/gudhi/Alpha_complex_3d.h @@ -57,8 +57,6 @@ namespace Gudhi { namespace alpha_complex { -thread_local double RELATIVE_PRECISION_OF_TO_DOUBLE = 0.00001; - // Value_from_iterator returns the filtration value from an iterator on alpha shapes values // // FAST SAFE EXACT -- cgit v1.2.3 From 495f3d9b51f5ed48151118fedcc61f5067f04d51 Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau Date: Wed, 30 Mar 2022 12:22:56 +0200 Subject: get/set float_relative_precision and its documentation --- src/python/doc/alpha_complex_user.rst | 3 ++- src/python/gudhi/alpha_complex.pyx | 28 ++++++++++++++++++++++++++++ src/python/include/Alpha_complex_interface.h | 10 ++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/python/doc/alpha_complex_user.rst b/src/python/doc/alpha_complex_user.rst index cfd22742..b060c86e 100644 --- a/src/python/doc/alpha_complex_user.rst +++ b/src/python/doc/alpha_complex_user.rst @@ -27,7 +27,8 @@ Remarks If you pass :code:`precision = 'exact'` to :func:`~gudhi.AlphaComplex.__init__`, the filtration values are the exact ones converted to float. This can be very slow. If you pass :code:`precision = 'safe'` (the default), the filtration values are only - guaranteed to have a small multiplicative error compared to the exact value. + guaranteed to have a small multiplicative error compared to the exact value, see + :func:`~gudhi.AlphaComplex.set_float_relative_precision` to modify the precision. A drawback, when computing persistence, is that an empty exact interval [10^12,10^12] may become a non-empty approximate interval [10^12,10^12+10^6]. Using :code:`precision = 'fast'` makes the computations slightly faster, and the combinatorics are still exact, but diff --git a/src/python/gudhi/alpha_complex.pyx b/src/python/gudhi/alpha_complex.pyx index a4888914..9af62b43 100644 --- a/src/python/gudhi/alpha_complex.pyx +++ b/src/python/gudhi/alpha_complex.pyx @@ -31,6 +31,10 @@ cdef extern from "Alpha_complex_interface.h" namespace "Gudhi": Alpha_complex_interface(vector[vector[double]] points, vector[double] weights, bool fast_version, bool exact_version) nogil except + vector[double] get_point(int vertex) nogil except + void create_simplex_tree(Simplex_tree_interface_full_featured* simplex_tree, double max_alpha_square, bool default_filtration_value) nogil except + + @staticmethod + void set_float_relative_precision(double precision) nogil + @staticmethod + double get_float_relative_precision() nogil # AlphaComplex python interface cdef class AlphaComplex: @@ -133,3 +137,27 @@ cdef class AlphaComplex: self.this_ptr.create_simplex_tree(stree_int_ptr, mas, compute_filtration) return stree + + @staticmethod + def set_float_relative_precision(precision): + """ + :param precision: When the AlphaComplex is constructed with :code:`precision = 'safe'` (the default), + one can set the float relative precision of filtration values computed in + :func:`~gudhi.AlphaComplex.create_simplex_tree`. + Default is :code:`1e-5` (cf. :func:`~gudhi.AlphaComplex.get_float_relative_precision`). + For more details, please refer to + `CGAL::Lazy_exact_nt::set_relative_precision_of_to_double `_ + :type precision: float + """ + if precision <=0. or precision >= 1.: + raise ValueError("Relative precision value must be strictly greater than 0 and strictly lower than 1") + Alpha_complex_interface.set_float_relative_precision(precision) + + @staticmethod + def get_float_relative_precision(): + """ + :returns: The float relative precision of filtration values computation in + :func:`~gudhi.AlphaComplex.create_simplex_tree`. + :rtype: float + """ + return Alpha_complex_interface.get_float_relative_precision() diff --git a/src/python/include/Alpha_complex_interface.h b/src/python/include/Alpha_complex_interface.h index 671af4a4..469b91ce 100644 --- a/src/python/include/Alpha_complex_interface.h +++ b/src/python/include/Alpha_complex_interface.h @@ -57,6 +57,16 @@ class Alpha_complex_interface { alpha_ptr_->create_simplex_tree(simplex_tree, max_alpha_square, default_filtration_value); } + static void set_float_relative_precision(double precision) { + // cf. Exact_alpha_complex_dD kernel type in Alpha_complex_factory.h + CGAL::Epeck_d::FT::set_relative_precision_of_to_double(precision); + } + + static double get_float_relative_precision() { + // cf. Exact_alpha_complex_dD kernel type in Alpha_complex_factory.h + return CGAL::Epeck_d::FT::get_relative_precision_of_to_double(); + } + private: std::unique_ptr alpha_ptr_; }; -- cgit v1.2.3 From 37dcedb59cd2a6b70119688ea24c978749d63154 Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau Date: Thu, 31 Mar 2022 16:37:20 +0200 Subject: Test the feature --- src/python/test/test_alpha_complex.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/python/test/test_alpha_complex.py b/src/python/test/test_alpha_complex.py index f15284f3..f81e6137 100755 --- a/src/python/test/test_alpha_complex.py +++ b/src/python/test/test_alpha_complex.py @@ -286,3 +286,30 @@ def _weighted_doc_example(precision): def test_weighted_doc_example(): for precision in ['fast', 'safe', 'exact']: _weighted_doc_example(precision) + +def test_float_relative_precision(): + assert AlphaComplex.get_float_relative_precision() == 1e-5 + # Must be > 0. + with pytest.raises(ValueError): + AlphaComplex.set_float_relative_precision(0.) + # Must be < 1. + with pytest.raises(ValueError): + AlphaComplex.set_float_relative_precision(1.) + + points = [[1, 1], [7, 0], [4, 6], [9, 6], [0, 14], [2, 19], [9, 17]] + st = AlphaComplex(points=points).create_simplex_tree() + filtrations = list(st.get_filtration()) + + # Get a better precision + AlphaComplex.set_float_relative_precision(1e-15) + assert AlphaComplex.get_float_relative_precision() == 1e-15 + + st = AlphaComplex(points=points).create_simplex_tree() + filtrations_better_resolution = list(st.get_filtration()) + + assert len(filtrations) == len(filtrations_better_resolution) + for idx in range(len(filtrations)): + # check simplex is the same + assert filtrations[idx][0] == filtrations_better_resolution[idx][0] + # check filtration is about the same with a relative precision of the worst case + assert filtrations[idx][1] == pytest.approx(filtrations_better_resolution[idx][1], rel=1e-5) -- cgit v1.2.3 From f4b543bb4891b1c2aa104e45cc5a0d07b56e6977 Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau Date: Thu, 31 Mar 2022 21:15:18 +0200 Subject: code review: no need to nogil for cheap functions. Repeat get_float_relative_precision is only for safe mode --- src/python/gudhi/alpha_complex.pyx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/python/gudhi/alpha_complex.pyx b/src/python/gudhi/alpha_complex.pyx index 9af62b43..e63796db 100644 --- a/src/python/gudhi/alpha_complex.pyx +++ b/src/python/gudhi/alpha_complex.pyx @@ -32,9 +32,9 @@ cdef extern from "Alpha_complex_interface.h" namespace "Gudhi": vector[double] get_point(int vertex) nogil except + void create_simplex_tree(Simplex_tree_interface_full_featured* simplex_tree, double max_alpha_square, bool default_filtration_value) nogil except + @staticmethod - void set_float_relative_precision(double precision) nogil + void set_float_relative_precision(double precision) @staticmethod - double get_float_relative_precision() nogil + double get_float_relative_precision() # AlphaComplex python interface cdef class AlphaComplex: @@ -157,7 +157,8 @@ cdef class AlphaComplex: def get_float_relative_precision(): """ :returns: The float relative precision of filtration values computation in - :func:`~gudhi.AlphaComplex.create_simplex_tree`. + :func:`~gudhi.AlphaComplex.create_simplex_tree` when the AlphaComplex is constructed with + :code:`precision = 'safe'` (the default). :rtype: float """ return Alpha_complex_interface.get_float_relative_precision() -- cgit v1.2.3 From 25172af7cbe5a3ea3017bed6fde53be471a7e4bf Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau Date: Tue, 5 Apr 2022 13:35:11 +0200 Subject: nogil for float_relative_precision methods --- 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 e63796db..375e1561 100644 --- a/src/python/gudhi/alpha_complex.pyx +++ b/src/python/gudhi/alpha_complex.pyx @@ -32,9 +32,9 @@ cdef extern from "Alpha_complex_interface.h" namespace "Gudhi": vector[double] get_point(int vertex) nogil except + void create_simplex_tree(Simplex_tree_interface_full_featured* simplex_tree, double max_alpha_square, bool default_filtration_value) nogil except + @staticmethod - void set_float_relative_precision(double precision) + void set_float_relative_precision(double precision) nogil @staticmethod - double get_float_relative_precision() + double get_float_relative_precision() nogil # AlphaComplex python interface cdef class AlphaComplex: -- cgit v1.2.3 From 84a264c27e0994542f1da3a4688157568a6b69b7 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Fri, 15 Apr 2022 20:02:06 +0200 Subject: Use "and" to separate authors with bibtex --- biblio/how_to_cite_gudhi.bib.in | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/biblio/how_to_cite_gudhi.bib.in b/biblio/how_to_cite_gudhi.bib.in index 54d10857..579dbf41 100644 --- a/biblio/how_to_cite_gudhi.bib.in +++ b/biblio/how_to_cite_gudhi.bib.in @@ -78,7 +78,7 @@ } @incollection{gudhi:SubSampling -, author = "Cl\'ement Jamin, Siargey Kachanovich" +, author = "Cl\'ement Jamin and Siargey Kachanovich" , title = "Subsampling" , publisher = "{GUDHI Editorial Board}" , edition = "{@GUDHI_VERSION@}" @@ -108,7 +108,7 @@ } @incollection{gudhi:RipsComplex -, author = "Cl\'ement Maria, Pawel Dlotko, Vincent Rouvreau, Marc Glisse" +, author = "Cl\'ement Maria and Pawel Dlotko and Vincent Rouvreau and Marc Glisse" , title = "Rips complex" , publisher = "{GUDHI Editorial Board}" , edition = "{@GUDHI_VERSION@}" @@ -158,7 +158,7 @@ } @incollection{gudhi:Collapse -, author = "Siddharth Pritam" +, author = "Siddharth Pritam and Marc Glisse" , title = "Edge collapse" , publisher = "{GUDHI Editorial Board}" , edition = "{@GUDHI_VERSION@}" -- cgit v1.2.3 From 5857c571388a4349934a266ca187b2c2ac10818c Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau <10407034+VincentRouvreau@users.noreply.github.com> Date: Thu, 21 Apr 2022 14:44:22 +0200 Subject: Make Windows compilation fails on error (#598) Use '-DEIGEN_DEFAULT_DENSE_INDEX_TYPE=int' as a workaround --- .github/workflows/pip-build-windows.yml | 8 ++++---- .github/workflows/pip-packaging-windows.yml | 8 ++++---- azure-pipelines.yml | 17 ++++++++++++----- src/cmake/modules/GUDHI_third_party_libraries.cmake | 9 +++++++++ src/python/CMakeLists.txt | 12 +++++++++++- 5 files changed, 40 insertions(+), 14 deletions(-) diff --git a/.github/workflows/pip-build-windows.yml b/.github/workflows/pip-build-windows.yml index 954b59d5..30b0bd94 100644 --- a/.github/workflows/pip-build-windows.yml +++ b/.github/workflows/pip-build-windows.yml @@ -30,14 +30,14 @@ jobs: run: | mkdir build cd ".\build\" - cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=c:\vcpkg\scripts\buildsystems\vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows .. + cmake -DCMAKE_BUILD_TYPE=Release -DFORCE_EIGEN_DEFAULT_DENSE_INDEX_TYPE_TO_INT=ON -DCMAKE_TOOLCHAIN_FILE=c:\vcpkg\scripts\buildsystems\vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows .. Get-Location dir cd ".\src\python\" - cp "C:\vcpkg\installed\x64-windows\bin\mpfr-6.dll" ".\gudhi\" - cp "C:\vcpkg\installed\x64-windows\bin\gmp.dll" ".\gudhi\" + cp "C:\vcpkg\installed\x64-windows\bin\mpfr*.dll" ".\gudhi\" + cp "C:\vcpkg\installed\x64-windows\bin\gmp*.dll" ".\gudhi\" python setup.py bdist_wheel - ls dist + ls ".\dist\" cd ".\dist\" Get-ChildItem *.whl | ForEach-Object{python -m pip install --user $_.Name} - name: Test python wheel diff --git a/.github/workflows/pip-packaging-windows.yml b/.github/workflows/pip-packaging-windows.yml index 962ae68a..142a114c 100644 --- a/.github/workflows/pip-packaging-windows.yml +++ b/.github/workflows/pip-packaging-windows.yml @@ -33,14 +33,14 @@ jobs: run: | mkdir build cd ".\build\" - cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=c:\vcpkg\scripts\buildsystems\vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows .. + cmake -DCMAKE_BUILD_TYPE=Release -DFORCE_EIGEN_DEFAULT_DENSE_INDEX_TYPE_TO_INT=ON -DCMAKE_TOOLCHAIN_FILE=c:\vcpkg\scripts\buildsystems\vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows .. Get-Location dir cd ".\src\python\" - cp "C:\vcpkg\installed\x64-windows\bin\mpfr-6.dll" ".\gudhi\" - cp "C:\vcpkg\installed\x64-windows\bin\gmp.dll" ".\gudhi\" + cp "C:\vcpkg\installed\x64-windows\bin\mpfr*.dll" ".\gudhi\" + cp "C:\vcpkg\installed\x64-windows\bin\gmp*.dll" ".\gudhi\" python setup.py bdist_wheel - ls dist + ls ".\dist\" cd ".\dist\" Get-ChildItem *.whl | ForEach-Object{python -m pip install --user $_.Name} - name: Test python wheel diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 21664244..a39f6d5c 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -30,7 +30,7 @@ jobs: - bash: | mkdir build cd build - cmake -DCMAKE_BUILD_TYPE:STRING=$(cmakeBuildType) -DWITH_GUDHI_TEST=ON -DWITH_GUDHI_UTILITIES=ON -DWITH_GUDHI_PYTHON=ON .. + cmake -DCMAKE_BUILD_TYPE:STRING=$(cmakeBuildType) -DWITH_GUDHI_EXAMPLE=ON -DWITH_GUDHI_TEST=ON -DWITH_GUDHI_UTILITIES=ON -DWITH_GUDHI_PYTHON=ON .. make make doxygen ctest --output-on-failure @@ -64,20 +64,27 @@ jobs: vcpkg install boost-filesystem:x64-windows boost-test:x64-windows boost-program-options:x64-windows tbb:x64-windows eigen3:x64-windows cgal:x64-windows displayName: 'Install build dependencies' - script: | - call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" amd64 + call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" amd64 + IF %errorlevel% NEQ 0 exit /b %errorlevel% mkdir build cd build - cmake -G "Visual Studio 16 2019" -A x64 -DCMAKE_BUILD_TYPE=Release $(cmakeVcpkgFlags) $(cmakeFlags) .. + cmake -G "Visual Studio 17 2022" -A x64 -DCMAKE_BUILD_TYPE=Release -DFORCE_EIGEN_DEFAULT_DENSE_INDEX_TYPE_TO_INT=ON $(cmakeVcpkgFlags) $(cmakeFlags) .. + IF %errorlevel% NEQ 0 exit /b %errorlevel% MSBuild GUDHIdev.sln /m /p:Configuration=Release /p:Platform=x64 + IF %errorlevel% NEQ 0 exit /b %errorlevel% ctest --output-on-failure -C Release -E diff_files + IF %errorlevel% NEQ 0 exit /b %errorlevel% cmake -DWITH_GUDHI_PYTHON=ON . + IF %errorlevel% NEQ 0 exit /b %errorlevel% cd src\python - copy "C:\vcpkg\installed\x64-windows\bin\mpfr-6.dll" ".\gudhi\" - copy "C:\vcpkg\installed\x64-windows\bin\gmp.dll" ".\gudhi\" + copy "C:\vcpkg\installed\x64-windows\bin\mpfr*.dll" ".\gudhi\" + copy "C:\vcpkg\installed\x64-windows\bin\gmp*.dll" ".\gudhi\" copy "C:\vcpkg\installed\x64-windows\bin\tbb.dll" ".\gudhi\" copy "C:\vcpkg\installed\x64-windows\bin\tbbmalloc.dll" ".\gudhi\" python setup.py build_ext --inplace + IF %errorlevel% NEQ 0 exit /b %errorlevel% SET PYTHONPATH=%CD%;%PYTHONPATH% echo %PYTHONPATH% ctest --output-on-failure -C Release + IF %errorlevel% NEQ 0 exit /b %errorlevel% displayName: 'Build and test' diff --git a/src/cmake/modules/GUDHI_third_party_libraries.cmake b/src/cmake/modules/GUDHI_third_party_libraries.cmake index 7c982b3b..6a94d1f5 100644 --- a/src/cmake/modules/GUDHI_third_party_libraries.cmake +++ b/src/cmake/modules/GUDHI_third_party_libraries.cmake @@ -19,6 +19,15 @@ if(GMP_FOUND) endif() endif() +# from windows vcpkg eigen 3.4.0#2 : build fails with +# error C2440: '': cannot convert from 'Eigen::EigenBase::Index' to '__gmp_expr' +# cf. https://gitlab.com/libeigen/eigen/-/issues/2476 +# Workaround is to compile with '-DEIGEN_DEFAULT_DENSE_INDEX_TYPE=int' +if (FORCE_EIGEN_DEFAULT_DENSE_INDEX_TYPE_TO_INT) + message("++ User explicit demand to force EIGEN_DEFAULT_DENSE_INDEX_TYPE to int") + add_definitions(-DEIGEN_DEFAULT_DENSE_INDEX_TYPE=int) +endif() + # In CMakeLists.txt, when include(${CGAL_USE_FILE}), CMAKE_CXX_FLAGS are overwritten. # cf. http://doc.cgal.org/latest/Manual/installation.html#title40 # A workaround is to include(${CGAL_USE_FILE}) before adding "-std=c++11". diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index fbfb0d1f..e31af02e 100644 --- a/src/python/CMakeLists.txt +++ b/src/python/CMakeLists.txt @@ -180,6 +180,15 @@ if(PYTHONINTERP_FOUND) set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}'alpha_complex', ") endif () + # from windows vcpkg eigen 3.4.0#2 : build fails with + # error C2440: '': cannot convert from 'Eigen::EigenBase::Index' to '__gmp_expr' + # cf. https://gitlab.com/libeigen/eigen/-/issues/2476 + # Workaround is to compile with '-DEIGEN_DEFAULT_DENSE_INDEX_TYPE=int' + if (FORCE_EIGEN_DEFAULT_DENSE_INDEX_TYPE_TO_INT) + set(GUDHI_PYTHON_EXTRA_COMPILE_ARGS "${GUDHI_PYTHON_EXTRA_COMPILE_ARGS}'-DEIGEN_DEFAULT_DENSE_INDEX_TYPE=int', ") + endif() + + add_gudhi_debug_info("Boost version ${Boost_VERSION}") if(CGAL_FOUND) if(NOT CGAL_VERSION VERSION_LESS 5.3.0) @@ -215,13 +224,14 @@ if(PYTHONINTERP_FOUND) endif(NOT GMP_LIBRARIES_DIR) add_GUDHI_PYTHON_lib_dir(${GMP_LIBRARIES_DIR}) message("** Add gmp ${GMP_LIBRARIES_DIR}") + # When FORCE_CGAL_NOT_TO_BUILD_WITH_GMPXX is set, not defining CGAL_USE_GMPXX is sufficient enough if(GMPXX_FOUND) add_gudhi_debug_info("GMPXX_LIBRARIES = ${GMPXX_LIBRARIES}") set(GUDHI_PYTHON_EXTRA_COMPILE_ARGS "${GUDHI_PYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_USE_GMPXX', ") add_GUDHI_PYTHON_lib("${GMPXX_LIBRARIES}") add_GUDHI_PYTHON_lib_dir(${GMPXX_LIBRARIES_DIR}) message("** Add gmpxx ${GMPXX_LIBRARIES_DIR}") - endif(GMPXX_FOUND) + endif() endif(GMP_FOUND) if(MPFR_FOUND) add_gudhi_debug_info("MPFR_LIBRARIES = ${MPFR_LIBRARIES}") -- cgit v1.2.3