From 97d80185d6ec4d5e8f81b4cd4936d29a6d63b05b Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Tue, 29 Nov 2016 16:50:55 +0000 Subject: Fix interface for Alpha complex and Tangential complex git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/ST_cythonize@1801 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 995b53c7f65057ec155988b90f17299665eab4ae --- src/cython/CMakeLists.txt | 4 ++ src/cython/cython/alpha_complex.pyx | 19 ++++---- src/cython/cython/simplex_tree.pyx | 48 ++++++++++++-------- src/cython/cython/tangential_complex.pyx | 12 +++-- src/cython/doc/alpha_complex_user.rst | 14 +++--- .../doc/persistence_graphical_tools_user.rst | 3 +- src/cython/doc/tangential_complex_user.rst | 53 ++++++++++++++++++---- ...ex_diagram_persistence_from_off_file_example.py | 3 +- .../example/alpha_complex_from_points_example.py | 3 +- src/cython/include/Alpha_complex_interface.h | 6 +-- src/cython/include/Tangential_complex_interface.h | 14 +++--- src/cython/test/test_alpha_complex.py | 6 +-- 12 files changed, 115 insertions(+), 70 deletions(-) (limited to 'src/cython') diff --git a/src/cython/CMakeLists.txt b/src/cython/CMakeLists.txt index 09ebb678..2746cab9 100644 --- a/src/cython/CMakeLists.txt +++ b/src/cython/CMakeLists.txt @@ -29,6 +29,10 @@ if(PYTHON_PATH AND CYTHON_PATH) if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-fp-model strict', ") endif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") + if (DEBUG_TRACES) + # For programs to be more verbose + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DDEBUG_TRACES', ") + endif() find_package(Eigen3 3.1.0) diff --git a/src/cython/cython/alpha_complex.pyx b/src/cython/cython/alpha_complex.pyx index ed518c38..93f9b87e 100644 --- a/src/cython/cython/alpha_complex.pyx +++ b/src/cython/cython/alpha_complex.pyx @@ -38,7 +38,7 @@ cdef extern from "Alpha_complex_interface.h" namespace "Gudhi": # bool from_file is a workaround for cython to find the correct signature Alpha_complex_interface(string off_file, bool from_file) vector[double] get_point(int vertex) - void create_simplex_tree(Simplex_tree_interface_full_featured simplex_tree, double max_alpha_square) + void create_simplex_tree(Simplex_tree_interface_full_featured* simplex_tree, double max_alpha_square) # AlphaComplex python interface cdef class AlphaComplex: @@ -100,19 +100,20 @@ cdef class AlphaComplex: :param vertex: The vertex. :type vertex: int - :returns: list of float -- the point. + :rtype: list of float + :returns: the point. """ cdef vector[double] point = self.thisptr.get_point(vertex) return point - def create_simplex_tree(self, SimplexTree simplex_tree, max_alpha_square=float('inf')): - """This function creates the given simplex tree from the Delaunay - Triangulation. - - :param simplex_tree: The simplex tree to create (must be empty) - :type simplex_tree: SimplexTree + def create_simplex_tree(self, max_alpha_square=float('inf')): + """ :param max_alpha_square: The maximum alpha square threshold the simplices shall not exceed. Default is set to infinity. :type max_alpha_square: float + :returns: A simplex tree created from the Delaunay Triangulation. + :rtype: SimplexTree """ - self.thisptr.create_simplex_tree(deref(simplex_tree.thisptr), max_alpha_square) \ No newline at end of file + simplex_tree = SimplexTree() + self.thisptr.create_simplex_tree(simplex_tree.thisptr, max_alpha_square) + return simplex_tree diff --git a/src/cython/cython/simplex_tree.pyx b/src/cython/cython/simplex_tree.pyx index cf7cbe26..06e2eb90 100644 --- a/src/cython/cython/simplex_tree.pyx +++ b/src/cython/cython/simplex_tree.pyx @@ -102,7 +102,8 @@ cdef class SimplexTree: def get_filtration(self): """This function returns the main simplicial complex filtration value. - :returns: float -- the simplicial complex filtration value. + :returns: The simplicial complex filtration value. + :rtype: float """ return self.thisptr.filtration() @@ -112,7 +113,8 @@ cdef class SimplexTree: :param simplex: The N-simplex, represented by a list of vertex. :type simplex: list of int. - :returns: float -- the simplicial complex filtration value. + :returns: The simplicial complex filtration value. + :rtype: float """ return self.thisptr.simplex_filtration(simplex) @@ -140,7 +142,8 @@ cdef class SimplexTree: """This function returns the number of vertices of the simplicial complex. - :returns: int -- the simplicial complex number of vertices. + :returns: The simplicial complex number of vertices. + :rtype: int """ return self.thisptr.num_vertices() @@ -148,14 +151,16 @@ cdef class SimplexTree: """This function returns the number of simplices of the simplicial complex. - :returns: int -- the simplicial complex number of simplices. + :returns: the simplicial complex number of simplices. + :rtype: int """ return self.thisptr.num_simplices() def dimension(self): """This function returns the dimension of the simplicial complex. - :returns: int -- the simplicial complex dimension. + :returns: the simplicial complex dimension. + :rtype: int """ return self.thisptr.dimension() @@ -173,7 +178,8 @@ cdef class SimplexTree: :param simplex: The N-simplex to find, represented by a list of vertex. :type simplex: list of int. - :returns: bool -- true if the simplex was found, false otherwise. + :returns: true if the simplex was found, false otherwise. + :rtype: bool """ cdef vector[int] complex for i in simplex: @@ -189,7 +195,8 @@ cdef class SimplexTree: :type simplex: list of int. :param filtration: The filtration value of the simplex. :type filtration: float. - :returns: bool -- true if the simplex was found, false otherwise. + :returns: true if the simplex was found, false otherwise. + :rtype: bool """ cdef vector[int] complex for i in simplex: @@ -201,8 +208,8 @@ cdef class SimplexTree: """This function returns the tree sorted by increasing filtration values. - :returns: list of tuples(simplex, filtration) -- the tree sorted by - increasing filtration values. + :returns: The tree sorted by increasing filtration values. + :rtype: list of tuples(simplex, filtration) """ cdef vector[pair[vector[int], double]] coface_tree \ = self.thisptr.get_filtered_tree() @@ -220,8 +227,8 @@ cdef class SimplexTree: :param dimension: The skeleton dimension value. :type dimension: int. - :returns: list of tuples(simplex, filtration) -- the skeleton tree - of a maximum dimension. + :returns: The skeleton tree of a maximum dimension. + :rtype: list of tuples(simplex, filtration) """ cdef vector[pair[vector[int], double]] coface_tree \ = self.thisptr.get_skeleton_tree(dimension) @@ -238,8 +245,8 @@ cdef class SimplexTree: :param simplex: The N-simplex, represented by a list of vertex. :type simplex: list of int. - :returns: list of tuples(simplex, filtration) -- the star tree of a - simplex. + :returns: The star tree of a simplex. + :rtype: list of tuples(simplex, filtration) """ cdef vector[int] complex for i in simplex: @@ -263,8 +270,8 @@ cdef class SimplexTree: :param codimension: The codimension. If codimension = 0, all cofaces are returned (equivalent of get_star_tree function) :type codimension: int. - :returns: list of tuples(simplex, filtration) -- the coface tree of a - simplex. + :returns: The coface tree of a simplex. + :rtype: list of tuples(simplex, filtration) """ cdef vector[int] complex for i in simplex: @@ -299,8 +306,8 @@ cdef class SimplexTree: 0.0. Sets min_persistence to -1.0 to see all values. :type min_persistence: float. - :note: list of pairs(dimension, pair(birth, death)) -- the - persistence of the simplicial complex. + :returns: The persistence of the simplicial complex. + :rtype: list of pairs(dimension, pair(birth, death)) """ if self.pcohptr != NULL: del self.pcohptr @@ -313,7 +320,8 @@ cdef class SimplexTree: def betti_numbers(self): """This function returns the Betti numbers of the simplicial complex. - :returns: list of int -- The Betti numbers ([B0, B1, ..., Bn]). + :returns: The Betti numbers ([B0, B1, ..., Bn]). + :rtype: list of int :note: betti_numbers function requires persistence function to be launched first. @@ -337,8 +345,8 @@ cdef class SimplexTree: numbers (persistent death > to_value). :type to_value: float. - :returns: list of int -- The persistent Betti numbers ([B0, B1, ..., - Bn]). + :returns: The persistent Betti numbers ([B0, B1, ..., Bn]). + :rtype: list of int :note: persistent_betti_numbers function requires persistence function to be launched first. diff --git a/src/cython/cython/tangential_complex.pyx b/src/cython/cython/tangential_complex.pyx index 35f1e384..f0e4eb02 100644 --- a/src/cython/cython/tangential_complex.pyx +++ b/src/cython/cython/tangential_complex.pyx @@ -37,12 +37,12 @@ cdef extern from "Tangential_complex_interface.h" namespace "Gudhi": Tangential_complex_interface(vector[vector[double]] points) # bool from_file is a workaround for cython to find the correct signature Tangential_complex_interface(string off_file, bool from_file) - vector[double] get_point(int vertex) + vector[double] get_point(unsigned vertex) unsigned number_of_vertices() unsigned number_of_simplices() unsigned number_of_inconsistent_simplices() unsigned number_of_inconsistent_stars() - void create_simplex_tree(Simplex_tree_interface_full_featured simplex_tree) + void create_simplex_tree(Simplex_tree_interface_full_featured* simplex_tree) # TangentialComplex python interface cdef class TangentialComplex: @@ -137,11 +137,15 @@ cdef class TangentialComplex: """ return self.thisptr.number_of_inconsistent_stars() - def create_simplex_tree(self, SimplexTree simplex_tree): + def create_simplex_tree(self): """This function creates the given simplex tree from the Delaunay Triangulation. :param simplex_tree: The simplex tree to create (must be empty) :type simplex_tree: SimplexTree + :returns: A simplex tree created from the Delaunay Triangulation. + :rtype: SimplexTree """ - self.thisptr.create_simplex_tree(deref(simplex_tree.thisptr)) \ No newline at end of file + simplex_tree = SimplexTree() + self.thisptr.create_simplex_tree(simplex_tree.thisptr) + return simplex_tree diff --git a/src/cython/doc/alpha_complex_user.rst b/src/cython/doc/alpha_complex_user.rst index 5ad3a9e7..ed2a470c 100644 --- a/src/cython/doc/alpha_complex_user.rst +++ b/src/cython/doc/alpha_complex_user.rst @@ -25,14 +25,13 @@ This example builds the Delaunay triangulation from the given points, and initia import gudhi alpha_complex = gudhi.AlphaComplex(points=[[1, 1], [7, 0], [4, 6], [9, 6], [0, 14], [2, 19], [9, 17]]) - simplex_tree = gudhi.SimplexTree() - alpha_complex.create_simplex_tree(simplex_tree, max_alpha_square=60.0) + simplex_tree = alpha_complex.create_simplex_tree(max_alpha_square=60.0) result_str = 'Alpha complex is of dimension ' + repr(simplex_tree.dimension()) + ' - ' + \ repr(simplex_tree.num_simplices()) + ' simplices - ' + \ repr(simplex_tree.num_vertices()) + ' vertices.' print(result_str) - for fitered_value in simplex_tree.get_filtered_tree(): - print(fitered_value) + for filtered_value in simplex_tree.get_filtered_tree(): + print(filtered_value) The output is: @@ -156,14 +155,13 @@ Then, it is asked to display information about the alpha complex: import gudhi alpha_complex = gudhi.AlphaComplex(off_file='alphacomplexdoc.off') - simplex_tree = gudhi.SimplexTree() - alpha_complex.create_simplex_tree(simplex_tree, max_alpha_square=59.0) + simplex_tree = alpha_complex.create_simplex_tree(max_alpha_square=59.0) result_str = 'Alpha complex is of dimension ' + repr(simplex_tree.dimension()) + ' - ' + \ repr(simplex_tree.num_simplices()) + ' simplices - ' + \ repr(simplex_tree.num_vertices()) + ' vertices.' print(result_str) - for fitered_value in simplex_tree.get_filtered_tree(): - print(fitered_value) + for filtered_value in simplex_tree.get_filtered_tree(): + print(filtered_value) the program output is: diff --git a/src/cython/doc/persistence_graphical_tools_user.rst b/src/cython/doc/persistence_graphical_tools_user.rst index b23ad5e6..43c695bf 100644 --- a/src/cython/doc/persistence_graphical_tools_user.rst +++ b/src/cython/doc/persistence_graphical_tools_user.rst @@ -41,7 +41,6 @@ This function can display the persistence result as a diagram: import gudhi alpha_complex = gudhi.AlphaComplex(off_file='tore3D_300.off') - simplex_tree = gudhi.SimplexTree() - alpha_complex.create_simplex_tree(simplex_tree) + simplex_tree = alpha_complex.create_simplex_tree() diag = simplex_tree.persistence() gudhi.diagram_persistence(diag) diff --git a/src/cython/doc/tangential_complex_user.rst b/src/cython/doc/tangential_complex_user.rst index 588de08c..33c03e34 100644 --- a/src/cython/doc/tangential_complex_user.rst +++ b/src/cython/doc/tangential_complex_user.rst @@ -111,20 +111,55 @@ itself and/or after the perturbation process. Simple example -------------- -This example builds the Tangential complex of point set. Note that the -dimension of the kernel here is dynamic, which is slower, but more flexible: -the intrinsic and ambient dimensions does not have to be known at compile-time. +This example builds the Tangential complex of point set. -testcode:: +.. testcode:: - import gudhi - tc = gudhi.TangentialComplex(points=[[1, 1], [7, 0], [4, 6], [9, 6], [0, 14], [2, 19], [9, 17]]) + import gudhi + tc = gudhi.TangentialComplex(points=[[1, 1], [7, 0], [4, 6], [9, 6], [0, 14], [2, 19], [9, 17]]) + result_str = 'Tangential contains ' + repr(tc.num_simplices()) + \ + ' simplices - ' + repr(tc.num_vertices()) + ' vertices.' + print(result_str) -The output is: + st = tc.create_simplex_tree() + result_str = 'Simplex tree is of dimension ' + repr(st.dimension()) + \ + ' - ' + repr(st.num_simplices()) + ' simplices - ' + \ + repr(st.num_vertices()) + ' vertices.' + print(result_str) + for filtered_value in st.get_filtered_tree(): + print(filtered_value) -testoutput:: +The output is: - Tangential complex is of dimension 2 - 25 simplices - 7 vertices. +.. testoutput:: + + Tangential contains 18 simplices - 7 vertices. + Simplex tree is of dimension 2 - 25 simplices - 7 vertices. + ([0], 0.0) + ([1], 0.0) + ([0, 1], 0.0) + ([2], 0.0) + ([0, 2], 0.0) + ([1, 2], 0.0) + ([0, 1, 2], 0.0) + ([3], 0.0) + ([1, 3], 0.0) + ([2, 3], 0.0) + ([1, 2, 3], 0.0) + ([4], 0.0) + ([0, 4], 0.0) + ([2, 4], 0.0) + ([0, 2, 4], 0.0) + ([5], 0.0) + ([4, 5], 0.0) + ([6], 0.0) + ([2, 6], 0.0) + ([3, 6], 0.0) + ([2, 3, 6], 0.0) + ([4, 6], 0.0) + ([2, 4, 6], 0.0) + ([5, 6], 0.0) + ([4, 5, 6], 0.0) Example with perturbation diff --git a/src/cython/example/alpha_complex_diagram_persistence_from_off_file_example.py b/src/cython/example/alpha_complex_diagram_persistence_from_off_file_example.py index 40d06f93..6cdd5506 100755 --- a/src/cython/example/alpha_complex_diagram_persistence_from_off_file_example.py +++ b/src/cython/example/alpha_complex_diagram_persistence_from_off_file_example.py @@ -53,8 +53,7 @@ with open(args.file, 'r') as f: print(message) alpha_complex = gudhi.AlphaComplex(off_file=args.file) - simplex_tree = gudhi.SimplexTree() - alpha_complex.create_simplex_tree(simplex_tree, max_alpha_square=args.max_alpha_square) + simplex_tree = alpha_complex.create_simplex_tree(max_alpha_square=args.max_alpha_square) message = "Number of simplices=" + repr(simplex_tree.num_simplices()) print(message) diff --git a/src/cython/example/alpha_complex_from_points_example.py b/src/cython/example/alpha_complex_from_points_example.py index 45319f7f..ae21c711 100755 --- a/src/cython/example/alpha_complex_from_points_example.py +++ b/src/cython/example/alpha_complex_from_points_example.py @@ -31,8 +31,7 @@ __license__ = "GPL v3" print("#####################################################################") print("AlphaComplex creation from points") alpha_complex = AlphaComplex(points=[[0, 0], [1, 0], [0, 1], [1, 1]]) -simplex_tree = SimplexTree() -alpha_complex.create_simplex_tree(simplex_tree, max_alpha_square=60.0) +simplex_tree = alpha_complex.create_simplex_tree(max_alpha_square=60.0) if simplex_tree.find([0, 1]): print("[0, 1] Found !!") diff --git a/src/cython/include/Alpha_complex_interface.h b/src/cython/include/Alpha_complex_interface.h index 15384206..81761c77 100644 --- a/src/cython/include/Alpha_complex_interface.h +++ b/src/cython/include/Alpha_complex_interface.h @@ -69,9 +69,9 @@ class Alpha_complex_interface { return vd; } - void create_simplex_tree(Simplex_tree_interface<>& simplex_tree, double max_alpha_square) { - alpha_complex_->create_complex(simplex_tree, max_alpha_square); - simplex_tree.initialize_filtration(); + void create_simplex_tree(Simplex_tree_interface<>* simplex_tree, double max_alpha_square) { + alpha_complex_->create_complex(*simplex_tree, max_alpha_square); + simplex_tree->initialize_filtration(); } private: diff --git a/src/cython/include/Tangential_complex_interface.h b/src/cython/include/Tangential_complex_interface.h index 49d66476..c7fce557 100644 --- a/src/cython/include/Tangential_complex_interface.h +++ b/src/cython/include/Tangential_complex_interface.h @@ -73,14 +73,12 @@ class Tangential_complex_interface { num_inconsistencies_ = tangential_complex_->number_of_inconsistent_simplices(); } - std::vector get_point(int vh) { + std::vector get_point(unsigned vh) { std::vector vd; - try { + if (vh < tangential_complex_->number_of_vertices()) { Point_d ph = tangential_complex_->get_point(vh); for (auto coord = ph.cartesian_begin(); coord < ph.cartesian_end(); coord++) vd.push_back(*coord); - } catch (std::out_of_range outofrange) { - // std::out_of_range is thrown in case not found. Other exceptions must be re-thrown } return vd; } @@ -101,9 +99,11 @@ class Tangential_complex_interface { return num_inconsistencies_.num_inconsistent_stars; } - void create_simplex_tree(Simplex_tree<>& simplex_tree) { - tangential_complex_->create_complex>(simplex_tree); - simplex_tree.initialize_filtration(); + void create_simplex_tree(Simplex_tree<>* simplex_tree) { + int max_dim = tangential_complex_->create_complex>(*simplex_tree); + // FIXME + simplex_tree->set_dimension(max_dim); + simplex_tree->initialize_filtration(); } private: diff --git a/src/cython/test/test_alpha_complex.py b/src/cython/test/test_alpha_complex.py index 3731ccda..b08ac0d7 100755 --- a/src/cython/test/test_alpha_complex.py +++ b/src/cython/test/test_alpha_complex.py @@ -36,8 +36,7 @@ def test_infinite_alpha(): alpha_complex = AlphaComplex(points=point_list) assert alpha_complex.__is_defined() == True - simplex_tree = SimplexTree() - alpha_complex.create_simplex_tree(simplex_tree) + simplex_tree = alpha_complex.create_simplex_tree() assert simplex_tree.__is_persistence_defined() == False assert simplex_tree.num_simplices() == 11 @@ -65,8 +64,7 @@ def test_filtered_alpha(): point_list = [[0, 0], [1, 0], [0, 1], [1, 1]] filtered_alpha = AlphaComplex(points=point_list) - simplex_tree = SimplexTree() - filtered_alpha.create_simplex_tree(simplex_tree, max_alpha_square=0.25) + simplex_tree = filtered_alpha.create_simplex_tree(max_alpha_square=0.25) assert simplex_tree.num_simplices() == 8 assert simplex_tree.num_vertices() == 4 -- cgit v1.2.3