From ad9c182c0ffa8b517cd20d174de823db05250514 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Wed, 25 Jan 2017 08:59:20 +0000 Subject: Fix rips complex with the new interface Remove mini simplex tree Fix persistent cohomology doc - only simplex tree used Remove useless type definition in Cython C++ interfaces git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/ST_cythonize@2003 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: fff43192b00df1c70d59109a6c14932013992ff1 --- src/cython/cython/mini_simplex_tree.pyx | 352 -------------------- src/cython/cython/rips_complex.pyx | 354 +++------------------ src/cython/doc/persistent_cohomology_sum.rst | 3 - src/cython/doc/persistent_cohomology_user.rst | 3 - src/cython/example/mini_simplex_tree_example.py | 73 ----- ...am_persistence_with_pandas_interface_example.py | 11 +- .../example/rips_complex_from_points_example.py | 10 +- src/cython/example/rips_persistence_diagram.py | 7 +- src/cython/gudhi.pyx.in | 1 - src/cython/include/Alpha_complex_interface.h | 9 +- src/cython/include/Cubical_complex_interface.h | 4 +- src/cython/include/Rips_complex_interface.h | 70 ++++ src/cython/include/Simplex_tree_interface.h | 34 +- src/cython/include/Subsampling_interface.h | 3 +- src/cython/include/Tangential_complex_interface.h | 5 - src/cython/include/Witness_complex_interface.h | 4 +- src/cython/test/test_mini_simplex_tree.py | 50 --- src/cython/test/test_rips_complex.py | 35 +- 18 files changed, 158 insertions(+), 870 deletions(-) delete mode 100644 src/cython/cython/mini_simplex_tree.pyx delete mode 100755 src/cython/example/mini_simplex_tree_example.py create mode 100644 src/cython/include/Rips_complex_interface.h delete mode 100755 src/cython/test/test_mini_simplex_tree.py (limited to 'src') diff --git a/src/cython/cython/mini_simplex_tree.pyx b/src/cython/cython/mini_simplex_tree.pyx deleted file mode 100644 index 3ba7e853..00000000 --- a/src/cython/cython/mini_simplex_tree.pyx +++ /dev/null @@ -1,352 +0,0 @@ -from cython cimport numeric -from libcpp.vector cimport vector -from libcpp.utility cimport pair - -"""This file is part of the Gudhi Library. The Gudhi library - (Geometric Understanding in Higher Dimensions) is a generic C++ - library for computational topology. - - Author(s): Vincent Rouvreau - - Copyright (C) 2016 INRIA - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -""" - -__author__ = "Vincent Rouvreau" -__copyright__ = "Copyright (C) 2016 INRIA" -__license__ = "GPL v3" - -cdef extern from "Simplex_tree_interface.h" namespace "Gudhi": - cdef cppclass Simplex_tree_options_mini: - pass - - cdef cppclass Simplex_tree_interface_mini "Gudhi::Simplex_tree_interface": - Simplex_tree() - double filtration() - double simplex_filtration(vector[int] simplex) - void set_filtration(double filtration) - void initialize_filtration() - int num_vertices() - int num_simplices() - void set_dimension(int dimension) - int dimension() - bint find_simplex(vector[int] simplex) - bint insert_simplex_and_subfaces(vector[int] simplex, - double filtration) - vector[pair[vector[int], double]] get_filtered_tree() - vector[pair[vector[int], double]] get_skeleton_tree(int dimension) - vector[pair[vector[int], double]] get_star_tree(vector[int] simplex) - vector[pair[vector[int], double]] get_coface_tree(vector[int] simplex, - int dimension) - void remove_maximal_simplex(vector[int] simplex) - -cdef extern from "Persistent_cohomology_interface.h" namespace "Gudhi": - cdef cppclass Mini_simplex_tree_persistence_interface "Gudhi::Persistent_cohomology_interface>": - Mini_simplex_tree_persistence_interface(Simplex_tree_interface_mini * st) - vector[pair[int, pair[double, double]]] get_persistence(int homology_coeff_field, double min_persistence) - vector[int] betti_numbers() - vector[int] persistent_betti_numbers(double from_value, double to_value) - -# MiniSimplexTree python interface -cdef class MiniSimplexTree: - """The simplex tree is an efficient and flexible data structure for - representing general (filtered) simplicial complexes. The data structure - is described in Jean-Daniel Boissonnat and Clément Maria. The Simplex - Tree: An Efficient Data Structure for General Simplicial Complexes. - Algorithmica, pages 1–22, 2014. - - This class is a non-filtered, with keys, and non contiguous vertices - version of the simplex tree. - """ - cdef Simplex_tree_interface_mini * thisptr - - cdef Mini_simplex_tree_persistence_interface * pcohptr - - # Fake constructor that does nothing but documenting the constructor - def __init__(self, points=[], max_alpha_square=float('inf')): - """MiniSimplexTree constructor. - """ - - # The real cython constructor - def __cinit__(self): - self.thisptr = new Simplex_tree_interface_mini() - - def __dealloc__(self): - if self.thisptr != NULL: - del self.thisptr - if self.pcohptr != NULL: - del self.pcohptr - - def __is_defined(self): - """Returns true if MiniSimplexTree pointer is not NULL. - """ - return self.thisptr != NULL - - def __is_persistence_defined(self): - """Returns true if Persistence pointer is not NULL. - """ - return self.pcohptr != NULL - - def get_filtration(self): - """This function returns the main simplicial complex filtration value. - - :returns: float -- the simplicial complex filtration value. - """ - return self.thisptr.filtration() - - def filtration(self, simplex): - """This function returns the simplicial complex filtration value for a - given N-simplex. - - :param simplex: The N-simplex, represented by a list of vertex. - :type simplex: list of int. - :returns: float -- the simplicial complex filtration value. - """ - return self.thisptr.simplex_filtration(simplex) - - def set_filtration(self, filtration): - """This function sets the main simplicial complex filtration value. - - :param filtration: The filtration value. - :type filtration: float. - """ - self.thisptr.set_filtration( filtration) - - def initialize_filtration(self): - """This function initializes and sorts the simplicial complex - filtration vector. - - .. note:: - - This function must be launched before persistence, betti_numbers, - persistent_betti_numbers or get_filtered_tree after inserting or - removing simplices. - """ - self.thisptr.initialize_filtration() - - def num_vertices(self): - """This function returns the number of vertices of the simplicial - complex. - - :returns: int -- the simplicial complex number of vertices. - """ - return self.thisptr.num_vertices() - - def num_simplices(self): - """This function returns the number of simplices of the simplicial - complex. - - :returns: int -- the simplicial complex number of simplices. - """ - return self.thisptr.num_simplices() - - def dimension(self): - """This function returns the dimension of the simplicial complex. - - :returns: int -- the simplicial complex dimension. - """ - return self.thisptr.dimension() - - def set_dimension(self, dimension): - """This function sets the dimension of the simplicial complex. - - :param dimension: The new dimension value. - :type dimension: int. - """ - self.thisptr.set_dimension(dimension) - - def find(self, simplex): - """This function returns if the N-simplex was found in the simplicial - complex or not. - - :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. - """ - cdef vector[int] complex - for i in simplex: - complex.push_back(i) - return self.thisptr.find_simplex(complex) - - def insert(self, simplex, filtration=0.0): - """This function inserts the given N-simplex with the given filtration - value (default value is '0.0'). - - :param simplex: The N-simplex to insert, represented by a list of - vertex. - :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. - """ - cdef vector[int] complex - for i in simplex: - complex.push_back(i) - return self.thisptr.insert_simplex_and_subfaces(complex, - filtration) - - def get_filtered_tree(self): - """This function returns the tree sorted by increasing filtration - values. - - :returns: list of tuples(simplex, filtration) -- the tree sorted by - increasing filtration values. - """ - cdef vector[pair[vector[int], double]] coface_tree \ - = self.thisptr.get_filtered_tree() - ct = [] - for filtered_complex in coface_tree: - v = [] - for vertex in filtered_complex.first: - v.append(vertex) - ct.append((v, filtered_complex.second)) - return ct - - def get_skeleton_tree(self, dimension): - """This function returns the tree skeleton of a maximum given - dimension. - - :param dimension: The skeleton dimension value. - :type dimension: int. - :returns: list of tuples(simplex, filtration) -- the skeleton tree - of a maximum dimension. - """ - cdef vector[pair[vector[int], double]] coface_tree \ - = self.thisptr.get_skeleton_tree(dimension) - ct = [] - for filtered_complex in coface_tree: - v = [] - for vertex in filtered_complex.first: - v.append(vertex) - ct.append((v, filtered_complex.second)) - return ct - - def get_star_tree(self, simplex): - """This function returns the star tree of a given N-simplex. - - :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. - """ - cdef vector[int] complex - for i in simplex: - complex.push_back(i) - cdef vector[pair[vector[int], double]] coface_tree \ - = self.thisptr.get_star_tree(complex) - ct = [] - for filtered_complex in coface_tree: - v = [] - for vertex in filtered_complex.first: - v.append(vertex) - ct.append((v, filtered_complex.second)) - return ct - - def get_coface_tree(self, simplex, codimension): - """This function returns the coface tree of a given N-simplex with a - given codimension. - - :param simplex: The N-simplex, represented by a list of vertex. - :type simplex: list of int. - :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. - """ - cdef vector[int] complex - for i in simplex: - complex.push_back(i) - cdef vector[pair[vector[int], double]] coface_tree \ - = self.thisptr.get_coface_tree(complex, codimension) - ct = [] - for filtered_complex in coface_tree: - v = [] - for vertex in filtered_complex.first: - v.append(vertex) - ct.append((v, filtered_complex.second)) - return ct - - def remove_maximal_simplex(self, simplex): - """This function removes a given maximal N-simplex from the simplicial - complex. - - :param simplex: The N-simplex, represented by a list of vertex. - :type simplex: list of int. - """ - self.thisptr.remove_maximal_simplex(simplex) - - def persistence(self, homology_coeff_field=11): - """This function returns the persistence of the simplicial complex. - - :param homology_coeff_field: The homology coefficient field. Must be a - prime number - :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. - :returns: list of pairs(dimension, pair(birth, death)) -- the - persistence of the simplicial complex. - """ - if self.pcohptr != NULL: - del self.pcohptr - self.pcohptr = new Mini_simplex_tree_persistence_interface(self.thisptr) - cdef vector[pair[int, pair[double, double]]] persistence_result - if self.pcohptr != NULL: - persistence_result = self.pcohptr.get_persistence(homology_coeff_field, 0) - return persistence_result - - def betti_numbers(self): - """This function returns the Betti numbers of the simplicial complex. - - :returns: list of int -- The Betti numbers ([B0, B1, ..., Bn]). - - :note: betti_numbers function requires persistence function to be - launched first. - """ - cdef vector[int] bn_result - if self.pcohptr != NULL: - bn_result = self.pcohptr.betti_numbers() - else: - print("betti_numbers function requires persistence function" - " to be launched first.") - return bn_result - - def persistent_betti_numbers(self, from_value, to_value): - """This function returns the persistent Betti numbers of the - simplicial complex. - - :param from_value: The persistence birth limit to be added in the - numbers (persistent birth <= from_value). - :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. - - :returns: list of int -- The persistent Betti numbers ([B0, B1, ..., - Bn]). - - :note: persistent_betti_numbers function requires persistence - function to be launched first. - """ - cdef vector[int] pbn_result - if self.pcohptr != NULL: - pbn_result = self.pcohptr.persistent_betti_numbers(from_value, to_value) - else: - print("persistent_betti_numbers function requires persistence function" - " to be launched first.") - return pbn_result diff --git a/src/cython/cython/rips_complex.pyx b/src/cython/cython/rips_complex.pyx index 08bd2388..2e739ac3 100644 --- a/src/cython/cython/rips_complex.pyx +++ b/src/cython/cython/rips_complex.pyx @@ -3,6 +3,7 @@ from libcpp.vector cimport vector from libcpp.utility cimport pair from libcpp.string cimport string from libcpp cimport bool +import os """This file is part of the Gudhi Library. The Gudhi library (Geometric Understanding in Higher Dimensions) is a generic C++ @@ -30,61 +31,37 @@ __author__ = "Vincent Rouvreau" __copyright__ = "Copyright (C) 2016 INRIA" __license__ = "GPL v3" -cdef extern from "Simplex_tree_interface.h" namespace "Gudhi": - cdef cppclass Simplex_tree_options_full_featured: - pass - - cdef cppclass Rips_complex_interface "Gudhi::Simplex_tree_interface": - Simplex_tree() - double filtration() - double simplex_filtration(vector[int] simplex) - void set_filtration(double filtration) - void initialize_filtration() - int num_vertices() - int num_simplices() - void set_dimension(int dimension) - int dimension() - bint find_simplex(vector[int] simplex) - bint insert_simplex_and_subfaces(vector[int] simplex, - double filtration) - vector[pair[vector[int], double]] get_filtered_tree() - vector[pair[vector[int], double]] get_skeleton_tree(int dimension) - vector[pair[vector[int], double]] get_star_tree(vector[int] simplex) - vector[pair[vector[int], double]] get_coface_tree(vector[int] simplex, - int dimension) - void remove_maximal_simplex(vector[int] simplex) - void graph_expansion(vector[vector[double]] points, int max_dimension, - double max_edge_length) - void graph_expansion(string off_file, int max_dimension, - double max_edge_length, bool from_file) - -cdef extern from "Persistent_cohomology_interface.h" namespace "Gudhi": - cdef cppclass Rips_complex_persistence_interface "Gudhi::Persistent_cohomology_interface>": - Rips_complex_persistence_interface(Rips_complex_interface * st) - vector[pair[int, pair[double, double]]] get_persistence(int homology_coeff_field, double min_persistence) - vector[int] betti_numbers() - vector[int] persistent_betti_numbers(double from_value, double to_value) +cdef extern from "Rips_complex_interface.h" namespace "Gudhi": + cdef cppclass Rips_complex_interface "Gudhi::rips_complex::Rips_complex_interface": + Rips_complex_interface(vector[vector[double]] points, double threshold) + # bool from_file is a workaround for cython to find the correct signature + Rips_complex_interface(string off_file, double threshold, bool from_file) + void create_simplex_tree(Simplex_tree_interface_full_featured* simplex_tree, int dim_max) # RipsComplex python interface cdef class RipsComplex: - """RipsComplex is a simplicial complex constructed from a list of points. + """RipsComplex is a simplicial complex constructed from the finite cells + of a Delaunay Triangulation. + + The filtration value of each simplex is computed as the square of the + circumradius of the simplex if the circumsphere is empty (the simplex is + then said to be Gabriel), and as the minimum of the filtration values of + the codimension 1 cofaces that make it not Gabriel otherwise. + + All simplices that have a filtration value strictly greater than a given + alpha squared value are not inserted into the complex. + + .. note:: - Each point Pn is inserted as a vertex in the simplicial complex with a - null filtration value. + When Rips_complex is constructed with an infinite value of alpha, the + complex is a Delaunay complex. - A N-simplex represented by the list of vertices Vi, ..., Vj is inserted in - the simplicial complex if all the points Pi, ..., Pj corresponding to the - vertices are within a distance less or equal to a given maximum edge length - value, and if N (dimension of the N-simplex) is less or equal to a given - maximum dimension. """ - cdef Rips_complex_interface * thisptr - cdef Rips_complex_persistence_interface * pcohptr + cdef Rips_complex_interface * thisptr # Fake constructor that does nothing but documenting the constructor - def __init__(self, points=[], off_file='', max_dimension=3, - max_edge_length=float('inf')): + def __init__(self, points=[], off_file='', max_edge_length=float('inf')): """RipsComplex constructor. :param points: A list of points in d-Dimension. @@ -95,291 +72,40 @@ cdef class RipsComplex: :param off_file: An OFF file style name. :type off_file: string - :param max_dimension: Maximum dimension of the complex to be expanded. - :type max_dimension: int - :param max_edge_length: Maximum edge length value (rips radius). - :type max_edge_length: double + :param max_edge_length: Rips value. + :type max_edge_length: int """ # The real cython constructor - def __cinit__(self, points=[], off_file='', max_dimension=3, - max_edge_length=float('inf')): - self.thisptr = new Rips_complex_interface() - # Constructor from graph expansion + def __cinit__(self, points=[], off_file='', max_edge_length=float('inf')): if off_file is not '': if os.path.isfile(off_file): - self.thisptr.graph_expansion(off_file, max_dimension, - max_edge_length, True) + self.thisptr = new Rips_complex_interface(off_file, + max_edge_length, + True) else: print("file " + off_file + " not found.") else: - self.thisptr.graph_expansion(points, max_dimension, - max_edge_length) + self.thisptr = new Rips_complex_interface(points, max_edge_length) + def __dealloc__(self): if self.thisptr != NULL: del self.thisptr - if self.pcohptr != NULL: - del self.pcohptr def __is_defined(self): """Returns true if RipsComplex pointer is not NULL. """ return self.thisptr != NULL - def __is_persistence_defined(self): - """Returns true if Persistence pointer is not NULL. - """ - return self.pcohptr != NULL - - def get_filtration(self): - """This function returns the main simplicial complex filtration value. - - :returns: float -- the simplicial complex filtration value. - """ - return self.thisptr.filtration() - - def filtration(self, simplex): - """This function returns the simplicial complex filtration value for a - given N-simplex. - - :param simplex: The N-simplex, represented by a list of vertex. - :type simplex: list of int. - :returns: float -- the simplicial complex filtration value. - """ - return self.thisptr.simplex_filtration(simplex) - - def set_filtration(self, filtration): - """This function sets the main simplicial complex filtration value. - - :param filtration: The filtration value. - :type filtration: float. + def create_simplex_tree(self, max_dimension=1): """ - self.thisptr.set_filtration( filtration) - - def initialize_filtration(self): - """This function initializes and sorts the simplicial complex - filtration vector. - - .. note:: - - This function must be launched before persistence, betti_numbers, - persistent_betti_numbers or get_filtered_tree after inserting or - removing simplices. - """ - self.thisptr.initialize_filtration() - - def num_vertices(self): - """This function returns the number of vertices of the simplicial - complex. - - :returns: int -- the simplicial complex number of vertices. - """ - return self.thisptr.num_vertices() - - def num_simplices(self): - """This function returns the number of simplices of the simplicial - complex. - - :returns: int -- the simplicial complex number of simplices. - """ - return self.thisptr.num_simplices() - - def dimension(self): - """This function returns the dimension of the simplicial complex. - - :returns: int -- the simplicial complex dimension. - """ - return self.thisptr.dimension() - - def set_dimension(self, dimension): - """This function sets the dimension of the simplicial complex. - - :param dimension: The new dimension value. - :type dimension: int. - """ - self.thisptr.set_dimension(dimension) - - def find(self, simplex): - """This function returns if the N-simplex was found in the simplicial - complex or not. - - :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. - """ - cdef vector[int] complex - for i in simplex: - complex.push_back(i) - return self.thisptr.find_simplex(complex) - - def insert(self, simplex, filtration=0.0): - """This function inserts the given N-simplex with the given filtration - value (default value is '0.0'). - - :param simplex: The N-simplex to insert, represented by a list of - vertex. - :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. - """ - cdef vector[int] complex - for i in simplex: - complex.push_back(i) - return self.thisptr.insert_simplex_and_subfaces(complex, - filtration) - - def get_filtered_tree(self): - """This function returns the tree sorted by increasing filtration - values. - - :returns: list of tuples(simplex, filtration) -- the tree sorted by - increasing filtration values. - """ - cdef vector[pair[vector[int], double]] coface_tree \ - = self.thisptr.get_filtered_tree() - ct = [] - for filtered_complex in coface_tree: - v = [] - for vertex in filtered_complex.first: - v.append(vertex) - ct.append((v, filtered_complex.second)) - return ct - - def get_skeleton_tree(self, dimension): - """This function returns the tree skeleton of a maximum given - dimension. - - :param dimension: The skeleton dimension value. - :type dimension: int. - :returns: list of tuples(simplex, filtration) -- the skeleton tree - of a maximum dimension. - """ - cdef vector[pair[vector[int], double]] coface_tree \ - = self.thisptr.get_skeleton_tree(dimension) - ct = [] - for filtered_complex in coface_tree: - v = [] - for vertex in filtered_complex.first: - v.append(vertex) - ct.append((v, filtered_complex.second)) - return ct - - def get_star_tree(self, simplex): - """This function returns the star tree of a given N-simplex. - - :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. - """ - cdef vector[int] complex - for i in simplex: - complex.push_back(i) - cdef vector[pair[vector[int], double]] coface_tree \ - = self.thisptr.get_star_tree(complex) - ct = [] - for filtered_complex in coface_tree: - v = [] - for vertex in filtered_complex.first: - v.append(vertex) - ct.append((v, filtered_complex.second)) - return ct - - def get_coface_tree(self, simplex, codimension): - """This function returns the coface tree of a given N-simplex with a - given codimension. - - :param simplex: The N-simplex, represented by a list of vertex. - :type simplex: list of int. - :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. - """ - cdef vector[int] complex - for i in simplex: - complex.push_back(i) - cdef vector[pair[vector[int], double]] coface_tree \ - = self.thisptr.get_coface_tree(complex, codimension) - ct = [] - for filtered_complex in coface_tree: - v = [] - for vertex in filtered_complex.first: - v.append(vertex) - ct.append((v, filtered_complex.second)) - return ct - - def remove_maximal_simplex(self, simplex): - """This function removes a given maximal N-simplex from the simplicial - complex. - - :param simplex: The N-simplex, represented by a list of vertex. - :type simplex: list of int. - """ - self.thisptr.remove_maximal_simplex(simplex) - - def persistence(self, homology_coeff_field=11, min_persistence=0): - """This function returns the persistence of the simplicial complex. - - :param homology_coeff_field: The homology coefficient field. Must be a - prime number - :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. - :note: list of pairs(dimension, pair(birth, death)) -- the - persistence of the simplicial complex. - """ - if self.pcohptr != NULL: - del self.pcohptr - self.pcohptr = new Rips_complex_persistence_interface(self.thisptr) - cdef vector[pair[int, pair[double, double]]] persistence_result - if self.pcohptr != NULL: - persistence_result = self.pcohptr.get_persistence(homology_coeff_field, min_persistence) - return persistence_result - - def betti_numbers(self): - """This function returns the Betti numbers of the simplicial complex. - - :returns: list of int -- The Betti numbers ([B0, B1, ..., Bn]). - - :note: betti_numbers function requires persistence function to be - launched first. - """ - cdef vector[int] bn_result - if self.pcohptr != NULL: - bn_result = self.pcohptr.betti_numbers() - else: - print("betti_numbers function requires persistence function" - " to be launched first.") - return bn_result - - def persistent_betti_numbers(self, from_value, to_value): - """This function returns the persistent Betti numbers of the - simplicial complex. - - :param from_value: The persistence birth limit to be added in the - numbers (persistent birth <= from_value). - :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. - - :returns: list of int -- The persistent Betti numbers ([B0, B1, ..., - Bn]). - - :note: persistent_betti_numbers function requires persistence - function to be launched first. + :param max_dimension: graph expansion for rips until this given maximal + dimension. + :type max_dimension: int + :returns: A simplex tree created from the Delaunay Triangulation. + :rtype: SimplexTree """ - cdef vector[int] pbn_result - if self.pcohptr != NULL: - pbn_result = self.pcohptr.persistent_betti_numbers(from_value, to_value) - else: - print("persistent_betti_numbers function requires persistence function" - " to be launched first.") - return pbn_result + simplex_tree = SimplexTree() + self.thisptr.create_simplex_tree(simplex_tree.thisptr, max_dimension) + return simplex_tree diff --git a/src/cython/doc/persistent_cohomology_sum.rst b/src/cython/doc/persistent_cohomology_sum.rst index b306b3d4..cf3029fc 100644 --- a/src/cython/doc/persistent_cohomology_sum.rst +++ b/src/cython/doc/persistent_cohomology_sum.rst @@ -21,8 +21,5 @@ | :doc:`persistent_cohomology_user` | Please refer to each data structure that contains persistence | | | feature for reference: | | | | -| | * :doc:`alpha_complex_ref` | -| | * :doc:`cubical_complex_ref` | | | * :doc:`simplex_tree_ref` | -| | * :doc:`witness_complex_ref` | +---------------------------------------------+----------------------------------------------------------------------+ diff --git a/src/cython/doc/persistent_cohomology_user.rst b/src/cython/doc/persistent_cohomology_user.rst index 33b19ce2..ca936754 100644 --- a/src/cython/doc/persistent_cohomology_user.rst +++ b/src/cython/doc/persistent_cohomology_user.rst @@ -11,10 +11,7 @@ Definition | :doc:`persistent_cohomology_user` | Please refer to each data structure that contains persistence | | | feature for reference: | | | | -| | * :doc:`alpha_complex_ref` | -| | * :doc:`cubical_complex_ref` | | | * :doc:`simplex_tree_ref` | -| | * :doc:`witness_complex_ref` | +---------------------------------------------+----------------------------------------------------------------------+ diff --git a/src/cython/example/mini_simplex_tree_example.py b/src/cython/example/mini_simplex_tree_example.py deleted file mode 100755 index 7b65a9d6..00000000 --- a/src/cython/example/mini_simplex_tree_example.py +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env python - -import gudhi - -"""This file is part of the Gudhi Library. The Gudhi library - (Geometric Understanding in Higher Dimensions) is a generic C++ - library for computational topology. - - Author(s): Vincent Rouvreau - - Copyright (C) 2016 INRIA - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -""" - -__author__ = "Vincent Rouvreau" -__copyright__ = "Copyright (C) 2016 INRIA" -__license__ = "GPL v3" - -print("#####################################################################") -print("MiniSimplexTree creation from insertion") - -""" Complex to build. - 1 3 - o---o - /X\ / - o---o o - 2 0 4 -""" - -triangle012 = [0, 1, 2] -edge03 = [0, 3] -edge13 = [1, 3] -vertex4 = [4] -mini_st = gudhi.MiniSimplexTree() -mini_st.insert(triangle012) -mini_st.insert(edge03) -mini_st.insert(edge13) -mini_st.insert(vertex4) - -# FIXME: Remove this line -mini_st.set_dimension(2) - -# initialize_filtration required before plain_homology -mini_st.initialize_filtration() - -print("persistence(homology_coeff_field=2)=") -print(mini_st.persistence(homology_coeff_field=2)) - -edge02 = [0, 2] -if mini_st.find(edge02): - # Only coface is 012 - print("coface(edge02,1)=", mini_st.get_coface_tree(edge02, 1)) - -if mini_st.get_coface_tree(triangle012, 1) == []: - # Precondition: Check the simplex has no coface before removing it. - mini_st.remove_maximal_simplex(triangle012) - -# initialize_filtration required after removing -mini_st.initialize_filtration() - -print("filtered_tree after triangle012 removal =", mini_st.get_filtered_tree()) diff --git a/src/cython/example/rips_complex_diagram_persistence_with_pandas_interface_example.py b/src/cython/example/rips_complex_diagram_persistence_with_pandas_interface_example.py index bcf2fbcb..8af1b767 100755 --- a/src/cython/example/rips_complex_diagram_persistence_with_pandas_interface_example.py +++ b/src/cython/example/rips_complex_diagram_persistence_with_pandas_interface_example.py @@ -53,16 +53,17 @@ message = "RipsComplex with max_edge_length=" + repr(args.max_edge_length) print(message) rips_complex = gudhi.RipsComplex(points=points.values, - max_dimension=len(points.values[0]), max_edge_length=args.max_edge_length) + max_edge_length=args.max_edge_length) -message = "Number of simplices=" + repr(rips_complex.num_simplices()) +simplex_tree = rips_complex.create_simplex_tree(max_dimension=len(points.values[0])) + +message = "Number of simplices=" + repr(simplex_tree.num_simplices()) print(message) -rips_complex.initialize_filtration() -diag = rips_complex.persistence() +diag = simplex_tree.persistence() print("betti_numbers()=") -print(rips_complex.betti_numbers()) +print(simplex_tree.betti_numbers()) if args.no_diagram == False: gudhi.diagram_persistence(diag) diff --git a/src/cython/example/rips_complex_from_points_example.py b/src/cython/example/rips_complex_from_points_example.py index 1a22d8e3..df6252cd 100755 --- a/src/cython/example/rips_complex_from_points_example.py +++ b/src/cython/example/rips_complex_from_points_example.py @@ -31,8 +31,10 @@ __license__ = "GPL v3" print("#####################################################################") print("RipsComplex creation from points") rips = gudhi.RipsComplex(points=[[0, 0], [1, 0], [0, 1], [1, 1]], - max_dimension=1, max_edge_length=42) + max_edge_length=42) -print("filtered_tree=", rips.get_filtered_tree()) -print("star([0])=", rips.get_star_tree([0])) -print("coface([0], 1)=", rips.get_coface_tree([0], 1)) +simplex_tree = rips.create_simplex_tree(max_dimension=1) + +print("filtered_tree=", simplex_tree.get_filtered_tree()) +print("star([0])=", simplex_tree.get_star_tree([0])) +print("coface([0], 1)=", simplex_tree.get_coface_tree([0], 1)) diff --git a/src/cython/example/rips_persistence_diagram.py b/src/cython/example/rips_persistence_diagram.py index fddea298..e485b2f5 100755 --- a/src/cython/example/rips_persistence_diagram.py +++ b/src/cython/example/rips_persistence_diagram.py @@ -31,9 +31,12 @@ __license__ = "GPL v3" print("#####################################################################") print("RipsComplex creation from points") rips = gudhi.RipsComplex(points=[[0, 0], [1, 0], [0, 1], [1, 1]], - max_dimension=1, max_edge_length=42) + max_edge_length=42) -diag = rips.persistence(homology_coeff_field=2, min_persistence=0) +simplex_tree = rips.create_simplex_tree(max_dimension=1) + + +diag = simplex_tree.persistence(homology_coeff_field=2, min_persistence=0) print("diag=", diag) gudhi.diagram_persistence(diag) diff --git a/src/cython/gudhi.pyx.in b/src/cython/gudhi.pyx.in index 60f4c30b..5dcb9d48 100644 --- a/src/cython/gudhi.pyx.in +++ b/src/cython/gudhi.pyx.in @@ -25,7 +25,6 @@ __copyright__ = "Copyright (C) 2016 INRIA" __license__ = "GPL v3" include "cython/simplex_tree.pyx" -include "cython/mini_simplex_tree.pyx" include "cython/rips_complex.pyx" include "cython/cubical_complex.pyx" include "cython/periodic_cubical_complex.pyx" diff --git a/src/cython/include/Alpha_complex_interface.h b/src/cython/include/Alpha_complex_interface.h index 81761c77..9f308ae9 100644 --- a/src/cython/include/Alpha_complex_interface.h +++ b/src/cython/include/Alpha_complex_interface.h @@ -29,9 +29,9 @@ #include "Simplex_tree_interface.h" -#include -#include // std::pair #include +#include +#include namespace Gudhi { @@ -40,11 +40,6 @@ namespace alpha_complex { class Alpha_complex_interface { using Dynamic_kernel = CGAL::Epick_d< CGAL::Dynamic_dimension_tag >; using Point_d = Dynamic_kernel::Point_d; - typedef typename Simplex_tree<>::Simplex_handle Simplex_handle; - typedef typename std::pair Insertion_result; - using Simplex = std::vector; - using Filtered_complex = std::pair; - using Complex_tree = std::vector; typedef typename Simplex_tree<>::Simplex_key Simplex_key; diff --git a/src/cython/include/Cubical_complex_interface.h b/src/cython/include/Cubical_complex_interface.h index 5d17ff6b..4c53523b 100644 --- a/src/cython/include/Cubical_complex_interface.h +++ b/src/cython/include/Cubical_complex_interface.h @@ -27,9 +27,9 @@ #include #include -#include -#include // std::pair #include +#include +#include namespace Gudhi { diff --git a/src/cython/include/Rips_complex_interface.h b/src/cython/include/Rips_complex_interface.h new file mode 100644 index 00000000..7e897b1d --- /dev/null +++ b/src/cython/include/Rips_complex_interface.h @@ -0,0 +1,70 @@ +/* This file is part of the Gudhi Library. The Gudhi library + * (Geometric Understanding in Higher Dimensions) is a generic C++ + * library for computational topology. + * + * Author(s): Vincent Rouvreau + * + * Copyright (C) 2016 INRIA + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef RIPS_COMPLEX_INTERFACE_H +#define RIPS_COMPLEX_INTERFACE_H + +#include +#include +#include +#include + +#include "Simplex_tree_interface.h" + +#include +#include +#include // std::pair +#include + +namespace Gudhi { + +namespace rips_complex { + +class Rips_complex_interface { + using Point_d = std::vector; + + public: + Rips_complex_interface(std::vector>&points, double threshold) { + rips_complex_ = new Rips_complex::Filtration_value>(points, threshold, + Euclidean_distance()); + } + + Rips_complex_interface(std::string off_file_name, double threshold, bool from_file = true) { + Gudhi::Points_off_reader off_reader(off_file_name); + rips_complex_ = new Rips_complex::Filtration_value>(off_reader.get_point_cloud(), + threshold, Euclidean_distance()); + } + + void create_simplex_tree(Simplex_tree_interface<>* simplex_tree, int dim_max) { + rips_complex_->create_complex(*simplex_tree, dim_max); + simplex_tree->initialize_filtration(); + } + + private: + Rips_complex::Filtration_value>* rips_complex_; +}; + +} // namespace rips_complex + +} // namespace Gudhi + +#endif // RIPS_COMPLEX_INTERFACE_H diff --git a/src/cython/include/Simplex_tree_interface.h b/src/cython/include/Simplex_tree_interface.h index 8e9dd966..19e02ca4 100644 --- a/src/cython/include/Simplex_tree_interface.h +++ b/src/cython/include/Simplex_tree_interface.h @@ -30,15 +30,17 @@ #include "Persistent_cohomology_interface.h" +#include #include #include // std::pair -#include namespace Gudhi { template class Simplex_tree_interface : public Simplex_tree { public: + typedef typename Simplex_tree::Filtration_value Filtration_value; + typedef typename Simplex_tree::Vertex_handle Vertex_handle; typedef typename Simplex_tree::Simplex_handle Simplex_handle; typedef typename std::pair Insertion_result; using Simplex = std::vector; @@ -115,42 +117,12 @@ class Simplex_tree_interface : public Simplex_tree { return coface_tree; } - void graph_expansion(std::vector>&points, int max_dimension, double max_edge_length) { - Graph_t prox_graph = compute_proximity_graph(points, max_edge_length, euclidean_distance>); - Simplex_tree::insert_graph(prox_graph); - Simplex_tree::expansion(max_dimension); - Simplex_tree::initialize_filtration(); - } - - void graph_expansion(std::string& off_file_name, int max_dimension, double max_edge_length, bool from_file=true) { - Gudhi::Points_off_reader> off_reader(off_file_name); - // Check the read operation was correct - if (!off_reader.is_valid()) { - std::cerr << "Unable to read file " << off_file_name << std::endl; - } else { - std::vector> points = off_reader.get_point_cloud(); - Graph_t prox_graph = compute_proximity_graph(points, max_edge_length, - euclidean_distance>); - Simplex_tree::insert_graph(prox_graph); - Simplex_tree::expansion(max_dimension); - Simplex_tree::initialize_filtration(); - } - } - void create_persistence(Gudhi::Persistent_cohomology_interface>* pcoh) { pcoh = new Gudhi::Persistent_cohomology_interface>(*this); } }; -struct Simplex_tree_options_mini : Simplex_tree_options_full_featured { - // Not doing persistence, so we don't need those - static const bool store_key = true; - static const bool store_filtration = false; - // I have few vertices - typedef short Vertex_handle; -}; - } // namespace Gudhi #endif // SIMPLEX_TREE_INTERFACE_H diff --git a/src/cython/include/Subsampling_interface.h b/src/cython/include/Subsampling_interface.h index 9340cd86..fb047441 100644 --- a/src/cython/include/Subsampling_interface.h +++ b/src/cython/include/Subsampling_interface.h @@ -29,8 +29,9 @@ #include #include -#include #include +#include +#include namespace Gudhi { diff --git a/src/cython/include/Tangential_complex_interface.h b/src/cython/include/Tangential_complex_interface.h index 9da32757..7c774c73 100644 --- a/src/cython/include/Tangential_complex_interface.h +++ b/src/cython/include/Tangential_complex_interface.h @@ -41,11 +41,6 @@ namespace tangential_complex { class Tangential_complex_interface { using Dynamic_kernel = CGAL::Epick_d< CGAL::Dynamic_dimension_tag >; using Point_d = Dynamic_kernel::Point_d; - typedef typename Simplex_tree<>::Simplex_handle Simplex_handle; - typedef typename std::pair Insertion_result; - using Simplex = std::vector; - using Filtered_complex = std::pair; - using Complex_tree = std::vector; using TC = Tangential_complex; public: diff --git a/src/cython/include/Witness_complex_interface.h b/src/cython/include/Witness_complex_interface.h index ab99adf5..a753bc1d 100644 --- a/src/cython/include/Witness_complex_interface.h +++ b/src/cython/include/Witness_complex_interface.h @@ -40,6 +40,8 @@ namespace witness_complex { class Witness_complex_interface { typedef typename Simplex_tree<>::Simplex_handle Simplex_handle; + typedef typename Simplex_tree<>::Filtration_value Filtration_value; + typedef typename Simplex_tree<>::Vertex_handle Vertex_handle; typedef typename std::pair Insertion_result; using Simplex = std::vector; using Filtered_complex = std::pair; @@ -51,7 +53,7 @@ class Witness_complex_interface { std::vector > knn; std::vector> landmarks; Gudhi::subsampling::pick_n_random_points(points, number_of_landmarks, std::back_inserter(landmarks)); - Gudhi::witness_complex::construct_closest_landmark_table(points, landmarks, knn); + Gudhi::witness_complex::construct_closest_landmark_table(points, landmarks, knn); Gudhi::witness_complex::witness_complex(knn, number_of_landmarks, points[0].size(), simplex_tree_); } diff --git a/src/cython/test/test_mini_simplex_tree.py b/src/cython/test/test_mini_simplex_tree.py deleted file mode 100755 index e44bfdbc..00000000 --- a/src/cython/test/test_mini_simplex_tree.py +++ /dev/null @@ -1,50 +0,0 @@ -from gudhi import MiniSimplexTree - -"""This file is part of the Gudhi Library. The Gudhi library - (Geometric Understanding in Higher Dimensions) is a generic C++ - library for computational topology. - - Author(s): Vincent Rouvreau - - Copyright (C) 2016 INRIA - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -""" - -__author__ = "Vincent Rouvreau" -__copyright__ = "Copyright (C) 2016 INRIA" -__license__ = "GPL v3" - - -def test_mini(): - triangle012 = [0, 1, 2] - edge03 = [0, 3] - mini_st = MiniSimplexTree() - assert mini_st.__is_defined() == True - assert mini_st.__is_persistence_defined() == False - assert mini_st.insert(triangle012) == True - assert mini_st.insert(edge03) == True - # FIXME: Remove this line - mini_st.set_dimension(2) - - edge02 = [0, 2] - assert mini_st.find(edge02) == True - assert mini_st.get_coface_tree(edge02, 1) == \ - [([0, 1, 2], 0.0)] - - # remove_maximal_simplex test - assert mini_st.get_coface_tree(triangle012, 1) == [] - mini_st.remove_maximal_simplex(triangle012) - assert mini_st.find(edge02) == True - assert mini_st.find(triangle012) == False diff --git a/src/cython/test/test_rips_complex.py b/src/cython/test/test_rips_complex.py index 877289cf..687e8529 100755 --- a/src/cython/test/test_rips_complex.py +++ b/src/cython/test/test_rips_complex.py @@ -30,36 +30,39 @@ __license__ = "GPL v3" def test_empty_rips(): rips_complex = RipsComplex() assert rips_complex.__is_defined() == True - assert rips_complex.__is_persistence_defined() == False def test_rips(): point_list = [[0, 0], [1, 0], [0, 1], [1, 1]] - rips_complex = RipsComplex(points=point_list, max_dimension=1, - max_edge_length=42) - assert rips_complex.__is_defined() == True - assert rips_complex.__is_persistence_defined() == False + rips_complex = RipsComplex(points=point_list, max_edge_length=42) + + simplex_tree = rips_complex.create_simplex_tree(max_dimension=1) + + assert simplex_tree.__is_defined() == True + assert simplex_tree.__is_persistence_defined() == False - assert rips_complex.num_simplices() == 10 - assert rips_complex.num_vertices() == 4 + assert simplex_tree.num_simplices() == 10 + assert simplex_tree.num_vertices() == 4 - assert rips_complex.get_filtered_tree() == \ + assert simplex_tree.get_filtered_tree() == \ [([0], 0.0), ([1], 0.0), ([2], 0.0), ([3], 0.0), ([0, 1], 1.0), ([0, 2], 1.0), ([1, 3], 1.0), ([2, 3], 1.0), ([1, 2], 1.4142135623730951), ([0, 3], 1.4142135623730951)] - assert rips_complex.get_star_tree([0]) == \ + assert simplex_tree.get_star_tree([0]) == \ [([0], 0.0), ([0, 1], 1.0), ([0, 2], 1.0), ([0, 3], 1.4142135623730951)] - assert rips_complex.get_coface_tree([0], 1) == \ + assert simplex_tree.get_coface_tree([0], 1) == \ [([0, 1], 1.0), ([0, 2], 1.0), ([0, 3], 1.4142135623730951)] def test_filtered_rips(): point_list = [[0, 0], [1, 0], [0, 1], [1, 1]] - filtered_rips = RipsComplex(points=point_list, max_dimension=1, - max_edge_length=1.0) - assert filtered_rips.__is_defined() == True - assert filtered_rips.__is_persistence_defined() == False + filtered_rips = RipsComplex(points=point_list, max_edge_length=1.0) + + simplex_tree = filtered_rips.create_simplex_tree(max_dimension=1) + + assert simplex_tree.__is_defined() == True + assert simplex_tree.__is_persistence_defined() == False - assert filtered_rips.num_simplices() == 8 - assert filtered_rips.num_vertices() == 4 + assert simplex_tree.num_simplices() == 8 + assert simplex_tree.num_vertices() == 4 -- cgit v1.2.3