diff options
author | vrouvrea <vrouvrea@636b058d-ea47-450e-bf9e-a15bfbe3eedb> | 2018-05-30 21:13:34 +0000 |
---|---|---|
committer | vrouvrea <vrouvrea@636b058d-ea47-450e-bf9e-a15bfbe3eedb> | 2018-05-30 21:13:34 +0000 |
commit | 7332184fd63e8ebbe7e9fcb0d4a2a694e9c54296 (patch) | |
tree | 178bca6c0fabe13784c1fb695a1713d722c681d9 | |
parent | 1f1033f14cef0b5b602a23c9f35659fa0168f1b4 (diff) | |
parent | 01cfd13aa84317debb4bf681309533b693322131 (diff) |
Merge branch python_2.1.0_fix_vincent
git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@3496 636b058d-ea47-450e-bf9e-a15bfbe3eedb
Former-commit-id: d4f09bc2e10151cec21fe3026e8dc1a530d15563
24 files changed, 224 insertions, 118 deletions
diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index 5d4ea30c..74a7281d 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -1238,9 +1238,8 @@ class Simplex_tree { } public: - /** \brief Browse the simplex tree to ensure the filtration is not decreasing. - * The simplex tree is browsed starting from the root until the leaf, and the filtration values are set with their - * parent value (increased), in case the values are decreasing. + /** \brief This function ensures that each simplex has a higher filtration value than its faces by increasing the + * filtration values. * @return The filtration modification information. * \post Some simplex tree functions require the filtration to be valid. `make_filtration_non_decreasing()` * function is not launching `initialize_filtration()` but returns the filtration modification information. If the diff --git a/src/cython/CMakeLists.txt b/src/cython/CMakeLists.txt index 1b953648..158c7561 100644 --- a/src/cython/CMakeLists.txt +++ b/src/cython/CMakeLists.txt @@ -181,7 +181,7 @@ if(CYTHON_FOUND) WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/tangential_complex_plain_homology_from_off_file_example.py" - --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off) + --no-diagram -i 2 -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off) add_gudhi_py_test(test_tangential_complex) diff --git a/src/cython/cython/persistence_graphical_tools.py b/src/cython/cython/persistence_graphical_tools.py index e2405e96..216ab8d6 100755 --- a/src/cython/cython/persistence_graphical_tools.py +++ b/src/cython/cython/persistence_graphical_tools.py @@ -1,4 +1,5 @@ import matplotlib.pyplot as plt +import matplotlib.patches as mpatches import numpy as np import os @@ -28,13 +29,13 @@ __author__ = "Vincent Rouvreau, Bertrand Michel" __copyright__ = "Copyright (C) 2016 Inria" __license__ = "GPL v3" -def __min_birth_max_death(persistence, band_boot=0.): +def __min_birth_max_death(persistence, band=0.): """This function returns (min_birth, max_death) from the persistence. :param persistence: The persistence to plot. :type persistence: list of tuples(dimension, tuple(birth, death)). - :param band_boot: bootstrap band - :type band_boot: float. + :param band: band + :type band: float. :returns: (float, float) -- (min_birth, max_death). """ # Look for minimum birth date and maximum death date for plot optimisation @@ -48,8 +49,8 @@ def __min_birth_max_death(persistence, band_boot=0.): max_death = float(interval[1][0]) if float(interval[1][0]) < min_birth: min_birth = float(interval[1][0]) - if band_boot > 0.: - max_death += band_boot + if band > 0.: + max_death += band return (min_birth, max_death) """ @@ -59,37 +60,27 @@ palette = ['#ff0000', '#00ff00', '#0000ff', '#00ffff', '#ff00ff', '#ffff00', '#000000', '#880000', '#008800', '#000088', '#888800', '#880088', '#008888'] -def show_palette_values(alpha=0.6): - """This function shows palette color values in function of the dimension. +def plot_persistence_barcode(persistence=[], persistence_file='', alpha=0.6, + max_barcodes=1000, inf_delta=0.1, legend=False): + """This function plots the persistence bar code from persistence values list + or from a :doc:`persistence file <fileformats>`. - :param alpha: alpha value in [0.0, 1.0] for horizontal bars (default is 0.6). - :type alpha: float. - :returns: plot the dimension palette values. - """ - colors = [] - for color in palette: - colors.append(color) - - y_pos = np.arange(len(palette)) - - plt.barh(y_pos, y_pos + 1, align='center', alpha=alpha, color=colors) - plt.ylabel('Dimension') - plt.title('Dimension palette values') - return plt - -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. + :param persistence: Persistence values list. :type persistence: list of tuples(dimension, tuple(birth, death)). - :param persistence_file: A persistence file style name (reset persistence if both are set). + :param persistence_file: A :doc:`persistence file <fileformats>` 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). + :param alpha: barcode transparency value (0.0 transparent through 1.0 opaque - default is 0.6). :type alpha: float. - :param max_barcodes: number of maximal barcodes to be displayed + :param max_barcodes: number of maximal barcodes to be displayed. + Set it to 0 to see all, Default value is 1000. (persistence will be sorted by life time if max_barcodes is set) :type max_barcodes: int. - :returns: plot -- An horizontal bar plot of persistence. + :param inf_delta: Infinity is placed at ((max_death - min_birth) x inf_delta). + A reasonable value is between 0.05 and 0.5 - default is 0.1. + :type inf_delta: float. + :returns: A matplotlib object containing horizontal bar plot of persistence + (launch `show()` method on it to display it). """ if persistence_file is not '': if os.path.isfile(persistence_file): @@ -107,9 +98,11 @@ def plot_persistence_barcode(persistence=[], persistence_file='', alpha=0.6, max # 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] + persistence = sorted(persistence, key=lambda birth: birth[1][0]) + (min_birth, max_death) = __min_birth_max_death(persistence) ind = 0 - delta = ((max_death - min_birth) / 10.0) + delta = ((max_death - min_birth) * inf_delta) # Replace infinity values with max_death + delta for bar code to be more # readable infinity = max_death + delta @@ -120,33 +113,49 @@ def plot_persistence_barcode(persistence=[], persistence_file='', alpha=0.6, max # Finite death case plt.barh(ind, (interval[1][1] - interval[1][0]), height=0.8, left = interval[1][0], alpha=alpha, - color = palette[interval[0]]) + color = palette[interval[0]], + linewidth=0) else: # Infinite death case for diagram to be nicer plt.barh(ind, (infinity - interval[1][0]), height=0.8, left = interval[1][0], alpha=alpha, - color = palette[interval[0]]) + color = palette[interval[0]], + linewidth=0) ind = ind + 1 + if legend: + dimensions = list(set(item[0] for item in persistence)) + plt.legend(handles=[mpatches.Patch(color=palette[dim], + label=str(dim)) for dim in dimensions], + loc='lower right') plt.title('Persistence barcode') # Ends plot on infinity value and starts a little bit before min_birth plt.axis([axis_start, infinity, 0, ind]) return plt -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. +def plot_persistence_diagram(persistence=[], persistence_file='', alpha=0.6, + band=0., max_plots=1000, inf_delta=0.1, legend=False): + """This function plots the persistence diagram from persistence values list + or from a :doc:`persistence file <fileformats>`. - :param persistence: The persistence to plot. + :param persistence: Persistence values list. :type persistence: list of tuples(dimension, tuple(birth, death)). - :param persistence_file: A persistence file style name (reset persistence if both are set). + :param persistence_file: A :doc:`persistence file <fileformats>` 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). + :param alpha: plot transparency value (0.0 transparent through 1.0 opaque - default is 0.6). :type alpha: float. - :param band_boot: bootstrap band (not displayed if :math:`\leq` 0.) - :type band_boot: float. + :param band: band (not displayed if :math:`\leq` 0. - default is 0.) + :type band: float. :param max_plots: number of maximal plots to be displayed + Set it to 0 to see all, Default value is 1000. + (persistence will be sorted by life time if max_plots is set) :type max_plots: int. - :returns: plot -- A diagram plot of persistence. + :param inf_delta: Infinity is placed at ((max_death - min_birth) x inf_delta). + A reasonable value is between 0.05 and 0.5 - default is 0.1. + :type inf_delta: float. + :returns: A matplotlib object containing diagram plot of persistence + (launch `show()` method on it to display it). """ if persistence_file is not '': if os.path.isfile(persistence_file): @@ -164,9 +173,9 @@ def plot_persistence_diagram(persistence=[], persistence_file='', alpha=0.6, ban # 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) + (min_birth, max_death) = __min_birth_max_death(persistence, band) ind = 0 - delta = ((max_death - min_birth) / 10.0) + delta = ((max_death - min_birth) * inf_delta) # Replace infinity values with max_death + delta for diagram to be more # readable infinity = max_death + delta @@ -179,8 +188,8 @@ def plot_persistence_diagram(persistence=[], persistence_file='', alpha=0.6, ban plt.plot(x, [infinity] * len(x), linewidth=1.0, color='k', alpha=alpha) plt.text(axis_start, infinity, r'$\infty$', color='k', alpha=alpha) # bootstrap band - if band_boot > 0.: - plt.fill_between(x, x, x+band_boot, alpha=alpha, facecolor='red') + if band > 0.: + plt.fill_between(x, x, x+band, alpha=alpha, facecolor='red') # Draw points in loop for interval in reversed(persistence): @@ -194,6 +203,10 @@ def plot_persistence_diagram(persistence=[], persistence_file='', alpha=0.6, ban color = palette[interval[0]]) ind = ind + 1 + if legend: + dimensions = list(set(item[0] for item in persistence)) + plt.legend(handles=[mpatches.Patch(color=palette[dim], label=str(dim)) for dim in dimensions]) + plt.title('Persistence diagram') plt.xlabel('Birth') plt.ylabel('Death') diff --git a/src/cython/cython/simplex_tree.pyx b/src/cython/cython/simplex_tree.pyx index 8abeb5f8..e302486b 100644 --- a/src/cython/cython/simplex_tree.pyx +++ b/src/cython/cython/simplex_tree.pyx @@ -55,6 +55,7 @@ cdef extern from "Simplex_tree_interface.h" namespace "Gudhi": void expansion(int max_dim) void remove_maximal_simplex(vector[int] simplex) bool prune_above_filtration(double filtration) + bool make_filtration_non_decreasing() 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>>": @@ -64,6 +65,7 @@ cdef extern from "Persistent_cohomology_interface.h" namespace "Gudhi": vector[int] persistent_betti_numbers(double from_value, double to_value) vector[pair[double,double]] intervals_in_dimension(int dimension) void write_output_diagram(string diagram_file_name) + vector[pair[vector[int], vector[int]]] persistence_pairs() # SimplexTree python interface cdef class SimplexTree: @@ -399,6 +401,26 @@ cdef class SimplexTree: """ self.thisptr.expansion(max_dim) + def make_filtration_non_decreasing(self): + """This function ensures that each simplex has a higher filtration + value than its faces by increasing the filtration values. + + :returns: The filtration modification information. + :rtype: bint + + + .. note:: + + Some simplex tree functions require the filtration to be valid. + make_filtration_non_decreasing function is not launching + :func:`initialize_filtration()<gudhi.SimplexTree.initialize_filtration>` + but returns the filtration modification + information. If the complex has changed , please call + :func:`initialize_filtration()<gudhi.SimplexTree.initialize_filtration>` + to recompute it. + """ + return self.thisptr.make_filtration_non_decreasing() + def persistence(self, homology_coeff_field=11, min_persistence=0, persistence_dim_max = False): """This function returns the persistence of the simplicial complex. @@ -486,6 +508,25 @@ cdef class SimplexTree: " to be launched first.") return intervals_result + def persistence_pairs(self): + """This function returns the persistence pairs of the simplicial + complex. + + :returns: The persistence intervals. + :rtype: list of pair of list of int + + :note: intervals_in_dim function requires + :func:`persistence()<gudhi.SimplexTree.persistence>` + function to be launched first. + """ + cdef vector[pair[vector[int],vector[int]]] persistence_pairs_result + if self.pcohptr != NULL: + persistence_pairs_result = self.pcohptr.persistence_pairs() + else: + print("persistence_pairs function requires persistence function" + " to be launched first.") + return persistence_pairs_result + def write_persistence_diagram(self, persistence_file=''): """This function writes the persistence intervals of the simplicial complex in a user given file name. diff --git a/src/cython/cython/tangential_complex.pyx b/src/cython/cython/tangential_complex.pyx index 10fa1468..4bb07076 100644 --- a/src/cython/cython/tangential_complex.pyx +++ b/src/cython/cython/tangential_complex.pyx @@ -33,9 +33,9 @@ __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) + Tangential_complex_interface(int intrisic_dim, vector[vector[double]] points) # bool from_file is a workaround for cython to find the correct signature - Tangential_complex_interface(string off_file, bool from_file) + Tangential_complex_interface(int intrisic_dim, string off_file, bool from_file) vector[double] get_point(unsigned vertex) unsigned number_of_vertices() unsigned number_of_simplices() @@ -54,9 +54,12 @@ cdef class TangentialComplex: cdef Tangential_complex_interface * thisptr # Fake constructor that does nothing but documenting the constructor - def __init__(self, points=None, off_file=''): + def __init__(self, intrisic_dim, points=None, off_file=''): """TangentialComplex constructor. + :param intrisic_dim: Intrinsic dimension of the manifold. + :type intrisic_dim: integer + :param points: A list of points in d-Dimension. :type points: list of list of double @@ -67,17 +70,17 @@ cdef class TangentialComplex: """ # The real cython constructor - def __cinit__(self, points=None, off_file=''): + def __cinit__(self, intrisic_dim, points=None, off_file=''): if off_file is not '': if os.path.isfile(off_file): - self.thisptr = new Tangential_complex_interface(str.encode(off_file), True) + self.thisptr = new Tangential_complex_interface(intrisic_dim, str.encode(off_file), True) else: print("file " + off_file + " not found.") else: if points is None: # Empty tangential construction points=[] - self.thisptr = new Tangential_complex_interface(points) + self.thisptr = new Tangential_complex_interface(intrisic_dim, points) def __dealloc__(self): diff --git a/src/cython/doc/installation.rst b/src/cython/doc/installation.rst index 52c5eb49..b0bc5f38 100644 --- a/src/cython/doc/installation.rst +++ b/src/cython/doc/installation.rst @@ -43,6 +43,9 @@ following command in a terminal: export PYTHONPATH='$PYTHONPATH:/path-to-gudhi/build/cython' ctest -R py_test +If tests fail, please try to :code:`import gudhi` and check the errors. +The problem can come from a third-party library bad link or installation. + Documentation ============= diff --git a/src/cython/doc/persistence_graphical_tools_ref.rst b/src/cython/doc/persistence_graphical_tools_ref.rst index 27c2f68a..a69c8ba2 100644 --- a/src/cython/doc/persistence_graphical_tools_ref.rst +++ b/src/cython/doc/persistence_graphical_tools_ref.rst @@ -3,6 +3,5 @@ Persistence graphical tools reference manual ============================================ .. autofunction:: gudhi.__min_birth_max_death -.. autofunction:: gudhi.show_palette_values .. autofunction:: gudhi.plot_persistence_barcode .. autofunction:: gudhi.plot_persistence_diagram diff --git a/src/cython/doc/persistence_graphical_tools_user.rst b/src/cython/doc/persistence_graphical_tools_user.rst index a5523d23..46f871c7 100644 --- a/src/cython/doc/persistence_graphical_tools_user.rst +++ b/src/cython/doc/persistence_graphical_tools_user.rst @@ -5,24 +5,6 @@ Definition .. include:: persistence_graphical_tools_sum.rst -Show palette values -------------------- - -This function is useful to show the color palette values of dimension: - - -.. testcode:: - - import gudhi - plt = gudhi.show_palette_values(alpha=1.0) - plt.show() - -.. plot:: - - import gudhi - plt = gudhi.show_palette_values(alpha=1.0) - plt.show() - Show persistence as a barcode ----------------------------- @@ -59,10 +41,10 @@ This function can display the persistence result as a diagram: import gudhi point_cloud = gudhi.read_off(off_file=gudhi.__root_source_dir__ + '/data/points/tore3D_1307.off') - rips_complex = gudhi.RipsComplex(points=point_cloud, max_edge_length=0.2) + rips_complex = gudhi.RipsComplex(points=point_cloud, max_edge_length=0.3) simplex_tree = rips_complex.create_simplex_tree(max_dimension=3) diag = simplex_tree.persistence() - plt = gudhi.plot_persistence_diagram(diag, band_boot=0.13) + plt = gudhi.plot_persistence_diagram(diag) plt.show() .. plot:: @@ -70,8 +52,8 @@ This function can display the persistence result as a diagram: import gudhi point_cloud = gudhi.read_off(off_file=gudhi.__root_source_dir__ + '/data/points/tore3D_1307.off') - rips_complex = gudhi.RipsComplex(points=point_cloud, max_edge_length=0.2) + rips_complex = gudhi.RipsComplex(points=point_cloud, max_edge_length=0.3) simplex_tree = rips_complex.create_simplex_tree(max_dimension=3) diag = simplex_tree.persistence() - plt = gudhi.plot_persistence_diagram(diag, band_boot=0.13) + plt = gudhi.plot_persistence_diagram(diag) plt.show() diff --git a/src/cython/doc/pyplots/diagram_persistence.py b/src/cython/doc/pyplots/diagram_persistence.py index ac20bf47..3bab0ca1 100755 --- a/src/cython/doc/pyplots/diagram_persistence.py +++ b/src/cython/doc/pyplots/diagram_persistence.py @@ -2,8 +2,8 @@ import gudhi point_cloud = gudhi.read_off(off_file=gudhi.__root_source_dir__ + \ '/data/points/tore3D_1307.off') -rips_complex = gudhi.RipsComplex(points=point_cloud, max_edge_length=0.2) +rips_complex = gudhi.RipsComplex(points=point_cloud, max_edge_length=0.3) simplex_tree = rips_complex.create_simplex_tree(max_dimension=3) diag = simplex_tree.persistence() -plt = gudhi.plot_persistence_diagram(diag, band_boot=0.13) +plt = gudhi.plot_persistence_diagram(diag) plt.show() diff --git a/src/cython/doc/pyplots/show_palette_values.py b/src/cython/doc/pyplots/show_palette_values.py deleted file mode 100755 index fdf9645f..00000000 --- a/src/cython/doc/pyplots/show_palette_values.py +++ /dev/null @@ -1,3 +0,0 @@ -import gudhi -plt = gudhi.show_palette_values(alpha=1.0) -plt.show() diff --git a/src/cython/doc/tangential_complex_user.rst b/src/cython/doc/tangential_complex_user.rst index efa6d7ce..fafb3193 100644 --- a/src/cython/doc/tangential_complex_user.rst +++ b/src/cython/doc/tangential_complex_user.rst @@ -122,8 +122,8 @@ This example builds the Tangential complex of point set read in an OFF file. .. testcode:: import gudhi - tc = gudhi.TangentialComplex(off_file=gudhi.__root_source_dir__ + \ - '/data/points/alphacomplexdoc.off') + tc = gudhi.TangentialComplex(intrisic_dim = 1, + off_file=gudhi.__root_source_dir__ + '/data/points/alphacomplexdoc.off') result_str = 'Tangential contains ' + repr(tc.num_simplices()) + \ ' simplices - ' + repr(tc.num_vertices()) + ' vertices.' print(result_str) @@ -169,7 +169,8 @@ simplices. .. testcode:: import gudhi - tc = gudhi.TangentialComplex(points=[[0.0, 0.0], [1.0, 0.0], [0.0, 1.0], [1.0, 1.0]]) + tc = gudhi.TangentialComplex(intrisic_dim = 1, + points=[[0.0, 0.0], [1.0, 0.0], [0.0, 1.0], [1.0, 1.0]]) result_str = 'Tangential contains ' + repr(tc.num_vertices()) + ' vertices.' print(result_str) diff --git a/src/cython/example/alpha_complex_diagram_persistence_from_off_file_example.py b/src/cython/example/alpha_complex_diagram_persistence_from_off_file_example.py index 27550025..4abe22d4 100755 --- a/src/cython/example/alpha_complex_diagram_persistence_from_off_file_example.py +++ b/src/cython/example/alpha_complex_diagram_persistence_from_off_file_example.py @@ -38,7 +38,7 @@ parser = argparse.ArgumentParser(description='AlphaComplex creation from ' 'points from the given OFF file.') parser.add_argument("-f", "--file", type=str, required=True) parser.add_argument("-a", "--max_alpha_square", type=float, default=0.5) -parser.add_argument("-b", "--band_boot", type=float, default=0.) +parser.add_argument("-b", "--band", type=float, default=0.) parser.add_argument('--no-diagram', default=False, action='store_true' , help='Flag for not to display the diagrams') args = parser.parse_args() @@ -64,7 +64,7 @@ with open(args.file, 'r') as f: print(simplex_tree.betti_numbers()) if args.no_diagram == False: - pplot = gudhi.plot_persistence_diagram(diag, band_boot=args.band_boot) + pplot = gudhi.plot_persistence_diagram(diag, band=args.band) pplot.show() else: print(args.file, "is not a valid OFF file") diff --git a/src/cython/example/euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py b/src/cython/example/euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py index 1c142d9a..3b29781f 100755 --- a/src/cython/example/euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py +++ b/src/cython/example/euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py @@ -40,7 +40,7 @@ parser.add_argument("-f", "--file", type=str, required=True) parser.add_argument("-a", "--max_alpha_square", type=float, required=True) parser.add_argument("-n", "--number_of_landmarks", type=int, required=True) parser.add_argument("-d", "--limit_dimension", type=int, required=True) -parser.add_argument("-b", "--band_boot", type=float, default=0.) +parser.add_argument("-b", "--band", type=float, default=0.) parser.add_argument('--no-diagram', default=False, action='store_true' , help='Flag for not to display the diagrams') args = parser.parse_args() @@ -71,7 +71,7 @@ with open(args.file, 'r') as f: print(simplex_tree.betti_numbers()) if args.no_diagram == False: - pplot = gudhi.plot_persistence_diagram(diag, band_boot=args.band_boot) + pplot = gudhi.plot_persistence_diagram(diag, band=args.band) pplot.show() else: print(args.file, "is not a valid OFF file") diff --git a/src/cython/example/euclidean_witness_complex_diagram_persistence_from_off_file_example.py b/src/cython/example/euclidean_witness_complex_diagram_persistence_from_off_file_example.py index 216fcff2..db34962d 100755 --- a/src/cython/example/euclidean_witness_complex_diagram_persistence_from_off_file_example.py +++ b/src/cython/example/euclidean_witness_complex_diagram_persistence_from_off_file_example.py @@ -40,7 +40,7 @@ parser.add_argument("-f", "--file", type=str, required=True) parser.add_argument("-a", "--max_alpha_square", type=float, required=True) parser.add_argument("-n", "--number_of_landmarks", type=int, required=True) parser.add_argument("-d", "--limit_dimension", type=int, required=True) -parser.add_argument("-b", "--band_boot", type=float, default=0.) +parser.add_argument("-b", "--band", type=float, default=0.) parser.add_argument('--no-diagram', default=False, action='store_true' , help='Flag for not to display the diagrams') args = parser.parse_args() @@ -71,7 +71,7 @@ with open(args.file, 'r') as f: print(simplex_tree.betti_numbers()) if args.no_diagram == False: - pplot = gudhi.plot_persistence_diagram(diag, band_boot=args.band_boot) + pplot = gudhi.plot_persistence_diagram(diag, band=args.band) pplot.show() else: print(args.file, "is not a valid OFF file") diff --git a/src/cython/example/gudhi_graphical_tools_example.py b/src/cython/example/gudhi_graphical_tools_example.py index 9f37efc0..ac3d146c 100755 --- a/src/cython/example/gudhi_graphical_tools_example.py +++ b/src/cython/example/gudhi_graphical_tools_example.py @@ -29,11 +29,6 @@ __copyright__ = "Copyright (C) 2016 Inria" __license__ = "GPL v3" print("#####################################################################") -print("Show palette colors values for dimension") - -gudhi.show_palette_values() - -print("#####################################################################") print("Show barcode persistence example") persistence = [(2, (1.0, float('inf'))), (1, (1.4142135623730951, float('inf'))), @@ -50,5 +45,5 @@ pplot.show() print("#####################################################################") print("Show diagram persistence example with a confidence band") -pplot = gudhi.plot_persistence_diagram(persistence, band_boot=0.2) +pplot = gudhi.plot_persistence_diagram(persistence, band=0.2) pplot.show() diff --git a/src/cython/example/rips_complex_diagram_persistence_from_correlation_matrix_file_example.py b/src/cython/example/rips_complex_diagram_persistence_from_correlation_matrix_file_example.py index 4142fa99..0c9dfc43 100755 --- a/src/cython/example/rips_complex_diagram_persistence_from_correlation_matrix_file_example.py +++ b/src/cython/example/rips_complex_diagram_persistence_from_correlation_matrix_file_example.py @@ -40,7 +40,7 @@ parser = argparse.ArgumentParser(description='RipsComplex creation from ' parser.add_argument("-f", "--file", type=str, required=True) parser.add_argument("-c", "--min_edge_correlation", type=float, default=0.5) parser.add_argument("-d", "--max_dimension", type=int, default=1) -parser.add_argument("-b", "--band_boot", type=float, default=0.) +parser.add_argument("-b", "--band", type=float, default=0.) parser.add_argument('--no-diagram', default=False, action='store_true' , help='Flag for not to display the diagrams') args = parser.parse_args() @@ -80,5 +80,5 @@ print(simplex_tree.betti_numbers()) invert_diag = [(diag[pers][0],(1.-diag[pers][1][0], 1.-diag[pers][1][1])) for pers in range(len(diag))] if args.no_diagram == False: - pplot = gudhi.plot_persistence_diagram(invert_diag, band_boot=args.band_boot) + pplot = gudhi.plot_persistence_diagram(invert_diag, band=args.band) pplot.show() diff --git a/src/cython/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py b/src/cython/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py index 01d1f38a..4d2ed577 100755 --- a/src/cython/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py +++ b/src/cython/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py @@ -39,7 +39,7 @@ parser = argparse.ArgumentParser(description='RipsComplex creation from ' parser.add_argument("-f", "--file", type=str, required=True) parser.add_argument("-e", "--max_edge_length", type=float, default=0.5) parser.add_argument("-d", "--max_dimension", type=int, default=1) -parser.add_argument("-b", "--band_boot", type=float, default=0.) +parser.add_argument("-b", "--band", type=float, default=0.) parser.add_argument('--no-diagram', default=False, action='store_true' , help='Flag for not to display the diagrams') args = parser.parse_args() @@ -63,5 +63,5 @@ print("betti_numbers()=") print(simplex_tree.betti_numbers()) if args.no_diagram == False: - pplot = gudhi.plot_persistence_diagram(diag, band_boot=args.band_boot) + pplot = gudhi.plot_persistence_diagram(diag, band=args.band) pplot.show() diff --git a/src/cython/example/rips_complex_diagram_persistence_from_off_file_example.py b/src/cython/example/rips_complex_diagram_persistence_from_off_file_example.py index 865c66b6..d15d5eb0 100755 --- a/src/cython/example/rips_complex_diagram_persistence_from_off_file_example.py +++ b/src/cython/example/rips_complex_diagram_persistence_from_off_file_example.py @@ -39,7 +39,7 @@ parser = argparse.ArgumentParser(description='RipsComplex creation from ' parser.add_argument("-f", "--file", type=str, required=True) parser.add_argument("-e", "--max_edge_length", type=float, default=0.5) parser.add_argument("-d", "--max_dimension", type=int, default=1) -parser.add_argument("-b", "--band_boot", type=float, default=0.) +parser.add_argument("-b", "--band", type=float, default=0.) parser.add_argument('--no-diagram', default=False, action='store_true' , help='Flag for not to display the diagrams') args = parser.parse_args() @@ -66,7 +66,7 @@ with open(args.file, 'r') as f: print(simplex_tree.betti_numbers()) if args.no_diagram == False: - pplot = gudhi.plot_persistence_diagram(diag, band_boot=args.band_boot) + pplot = gudhi.plot_persistence_diagram(diag, band=args.band) pplot.show() else: print(args.file, "is not a valid OFF file") diff --git a/src/cython/example/tangential_complex_plain_homology_from_off_file_example.py b/src/cython/example/tangential_complex_plain_homology_from_off_file_example.py index 680a8bf8..0f8f5e80 100755 --- a/src/cython/example/tangential_complex_plain_homology_from_off_file_example.py +++ b/src/cython/example/tangential_complex_plain_homology_from_off_file_example.py @@ -33,11 +33,12 @@ parser = argparse.ArgumentParser(description='TangentialComplex creation from ' 'points read in a OFF file.', epilog='Example: ' 'example/tangential_complex_plain_homology_from_off_file_example.py ' - '-f ../data/points/tore3D_300.off' + '-f ../data/points/tore3D_300.off -i 3' '- Constructs a tangential complex with the ' 'points from the given OFF file') parser.add_argument("-f", "--file", type=str, required=True) -parser.add_argument("-b", "--band_boot", type=float, default=0.) +parser.add_argument("-i", "--intrisic_dim", type=int, required=True) +parser.add_argument("-b", "--band", type=float, default=0.) parser.add_argument('--no-diagram', default=False, action='store_true' , help='Flag for not to display the diagrams') args = parser.parse_args() @@ -48,7 +49,7 @@ with open(args.file, 'r') as f: print("#####################################################################") print("TangentialComplex creation from points read in a OFF file") - tc = gudhi.TangentialComplex(off_file=args.file) + tc = gudhi.TangentialComplex(intrisic_dim = args.intrisic_dim, off_file=args.file) st = tc.create_simplex_tree() message = "Number of simplices=" + repr(st.num_simplices()) @@ -60,7 +61,7 @@ with open(args.file, 'r') as f: print(st.betti_numbers()) if args.no_diagram == False: - pplot = gudhi.plot_persistence_diagram(diag, band_boot=args.band_boot) + pplot = gudhi.plot_persistence_diagram(diag, band=args.band) pplot.show() else: print(args.file, "is not a valid OFF file") diff --git a/src/cython/include/Persistent_cohomology_interface.h b/src/cython/include/Persistent_cohomology_interface.h index a86b1187..dee5e487 100644 --- a/src/cython/include/Persistent_cohomology_interface.h +++ b/src/cython/include/Persistent_cohomology_interface.h @@ -85,6 +85,32 @@ persistent_cohomology::Persistent_cohomology<FilteredComplex, persistent_cohomol return persistence; } + std::vector<std::pair<std::vector<int>, std::vector<int>>> persistence_pairs() { + auto pairs = persistent_cohomology::Persistent_cohomology<FilteredComplex, + persistent_cohomology::Field_Zp>::get_persistent_pairs(); + + std::vector<std::pair<std::vector<int>, std::vector<int>>> persistence_pairs; + persistence_pairs.reserve(pairs.size()); + for (auto pair : pairs) { + std::vector<int> birth; + if (get<0>(pair) != stptr_->null_simplex()) { + for (auto vertex : stptr_->simplex_vertex_range(get<0>(pair))) { + birth.push_back(vertex); + } + } + + std::vector<int> death; + if (get<1>(pair) != stptr_->null_simplex()) { + for (auto vertex : stptr_->simplex_vertex_range(get<1>(pair))) { + death.push_back(vertex); + } + } + + persistence_pairs.push_back(std::make_pair(birth,death)); + } + return persistence_pairs; + } + private: // A copy FilteredComplex* stptr_; diff --git a/src/cython/include/Tangential_complex_interface.h b/src/cython/include/Tangential_complex_interface.h index 2772460a..71418886 100644 --- a/src/cython/include/Tangential_complex_interface.h +++ b/src/cython/include/Tangential_complex_interface.h @@ -45,24 +45,19 @@ class Tangential_complex_interface { using TC = Tangential_complex<Dynamic_kernel, CGAL::Dynamic_dimension_tag, CGAL::Parallel_tag>; public: - Tangential_complex_interface(const std::vector<std::vector<double>>& points) { + Tangential_complex_interface(int intrisic_dim, const std::vector<std::vector<double>>& points) { Dynamic_kernel k; - unsigned intrisic_dim = 0; - if (points.size() > 0) - intrisic_dim = points[0].size() - 1; tangential_complex_ = new TC(points, intrisic_dim, k); tangential_complex_->compute_tangential_complex(); num_inconsistencies_ = tangential_complex_->number_of_inconsistent_simplices(); } - Tangential_complex_interface(const std::string& off_file_name, bool from_file = true) { - Gudhi::Points_off_reader<Point_d> off_reader(off_file_name); + Tangential_complex_interface(int intrisic_dim, const std::string& off_file_name, bool from_file = true) { Dynamic_kernel k; - unsigned intrisic_dim = 0; + + Gudhi::Points_off_reader<Point_d> off_reader(off_file_name); std::vector<Point_d> points = off_reader.get_point_cloud(); - if (points.size() > 0) - intrisic_dim = points[0].size() - 1; tangential_complex_ = new TC(points, intrisic_dim, k); tangential_complex_->compute_tangential_complex(); diff --git a/src/cython/setup.py.in b/src/cython/setup.py.in index b6ca4bcb..a798717d 100644 --- a/src/cython/setup.py.in +++ b/src/cython/setup.py.in @@ -46,4 +46,11 @@ setup( version='@GUDHI_VERSION@', url='http://gudhi.gforge.inria.fr/', ext_modules = cythonize(gudhi), + + #install_requires = required, + install_requires = [ + "matplotlib", + "numpy", + "cython", + ], ) diff --git a/src/cython/test/test_simplex_tree.py b/src/cython/test/test_simplex_tree.py index 029e7729..cb701c9a 100755 --- a/src/cython/test/test_simplex_tree.py +++ b/src/cython/test/test_simplex_tree.py @@ -161,3 +161,47 @@ def test_automatic_dimension(): assert st.upper_bound_dimension() == 2 assert st.dimension() == 1 assert st.upper_bound_dimension() == 1 + +def test_make_filtration_non_decreasing(): + st = SimplexTree() + assert st.__is_defined() == True + assert st.__is_persistence_defined() == False + + # Inserted simplex: + # 1 + # o + # /X\ + # o---o---o---o + # 2 0 3\X/4 + # o + # 5 + assert st.insert([2, 1, 0], filtration=2.0) == True + assert st.insert([3, 0], filtration=2.0) == True + assert st.insert([3, 4, 5], filtration=2.0) == True + + assert st.make_filtration_non_decreasing() == False + + # Because of non decreasing property of simplex tree, { 0 } , { 1 } and + # { 0, 1 } are going to be set from value 2.0 to 1.0 + st.insert([0, 1, 6, 7], filtration=1.0); + + assert st.make_filtration_non_decreasing() == False + + # Modify specific values to test make_filtration_non_decreasing + st.assign_filtration([0,1,6,7], 0.8); + st.assign_filtration([0,1,6], 0.9); + st.assign_filtration([0,6], 0.6); + st.assign_filtration([3,4,5], 1.2); + st.assign_filtration([3,4], 1.1); + st.assign_filtration([4,5], 1.99); + + assert st.make_filtration_non_decreasing() == True + + assert st.filtration([0,1,6,7]) == 1. + assert st.filtration([0,1,6]) == 1. + assert st.filtration([0,1]) == 1. + assert st.filtration([0]) == 1. + assert st.filtration([1]) == 1. + assert st.filtration([3,4,5]) == 2. + assert st.filtration([3,4]) == 2. + assert st.filtration([4,5]) == 2. diff --git a/src/cython/test/test_tangential_complex.py b/src/cython/test/test_tangential_complex.py index fe623c7b..5385a0d3 100755 --- a/src/cython/test/test_tangential_complex.py +++ b/src/cython/test/test_tangential_complex.py @@ -29,7 +29,7 @@ __license__ = "GPL v3" def test_tangential(): point_list = [[0.0, 0.0], [1.0, 0.0], [0.0, 1.0], [1.0, 1.0]] - tc = TangentialComplex(points=point_list) + tc = TangentialComplex(intrisic_dim = 1, points=point_list) assert tc.__is_defined() == True assert tc.num_vertices() == 4 |