diff options
author | vrouvrea <vrouvrea@636b058d-ea47-450e-bf9e-a15bfbe3eedb> | 2017-08-09 10:44:44 +0000 |
---|---|---|
committer | vrouvrea <vrouvrea@636b058d-ea47-450e-bf9e-a15bfbe3eedb> | 2017-08-09 10:44:44 +0000 |
commit | 947d6f3b5bf90689e0d1ba6a4d566bab0730b5a9 (patch) | |
tree | 3e37ed2dc5acd8d42b6a15bf4aba8cfe9bfeaae8 /src/cython | |
parent | 295d60787357806ae9aac1bfab98f3fefcd759a0 (diff) | |
parent | 1129608c2add6f15538b3e281d75119f0e1bc8b0 (diff) |
Merge last trunk modifications
persistence file reader Python interface
persistence_graphical_tools improvement (max_plots and max_barcodes, and from a persistence file)
git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/persistence_diagram_improvement@2604 636b058d-ea47-450e-bf9e-a15bfbe3eedb
Former-commit-id: db80333d4f34151be0c32024af597d90d221a97f
Diffstat (limited to 'src/cython')
-rwxr-xr-x | src/cython/cython/persistence_graphical_tools.py | 55 | ||||
-rw-r--r-- | src/cython/cython/simplex_tree.pyx | 48 | ||||
-rw-r--r-- | src/cython/doc/persistence_graphical_tools_user.rst | 20 | ||||
-rwxr-xr-x | src/cython/doc/pyplots/barcode_persistence.py | 3 | ||||
-rwxr-xr-x | src/cython/doc/pyplots/diagram_persistence.py | 4 | ||||
-rwxr-xr-x | src/cython/doc/pyplots/show_palette_values.py | 3 | ||||
-rw-r--r-- | src/cython/include/Simplex_tree_interface.h | 8 | ||||
-rwxr-xr-x | src/cython/test/test_cubical_complex.py | 4 |
8 files changed, 96 insertions, 49 deletions
diff --git a/src/cython/cython/persistence_graphical_tools.py b/src/cython/cython/persistence_graphical_tools.py index da709b8a..fb837e29 100755 --- a/src/cython/cython/persistence_graphical_tools.py +++ b/src/cython/cython/persistence_graphical_tools.py @@ -1,5 +1,6 @@ import matplotlib.pyplot as plt import numpy as np +import os """This file is part of the Gudhi Library. The Gudhi library (Geometric Understanding in Higher Dimensions) is a generic C++ @@ -23,7 +24,7 @@ import numpy as np along with this program. If not, see <http://www.gnu.org/licenses/>. """ -__author__ = "Vincent Rouvreau" +__author__ = "Vincent Rouvreau, Bertrand Michel" __copyright__ = "Copyright (C) 2016 INRIA" __license__ = "GPL v3" @@ -63,7 +64,7 @@ def show_palette_values(alpha=0.6): :param alpha: alpha value in [0.0, 1.0] for horizontal bars (default is 0.6). :type alpha: float. - :returns: plot -- An horizontal bar plot of dimensions color. + :returns: plot the dimension palette values. """ colors = [] for color in palette: @@ -74,18 +75,38 @@ def show_palette_values(alpha=0.6): plt.barh(y_pos, y_pos + 1, align='center', alpha=alpha, color=colors) plt.ylabel('Dimension') plt.title('Dimension palette values') + return plt - plt.show() - -def plot_persistence_barcode(persistence, alpha=0.6): +def plot_persistence_barcode(persistence=[], persistence_file='', alpha=0.6, max_barcodes=0): """This function plots the persistence bar code. :param persistence: The persistence to plot. :type persistence: list of tuples(dimension, tuple(birth, death)). + :param persistence_file: A persistence file style name (reset persistence if both are set). + :type persistence_file: string :param alpha: alpha value in [0.0, 1.0] for horizontal bars (default is 0.6). :type alpha: float. + :param max_barcodes: number of maximal barcodes to be displayed + (persistence will be sorted by life time if max_barcodes is set) + :type max_barcodes: int. :returns: plot -- An horizontal bar plot of persistence. """ + if persistence_file is not '': + if os.path.isfile(persistence_file): + # Reset persistence + persistence = [] + diag = read_persistence_intervals_grouped_by_dimension(persistence_file=persistence_file) + for key in diag.keys(): + for persistence_interval in diag[key]: + persistence.append((key, persistence_interval)) + else: + print("file " + persistence_file + " not found.") + return None + + if max_barcodes > 0 and max_barcodes < len(persistence): + # Sort by life time, then takes only the max_plots elements + persistence = sorted(persistence, key=lambda life_time: life_time[1][1]-life_time[1][0], reverse=True)[:max_barcodes] + (min_birth, max_death) = __min_birth_max_death(persistence) ind = 0 delta = ((max_death - min_birth) / 10.0) @@ -110,19 +131,39 @@ def plot_persistence_barcode(persistence, alpha=0.6): plt.title('Persistence barcode') # Ends plot on infinity value and starts a little bit before min_birth plt.axis([axis_start, infinity, 0, ind]) - plt.show() + return plt -def plot_persistence_diagram(persistence, alpha=0.6, band_boot=0.): +def plot_persistence_diagram(persistence=[], persistence_file='', alpha=0.6, band_boot=0., max_plots=0): """This function plots the persistence diagram with an optional confidence band. :param persistence: The persistence to plot. :type persistence: list of tuples(dimension, tuple(birth, death)). + :param persistence_file: A persistence file style name (reset persistence if both are set). + :type persistence_file: string :param alpha: alpha value in [0.0, 1.0] for points and horizontal infinity line (default is 0.6). :type alpha: float. :param band_boot: bootstrap band (not displayed if :math:`\leq` 0.) :type band_boot: float. + :param max_plots: number of maximal plots to be displayed + :type max_plots: int. :returns: plot -- A diagram plot of persistence. """ + if persistence_file is not '': + if os.path.isfile(persistence_file): + # Reset persistence + persistence = [] + diag = read_persistence_intervals_grouped_by_dimension(persistence_file=persistence_file) + for key in diag.keys(): + for persistence_interval in diag[key]: + persistence.append((key, persistence_interval)) + else: + print("file " + persistence_file + " not found.") + return None + + if max_plots > 0 and max_plots < len(persistence): + # Sort by life time, then takes only the max_plots elements + persistence = sorted(persistence, key=lambda life_time: life_time[1][1]-life_time[1][0], reverse=True)[:max_plots] + (min_birth, max_death) = __min_birth_max_death(persistence, band_boot) ind = 0 delta = ((max_death - min_birth) / 10.0) diff --git a/src/cython/cython/simplex_tree.pyx b/src/cython/cython/simplex_tree.pyx index 9d40a8b5..2acdac3c 100644 --- a/src/cython/cython/simplex_tree.pyx +++ b/src/cython/cython/simplex_tree.pyx @@ -183,10 +183,10 @@ cdef class SimplexTree: :returns: true if the simplex was found, false otherwise. :rtype: bool """ - cdef vector[int] complex + cdef vector[int] csimplex for i in simplex: - complex.push_back(i) - return self.thisptr.find_simplex(complex) + csimplex.push_back(i) + return self.thisptr.find_simplex(csimplex) def insert(self, simplex, filtration=0.0): """This function inserts the given N-simplex and its subfaces with the @@ -200,10 +200,10 @@ cdef class SimplexTree: :returns: true if the simplex was found, false otherwise. :rtype: bool """ - cdef vector[int] complex + cdef vector[int] csimplex for i in simplex: - complex.push_back(i) - return self.thisptr.insert_simplex_and_subfaces(complex, + csimplex.push_back(i) + return self.thisptr.insert_simplex_and_subfaces(csimplex, <double>filtration) def get_filtration(self): @@ -232,35 +232,35 @@ cdef class SimplexTree: :returns: The (simplices of the) skeleton of a maximum dimension. :rtype: list of tuples(simplex, filtration) """ - cdef vector[pair[vector[int], double]] skeletons \ + cdef vector[pair[vector[int], double]] skeleton \ = self.thisptr.get_skeleton(<int>dimension) ct = [] - for filtered_complex in skeletons: + for filtered_simplex in skeleton: v = [] - for vertex in filtered_complex.first: + for vertex in filtered_simplex.first: v.append(vertex) - ct.append((v, filtered_complex.second)) + ct.append((v, filtered_simplex.second)) return ct def get_star(self, simplex): - """This function returns the stars of a given N-simplex. + """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. :returns: The (simplices of the) star of a simplex. :rtype: list of tuples(simplex, filtration) """ - cdef vector[int] complex + cdef vector[int] csimplex for i in simplex: - complex.push_back(i) - cdef vector[pair[vector[int], double]] stars \ - = self.thisptr.get_star(complex) + csimplex.push_back(i) + cdef vector[pair[vector[int], double]] star \ + = self.thisptr.get_star(csimplex) ct = [] - for filtered_complex in stars: + for filtered_simplex in star: v = [] - for vertex in filtered_complex.first: + for vertex in filtered_simplex.first: v.append(vertex) - ct.append((v, filtered_complex.second)) + ct.append((v, filtered_simplex.second)) return ct def get_cofaces(self, simplex, codimension): @@ -275,17 +275,17 @@ cdef class SimplexTree: :returns: The (simplices of the) cofaces of a simplex :rtype: list of tuples(simplex, filtration) """ - cdef vector[int] complex + cdef vector[int] csimplex for i in simplex: - complex.push_back(i) + csimplex.push_back(i) cdef vector[pair[vector[int], double]] cofaces \ - = self.thisptr.get_cofaces(complex, <int>codimension) + = self.thisptr.get_cofaces(csimplex, <int>codimension) ct = [] - for filtered_complex in cofaces: + for filtered_simplex in cofaces: v = [] - for vertex in filtered_complex.first: + for vertex in filtered_simplex.first: v.append(vertex) - ct.append((v, filtered_complex.second)) + ct.append((v, filtered_simplex.second)) return ct def remove_maximal_simplex(self, simplex): diff --git a/src/cython/doc/persistence_graphical_tools_user.rst b/src/cython/doc/persistence_graphical_tools_user.rst index bc731f12..13198162 100644 --- a/src/cython/doc/persistence_graphical_tools_user.rst +++ b/src/cython/doc/persistence_graphical_tools_user.rst @@ -14,12 +14,14 @@ This function is useful to show the color palette values of dimension: .. testcode:: import gudhi - gudhi.show_palette_values(alpha=1.0) + plt = gudhi.show_palette_values(alpha=1.0) + plt.show() .. plot:: import gudhi - gudhi.show_palette_values(alpha=1.0) + plt = gudhi.show_palette_values(alpha=1.0) + plt.show() Show persistence as a barcode ----------------------------- @@ -32,7 +34,8 @@ This function can display the persistence result as a barcode: periodic_cc = gudhi.PeriodicCubicalComplex(perseus_file='3d_torus.txt') diag = periodic_cc.persistence() - gudhi.plot_persistence_barcode(diag) + plt = gudhi.plot_persistence_barcode(diag) + plt.show() .. plot:: @@ -40,7 +43,8 @@ This function can display the persistence result as a barcode: periodic_cc = gudhi.PeriodicCubicalComplex(perseus_file='3d_torus.txt') diag = periodic_cc.persistence() - gudhi.plot_persistence_barcode(diag) + plt = gudhi.plot_persistence_barcode(diag) + plt.show() Show persistence as a diagram ----------------------------- @@ -54,8 +58,8 @@ This function can display the persistence result as a diagram: rips_complex = gudhi.RipsComplex(off_file='tore3D_1307.off', max_edge_length=0.2) simplex_tree = rips_complex.create_simplex_tree(max_dimension=3) diag = simplex_tree.persistence() - pplot = gudhi.plot_persistence_diagram(diag, band_boot=0.13) - pplot.show() + plt = gudhi.plot_persistence_diagram(diag, band_boot=0.13) + plt.show() .. plot:: @@ -64,5 +68,5 @@ This function can display the persistence result as a diagram: rips_complex = gudhi.RipsComplex(off_file='tore3D_1307.off', max_edge_length=0.2) simplex_tree = rips_complex.create_simplex_tree(max_dimension=3) diag = simplex_tree.persistence() - pplot = gudhi.plot_persistence_diagram(diag, band_boot=0.13) - pplot.show() + plt = gudhi.plot_persistence_diagram(diag, band_boot=0.13) + plt.show() diff --git a/src/cython/doc/pyplots/barcode_persistence.py b/src/cython/doc/pyplots/barcode_persistence.py index b021049f..9cd3149d 100755 --- a/src/cython/doc/pyplots/barcode_persistence.py +++ b/src/cython/doc/pyplots/barcode_persistence.py @@ -2,4 +2,5 @@ import gudhi periodic_cc = gudhi.PeriodicCubicalComplex(perseus_file='3d_torus.txt') diag = periodic_cc.persistence() -gudhi.plot_persistence_barcode(diag) +plt = gudhi.plot_persistence_barcode(diag) +plt.show() diff --git a/src/cython/doc/pyplots/diagram_persistence.py b/src/cython/doc/pyplots/diagram_persistence.py index 56d6c50f..30661965 100755 --- a/src/cython/doc/pyplots/diagram_persistence.py +++ b/src/cython/doc/pyplots/diagram_persistence.py @@ -3,5 +3,5 @@ import gudhi rips_complex = gudhi.RipsComplex(off_file='tore3D_1307.off', max_edge_length=0.2) simplex_tree = rips_complex.create_simplex_tree(max_dimension=3) diag = simplex_tree.persistence() -pplot = gudhi.plot_persistence_diagram(diag, band_boot=0.13) -pplot.show() +plt = gudhi.plot_persistence_diagram(diag, band_boot=0.13) +plt.show() diff --git a/src/cython/doc/pyplots/show_palette_values.py b/src/cython/doc/pyplots/show_palette_values.py index e72a55fd..fdf9645f 100755 --- a/src/cython/doc/pyplots/show_palette_values.py +++ b/src/cython/doc/pyplots/show_palette_values.py @@ -1,2 +1,3 @@ import gudhi -gudhi.show_palette_values(alpha=1.0) +plt = gudhi.show_palette_values(alpha=1.0) +plt.show() diff --git a/src/cython/include/Simplex_tree_interface.h b/src/cython/include/Simplex_tree_interface.h index 45ce1916..09e7e992 100644 --- a/src/cython/include/Simplex_tree_interface.h +++ b/src/cython/include/Simplex_tree_interface.h @@ -70,14 +70,14 @@ class Simplex_tree_interface : public Simplex_tree<SimplexTreeOptions> { } // Do not interface this function, only used in strong witness interface for complex creation - bool insert_simplex(const std::vector<std::size_t>& complex, Filtration_value filtration = 0) { - Insertion_result result = Base::insert_simplex(complex, filtration); + bool insert_simplex(const std::vector<std::size_t>& simplex, Filtration_value filtration = 0) { + Insertion_result result = Base::insert_simplex(simplex, filtration); return (result.second); } // Do not interface this function, only used in strong witness interface for complex creation - bool insert_simplex_and_subfaces(const std::vector<std::size_t>& complex, Filtration_value filtration = 0) { - Insertion_result result = Base::insert_simplex_and_subfaces(complex, filtration); + bool insert_simplex_and_subfaces(const std::vector<std::size_t>& simplex, Filtration_value filtration = 0) { + Insertion_result result = Base::insert_simplex_and_subfaces(simplex, filtration); return (result.second); } diff --git a/src/cython/test/test_cubical_complex.py b/src/cython/test/test_cubical_complex.py index 2e281ee4..9a365823 100755 --- a/src/cython/test/test_cubical_complex.py +++ b/src/cython/test/test_cubical_complex.py @@ -67,7 +67,7 @@ def test_dimension_constructor(): top_dimensional_cells = [1,2,3,4,5,6,7,8,9]) assert cub.__is_defined() == True assert cub.__is_persistence_defined() == False - assert cub.persistence() == [(1, (0.0, 100.0)), (0, (0.0, 1.8446744073709552e+19))] + assert cub.persistence() == [(1, (0.0, 100.0)), (0, (0.0, float('inf')))] assert cub.__is_persistence_defined() == True assert cub.betti_numbers() == [1, 0] assert cub.persistent_betti_numbers(0, 1000) == [0, 0] @@ -80,7 +80,7 @@ def test_dimension_constructor(): cub = CubicalComplex(perseus_file='CubicalOneSphere.txt') assert cub.__is_defined() == True assert cub.__is_persistence_defined() == False - assert cub.persistence() == [(1, (0.0, 100.0)), (0, (0.0, 1.8446744073709552e+19))] + assert cub.persistence() == [(1, (0.0, 100.0)), (0, (0.0, float('inf')))] assert cub.__is_persistence_defined() == True assert cub.betti_numbers() == [1, 0, 0] assert cub.persistent_betti_numbers(0, 1000) == [1, 0, 0] |