summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Rouvreau <10407034+VincentRouvreau@users.noreply.github.com>2020-12-12 08:02:02 +0100
committerGitHub <noreply@github.com>2020-12-12 08:02:02 +0100
commit1a6f1aa1b3119d5b211eda8fb0908a845c920fa5 (patch)
treeb8bc3c35175871facfb94bfcf589c0a2c53b44b6
parentd712ec89c9940bcc4629f1177755f859cd7e7c59 (diff)
parentba3be8d118a9720677b7776ae9a22c10cfcc0cef (diff)
Merge pull request #436 from VincentRouvreau/ci_without_cgal
Add build and tests wo cgal and eigen and wo cgal
-rw-r--r--.circleci/config.yml126
-rw-r--r--src/python/CMakeLists.txt6
-rwxr-xr-xsrc/python/example/diagram_vectorizations_distances_kernels.py19
-rw-r--r--src/python/gudhi/__init__.py.in4
-rw-r--r--src/python/gudhi/simplex_tree.pxd2
-rw-r--r--src/python/gudhi/simplex_tree.pyx3
-rw-r--r--src/python/include/Simplex_tree_interface.h6
-rwxr-xr-xsrc/python/test/test_simplex_tree.py17
8 files changed, 169 insertions, 14 deletions
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 285a66a5..d95b8d36 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -95,10 +95,136 @@ jobs:
path: /tmp/doxygen
destination: doxygen
+ examples_without_cgal_eigen:
+ docker:
+ - image: gudhi/ci_for_gudhi_wo_cgal:latest
+ steps:
+ - checkout
+ - run:
+ name: Build and test examples without cgal and eigen
+ command: |
+ mkdir build
+ cd build
+ cmake -DCMAKE_BUILD_TYPE=Release -DWITH_GUDHI_EXAMPLE=ON -DWITH_GUDHI_TEST=OFF -DWITH_GUDHI_UTILITIES=OFF -DWITH_GUDHI_PYTHON=OFF ..
+ make all
+ ctest --output-on-failure
+
+ tests_without_cgal_eigen:
+ docker:
+ - image: gudhi/ci_for_gudhi_wo_cgal:latest
+ steps:
+ - checkout
+ - run:
+ name: Build and test unitary tests without cgal and eigen
+ command: |
+ mkdir build
+ cd build
+ cmake -DCMAKE_BUILD_TYPE=Release -DWITH_GUDHI_EXAMPLE=OFF -DWITH_GUDHI_TEST=ON -DWITH_GUDHI_UTILITIES=OFF -DWITH_GUDHI_PYTHON=OFF ..
+ make all
+ ctest --output-on-failure
+
+ utils_without_cgal_eigen:
+ docker:
+ - image: gudhi/ci_for_gudhi_wo_cgal:latest
+ steps:
+ - checkout
+ - run:
+ name: Build and test utilities without cgal and eigen
+ command: |
+ mkdir build
+ cd build
+ cmake -DCMAKE_BUILD_TYPE=Release -DWITH_GUDHI_EXAMPLE=OFF -DWITH_GUDHI_TEST=OFF -DWITH_GUDHI_UTILITIES=ON -DWITH_GUDHI_PYTHON=OFF ..
+ make all
+ ctest --output-on-failure
+
+ python_without_cgal_eigen:
+ docker:
+ - image: gudhi/ci_for_gudhi_wo_cgal:latest
+ steps:
+ - checkout
+ - run:
+ name: Build and test python module without cgal and eigen
+ command: |
+ git submodule init
+ git submodule update
+ mkdir build
+ cd build
+ cmake -DCMAKE_BUILD_TYPE=Release -DWITH_GUDHI_EXAMPLE=OFF -DWITH_GUDHI_UTILITIES=OFF -DWITH_GUDHI_PYTHON=ON -DPython_ADDITIONAL_VERSIONS=3 ..
+ cd src/python
+ python3 setup.py build_ext --inplace
+ ctest --output-on-failure
+
+ examples_without_cgal:
+ docker:
+ - image: gudhi/ci_for_gudhi_wo_cgal:latest
+ steps:
+ - checkout
+ - run:
+ name: Build and test examples without cgal
+ command: |
+ mkdir build
+ cd build
+ cmake -DCMAKE_BUILD_TYPE=Release -DEIGEN3_INCLUDE_DIR=/eigen-3.3.9 -DWITH_GUDHI_EXAMPLE=ON -DWITH_GUDHI_TEST=OFF -DWITH_GUDHI_UTILITIES=OFF -DWITH_GUDHI_PYTHON=OFF ..
+ make all
+ ctest --output-on-failure
+
+ tests_without_cgal:
+ docker:
+ - image: gudhi/ci_for_gudhi_wo_cgal:latest
+ steps:
+ - checkout
+ - run:
+ name: Build and test unitary tests without cgal
+ command: |
+ mkdir build
+ cd build
+ cmake -DCMAKE_BUILD_TYPE=Release -DEIGEN3_INCLUDE_DIR=/eigen-3.3.9 -DWITH_GUDHI_EXAMPLE=OFF -DWITH_GUDHI_TEST=ON -DWITH_GUDHI_UTILITIES=OFF -DWITH_GUDHI_PYTHON=OFF ..
+ make all
+ ctest --output-on-failure
+
+ utils_without_cgal:
+ docker:
+ - image: gudhi/ci_for_gudhi_wo_cgal:latest
+ steps:
+ - checkout
+ - run:
+ name: Build and test utilities without cgal
+ command: |
+ mkdir build
+ cd build
+ cmake -DCMAKE_BUILD_TYPE=Release -DEIGEN3_INCLUDE_DIR=/eigen-3.3.9 -DWITH_GUDHI_EXAMPLE=OFF -DWITH_GUDHI_TEST=OFF -DWITH_GUDHI_UTILITIES=ON -DWITH_GUDHI_PYTHON=OFF ..
+ make all
+ ctest --output-on-failure
+
+ python_without_cgal:
+ docker:
+ - image: gudhi/ci_for_gudhi_wo_cgal:latest
+ steps:
+ - checkout
+ - run:
+ name: Build and test python module without cgal
+ command: |
+ git submodule init
+ git submodule update
+ mkdir build
+ cd build
+ cmake -DCMAKE_BUILD_TYPE=Release -DEIGEN3_INCLUDE_DIR=/eigen-3.3.9 -DWITH_GUDHI_EXAMPLE=OFF -DWITH_GUDHI_UTILITIES=OFF -DWITH_GUDHI_PYTHON=ON -DPython_ADDITIONAL_VERSIONS=3 ..
+ cd src/python
+ python3 setup.py build_ext --inplace
+ ctest --output-on-failure
+
workflows:
version: 2
build:
jobs:
+ - examples_without_cgal_eigen
+ - tests_without_cgal_eigen
+ - utils_without_cgal_eigen
+ - python_without_cgal_eigen
+ - examples_without_cgal
+ - tests_without_cgal
+ - utils_without_cgal
+ - python_without_cgal
- examples
- tests
- utils
diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt
index 56b6876c..5c1402a6 100644
--- a/src/python/CMakeLists.txt
+++ b/src/python/CMakeLists.txt
@@ -133,6 +133,10 @@ if(PYTHONINTERP_FOUND)
add_gudhi_debug_info("Eigen3 version ${EIGEN3_VERSION}")
# No problem, even if no CGAL found
set(GUDHI_PYTHON_EXTRA_COMPILE_ARGS "${GUDHI_PYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_EIGEN3_ENABLED', ")
+ set(GUDHI_PYTHON_EXTRA_COMPILE_ARGS "${GUDHI_PYTHON_EXTRA_COMPILE_ARGS}'-DGUDHI_USE_EIGEN3', ")
+ set(GUDHI_USE_EIGEN3 "True")
+ else (EIGEN3_FOUND)
+ set(GUDHI_USE_EIGEN3 "False")
endif (EIGEN3_FOUND)
set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}'off_reader', ")
@@ -504,7 +508,7 @@ if(PYTHONINTERP_FOUND)
endif()
# Representations
- if(SKLEARN_FOUND AND MATPLOTLIB_FOUND)
+ if(SKLEARN_FOUND AND MATPLOTLIB_FOUND AND OT_FOUND AND NOT CGAL_VERSION VERSION_LESS 4.11.0)
add_gudhi_py_test(test_representations)
endif()
diff --git a/src/python/example/diagram_vectorizations_distances_kernels.py b/src/python/example/diagram_vectorizations_distances_kernels.py
index c4a71a7a..2801576e 100755
--- a/src/python/example/diagram_vectorizations_distances_kernels.py
+++ b/src/python/example/diagram_vectorizations_distances_kernels.py
@@ -5,11 +5,11 @@ import numpy as np
from sklearn.kernel_approximation import RBFSampler
from sklearn.preprocessing import MinMaxScaler
-from gudhi.representations import DiagramSelector, Clamping, Landscape, Silhouette, BettiCurve, ComplexPolynomial,\
+from gudhi.representations import (DiagramSelector, Clamping, Landscape, Silhouette, BettiCurve, ComplexPolynomial,\
TopologicalVector, DiagramScaler, BirthPersistenceTransform,\
PersistenceImage, PersistenceWeightedGaussianKernel, Entropy, \
PersistenceScaleSpaceKernel, SlicedWassersteinDistance,\
- SlicedWassersteinKernel, BottleneckDistance, PersistenceFisherKernel, WassersteinDistance
+ SlicedWassersteinKernel, PersistenceFisherKernel, WassersteinDistance)
D1 = np.array([[0.,4.],[1.,2.],[3.,8.],[6.,8.], [0., np.inf], [5., np.inf]])
@@ -93,14 +93,21 @@ print("SW distance is " + str(sW(D1, D2)))
SW = SlicedWassersteinKernel(num_directions=100, bandwidth=1.)
print("SW kernel is " + str(SW(D1, D2)))
-W = WassersteinDistance(order=2, internal_p=2, mode="pot")
-print("Wasserstein distance (POT) is " + str(W(D1, D2)))
+try:
+ W = WassersteinDistance(order=2, internal_p=2, mode="pot")
+ print("Wasserstein distance (POT) is " + str(W(D1, D2)))
+except ImportError:
+ print("WassersteinDistance (POT) is not available, you may be missing pot.")
W = WassersteinDistance(order=2, internal_p=2, mode="hera", delta=0.0001)
print("Wasserstein distance (hera) is " + str(W(D1, D2)))
-W = BottleneckDistance(epsilon=.001)
-print("Bottleneck distance is " + str(W(D1, D2)))
+try:
+ from gudhi.representations import BottleneckDistance
+ W = BottleneckDistance(epsilon=.001)
+ print("Bottleneck distance is " + str(W(D1, D2)))
+except ImportError:
+ print("BottleneckDistance is not available, you may be missing CGAL.")
PF = PersistenceFisherKernel(bandwidth_fisher=1., bandwidth=1.)
print("PF kernel is " + str(PF(D1, D2)))
diff --git a/src/python/gudhi/__init__.py.in b/src/python/gudhi/__init__.py.in
index 79e12fbc..3043201a 100644
--- a/src/python/gudhi/__init__.py.in
+++ b/src/python/gudhi/__init__.py.in
@@ -23,6 +23,10 @@ __all__ = [@GUDHI_PYTHON_MODULES@ @GUDHI_PYTHON_MODULES_EXTRA@]
__available_modules = ''
__missing_modules = ''
+# For unitary tests purpose
+# could use "if 'collapse_edges' in gudhi.__all__" when collapse edges will have a python module
+__GUDHI_USE_EIGEN3 = @GUDHI_USE_EIGEN3@
+
# Try to import * from gudhi.__module_name for default modules.
# Extra modules require an explicit import by the user (mostly because of
# unusual dependencies, but also to avoid cluttering namespace gudhi and
diff --git a/src/python/gudhi/simplex_tree.pxd b/src/python/gudhi/simplex_tree.pxd
index 3c4cbed3..000323af 100644
--- a/src/python/gudhi/simplex_tree.pxd
+++ b/src/python/gudhi/simplex_tree.pxd
@@ -63,7 +63,7 @@ cdef extern from "Simplex_tree_interface.h" namespace "Gudhi":
bool make_filtration_non_decreasing() nogil
void compute_extended_filtration() nogil
vector[vector[pair[int, pair[double, double]]]] compute_extended_persistence_subdiagrams(vector[pair[int, pair[double, double]]] dgm, double min_persistence) nogil
- Simplex_tree_interface_full_featured* collapse_edges(int nb_collapse_iteration) nogil
+ Simplex_tree_interface_full_featured* collapse_edges(int nb_collapse_iteration) nogil except +
void reset_filtration(double filtration, int dimension) nogil
# Iterators over Simplex tree
pair[vector[int], double] get_simplex_and_filtration(Simplex_tree_simplex_handle f_simplex) nogil
diff --git a/src/python/gudhi/simplex_tree.pyx b/src/python/gudhi/simplex_tree.pyx
index cdd2e87b..665d41e6 100644
--- a/src/python/gudhi/simplex_tree.pyx
+++ b/src/python/gudhi/simplex_tree.pyx
@@ -627,6 +627,9 @@ cdef class SimplexTree:
:param nb_iterations: The number of edge collapse iterations to perform. Default is 1.
:type nb_iterations: int
+
+ :note: collapse_edges method requires `Eigen <installation.html#eigen>`_ >= 3.1.0 and an exception is thrown
+ if this method is not available.
"""
# Backup old pointer
cdef Simplex_tree_interface_full_featured* ptr = self.get_ptr()
diff --git a/src/python/include/Simplex_tree_interface.h b/src/python/include/Simplex_tree_interface.h
index baff3850..629f6083 100644
--- a/src/python/include/Simplex_tree_interface.h
+++ b/src/python/include/Simplex_tree_interface.h
@@ -15,7 +15,9 @@
#include <gudhi/distance_functions.h>
#include <gudhi/Simplex_tree.h>
#include <gudhi/Points_off_io.h>
+#ifdef GUDHI_USE_EIGEN3
#include <gudhi/Flag_complex_edge_collapser.h>
+#endif
#include <iostream>
#include <vector>
@@ -162,6 +164,7 @@ class Simplex_tree_interface : public Simplex_tree<SimplexTreeOptions> {
}
Simplex_tree_interface* collapse_edges(int nb_collapse_iteration) {
+#ifdef GUDHI_USE_EIGEN3
using Filtered_edge = std::tuple<Vertex_handle, Vertex_handle, Filtration_value>;
std::vector<Filtered_edge> edges;
for (Simplex_handle sh : Base::skeleton_simplex_range(1)) {
@@ -187,6 +190,9 @@ class Simplex_tree_interface : public Simplex_tree<SimplexTreeOptions> {
collapsed_stree_ptr->insert({std::get<0>(remaining_edge), std::get<1>(remaining_edge)}, std::get<2>(remaining_edge));
}
return collapsed_stree_ptr;
+#else
+ throw std::runtime_error("Unable to collapse edges as it requires Eigen3 >= 3.1.0.");
+#endif
}
// Iterator over the simplex tree
diff --git a/src/python/test/test_simplex_tree.py b/src/python/test/test_simplex_tree.py
index 3b23fa0b..a3eacaa9 100755
--- a/src/python/test/test_simplex_tree.py
+++ b/src/python/test/test_simplex_tree.py
@@ -8,7 +8,7 @@
- YYYY/MM Author: Description of the modification
"""
-from gudhi import SimplexTree
+from gudhi import SimplexTree, __GUDHI_USE_EIGEN3
import pytest
__author__ = "Vincent Rouvreau"
@@ -353,11 +353,16 @@ def test_collapse_edges():
assert st.num_simplices() == 10
- st.collapse_edges()
- assert st.num_simplices() == 9
- assert st.find([1, 3]) == False
- for simplex in st.get_skeleton(0):
- assert simplex[1] == 1.
+ if __GUDHI_USE_EIGEN3:
+ st.collapse_edges()
+ assert st.num_simplices() == 9
+ assert st.find([1, 3]) == False
+ for simplex in st.get_skeleton(0):
+ assert simplex[1] == 1.
+ else:
+ # If no Eigen3, collapse_edges throws an exception
+ with pytest.raises(RuntimeError):
+ st.collapse_edges()
def test_reset_filtration():
st = SimplexTree()