From 2976ab407d564b46173aeedf5c1e876b5cfc5a97 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Mon, 28 Nov 2016 21:47:57 +0000 Subject: Cythonize Tangential git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/ST_cythonize@1796 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 4f9968db1b5b63f0970abcb74d4cb7a5a105b2fa --- src/cython/cython/tangential_complex.pyx | 292 +++------------------- src/cython/include/Tangential_complex_interface.h | 150 ++--------- 2 files changed, 62 insertions(+), 380 deletions(-) (limited to 'src') diff --git a/src/cython/cython/tangential_complex.pyx b/src/cython/cython/tangential_complex.pyx index 01782004..35f1e384 100644 --- a/src/cython/cython/tangential_complex.pyx +++ b/src/cython/cython/tangential_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 +from cython.operator cimport dereference as deref import os """This file is part of the Gudhi Library. The Gudhi library @@ -33,30 +34,15 @@ __license__ = "GPL v3" cdef extern from "Tangential_complex_interface.h" namespace "Gudhi": cdef cppclass Tangential_complex_interface "Gudhi::tangential_complex::Tangential_complex_interface": - Tangential_complex_interface(vector[vector[double]] points, double max_alpha_square) + 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, double max_alpha_square, bool from_file) - 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) + Tangential_complex_interface(string off_file, bool from_file) vector[double] get_point(int vertex) - vector[pair[int, pair[double, double]]] get_persistence(int homology_coeff_field, double min_persistence) - vector[int] get_betti_numbers() - vector[int] get_persistent_betti_numbers(double from_value, double to_value) + 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) # TangentialComplex python interface cdef class TangentialComplex: @@ -81,7 +67,7 @@ cdef class TangentialComplex: cdef Tangential_complex_interface * thisptr # Fake constructor that does nothing but documenting the constructor - def __init__(self, points=None, off_file='', max_alpha_square=float('inf')): + def __init__(self, points=None, off_file=''): """TangentialComplex constructor. :param points: A list of points in d-Dimension. @@ -91,22 +77,17 @@ cdef class TangentialComplex: :param off_file: An OFF file style name. :type off_file: string - - :param max_alpha_square: Maximum Tangential square value. Default is :math:`\infty` - :type max_alpha_square: double """ # The real cython constructor - def __cinit__(self, points=[], off_file='', max_alpha_square=float('inf')): + def __cinit__(self, points=[], off_file=''): if off_file is not '': if os.path.isfile(off_file): - self.thisptr = new Tangential_complex_interface(off_file, - max_alpha_square, True) + self.thisptr = new Tangential_complex_interface(off_file, True) else: print("file " + off_file + " not found.") else: - self.thisptr = new Tangential_complex_interface(points, - max_alpha_square) + self.thisptr = new Tangential_complex_interface(points) def __dealloc__(self): @@ -118,195 +99,6 @@ cdef class TangentialComplex: """ return self.thisptr != 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 get_point(self, vertex): """This function returns the point corresponding to a given vertex. @@ -317,47 +109,39 @@ cdef class TangentialComplex: cdef vector[double] point = self.thisptr.get_point(vertex) return point - def persistence(self, homology_coeff_field=11, min_persistence=0.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. + def num_vertices(self): + """This function returns the number of vertices. + + :returns: unsigned -- the number of vertices. """ - return self.thisptr.get_persistence(homology_coeff_field, min_persistence) + return self.thisptr.number_of_vertices() - def betti_numbers(self): - """This function returns the Betti numbers of the simplicial complex. + def num_simplices(self): + """This function returns the number of simplices. - :returns: list of int -- The Betti numbers ([B0, B1, ..., Bn]). + :returns: unsigned -- the number of simplices. + """ + return self.thisptr.number_of_simplices() - :note: betti_numbers function requires persistence function to be - launched first. + def num_inconsistent_simplices(self): + """This function returns the number of inconsistent simplices. + + :returns: unsigned -- the number of inconsistent simplices. """ - return self.thisptr.get_betti_numbers() + return self.thisptr.number_of_inconsistent_simplices() - def persistent_betti_numbers(self, from_value, to_value): - """This function returns the persistent Betti numbers of the - simplicial complex. + def num_inconsistent_stars(self): + """This function returns the number of inconsistent stars. - :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: unsigned -- the number of inconsistent stars. + """ + return self.thisptr.number_of_inconsistent_stars() - :returns: list of int -- The persistent Betti numbers ([B0, B1, ..., - Bn]). + def create_simplex_tree(self, SimplexTree simplex_tree): + """This function creates the given simplex tree from the Delaunay + Triangulation. - :note: persistent_betti_numbers function requires persistence - function to be launched first. + :param simplex_tree: The simplex tree to create (must be empty) + :type simplex_tree: SimplexTree """ - return self.thisptr.get_persistent_betti_numbers(from_value, to_value) + self.thisptr.create_simplex_tree(deref(simplex_tree.thisptr)) \ No newline at end of file diff --git a/src/cython/include/Tangential_complex_interface.h b/src/cython/include/Tangential_complex_interface.h index e9750e85..49d66476 100644 --- a/src/cython/include/Tangential_complex_interface.h +++ b/src/cython/include/Tangential_complex_interface.h @@ -28,7 +28,6 @@ #include #include -#include "Persistent_cohomology_interface.h" #include "Simplex_tree_interface.h" #include @@ -50,20 +49,18 @@ class Tangential_complex_interface { using TC = Tangential_complex; public: - Tangential_complex_interface(std::vector>&points, double max_alpha_square) - : pcoh_(nullptr) { + Tangential_complex_interface(std::vector>&points) { Dynamic_kernel k; unsigned intrisic_dim = 0; if (points.size() > 0) intrisic_dim = points[0].size(); tangential_complex_ = new TC(points, intrisic_dim, k); - tangential_complex_->create_complex(simplex_tree_, max_alpha_square); - simplex_tree_.initialize_filtration(); + tangential_complex_->compute_tangential_complex(); + num_inconsistencies_ = tangential_complex_->number_of_inconsistent_simplices(); } - Tangential_complex_interface(std::string off_file_name, double max_alpha_square, bool from_file = true) - : pcoh_(nullptr) { + Tangential_complex_interface(std::string off_file_name, bool from_file = true) { Gudhi::Points_off_reader off_reader(off_file_name); Dynamic_kernel k; unsigned intrisic_dim = 0; @@ -72,103 +69,8 @@ class Tangential_complex_interface { intrisic_dim = points[0].size(); tangential_complex_ = new TC(points, intrisic_dim, k); - tangential_complex_->create_complex(simplex_tree_, max_alpha_square); - simplex_tree_.initialize_filtration(); - } - - bool find_simplex(const Simplex& vh) { - return (simplex_tree_.find(vh) != simplex_tree_.null_simplex()); - } - - bool insert_simplex_and_subfaces(const Simplex& complex, Filtration_value filtration = 0) { - Insertion_result result = simplex_tree_.insert_simplex_and_subfaces(complex, filtration); - return (result.second); - } - - Filtration_value simplex_filtration(const Simplex& complex) { - return simplex_tree_.filtration(simplex_tree_.find(complex)); - } - - void remove_maximal_simplex(const Simplex& complex) { - return simplex_tree_.remove_maximal_simplex(simplex_tree_.find(complex)); - } - - Complex_tree get_filtered_tree() { - Complex_tree filtered_tree; - for (auto f_simplex : simplex_tree_.filtration_simplex_range()) { - Simplex simplex; - for (auto vertex : simplex_tree_.simplex_vertex_range(f_simplex)) { - simplex.insert(simplex.begin(), vertex); - } - filtered_tree.push_back(std::make_pair(simplex, simplex_tree_.filtration(f_simplex))); - } - return filtered_tree; - - } - - Complex_tree get_skeleton_tree(int dimension) { - Complex_tree skeleton_tree; - for (auto f_simplex : simplex_tree_.skeleton_simplex_range(dimension)) { - Simplex simplex; - for (auto vertex : simplex_tree_.simplex_vertex_range(f_simplex)) { - simplex.insert(simplex.begin(), vertex); - } - skeleton_tree.push_back(std::make_pair(simplex, simplex_tree_.filtration(f_simplex))); - } - return skeleton_tree; - } - - Complex_tree get_star_tree(const Simplex& complex) { - Complex_tree star_tree; - for (auto f_simplex : simplex_tree_.star_simplex_range(simplex_tree_.find(complex))) { - Simplex simplex; - for (auto vertex : simplex_tree_.simplex_vertex_range(f_simplex)) { - simplex.insert(simplex.begin(), vertex); - } - star_tree.push_back(std::make_pair(simplex, simplex_tree_.filtration(f_simplex))); - } - return star_tree; - } - - Complex_tree get_coface_tree(const Simplex& complex, int dimension) { - Complex_tree coface_tree; - for (auto f_simplex : simplex_tree_.cofaces_simplex_range(simplex_tree_.find(complex), dimension)) { - Simplex simplex; - for (auto vertex : simplex_tree_.simplex_vertex_range(f_simplex)) { - simplex.insert(simplex.begin(), vertex); - } - coface_tree.push_back(std::make_pair(simplex, simplex_tree_.filtration(f_simplex))); - } - return coface_tree; - } - - // Specific to Witness complex because no inheritance - Filtration_value filtration() const { - return simplex_tree_.filtration(); - } - - void set_filtration(Filtration_value fil) { - simplex_tree_.set_filtration(fil); - } - - void initialize_filtration() { - simplex_tree_.initialize_filtration(); - } - - size_t num_vertices() const { - return simplex_tree_.num_vertices(); - } - - size_t num_simplices() { - return simplex_tree_.num_simplices(); - } - - int dimension() const { - return simplex_tree_.dimension(); - } - - void set_dimension(int dimension) { - simplex_tree_.set_dimension(dimension); + tangential_complex_->compute_tangential_complex(); + num_inconsistencies_ = tangential_complex_->number_of_inconsistent_simplices(); } std::vector get_point(int vh) { @@ -183,34 +85,30 @@ class Tangential_complex_interface { return vd; } - std::vector>> get_persistence(int homology_coeff_field, double min_persistence) { - if (pcoh_ != nullptr) { - delete pcoh_; - } - pcoh_ = new Persistent_cohomology_interface>(&simplex_tree_); - return pcoh_->get_persistence(homology_coeff_field, min_persistence); + unsigned number_of_vertices() { + return tangential_complex_->number_of_vertices(); } - - std::vector get_betti_numbers() const { - if (pcoh_ != nullptr) { - return pcoh_->betti_numbers(); - } - std::vector betti_numbers; - return betti_numbers; + + unsigned number_of_simplices() { + return num_inconsistencies_.num_simplices; } - std::vector get_persistent_betti_numbers(Filtration_value from, Filtration_value to) const { - if (pcoh_ != nullptr) { - return pcoh_->persistent_betti_numbers(from, to); - } - std::vector persistent_betti_numbers; - return persistent_betti_numbers; + unsigned number_of_inconsistent_simplices() { + return num_inconsistencies_.num_inconsistent_simplices; } - + + unsigned number_of_inconsistent_stars() { + return num_inconsistencies_.num_inconsistent_stars; + } + + void create_simplex_tree(Simplex_tree<>& simplex_tree) { + tangential_complex_->create_complex>(simplex_tree); + simplex_tree.initialize_filtration(); + } + private: - Simplex_tree<> simplex_tree_; - Persistent_cohomology_interface>* pcoh_; TC* tangential_complex_; + TC::Num_inconsistencies num_inconsistencies_; }; } // namespace tangential_complex -- cgit v1.2.3