summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorROUVREAU Vincent <vincent.rouvreau@inria.fr>2021-03-24 15:27:11 +0100
committerROUVREAU Vincent <vincent.rouvreau@inria.fr>2021-03-24 15:27:11 +0100
commit77e577eb28ca7622553cd0527db76d46b473c445 (patch)
tree74c279ec1b90292a2df33dbe7a4dca0a6673af71 /src
parent0f19f5ecd180ac92458d5257696f1f367de54ca8 (diff)
Remove read_weights and depreciate off_file
Diffstat (limited to 'src')
-rw-r--r--src/python/doc/alpha_complex_user.rst8
-rwxr-xr-xsrc/python/example/alpha_complex_diagram_persistence_from_off_file_example.py55
-rwxr-xr-xsrc/python/example/alpha_rips_persistence_bottleneck_distance.py110
-rwxr-xr-xsrc/python/example/plot_alpha_complex.py5
-rw-r--r--src/python/gudhi/alpha_complex.pyx30
-rw-r--r--src/python/gudhi/reader_utils.pyx16
-rwxr-xr-xsrc/python/test/test_alpha_complex.py116
-rwxr-xr-xsrc/python/test/test_reader_utils.py16
8 files changed, 128 insertions, 228 deletions
diff --git a/src/python/doc/alpha_complex_user.rst b/src/python/doc/alpha_complex_user.rst
index f59f69e7..2b4b75cf 100644
--- a/src/python/doc/alpha_complex_user.rst
+++ b/src/python/doc/alpha_complex_user.rst
@@ -243,7 +243,8 @@ The output is:
Example from OFF file
^^^^^^^^^^^^^^^^^^^^^
-This example builds the alpha complex from 300 random points on a 2-torus, given by an `OFF file <fileformats.html#off-file-format>`_.
+This example builds the alpha complex from 300 random points on a 2-torus, given by an
+`OFF file <fileformats.html#off-file-format>`_.
Then, it computes the persistence diagram and displays it:
@@ -252,8 +253,9 @@ Then, it computes the persistence diagram and displays it:
import matplotlib.pyplot as plt
import gudhi as gd
- ac = gd.AlphaComplex(off_file=gd.__root_source_dir__ + '/data/points/tore3D_300.off')
- stree = ac.create_simplex_tree()
+ off_file = gd.__root_source_dir__ + '/data/points/tore3D_300.off'
+ points = gd.read_points_from_off_file(off_file = off_file)
+ stree = gd.AlphaComplex(points = points).create_simplex_tree()
dgm = stree.persistence()
gd.plot_persistence_diagram(dgm, legend = True)
plt.show()
diff --git a/src/python/example/alpha_complex_diagram_persistence_from_off_file_example.py b/src/python/example/alpha_complex_diagram_persistence_from_off_file_example.py
index fe03be31..c96121a6 100755
--- a/src/python/example/alpha_complex_diagram_persistence_from_off_file_example.py
+++ b/src/python/example/alpha_complex_diagram_persistence_from_off_file_example.py
@@ -1,9 +1,7 @@
#!/usr/bin/env python
import argparse
-import errno
-import os
-import gudhi
+import gudhi as gd
""" This file is part of the Gudhi Library - https://gudhi.inria.fr/ -
which is released under MIT.
@@ -41,33 +39,24 @@ parser.add_argument(
args = parser.parse_args()
-with open(args.file, "r") as f:
- first_line = f.readline()
- if (first_line == "OFF\n") or (first_line == "nOFF\n"):
- print("##############################################################")
- print("AlphaComplex creation from points read in a OFF file")
-
- alpha_complex = gudhi.AlphaComplex(off_file=args.file)
- if args.max_alpha_square is not None:
- print("with max_edge_length=", args.max_alpha_square)
- simplex_tree = alpha_complex.create_simplex_tree(
- max_alpha_square=args.max_alpha_square
- )
- else:
- simplex_tree = alpha_complex.create_simplex_tree()
-
- print("Number of simplices=", simplex_tree.num_simplices())
-
- diag = simplex_tree.persistence()
-
- print("betti_numbers()=", simplex_tree.betti_numbers())
-
- if args.no_diagram == False:
- import matplotlib.pyplot as plot
- gudhi.plot_persistence_diagram(diag, band=args.band)
- plot.show()
- else:
- raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT),
- args.file)
-
- f.close()
+print("##############################################################")
+print("AlphaComplex creation from points read in a OFF file")
+
+points = gd.read_points_from_off_file(off_file = args.file)
+alpha_complex = gd.AlphaComplex(points = points)
+if args.max_alpha_square is not None:
+ print("with max_edge_length=", args.max_alpha_square)
+ simplex_tree = alpha_complex.create_simplex_tree(
+ max_alpha_square=args.max_alpha_square
+ )
+else:
+ simplex_tree = alpha_complex.create_simplex_tree()
+
+print("Number of simplices=", simplex_tree.num_simplices())
+
+diag = simplex_tree.persistence()
+print("betti_numbers()=", simplex_tree.betti_numbers())
+if args.no_diagram == False:
+ import matplotlib.pyplot as plot
+ gd.plot_persistence_diagram(diag, band=args.band)
+ plot.show()
diff --git a/src/python/example/alpha_rips_persistence_bottleneck_distance.py b/src/python/example/alpha_rips_persistence_bottleneck_distance.py
index 3e12b0d5..6b97fb3b 100755
--- a/src/python/example/alpha_rips_persistence_bottleneck_distance.py
+++ b/src/python/example/alpha_rips_persistence_bottleneck_distance.py
@@ -1,10 +1,8 @@
#!/usr/bin/env python
-import gudhi
+import gudhi as gd
import argparse
import math
-import errno
-import os
import numpy as np
""" This file is part of the Gudhi Library - https://gudhi.inria.fr/ -
@@ -37,70 +35,60 @@ parser.add_argument("-t", "--threshold", type=float, default=0.5)
parser.add_argument("-d", "--max_dimension", type=int, default=1)
args = parser.parse_args()
-with open(args.file, "r") as f:
- first_line = f.readline()
- if (first_line == "OFF\n") or (first_line == "nOFF\n"):
- point_cloud = gudhi.read_points_from_off_file(off_file=args.file)
- print("##############################################################")
- print("RipsComplex creation from points read in a OFF file")
+point_cloud = gd.read_points_from_off_file(off_file=args.file)
+print("##############################################################")
+print("RipsComplex creation from points read in a OFF file")
- message = "RipsComplex with max_edge_length=" + repr(args.threshold)
- print(message)
+message = "RipsComplex with max_edge_length=" + repr(args.threshold)
+print(message)
- rips_complex = gudhi.RipsComplex(
- points=point_cloud, max_edge_length=args.threshold
- )
-
- rips_stree = rips_complex.create_simplex_tree(
- max_dimension=args.max_dimension)
-
- message = "Number of simplices=" + repr(rips_stree.num_simplices())
- print(message)
-
- rips_stree.compute_persistence()
-
- print("##############################################################")
- print("AlphaComplex creation from points read in a OFF file")
-
- message = "AlphaComplex with max_edge_length=" + repr(args.threshold)
- print(message)
-
- alpha_complex = gudhi.AlphaComplex(points=point_cloud)
- alpha_stree = alpha_complex.create_simplex_tree(
- max_alpha_square=(args.threshold * args.threshold)
- )
-
- message = "Number of simplices=" + repr(alpha_stree.num_simplices())
- print(message)
+rips_complex = gd.RipsComplex(
+ points=point_cloud, max_edge_length=args.threshold
+)
- alpha_stree.compute_persistence()
+rips_stree = rips_complex.create_simplex_tree(
+ max_dimension=args.max_dimension)
- max_b_distance = 0.0
- for dim in range(args.max_dimension):
- # Alpha persistence values needs to be transform because filtration
- # values are alpha square values
- alpha_intervals = np.sqrt(alpha_stree.persistence_intervals_in_dimension(dim))
+message = "Number of simplices=" + repr(rips_stree.num_simplices())
+print(message)
- rips_intervals = rips_stree.persistence_intervals_in_dimension(dim)
- bottleneck_distance = gudhi.bottleneck_distance(
- rips_intervals, alpha_intervals
- )
- message = (
- "In dimension "
- + repr(dim)
- + ", bottleneck distance = "
- + repr(bottleneck_distance)
- )
- print(message)
- max_b_distance = max(bottleneck_distance, max_b_distance)
+rips_stree.compute_persistence()
- print("==============================================================")
- message = "Bottleneck distance is " + repr(max_b_distance)
- print(message)
+print("##############################################################")
+print("AlphaComplex creation from points read in a OFF file")
- else:
- raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT),
- args.file)
+message = "AlphaComplex with max_edge_length=" + repr(args.threshold)
+print(message)
+alpha_complex = gd.AlphaComplex(points=point_cloud)
+alpha_stree = alpha_complex.create_simplex_tree(
+ max_alpha_square=(args.threshold * args.threshold)
+)
- f.close()
+message = "Number of simplices=" + repr(alpha_stree.num_simplices())
+print(message)
+
+alpha_stree.compute_persistence()
+
+max_b_distance = 0.0
+for dim in range(args.max_dimension):
+ # Alpha persistence values needs to be transform because filtration
+ # values are alpha square values
+ alpha_intervals = np.sqrt(alpha_stree.persistence_intervals_in_dimension(dim))
+
+ rips_intervals = rips_stree.persistence_intervals_in_dimension(dim)
+ bottleneck_distance = gd.bottleneck_distance(
+ rips_intervals, alpha_intervals
+ )
+ message = (
+ "In dimension "
+ + repr(dim)
+ + ", bottleneck distance = "
+ + repr(bottleneck_distance)
+ )
+ print(message)
+ max_b_distance = max(bottleneck_distance, max_b_distance)
+
+print("==============================================================")
+message = "Bottleneck distance is " + repr(max_b_distance)
+print(message)
diff --git a/src/python/example/plot_alpha_complex.py b/src/python/example/plot_alpha_complex.py
index 99c18a7c..0924619b 100755
--- a/src/python/example/plot_alpha_complex.py
+++ b/src/python/example/plot_alpha_complex.py
@@ -1,8 +1,9 @@
#!/usr/bin/env python
import numpy as np
-import gudhi
-ac = gudhi.AlphaComplex(off_file='../../data/points/tore3D_1307.off')
+import gudhi as gd
+points = gd.read_points_from_off_file(off_file = '../../data/points/tore3D_1307.off')
+ac = gd.AlphaComplex(points = points)
st = ac.create_simplex_tree()
points = np.array([ac.get_point(i) for i in range(st.num_vertices())])
# We want to plot the alpha-complex with alpha=0.1.
diff --git a/src/python/gudhi/alpha_complex.pyx b/src/python/gudhi/alpha_complex.pyx
index 9c364b76..5d181391 100644
--- a/src/python/gudhi/alpha_complex.pyx
+++ b/src/python/gudhi/alpha_complex.pyx
@@ -18,10 +18,11 @@ from libcpp cimport bool
from libc.stdint cimport intptr_t
import errno
import os
+import warnings
from gudhi.simplex_tree cimport *
from gudhi.simplex_tree import SimplexTree
-from gudhi import read_points_from_off_file, read_weights
+from gudhi import read_points_from_off_file
__author__ = "Vincent Rouvreau"
__copyright__ = "Copyright (C) 2016 Inria"
@@ -56,54 +57,45 @@ cdef class AlphaComplex:
cdef Alpha_complex_interface * this_ptr
# Fake constructor that does nothing but documenting the constructor
- def __init__(self, points=[], off_file='', weights=[], weight_file='', precision='safe'):
+ def __init__(self, points=[], off_file='', weights=[], precision='safe'):
"""AlphaComplex constructor.
:param points: A list of points in d-Dimension.
:type points: Iterable[Iterable[float]]
- :param off_file: An `OFF file style <fileformats.html#off-file-format>`_ name.
- If an `off_file` is given with `points` as arguments, only points from the
- file are taken into account.
+ :param off_file: **[deprecated]** An `OFF file style <fileformats.html#off-file-format>`_
+ name.
+ If an `off_file` is given with `points` as arguments, only points from the file are
+ taken into account.
:type off_file: string
:param weights: A list of weights. If set, the number of weights must correspond to the
number of points.
:type weights: Iterable[float]
- :param weight_file: A file containing a list of weights (one per line).
- If a `weight_file` is given with `weights` as arguments, only weights from the
- file are taken into account.
-
- :type weight_file: string
-
:param precision: Alpha complex precision can be 'fast', 'safe' or 'exact'. Default is
'safe'.
:type precision: string
- :raises FileNotFoundError: If `off_file` and/or `weight_file` is set but not found.
+ :raises FileNotFoundError: **[deprecated]** If `off_file` is set but not found.
:raises ValueError: In case of inconsistency between the number of points and weights.
"""
# The real cython constructor
- def __cinit__(self, points = [], off_file = '', weights=[], weight_file='', precision = 'safe'):
+ def __cinit__(self, points = [], off_file = '', weights=[], precision = 'safe'):
assert precision in ['fast', 'safe', 'exact'], \
"Alpha complex precision can only be 'fast', 'safe' or 'exact'"
cdef bool fast = precision == 'fast'
cdef bool exact = precision == 'exact'
if off_file:
+ warnings.warn("off_file is a deprecated parameter, please consider using gudhi.read_points_from_off_file",
+ DeprecationWarning)
if os.path.isfile(off_file):
points = read_points_from_off_file(off_file = off_file)
else:
raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT), off_file)
- if weight_file:
- if os.path.isfile(weight_file):
- weights = read_weights(weight_file = weight_file)
- else:
- raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT), weight_file)
-
# weights are set but is inconsistent with the number of points
if len(weights) != 0 and len(weights) != len(points):
raise ValueError("Inconsistency between the number of points and weights")
diff --git a/src/python/gudhi/reader_utils.pyx b/src/python/gudhi/reader_utils.pyx
index f997ad3e..fe1c3a2e 100644
--- a/src/python/gudhi/reader_utils.pyx
+++ b/src/python/gudhi/reader_utils.pyx
@@ -84,19 +84,3 @@ def read_persistence_intervals_in_dimension(persistence_file='', only_this_dim=-
'utf-8'), only_this_dim))
print("file " + persistence_file + " not set or not found.")
return []
-
-def read_weights(weight_file=''):
- """Reads a file containing weights. Only one float value per line is read and stored.
- The return value is a `list(weight)`.
-
- :param weight_file: A weight file style name (one weight per line).
- :type weight_file: string
-
- :returns: A list of weights.
- :rtype: List[float]
- """
- weights=[]
- with open(weight_file, 'r') as wfile:
- weights = [float(wline) for wline in wfile if wline.strip()]
- return weights
-
diff --git a/src/python/test/test_alpha_complex.py b/src/python/test/test_alpha_complex.py
index a0de46c3..e0f2b5df 100755
--- a/src/python/test/test_alpha_complex.py
+++ b/src/python/test/test_alpha_complex.py
@@ -12,6 +12,8 @@ import gudhi as gd
import math
import numpy as np
import pytest
+import warnings
+
try:
# python3
from itertools import zip_longest
@@ -203,7 +205,13 @@ def test_delaunay_complex():
_delaunay_complex(precision)
def _3d_points_on_a_plane(precision, default_filtration_value):
- alpha = gd.AlphaComplex(off_file='alphacomplexdoc.off', precision = precision)
+ alpha = gd.AlphaComplex(points = [[1.0, 1.0 , 0.0],
+ [7.0, 0.0 , 0.0],
+ [4.0, 6.0 , 0.0],
+ [9.0, 6.0 , 0.0],
+ [0.0, 14.0, 0.0],
+ [2.0, 19.0, 0.0],
+ [9.0, 17.0, 0.0]], precision = precision)
simplex_tree = alpha.create_simplex_tree(default_filtration_value = default_filtration_value)
assert simplex_tree.dimension() == 2
@@ -211,28 +219,16 @@ def _3d_points_on_a_plane(precision, default_filtration_value):
assert simplex_tree.num_simplices() == 25
def test_3d_points_on_a_plane():
- off_file = open("alphacomplexdoc.off", "w")
- off_file.write("OFF \n" \
- "7 0 0 \n" \
- "1.0 1.0 0.0\n" \
- "7.0 0.0 0.0\n" \
- "4.0 6.0 0.0\n" \
- "9.0 6.0 0.0\n" \
- "0.0 14.0 0.0\n" \
- "2.0 19.0 0.0\n" \
- "9.0 17.0 0.0\n" )
- off_file.close()
-
for default_filtration_value in [True, False]:
for precision in ['fast', 'safe', 'exact']:
_3d_points_on_a_plane(precision, default_filtration_value)
def _3d_tetrahedrons(precision):
points = 10*np.random.rand(10, 3)
- alpha = gd.AlphaComplex(points=points, precision = precision)
+ alpha = gd.AlphaComplex(points = points, precision = precision)
st_alpha = alpha.create_simplex_tree(default_filtration_value = False)
# New AlphaComplex for get_point to work
- delaunay = gd.AlphaComplex(points=points, precision = precision)
+ delaunay = gd.AlphaComplex(points = points, precision = precision)
st_delaunay = delaunay.create_simplex_tree(default_filtration_value = True)
delaunay_tetra = []
@@ -262,11 +258,7 @@ def test_3d_tetrahedrons():
for precision in ['fast', 'safe', 'exact']:
_3d_tetrahedrons(precision)
-def test_non_existing_off_file():
- with pytest.raises(FileNotFoundError):
- alpha = gd.AlphaComplex(off_file="pouetpouettralala.toubiloubabdou")
-
-def test_non_existing_weight_file():
+def test_off_file_deprecation_warning():
off_file = open("alphacomplexdoc.off", "w")
off_file.write("OFF \n" \
"7 0 0 \n" \
@@ -279,67 +271,32 @@ def test_non_existing_weight_file():
"9.0 17.0 0.0\n" )
off_file.close()
- with pytest.raises(FileNotFoundError):
- alpha = gd.AlphaComplex(off_file="alphacomplexdoc.off",
- weight_file="pouetpouettralala.toubiloubabdou")
+ with pytest.warns(DeprecationWarning):
+ alpha = gd.AlphaComplex(off_file="alphacomplexdoc.off")
+def test_non_existing_off_file():
+ with pytest.raises(FileNotFoundError):
+ alpha = gd.AlphaComplex(off_file="pouetpouettralala.toubiloubabdou")
-def test_inconsistency_off_weight_file():
- off_file = open("alphacomplexdoc.off", "w")
- off_file.write("OFF \n" \
- "7 0 0 \n" \
- "1.0 1.0 0.0\n" \
- "7.0 0.0 0.0\n" \
- "4.0 6.0 0.0\n" \
- "9.0 6.0 0.0\n" \
- "0.0 14.0 0.0\n" \
- "2.0 19.0 0.0\n" \
- "9.0 17.0 0.0\n" )
- off_file.close()
- # 7 points, 8 weights, on purpose
- weight_file = open("alphacomplexdoc.wgt", "w")
- weight_file.write("5.0\n" \
- "2.0\n" \
- "7.0\n" \
- "4.0\n" \
- "9.0\n" \
- "0.0\n" \
- "2.0\n" \
- "9.0\n" )
- weight_file.close()
-
+def test_inconsistency_points_and_weights():
+ points = [[1.0, 1.0 , 0.0],
+ [7.0, 0.0 , 0.0],
+ [4.0, 6.0 , 0.0],
+ [9.0, 6.0 , 0.0],
+ [0.0, 14.0, 0.0],
+ [2.0, 19.0, 0.0],
+ [9.0, 17.0, 0.0]]
with pytest.raises(ValueError):
- alpha = gd.AlphaComplex(off_file="alphacomplexdoc.off",
- weight_file="alphacomplexdoc.wgt")
+ # 7 points, 8 weights, on purpose
+ alpha = gd.AlphaComplex(points = points,
+ weights = [1., 2., 3., 4., 5., 6., 7., 8.])
- # 7 points, 6 weights, on purpose
with pytest.raises(ValueError):
- alpha = gd.AlphaComplex(off_file="alphacomplexdoc.off",
- weights=[1., 2., 3., 4., 5., 6.])
-
-def _with_or_without_weight_file(precision):
- off_file = open("weightalphacomplex.off", "w")
- off_file.write("OFF \n" \
- "5 0 0 \n" \
- "1. -1. -1. \n" \
- "-1. 1. -1. \n" \
- "-1. -1. 1. \n" \
- "1. 1. 1. \n" \
- "2. 2. 2.")
- off_file.close()
-
- weight_file = open("weightalphacomplex.wgt", "w")
- weight_file.write("4.0\n" \
- "4.0\n" \
- "4.0\n" \
- "4.0\n" \
- "1.0\n" )
- weight_file.close()
-
- stree_from_files = gd.AlphaComplex(off_file="weightalphacomplex.off",
- weight_file="weightalphacomplex.wgt",
- precision = precision).create_simplex_tree()
+ # 7 points, 6 weights, on purpose
+ alpha = gd.AlphaComplex(points = points,
+ weights = [1., 2., 3., 4., 5., 6.])
+def _doc_example(precision):
stree_from_values = gd.AlphaComplex(points=[[ 1., -1., -1.],
[-1., 1., -1.],
[-1., -1., 1.],
@@ -348,8 +305,11 @@ def _with_or_without_weight_file(precision):
weights = [4., 4., 4., 4., 1.],
precision = precision).create_simplex_tree()
- assert stree_from_files == stree_from_values
+ assert stree_from_values.filtration([0, 1, 2, 3]) == pytest.approx(-1.)
+ assert stree_from_values.filtration([0, 1, 3, 4]) == pytest.approx(95.)
+ assert stree_from_values.filtration([0, 2, 3, 4]) == pytest.approx(95.)
+ assert stree_from_values.filtration([1, 2, 3, 4]) == pytest.approx(95.)
-def test_with_or_without_weight_file():
+def test_doc_example():
for precision in ['fast', 'safe', 'exact']:
- _with_or_without_weight_file(precision)
+ _doc_example(precision)
diff --git a/src/python/test/test_reader_utils.py b/src/python/test/test_reader_utils.py
index 91de9ba0..4fc7c00f 100755
--- a/src/python/test/test_reader_utils.py
+++ b/src/python/test/test_reader_utils.py
@@ -125,19 +125,3 @@ def test_read_persistence_intervals_with_dimension():
1: [(9.6, 14.0), (3.0, float("Inf"))],
3: [(34.2, 34.974)],
}
-
-
-def test_non_existing_weights_file():
- with raises(FileNotFoundError):
- # Try to open a non existing file
- persistence = gd.read_weights(weight_file="pouetpouettralala.toubiloubabdou")
-
-def test_read_weights():
- # Create test file
- test_file = open("test_read_weights.wgt", "w")
- test_file.write(
- "2.7\n 9.6 \n\t34.2\n3.\t\n\n"
- )
- test_file.close()
- weights = gd.read_weights(weight_file = "test_read_weights.wgt")
- assert weights == [2.7, 9.6, 34.2, 3.]