diff options
author | vrouvrea <vrouvrea@636b058d-ea47-450e-bf9e-a15bfbe3eedb> | 2016-05-31 15:34:04 +0000 |
---|---|---|
committer | vrouvrea <vrouvrea@636b058d-ea47-450e-bf9e-a15bfbe3eedb> | 2016-05-31 15:34:04 +0000 |
commit | 7c20f9bf5829aa4ebe26ee59fb0120852dc0a5f3 (patch) | |
tree | 7ecb0a94384406746d8283387ceb4f7ccf934f9d /src | |
parent | 1e283611d2999003353e57f429bc9a0513fb0508 (diff) |
Add CONVENTIONS file to say Gudhi follows PEP8
Add persistence and betti numbers getters
git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/ST_cythonize@1228 636b058d-ea47-450e-bf9e-a15bfbe3eedb
Former-commit-id: d52d7e30d3feffe206deb14e741960987ba9fa7c
Diffstat (limited to 'src')
-rw-r--r-- | src/cython/CONVENTIONS | 9 | ||||
-rwxr-xr-x | src/cython/example/alpha_complex_example.py | 10 | ||||
-rwxr-xr-x | src/cython/example/mini_simplex_tree_example.py | 3 | ||||
-rwxr-xr-x | src/cython/example/rips_complex_example.py | 4 | ||||
-rwxr-xr-x | src/cython/example/simplex_tree_example.py | 9 | ||||
-rw-r--r-- | src/cython/src/cpp/Persistent_cohomology_interface.h | 55 | ||||
-rw-r--r-- | src/cython/src/cython/alpha_complex.pyx | 39 | ||||
-rw-r--r-- | src/cython/src/cython/mini_simplex_tree.pyx | 41 | ||||
-rw-r--r-- | src/cython/src/cython/rips_complex.pyx | 39 | ||||
-rw-r--r-- | src/cython/src/cython/simplex_tree.pyx | 40 |
10 files changed, 204 insertions, 45 deletions
diff --git a/src/cython/CONVENTIONS b/src/cython/CONVENTIONS new file mode 100644 index 00000000..804e97f3 --- /dev/null +++ b/src/cython/CONVENTIONS @@ -0,0 +1,9 @@ +Gudhi is following PEP8 conventions. + +Please refer to: +https://www.python.org/dev/peps/pep-0008/ + +A summary: + - modules (filenames) should have short, all-lowercase names, and they can contain underscores. + - packages (directories) should have short, all-lowercase names, preferably without underscores. + - classes should use the CapWords convention.
\ No newline at end of file diff --git a/src/cython/example/alpha_complex_example.py b/src/cython/example/alpha_complex_example.py index 6996b692..37c04f23 100755 --- a/src/cython/example/alpha_complex_example.py +++ b/src/cython/example/alpha_complex_example.py @@ -66,6 +66,12 @@ print("coface([0], 1)=", alpha_complex.get_coface_tree([0], 1)) print("point[0]=", alpha_complex.get_point(0)) print("point[5]=", alpha_complex.get_point(5)) +print("betti_numbers()=") +print(alpha_complex.betti_numbers()) + alpha_complex.initialize_filtration() -print("persistence(2)=", alpha_complex.persistence(homology_coeff_field=2, - min_persistence=0)) +print("persistence(homology_coeff_field=2, min_persistence=0)=") +print(alpha_complex.persistence(homology_coeff_field=2, min_persistence=0)) + +print("betti_numbers()=") +print(alpha_complex.betti_numbers()) diff --git a/src/cython/example/mini_simplex_tree_example.py b/src/cython/example/mini_simplex_tree_example.py index 0461a1df..d7189ddf 100755 --- a/src/cython/example/mini_simplex_tree_example.py +++ b/src/cython/example/mini_simplex_tree_example.py @@ -55,7 +55,8 @@ mini_st.set_dimension(2) # initialize_filtration required before plain_homology mini_st.initialize_filtration() -print("plain_homology(2)=", mini_st.plain_homology(2)) +print("persistence(homology_coeff_field=2)=") +print(mini_st.persistence(homology_coeff_field=2)) edge02 = [0, 2] if mini_st.find(edge02): diff --git a/src/cython/example/rips_complex_example.py b/src/cython/example/rips_complex_example.py index eba3f298..449ea2b3 100755 --- a/src/cython/example/rips_complex_example.py +++ b/src/cython/example/rips_complex_example.py @@ -37,5 +37,5 @@ 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)) -print("persistence(2)=", rips.persistence(homology_coeff_field=2, - min_persistence=0)) +print("persistence(homology_coeff_field=2, min_persistence=0)=") +print(rips.persistence(homology_coeff_field=2, min_persistence=0)) diff --git a/src/cython/example/simplex_tree_example.py b/src/cython/example/simplex_tree_example.py index bdaabca2..45d57c53 100755 --- a/src/cython/example/simplex_tree_example.py +++ b/src/cython/example/simplex_tree_example.py @@ -2,8 +2,6 @@ import gudhi -st = gudhi.SimplexTree() - """This file is part of the Gudhi Library. The Gudhi library (Geometric Understanding in Higher Dimensions) is a generic C++ library for computational topology. @@ -32,6 +30,9 @@ __license__ = "GPL v3" print("#####################################################################") print("SimplexTree creation from insertion") + +st = gudhi.SimplexTree() + if st.insert([0, 1]): print("Inserted !!") else: @@ -64,5 +65,5 @@ print("skeleton_tree[2]=", st.get_skeleton_tree(2)) print("skeleton_tree[1]=", st.get_skeleton_tree(1)) print("skeleton_tree[0]=", st.get_skeleton_tree(0)) -print("persistence(2)=", st.persistence(homology_coeff_field=2, - min_persistence=0)) +print("persistence(homology_coeff_field=2, min_persistence=0)=") +print(st.persistence(homology_coeff_field=2, min_persistence=0)) diff --git a/src/cython/src/cpp/Persistent_cohomology_interface.h b/src/cython/src/cpp/Persistent_cohomology_interface.h index adfca638..53aea58e 100644 --- a/src/cython/src/cpp/Persistent_cohomology_interface.h +++ b/src/cython/src/cpp/Persistent_cohomology_interface.h @@ -25,19 +25,62 @@ #include <gudhi/Persistent_cohomology.h> +#include <vector> +#include <utility> // for std::pair + namespace Gudhi { template<class FilteredComplex> class Persistent_cohomology_interface : public -persistent_cohomology::Persistent_cohomology<FilteredComplex,persistent_cohomology::Field_Zp> { +persistent_cohomology::Persistent_cohomology<FilteredComplex, persistent_cohomology::Field_Zp> { + private: + /* + * Compare two intervals by dimension, then by length. + */ + struct cmp_intervals_by_dim_then_length { + + explicit cmp_intervals_by_dim_then_length(FilteredComplex * sc) + : sc_(sc) { } + + template<typename Persistent_interval> + bool operator()(const Persistent_interval & p1, const Persistent_interval & p2) { + if (sc_->dimension(get < 0 > (p1)) == sc_->dimension(get < 0 > (p2))) + return (sc_->filtration(get < 1 > (p1)) - sc_->filtration(get < 0 > (p1)) + > sc_->filtration(get < 1 > (p2)) - sc_->filtration(get < 0 > (p2))); + else + return (sc_->dimension(get < 0 > (p1)) > sc_->dimension(get < 0 > (p2))); + } + FilteredComplex* sc_; + }; + public: + Persistent_cohomology_interface(FilteredComplex* stptr) - : persistent_cohomology::Persistent_cohomology<FilteredComplex,persistent_cohomology::Field_Zp>(*stptr) { } - void get_persistence(int homology_coeff_field, double min_persistence) { - persistent_cohomology::Persistent_cohomology<FilteredComplex,persistent_cohomology::Field_Zp>::init_coefficients(homology_coeff_field); - persistent_cohomology::Persistent_cohomology<FilteredComplex,persistent_cohomology::Field_Zp>::compute_persistent_cohomology(min_persistence); - persistent_cohomology::Persistent_cohomology<FilteredComplex,persistent_cohomology::Field_Zp>::output_diagram(); + : persistent_cohomology::Persistent_cohomology<FilteredComplex, persistent_cohomology::Field_Zp>(*stptr), + stptr_(stptr) { } + + std::vector<std::pair<int, std::pair<double, double>>> get_persistence(int homology_coeff_field, double min_persistence) { + persistent_cohomology::Persistent_cohomology<FilteredComplex, persistent_cohomology::Field_Zp>::init_coefficients(homology_coeff_field); + persistent_cohomology::Persistent_cohomology<FilteredComplex, persistent_cohomology::Field_Zp>::compute_persistent_cohomology(min_persistence); + + // Custom sort and output persistence + cmp_intervals_by_dim_then_length cmp(stptr_); + auto persistent_pairs = persistent_cohomology::Persistent_cohomology<FilteredComplex, persistent_cohomology::Field_Zp>::get_persistent_pairs(); + std::sort(std::begin(persistent_pairs), std::end(persistent_pairs), cmp); + + std::vector<std::pair<int, std::pair<double, double>>> persistence; + for (auto pair : persistent_pairs) { + persistence.push_back(std::make_pair(stptr_->dimension(get<0>(pair)), + std::make_pair(stptr_->filtration(get<0>(pair)), + stptr_->filtration(get<1>(pair))))); + } + return persistence; + } + + private: + // A copy + FilteredComplex* stptr_; }; diff --git a/src/cython/src/cython/alpha_complex.pyx b/src/cython/src/cython/alpha_complex.pyx index a06134c8..5df7a659 100644 --- a/src/cython/src/cython/alpha_complex.pyx +++ b/src/cython/src/cython/alpha_complex.pyx @@ -53,12 +53,16 @@ cdef extern from "Alpha_complex_interface.h" namespace "Gudhi": cdef extern from "Persistent_cohomology_interface.h" namespace "Gudhi": cdef cppclass Alpha_complex_persistence_interface "Gudhi::Persistent_cohomology_interface<Gudhi::alphacomplex::Alpha_complex< CGAL::Epick_d< CGAL::Dynamic_dimension_tag > >>": Alpha_complex_persistence_interface(Alpha_complex_interface * st) - void get_persistence(int homology_coeff_field, double min_persistence) + 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) # AlphaComplex python interface cdef class AlphaComplex: cdef Alpha_complex_interface * thisptr + cdef Alpha_complex_persistence_interface * pcohptr + def __cinit__(self, points=None, max_alpha_square=float('inf')): if points is not None: self.thisptr = new Alpha_complex_interface(points, @@ -67,6 +71,8 @@ cdef class AlphaComplex: def __dealloc__(self): if self.thisptr != NULL: del self.thisptr + if self.pcohptr != NULL: + del self.pcohptr def get_filtration(self): return self.thisptr.filtration() @@ -163,9 +169,28 @@ cdef class AlphaComplex: return point def persistence(self, homology_coeff_field=11, min_persistence=0): - cdef Alpha_complex_persistence_interface * pcohptr \ - = new Alpha_complex_persistence_interface(self.thisptr) - if pcohptr != NULL: - pcohptr.get_persistence(homology_coeff_field, min_persistence) - del pcohptr - return 5 + if self.pcohptr != NULL: + del self.pcohptr + self.pcohptr = new Alpha_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): + 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): + cdef vector[int] pbn_result + if self.pcohptr != NULL: + pbn_result = self.pcohptr.persistent_betti_numbers(<double>from_value, <double>to_value) + else: + print("persistent_betti_numbers function requires persistence function" + " to be launched first.") + return pbn_result diff --git a/src/cython/src/cython/mini_simplex_tree.pyx b/src/cython/src/cython/mini_simplex_tree.pyx index b836fb88..a5077820 100644 --- a/src/cython/src/cython/mini_simplex_tree.pyx +++ b/src/cython/src/cython/mini_simplex_tree.pyx @@ -55,18 +55,24 @@ cdef extern from "Simplex_tree_interface.h" namespace "Gudhi": cdef extern from "Persistent_cohomology_interface.h" namespace "Gudhi": cdef cppclass Mini_simplex_tree_persistence_interface "Gudhi::Persistent_cohomology_interface<Gudhi::Simplex_tree<Gudhi::Simplex_tree_options_mini>>": Mini_simplex_tree_persistence_interface(Simplex_tree_interface_mini * st) - void get_persistence(int homology_coeff_field, double min_persistence) + 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: cdef Simplex_tree_interface_mini * thisptr + cdef Mini_simplex_tree_persistence_interface * pcohptr + 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 get_filtration(self): return self.thisptr.filtration() @@ -158,10 +164,29 @@ cdef class MiniSimplexTree: def remove_maximal_simplex(self, simplex): self.thisptr.remove_maximal_simplex(simplex) - def plain_homology(self, homology_coeff_field=11): - cdef Mini_simplex_tree_persistence_interface * pcohptr \ - = new Mini_simplex_tree_persistence_interface(self.thisptr) - if pcohptr != NULL: - pcohptr.get_persistence(homology_coeff_field, 0) - del pcohptr - return 5 + def persistence(self, homology_coeff_field=11): + 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): + 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): + cdef vector[int] pbn_result + if self.pcohptr != NULL: + pbn_result = self.pcohptr.persistent_betti_numbers(<double>from_value, <double>to_value) + else: + print("persistent_betti_numbers function requires persistence function" + " to be launched first.") + return pbn_result diff --git a/src/cython/src/cython/rips_complex.pyx b/src/cython/src/cython/rips_complex.pyx index 3ca890d9..d01f79cb 100644 --- a/src/cython/src/cython/rips_complex.pyx +++ b/src/cython/src/cython/rips_complex.pyx @@ -57,12 +57,16 @@ cdef extern from "Simplex_tree_interface.h" namespace "Gudhi": cdef extern from "Persistent_cohomology_interface.h" namespace "Gudhi": cdef cppclass Rips_complex_persistence_interface "Gudhi::Persistent_cohomology_interface<Gudhi::Simplex_tree<Gudhi::Simplex_tree_options_full_featured>>": Rips_complex_persistence_interface(Rips_complex_interface * st) - void get_persistence(int homology_coeff_field, double min_persistence) + 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) # RipsComplex python interface cdef class RipsComplex: cdef Rips_complex_interface * thisptr + cdef Rips_complex_persistence_interface * pcohptr + def __cinit__(self, points=None, max_dimension=3, max_edge_length=float('inf')): self.thisptr = new Rips_complex_interface() @@ -74,6 +78,8 @@ cdef class RipsComplex: def __dealloc__(self): if self.thisptr != NULL: del self.thisptr + if self.pcohptr != NULL: + del self.pcohptr def get_filtration(self): return self.thisptr.filtration() @@ -166,9 +172,28 @@ cdef class RipsComplex: self.thisptr.remove_maximal_simplex(simplex) def persistence(self, homology_coeff_field=11, min_persistence=0): - cdef Rips_complex_persistence_interface * pcohptr \ - = new Rips_complex_persistence_interface(self.thisptr) - if pcohptr != NULL: - pcohptr.get_persistence(homology_coeff_field, min_persistence) - del pcohptr - return 5 + 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): + 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): + cdef vector[int] pbn_result + if self.pcohptr != NULL: + pbn_result = self.pcohptr.persistent_betti_numbers(<double>from_value, <double>to_value) + else: + print("persistent_betti_numbers function requires persistence function" + " to be launched first.") + return pbn_result diff --git a/src/cython/src/cython/simplex_tree.pyx b/src/cython/src/cython/simplex_tree.pyx index e3cdc27b..071b19e3 100644 --- a/src/cython/src/cython/simplex_tree.pyx +++ b/src/cython/src/cython/simplex_tree.pyx @@ -55,18 +55,24 @@ cdef extern from "Simplex_tree_interface.h" namespace "Gudhi": cdef extern from "Persistent_cohomology_interface.h" namespace "Gudhi": cdef cppclass Simplex_tree_persistence_interface "Gudhi::Persistent_cohomology_interface<Gudhi::Simplex_tree<Gudhi::Simplex_tree_options_full_featured>>": Simplex_tree_persistence_interface(Simplex_tree_interface_full_featured * st) - void get_persistence(int homology_coeff_field, double min_persistence) + 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) # SimplexTree python interface cdef class SimplexTree: cdef Simplex_tree_interface_full_featured * thisptr + cdef Simplex_tree_persistence_interface * pcohptr + def __cinit__(self): self.thisptr = new Simplex_tree_interface_full_featured() def __dealloc__(self): if self.thisptr != NULL: del self.thisptr + if self.pcohptr != NULL: + del self.pcohptr def get_filtration(self): return self.thisptr.filtration() @@ -159,10 +165,28 @@ cdef class SimplexTree: self.thisptr.remove_maximal_simplex(simplex) def persistence(self, homology_coeff_field=11, min_persistence=0): - cdef Simplex_tree_persistence_interface * pcohptr \ - = new Simplex_tree_persistence_interface(self.thisptr) - if pcohptr != NULL: - pcohptr.get_persistence(homology_coeff_field, min_persistence) - del pcohptr - return 5 - + if self.pcohptr != NULL: + del self.pcohptr + self.pcohptr = new 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, min_persistence) + return persistence_result + + def betti_numbers(self): + 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): + cdef vector[int] pbn_result + if self.pcohptr != NULL: + pbn_result = self.pcohptr.persistent_betti_numbers(<double>from_value, <double>to_value) + else: + print("persistent_betti_numbers function requires persistence function" + " to be launched first.") + return pbn_result |