summaryrefslogtreecommitdiff
path: root/src/python/gudhi
diff options
context:
space:
mode:
authortlacombe <lacombe1993@gmail.com>2020-03-31 12:53:42 +0200
committertlacombe <lacombe1993@gmail.com>2020-03-31 12:53:42 +0200
commite6c21aa957bbf66854f31824cd4313c61f7ea9fc (patch)
tree091c246f585e5836a2b1868414227d3d12938eaa /src/python/gudhi
parentdae83f0907a5bd94cb483ad0f54755da2d49fb75 (diff)
parent2f46606b406aafc69e37a68dca33e1858ab7b817 (diff)
merged master
Diffstat (limited to 'src/python/gudhi')
-rw-r--r--src/python/gudhi/alpha_complex.pyx10
-rw-r--r--src/python/gudhi/cubical_complex.pyx17
-rw-r--r--src/python/gudhi/nerve_gic.pyx37
-rw-r--r--src/python/gudhi/off_reader.pyx12
-rw-r--r--src/python/gudhi/periodic_cubical_complex.pyx8
-rw-r--r--src/python/gudhi/simplex_tree.pxd2
-rw-r--r--src/python/gudhi/simplex_tree.pyx51
7 files changed, 109 insertions, 28 deletions
diff --git a/src/python/gudhi/alpha_complex.pyx b/src/python/gudhi/alpha_complex.pyx
index fff3e920..e04dc652 100644
--- a/src/python/gudhi/alpha_complex.pyx
+++ b/src/python/gudhi/alpha_complex.pyx
@@ -1,5 +1,7 @@
-# This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT.
-# See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details.
+# This file is part of the Gudhi Library - https://gudhi.inria.fr/ -
+# which is released under MIT.
+# See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full
+# license details.
# Author(s): Vincent Rouvreau
#
# Copyright (C) 2016 Inria
@@ -7,6 +9,7 @@
# Modification(s):
# - YYYY/MM Author: Description of the modification
+from __future__ import print_function
from cython cimport numeric
from libcpp.vector cimport vector
from libcpp.utility cimport pair
@@ -69,7 +72,8 @@ cdef class AlphaComplex:
def __cinit__(self, points = None, off_file = ''):
if off_file:
if os.path.isfile(off_file):
- self.thisptr = new Alpha_complex_interface(off_file.encode('utf-8'), True)
+ self.thisptr = new Alpha_complex_interface(
+ off_file.encode('utf-8'), True)
else:
print("file " + off_file + " not found.")
else:
diff --git a/src/python/gudhi/cubical_complex.pyx b/src/python/gudhi/cubical_complex.pyx
index cbeda014..d5ad1266 100644
--- a/src/python/gudhi/cubical_complex.pyx
+++ b/src/python/gudhi/cubical_complex.pyx
@@ -1,5 +1,7 @@
-# This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT.
-# See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details.
+# This file is part of the Gudhi Library - https://gudhi.inria.fr/ -
+# which is released under MIT.
+# See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full
+# license details.
# Author(s): Vincent Rouvreau
#
# Copyright (C) 2016 Inria
@@ -7,12 +9,15 @@
# Modification(s):
# - YYYY/MM Author: Description of the modification
+from __future__ import print_function
from cython cimport numeric
from libcpp.vector cimport vector
from libcpp.utility cimport pair
from libcpp.string cimport string
from libcpp cimport bool
+import errno
import os
+import sys
import numpy as np
@@ -87,10 +92,12 @@ cdef class CubicalComplex:
if os.path.isfile(perseus_file):
self.thisptr = new Bitmap_cubical_complex_base_interface(perseus_file.encode('utf-8'))
else:
- print("file " + perseus_file + " not found.")
+ raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT),
+ perseus_file)
else:
print("CubicalComplex can be constructed from dimensions and "
- "top_dimensional_cells or from a Perseus-style file name.")
+ "top_dimensional_cells or from a Perseus-style file name.",
+ file=sys.stderr)
def __dealloc__(self):
if self.thisptr != NULL:
@@ -199,5 +206,5 @@ cdef class CubicalComplex:
intervals_result = self.pcohptr.intervals_in_dimension(dimension)
else:
print("intervals_in_dim function requires persistence function"
- " to be launched first.")
+ " to be launched first.", file=sys.stderr)
return np.array(intervals_result)
diff --git a/src/python/gudhi/nerve_gic.pyx b/src/python/gudhi/nerve_gic.pyx
index 45cc8eba..9c89b239 100644
--- a/src/python/gudhi/nerve_gic.pyx
+++ b/src/python/gudhi/nerve_gic.pyx
@@ -1,5 +1,7 @@
-# This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT.
-# See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details.
+# This file is part of the Gudhi Library - https://gudhi.inria.fr/ -
+# which is released under MIT.
+# See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full
+# license details.
# Author(s): Vincent Rouvreau
#
# Copyright (C) 2018 Inria
@@ -7,11 +9,13 @@
# Modification(s):
# - YYYY/MM Author: Description of the modification
+from __future__ import print_function
from cython cimport numeric
from libcpp.vector cimport vector
from libcpp.utility cimport pair
from libcpp.string cimport string
from libcpp cimport bool
+import errno
import os
from libc.stdint cimport intptr_t
@@ -96,7 +100,8 @@ cdef class CoverComplex:
return self.thisptr != NULL
def set_point_cloud_from_range(self, cloud):
- """ Reads and stores the input point cloud from a vector stored in memory.
+ """ Reads and stores the input point cloud from a vector stored in
+ memory.
:param cloud: Input vector containing the point cloud.
:type cloud: vector[vector[double]]
@@ -104,7 +109,8 @@ cdef class CoverComplex:
return self.thisptr.set_point_cloud_from_range(cloud)
def set_distances_from_range(self, distance_matrix):
- """ Reads and stores the input distance matrix from a vector stored in memory.
+ """ Reads and stores the input distance matrix from a vector stored in
+ memory.
:param distance_matrix: Input vector containing the distance matrix.
:type distance_matrix: vector[vector[double]]
@@ -163,7 +169,8 @@ cdef class CoverComplex:
"""
stree = SimplexTree()
cdef intptr_t stree_int_ptr=stree.thisptr
- self.thisptr.create_simplex_tree(<Simplex_tree_interface_full_featured*>stree_int_ptr)
+ self.thisptr.create_simplex_tree(
+ <Simplex_tree_interface_full_featured*>stree_int_ptr)
return stree
def find_simplices(self):
@@ -182,8 +189,8 @@ cdef class CoverComplex:
if os.path.isfile(off_file):
return self.thisptr.read_point_cloud(off_file.encode('utf-8'))
else:
- print("file " + off_file + " not found.")
- return False
+ raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT),
+ off_file)
def set_automatic_resolution(self):
"""Computes the optimal length of intervals (i.e. the smallest interval
@@ -214,7 +221,8 @@ cdef class CoverComplex:
if os.path.isfile(color_file_name):
self.thisptr.set_color_from_file(color_file_name.encode('utf-8'))
else:
- print("file " + color_file_name + " not found.")
+ raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT),
+ color_file_name)
def set_color_from_range(self, color):
"""Computes the function used to color the nodes of the simplicial
@@ -235,7 +243,8 @@ cdef class CoverComplex:
if os.path.isfile(cover_file_name):
self.thisptr.set_cover_from_file(cover_file_name.encode('utf-8'))
else:
- print("file " + cover_file_name + " not found.")
+ raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT),
+ cover_file_name)
def set_cover_from_function(self):
"""Creates a cover C from the preimages of the function f.
@@ -268,7 +277,8 @@ cdef class CoverComplex:
if os.path.isfile(func_file_name):
self.thisptr.set_function_from_file(func_file_name.encode('utf-8'))
else:
- print("file " + func_file_name + " not found.")
+ raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT),
+ func_file_name)
def set_function_from_range(self, function):
"""Creates the function f from a vector stored in memory.
@@ -302,14 +312,15 @@ cdef class CoverComplex:
"""Creates a graph G from a file containing the edges.
:param graph_file_name: Name of the input graph file. The graph file
- contains one edge per line, each edge being represented by the IDs of
- its two nodes.
+ contains one edge per line, each edge being represented by the IDs
+ of its two nodes.
:type graph_file_name: string
"""
if os.path.isfile(graph_file_name):
self.thisptr.set_graph_from_file(graph_file_name.encode('utf-8'))
else:
- print("file " + graph_file_name + " not found.")
+ raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT),
+ graph_file_name)
def set_graph_from_OFF(self):
"""Creates a graph G from the triangulation given by the input OFF
diff --git a/src/python/gudhi/off_reader.pyx b/src/python/gudhi/off_reader.pyx
index 7e6d9d80..a3200704 100644
--- a/src/python/gudhi/off_reader.pyx
+++ b/src/python/gudhi/off_reader.pyx
@@ -1,5 +1,7 @@
-# This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT.
-# See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details.
+# This file is part of the Gudhi Library - https://gudhi.inria.fr/ -
+# which is released under MIT.
+# See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full
+# license details.
# Author(s): Vincent Rouvreau
#
# Copyright (C) 2016 Inria
@@ -7,9 +9,11 @@
# Modification(s):
# - YYYY/MM Author: Description of the modification
+from __future__ import print_function
from cython cimport numeric
from libcpp.vector cimport vector
from libcpp.string cimport string
+import errno
import os
__author__ = "Vincent Rouvreau"
@@ -32,6 +36,6 @@ def read_points_from_off_file(off_file=''):
if os.path.isfile(off_file):
return read_points_from_OFF_file(off_file.encode('utf-8'))
else:
- print("file " + off_file + " not found.")
- return []
+ raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT),
+ off_file)
diff --git a/src/python/gudhi/periodic_cubical_complex.pyx b/src/python/gudhi/periodic_cubical_complex.pyx
index 37f76201..fd08b976 100644
--- a/src/python/gudhi/periodic_cubical_complex.pyx
+++ b/src/python/gudhi/periodic_cubical_complex.pyx
@@ -7,11 +7,13 @@
# Modification(s):
# - YYYY/MM Author: Description of the modification
+from __future__ import print_function
from cython cimport numeric
from libcpp.vector cimport vector
from libcpp.utility cimport pair
from libcpp.string cimport string
from libcpp cimport bool
+import sys
import os
import numpy as np
@@ -95,12 +97,12 @@ cdef class PeriodicCubicalComplex:
if os.path.isfile(perseus_file):
self.thisptr = new Periodic_cubical_complex_base_interface(perseus_file.encode('utf-8'))
else:
- print("file " + perseus_file + " not found.")
+ print("file " + perseus_file + " not found.", file=sys.stderr)
else:
print("CubicalComplex can be constructed from dimensions, "
"top_dimensional_cells and periodic_dimensions, or from "
"top_dimensional_cells and periodic_dimensions or from "
- "a Perseus-style file name.")
+ "a Perseus-style file name.", file=sys.stderr)
def __dealloc__(self):
if self.thisptr != NULL:
@@ -209,5 +211,5 @@ cdef class PeriodicCubicalComplex:
intervals_result = self.pcohptr.intervals_in_dimension(dimension)
else:
print("intervals_in_dim function requires persistence function"
- " to be launched first.")
+ " to be launched first.", file=sys.stderr)
return np.array(intervals_result)
diff --git a/src/python/gudhi/simplex_tree.pxd b/src/python/gudhi/simplex_tree.pxd
index 82f155de..595f22bb 100644
--- a/src/python/gudhi/simplex_tree.pxd
+++ b/src/python/gudhi/simplex_tree.pxd
@@ -57,6 +57,8 @@ cdef extern from "Simplex_tree_interface.h" namespace "Gudhi":
void remove_maximal_simplex(vector[int] simplex)
bool prune_above_filtration(double filtration)
bool make_filtration_non_decreasing()
+ void compute_extended_filtration()
+ vector[vector[pair[int, pair[double, double]]]] compute_extended_persistence_subdiagrams(vector[pair[int, pair[double, double]]] dgm, double min_persistence)
# Iterators over Simplex tree
pair[vector[int], double] get_simplex_and_filtration(Simplex_tree_simplex_handle f_simplex)
Simplex_tree_simplices_iterator get_simplices_iterator_begin()
diff --git a/src/python/gudhi/simplex_tree.pyx b/src/python/gudhi/simplex_tree.pyx
index c01cc905..cc3753e1 100644
--- a/src/python/gudhi/simplex_tree.pyx
+++ b/src/python/gudhi/simplex_tree.pyx
@@ -396,6 +396,57 @@ cdef class SimplexTree:
"""
return self.get_ptr().make_filtration_non_decreasing()
+ def extend_filtration(self):
+ """ Extend filtration for computing extended persistence. This function only uses the
+ filtration values at the 0-dimensional simplices, and computes the extended persistence
+ diagram induced by the lower-star filtration computed with these values.
+
+ .. note::
+
+ Note that after calling this function, the filtration
+ values are actually modified within the Simplex_tree.
+ The function :func:`extended_persistence()<gudhi.SimplexTree.extended_persistence>`
+ retrieves the original values.
+
+ .. note::
+
+ Note that this code creates an extra vertex internally, so you should make sure that
+ the Simplex_tree does not contain a vertex with the largest possible value (i.e., 4294967295).
+ """
+ return self.get_ptr().compute_extended_filtration()
+
+ def extended_persistence(self, homology_coeff_field=11, min_persistence=0):
+ """This function retrieves good values for extended persistence, and separate the diagrams
+ into the Ordinary, Relative, Extended+ and Extended- subdiagrams.
+
+ :param homology_coeff_field: The homology coefficient field. Must be a
+ prime number. Default value is 11.
+ :type homology_coeff_field: int.
+ :param min_persistence: The minimum persistence value (i.e., the absolute value of the difference between the persistence diagram point coordinates) 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: A list of four persistence diagrams in the format described in :func:`persistence()<gudhi.SimplexTree.persistence>`. The first one is Ordinary, the second one is Relative, the third one is Extended+ and the fourth one is Extended-. See https://link.springer.com/article/10.1007/s10208-008-9027-z and/or section 2.2 in https://link.springer.com/article/10.1007/s10208-017-9370-z for a description of these subtypes.
+
+ .. note::
+
+ This function should be called only if :func:`extend_filtration()<gudhi.SimplexTree.extend_filtration>` has been called first!
+
+ .. note::
+
+ The coordinates of the persistence diagram points might be a little different than the
+ original filtration values due to the internal transformation (scaling to [-2,-1]) that is
+ performed on these values during the computation of extended persistence.
+ """
+ cdef vector[pair[int, pair[double, double]]] persistence_result
+ if self.pcohptr != NULL:
+ del self.pcohptr
+ self.pcohptr = new Simplex_tree_persistence_interface(self.get_ptr(), False)
+ persistence_result = self.pcohptr.get_persistence(homology_coeff_field, -1.)
+ return self.get_ptr().compute_extended_persistence_subdiagrams(persistence_result, min_persistence)
+
+
def persistence(self, homology_coeff_field=11, min_persistence=0, persistence_dim_max = False):
"""This function returns the persistence of the simplicial complex.