From 76a61bcd3279a98bd84856b011869a0be2ba99cd Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Thu, 30 Jul 2020 12:36:16 +0200 Subject: collapse edges for python simplex tree --- src/python/gudhi/simplex_tree.pyx | 63 +++++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 23 deletions(-) (limited to 'src/python/gudhi/simplex_tree.pyx') diff --git a/src/python/gudhi/simplex_tree.pyx b/src/python/gudhi/simplex_tree.pyx index 20e66d9f..236435a7 100644 --- a/src/python/gudhi/simplex_tree.pyx +++ b/src/python/gudhi/simplex_tree.pyx @@ -69,7 +69,7 @@ cdef class SimplexTree: this simplicial complex, or +infinity if it is not in the complex. :param simplex: The N-simplex, represented by a list of vertex. - :type simplex: list of int. + :type simplex: list of int :returns: The simplicial complex filtration value. :rtype: float """ @@ -80,7 +80,7 @@ cdef class SimplexTree: given N-simplex. :param simplex: The N-simplex, represented by a list of vertex. - :type simplex: list of int. + :type simplex: list of int :param filtration: The new filtration value. :type filtration: float @@ -153,7 +153,7 @@ cdef class SimplexTree: """This function sets the dimension of the simplicial complex. :param dimension: The new dimension value. - :type dimension: int. + :type dimension: int .. note:: @@ -172,7 +172,7 @@ cdef class SimplexTree: complex or not. :param simplex: The N-simplex to find, represented by a list of vertex. - :type simplex: list of int. + :type simplex: list of int :returns: true if the simplex was found, false otherwise. :rtype: bool """ @@ -186,9 +186,9 @@ cdef class SimplexTree: :param simplex: The N-simplex to insert, represented by a list of vertex. - :type simplex: list of int. + :type simplex: list of int :param filtration: The filtration value of the simplex. - :type filtration: float. + :type filtration: float :returns: true if the simplex was not yet in the complex, false otherwise (whatever its original filtration value). :rtype: bool @@ -228,7 +228,7 @@ cdef class SimplexTree: """This function returns a generator with the (simplices of the) skeleton of a maximum given dimension. :param dimension: The skeleton dimension value. - :type dimension: int. + :type dimension: int :returns: The (simplices of the) skeleton of a maximum dimension. :rtype: generator with tuples(simplex, filtration) """ @@ -243,7 +243,7 @@ cdef class SimplexTree: """This function returns the star of a given N-simplex. :param simplex: The N-simplex, represented by a list of vertex. - :type simplex: list of int. + :type simplex: list of int :returns: The (simplices of the) star of a simplex. :rtype: list of tuples(simplex, filtration) """ @@ -265,10 +265,10 @@ cdef class SimplexTree: given codimension. :param simplex: The N-simplex, represented by a list of vertex. - :type simplex: list of int. + :type simplex: list of int :param codimension: The codimension. If codimension = 0, all cofaces are returned (equivalent of get_star function) - :type codimension: int. + :type codimension: int :returns: The (simplices of the) cofaces of a simplex :rtype: list of tuples(simplex, filtration) """ @@ -290,7 +290,7 @@ cdef class SimplexTree: complex. :param simplex: The N-simplex, represented by a list of vertex. - :type simplex: list of int. + :type simplex: list of int .. note:: @@ -308,7 +308,7 @@ cdef class SimplexTree: """Prune above filtration value given as parameter. :param filtration: Maximum threshold value. - :type filtration: float. + :type filtration: float :returns: The filtration modification information. :rtype: bool @@ -342,7 +342,7 @@ cdef class SimplexTree: 1 when calling the method. :param max_dim: The maximal dimension. - :type max_dim: int. + :type max_dim: int """ cdef int maxdim = max_dim with nogil: @@ -383,12 +383,12 @@ cdef class SimplexTree: :param homology_coeff_field: The homology coefficient field. Must be a prime number. Default value is 11. - :type homology_coeff_field: int. + :type homology_coeff_field: int :param min_persistence: The minimum persistence value (i.e., the absolute value of the difference between the persistence diagram point coordinates) to take into account (strictly greater than min_persistence). Default value is 0.0. Sets min_persistence to -1.0 to see all values. - :type min_persistence: float. + :type min_persistence: float :returns: A list of four persistence diagrams in the format described in :func:`persistence`. The first one is Ordinary, the second one is Relative, the third one is Extended+ and the fourth one is Extended-. See https://link.springer.com/article/10.1007/s10208-008-9027-z and/or section 2.2 in https://link.springer.com/article/10.1007/s10208-017-9370-z for a description of these subtypes. .. note:: @@ -415,12 +415,12 @@ cdef class SimplexTree: :param homology_coeff_field: The homology coefficient field. Must be a prime number. Default value is 11. - :type homology_coeff_field: int. + :type homology_coeff_field: int :param min_persistence: The minimum persistence value to take into account (strictly greater than min_persistence). Default value is 0.0. Set min_persistence to -1.0 to see all values. - :type min_persistence: float. + :type min_persistence: float :param persistence_dim_max: If true, the persistent homology for the maximal dimension in the complex is computed. If false, it is ignored. Default is false. @@ -438,12 +438,12 @@ cdef class SimplexTree: :param homology_coeff_field: The homology coefficient field. Must be a prime number. Default value is 11. - :type homology_coeff_field: int. + :type homology_coeff_field: int :param min_persistence: The minimum persistence value to take into account (strictly greater than min_persistence). Default value is 0.0. Sets min_persistence to -1.0 to see all values. - :type min_persistence: float. + :type min_persistence: float :param persistence_dim_max: If true, the persistent homology for the maximal dimension in the complex is computed. If false, it is ignored. Default is false. @@ -478,10 +478,10 @@ cdef class SimplexTree: :param from_value: The persistence birth limit to be added in the numbers (persistent birth <= from_value). - :type from_value: float. + :type from_value: float :param to_value: The persistence death limit to be added in the numbers (persistent death > to_value). - :type to_value: float. + :type to_value: float :returns: The persistent Betti numbers ([B0, B1, ..., Bn]). :rtype: list of int @@ -498,7 +498,7 @@ cdef class SimplexTree: complex in a specific dimension. :param dimension: The specific dimension. - :type dimension: int. + :type dimension: int :returns: The persistence intervals. :rtype: numpy array of dimension 2 @@ -527,7 +527,7 @@ cdef class SimplexTree: complex in a user given file name. :param persistence_file: Name of the file. - :type persistence_file: string. + :type persistence_file: string :note: intervals_in_dim function requires :func:`compute_persistence` @@ -581,3 +581,20 @@ cdef class SimplexTree: infinite0 = np_array(next(l)) infinites = [np_array(d).reshape(-1,2) for d in l] return (normal0, normals, infinite0, infinites) + + def collapse_edges(self, nb_iterations = 1): + """Assuming the simplex tree is a 1-skeleton graph, this function collapse edges and resets the simplex tree + from the remaining edges. + A good candidate is to build a simplex tree on top of a :class:`~gudhi.RipsComplex` of dimension 1 before + collapsing edges. + + :param nb_iterations: The number of edge collapse iterations to perform. Default is 1. + :type nb_iterations: int + """ + # Backup old pointer + cdef Simplex_tree_interface_full_featured* ptr = self.get_ptr() + # New pointer is a new collapsed simplex tree + self.thisptr = (self.get_ptr().collapse_edges(nb_iterations)) + # Delete old pointer + if ptr != NULL: + del ptr -- cgit v1.2.3 From 12c0266d7defec73a6e8da3990a7fc8d482cbde5 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Fri, 31 Jul 2020 15:23:40 +0200 Subject: code review: nogil and use ptr as suggested --- src/python/gudhi/simplex_tree.pyx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'src/python/gudhi/simplex_tree.pyx') diff --git a/src/python/gudhi/simplex_tree.pyx b/src/python/gudhi/simplex_tree.pyx index 236435a7..9eee5e14 100644 --- a/src/python/gudhi/simplex_tree.pyx +++ b/src/python/gudhi/simplex_tree.pyx @@ -593,8 +593,10 @@ cdef class SimplexTree: """ # Backup old pointer cdef Simplex_tree_interface_full_featured* ptr = self.get_ptr() - # New pointer is a new collapsed simplex tree - self.thisptr = (self.get_ptr().collapse_edges(nb_iterations)) - # Delete old pointer - if ptr != NULL: - del ptr + cdef int nb_iter = nb_iterations + with nogil: + # New pointer is a new collapsed simplex tree + self.thisptr = (ptr.collapse_edges(nb_iter)) + # Delete old pointer + if ptr != NULL: + del ptr -- cgit v1.2.3 From d27d7839a3c32513ffc60eb709765c6a89e0e208 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Fri, 31 Jul 2020 16:21:55 +0200 Subject: Rebuild example page and link to example. Add also a link to the publication. Doc review: document edge collapse ignores simplices of higher dimension. --- src/python/doc/examples.rst | 33 ++++++++++++++++++--------------- src/python/gudhi/simplex_tree.pyx | 8 +++++--- 2 files changed, 23 insertions(+), 18 deletions(-) (limited to 'src/python/gudhi/simplex_tree.pyx') diff --git a/src/python/doc/examples.rst b/src/python/doc/examples.rst index a42227e3..76e5d4c7 100644 --- a/src/python/doc/examples.rst +++ b/src/python/doc/examples.rst @@ -7,27 +7,30 @@ Examples .. only:: builder_html - * :download:`rips_complex_from_points_example.py <../example/rips_complex_from_points_example.py>` + * :download:`alpha_complex_diagram_persistence_from_off_file_example.py <../example/alpha_complex_diagram_persistence_from_off_file_example.py>` * :download:`alpha_complex_from_points_example.py <../example/alpha_complex_from_points_example.py>` - * :download:`simplex_tree_example.py <../example/simplex_tree_example.py>` * :download:`alpha_rips_persistence_bottleneck_distance.py <../example/alpha_rips_persistence_bottleneck_distance.py>` - * :download:`tangential_complex_plain_homology_from_off_file_example.py <../example/tangential_complex_plain_homology_from_off_file_example.py>` - * :download:`alpha_complex_diagram_persistence_from_off_file_example.py <../example/alpha_complex_diagram_persistence_from_off_file_example.py>` - * :download:`periodic_cubical_complex_barcode_persistence_from_perseus_file_example.py <../example/periodic_cubical_complex_barcode_persistence_from_perseus_file_example.py>` * :download:`bottleneck_basic_example.py <../example/bottleneck_basic_example.py>` - * :download:`gudhi_graphical_tools_example.py <../example/gudhi_graphical_tools_example.py>` - * :download:`plot_simplex_tree_dim012.py <../example/plot_simplex_tree_dim012.py>` - * :download:`plot_rips_complex.py <../example/plot_rips_complex.py>` - * :download:`plot_alpha_complex.py <../example/plot_alpha_complex.py>` - * :download:`witness_complex_from_nearest_landmark_table.py <../example/witness_complex_from_nearest_landmark_table.py>` + * :download:`coordinate_graph_induced_complex.py <../example/coordinate_graph_induced_complex.py>` + * :download:`diagram_vectorizations_distances_kernels.py <../example/diagram_vectorizations_distances_kernels.py>` * :download:`euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py <../example/euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py>` * :download:`euclidean_witness_complex_diagram_persistence_from_off_file_example.py <../example/euclidean_witness_complex_diagram_persistence_from_off_file_example.py>` - * :download:`rips_complex_diagram_persistence_from_off_file_example.py <../example/rips_complex_diagram_persistence_from_off_file_example.py>` + * :download:`functional_graph_induced_complex.py <../example/functional_graph_induced_complex.py>` + * :download:`gudhi_graphical_tools_example.py <../example/gudhi_graphical_tools_example.py>` + * :download:`nerve_of_a_covering.py <../example/nerve_of_a_covering.py>` + * :download:`periodic_cubical_complex_barcode_persistence_from_perseus_file_example.py <../example/periodic_cubical_complex_barcode_persistence_from_perseus_file_example.py>` + * :download:`plot_alpha_complex.py <../example/plot_alpha_complex.py>` + * :download:`plot_rips_complex.py <../example/plot_rips_complex.py>` + * :download:`plot_simplex_tree_dim012.py <../example/plot_simplex_tree_dim012.py>` + * :download:`random_cubical_complex_persistence_example.py <../example/random_cubical_complex_persistence_example.py>` + * :download:`rips_complex_diagram_persistence_from_correlation_matrix_file_example.py <../example/rips_complex_diagram_persistence_from_correlation_matrix_file_example.py>` * :download:`rips_complex_diagram_persistence_from_distance_matrix_file_example.py <../example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py>` + * :download:`rips_complex_diagram_persistence_from_off_file_example.py <../example/rips_complex_diagram_persistence_from_off_file_example.py>` + * :download:`rips_complex_edge_collapse_example.py <../example/rips_complex_edge_collapse_example.py>` + * :download:`rips_complex_from_points_example.py <../example/rips_complex_from_points_example.py>` * :download:`rips_persistence_diagram.py <../example/rips_persistence_diagram.py>` + * :download:`simplex_tree_example.py <../example/simplex_tree_example.py>` * :download:`sparse_rips_persistence_diagram.py <../example/sparse_rips_persistence_diagram.py>` - * :download:`random_cubical_complex_persistence_example.py <../example/random_cubical_complex_persistence_example.py>` - * :download:`coordinate_graph_induced_complex.py <../example/coordinate_graph_induced_complex.py>` - * :download:`functional_graph_induced_complex.py <../example/functional_graph_induced_complex.py>` + * :download:`tangential_complex_plain_homology_from_off_file_example.py <../example/tangential_complex_plain_homology_from_off_file_example.py>` * :download:`voronoi_graph_induced_complex.py <../example/voronoi_graph_induced_complex.py>` - * :download:`nerve_of_a_covering.py <../example/nerve_of_a_covering.py>` + * :download:`witness_complex_from_nearest_landmark_table.py <../example/witness_complex_from_nearest_landmark_table.py>` diff --git a/src/python/gudhi/simplex_tree.pyx b/src/python/gudhi/simplex_tree.pyx index 9eee5e14..62f81d0b 100644 --- a/src/python/gudhi/simplex_tree.pyx +++ b/src/python/gudhi/simplex_tree.pyx @@ -583,10 +583,12 @@ cdef class SimplexTree: return (normal0, normals, infinite0, infinites) def collapse_edges(self, nb_iterations = 1): - """Assuming the simplex tree is a 1-skeleton graph, this function collapse edges and resets the simplex tree - from the remaining edges. + """Assuming the simplex tree is a 1-skeleton graph, this method collapse edges (simplices of higher dimension + are ignored) and resets the simplex tree from the remaining edges. A good candidate is to build a simplex tree on top of a :class:`~gudhi.RipsComplex` of dimension 1 before - collapsing edges. + collapsing edges + (cf. :download:`rips_complex_edge_collapse_example.py <../example/rips_complex_edge_collapse_example.py>`). + For implementation details, please refer to :cite:`edgecollapsesocg2020`. :param nb_iterations: The number of edge collapse iterations to perform. Default is 1. :type nb_iterations: int -- cgit v1.2.3 From 010e8625ace3bbbfd09b7946237e8f3f04159452 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Mon, 3 Aug 2020 09:14:35 +0200 Subject: code review: no need to test if pointer is NULL --- src/python/gudhi/simplex_tree.pyx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/python/gudhi/simplex_tree.pyx') diff --git a/src/python/gudhi/simplex_tree.pyx b/src/python/gudhi/simplex_tree.pyx index 62f81d0b..dfb1d985 100644 --- a/src/python/gudhi/simplex_tree.pyx +++ b/src/python/gudhi/simplex_tree.pyx @@ -600,5 +600,4 @@ cdef class SimplexTree: # New pointer is a new collapsed simplex tree self.thisptr = (ptr.collapse_edges(nb_iter)) # Delete old pointer - if ptr != NULL: - del ptr + del ptr -- cgit v1.2.3