From b5510c0c362cd2bef79d82fd9809e654aea73957 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Mon, 16 Dec 2019 23:10:24 +0100 Subject: Add numpy ndarray to init a cubical and a periodic one --- src/python/doc/cubical_complex_user.rst | 4 +-- src/python/gudhi/cubical_complex.pyx | 27 ++++++++++++++----- src/python/gudhi/periodic_cubical_complex.pyx | 39 ++++++++++++++++++++++----- src/python/test/test_cubical_complex.py | 33 ++++++++++++++++++++--- 4 files changed, 84 insertions(+), 19 deletions(-) diff --git a/src/python/doc/cubical_complex_user.rst b/src/python/doc/cubical_complex_user.rst index b13b500e..21806038 100644 --- a/src/python/doc/cubical_complex_user.rst +++ b/src/python/doc/cubical_complex_user.rst @@ -142,8 +142,8 @@ Or it can be defined as follows: .. testcode:: from gudhi import PeriodicCubicalComplex as pcc - periodic_cc = pcc(dimensions=[3,3], - top_dimensional_cells= [0, 0, 0, 0, 1, 0, 0, 0, 0], + from numpy import array as np_array + periodic_cc = pcc(numpy_array = np_array([[0, 0, 0], [0, 1, 0], [0, 0, 0]]), periodic_dimensions=[True, False]) result_str = 'Periodic cubical complex is of dimension ' + repr(periodic_cc.dimension()) + ' - ' + \ repr(periodic_cc.num_simplices()) + ' simplices.' diff --git a/src/python/gudhi/cubical_complex.pyx b/src/python/gudhi/cubical_complex.pyx index 011c407c..2ec0146a 100644 --- a/src/python/gudhi/cubical_complex.pyx +++ b/src/python/gudhi/cubical_complex.pyx @@ -5,7 +5,7 @@ from libcpp.string cimport string from libcpp cimport bool import os -from numpy import array as np_array +import numpy as np # 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. @@ -47,7 +47,7 @@ cdef class CubicalComplex: # Fake constructor that does nothing but documenting the constructor def __init__(self, dimensions=None, top_dimensional_cells=None, - perseus_file=''): + numpy_array=None, perseus_file=''): """CubicalComplex constructor from dimensions and top_dimensional_cells or from a Perseus-style file name. @@ -58,16 +58,31 @@ cdef class CubicalComplex: Or + :param numpy_array: Filtration values in a d-array. + :type numpy_array: numpy ndarray + + Or + :param perseus_file: A Perseus-style file name. :type perseus_file: string """ # The real cython constructor def __cinit__(self, dimensions=None, top_dimensional_cells=None, - perseus_file=''): - if (dimensions is not None) and (top_dimensional_cells is not None) and (perseus_file == ''): + numpy_array=None, perseus_file=''): + if ((dimensions is not None) and (top_dimensional_cells is not None) + and (numpy_array is None) and (perseus_file == '')): self.thisptr = new Bitmap_cubical_complex_base_interface(dimensions, top_dimensional_cells) - elif (dimensions is None) and (top_dimensional_cells is None) and (perseus_file != ''): + elif ((dimensions is None) and (top_dimensional_cells is None) + and (numpy_array is not None) and (perseus_file == '')): + if isinstance(numpy_array, np.ndarray): + dimensions = list(numpy_array.shape) + top_dimensional_cells = numpy_array.flatten().tolist() + self.thisptr = new Bitmap_cubical_complex_base_interface(dimensions, top_dimensional_cells) + else: + print("numpy_array is not an instance of ndarray. It is a " + type(numpy_array)) + elif ((dimensions is None) and (top_dimensional_cells is None) + and (numpy_array is None) and (perseus_file != '')): if os.path.isfile(perseus_file): self.thisptr = new Bitmap_cubical_complex_base_interface(str.encode(perseus_file)) else: @@ -184,4 +199,4 @@ cdef class CubicalComplex: else: print("intervals_in_dim function requires persistence function" " to be launched first.") - return np_array(intervals_result) + return np.array(intervals_result) diff --git a/src/python/gudhi/periodic_cubical_complex.pyx b/src/python/gudhi/periodic_cubical_complex.pyx index c89055db..8318b7d3 100644 --- a/src/python/gudhi/periodic_cubical_complex.pyx +++ b/src/python/gudhi/periodic_cubical_complex.pyx @@ -5,7 +5,7 @@ from libcpp.string cimport string from libcpp cimport bool import os -from numpy import array as np_array +import numpy as np # 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. @@ -47,7 +47,7 @@ cdef class PeriodicCubicalComplex: # Fake constructor that does nothing but documenting the constructor def __init__(self, dimensions=None, top_dimensional_cells=None, - periodic_dimensions=None, perseus_file=''): + numpy_array=None, periodic_dimensions=None, perseus_file=''): """PeriodicCubicalComplex constructor from dimensions and top_dimensional_cells or from a Perseus-style file name. @@ -60,16 +60,41 @@ cdef class PeriodicCubicalComplex: Or + :param numpy_array: Filtration values in a d-array. + :type numpy_array: numpy ndarray + :param periodic_dimensions: A list of top dimensional cells periodicity value. + :type periodic_dimensions: list of boolean + + Or + :param perseus_file: A Perseus-style file name. :type perseus_file: string """ # The real cython constructor def __cinit__(self, dimensions=None, top_dimensional_cells=None, - periodic_dimensions=None, perseus_file=''): - if (dimensions is not None) and (top_dimensional_cells is not None) and (periodic_dimensions is not None) and (perseus_file == ''): - self.thisptr = new Periodic_cubical_complex_base_interface(dimensions, top_dimensional_cells, periodic_dimensions) - elif (dimensions is None) and (top_dimensional_cells is None) and (periodic_dimensions is None) and (perseus_file != ''): + numpy_array=None, periodic_dimensions=None, + perseus_file=''): + if ((dimensions is not None) and (top_dimensional_cells is not None) + and (numpy_array is None) and (periodic_dimensions is not None) + and (perseus_file == '')): + self.thisptr = new Periodic_cubical_complex_base_interface(dimensions, + top_dimensional_cells, + periodic_dimensions) + elif ((dimensions is None) and (top_dimensional_cells is None) + and (numpy_array is not None) and (periodic_dimensions is not None) + and (perseus_file == '')): + if isinstance(numpy_array, np.ndarray): + dimensions = list(numpy_array.shape) + top_dimensional_cells = numpy_array.flatten().tolist() + self.thisptr = new Periodic_cubical_complex_base_interface(dimensions, + top_dimensional_cells, + periodic_dimensions) + else: + print("numpy_array is not an instance of ndarray. It is a " + type(numpy_array)) + elif ((dimensions is None) and (top_dimensional_cells is None) + and (numpy_array is None) and (periodic_dimensions is None) + and (perseus_file != '')): if os.path.isfile(perseus_file): self.thisptr = new Periodic_cubical_complex_base_interface(str.encode(perseus_file)) else: @@ -186,4 +211,4 @@ cdef class PeriodicCubicalComplex: else: print("intervals_in_dim function requires persistence function" " to be launched first.") - return np_array(intervals_result) + return np.array(intervals_result) diff --git a/src/python/test/test_cubical_complex.py b/src/python/test/test_cubical_complex.py index 68f54fbe..a37d7821 100755 --- a/src/python/test/test_cubical_complex.py +++ b/src/python/test/test_cubical_complex.py @@ -1,4 +1,5 @@ from gudhi import CubicalComplex +import numpy as np """ 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. @@ -56,7 +57,7 @@ def test_dimension_or_perseus_file_constructor(): assert cub.__is_persistence_defined() == False -def test_dimension_simple_constructor(): +def simple_constructor(cub): cub = CubicalComplex( dimensions=[3, 3], top_dimensional_cells=[1, 2, 3, 4, 5, 6, 7, 8, 9] ) @@ -67,12 +68,22 @@ def test_dimension_simple_constructor(): assert cub.betti_numbers() == [1, 0, 0] assert cub.persistent_betti_numbers(0, 1000) == [0, 0, 0] - -def test_user_case_simple_constructor(): +def test_simple_constructor_from_top_cells(): cub = CubicalComplex( dimensions=[3, 3], - top_dimensional_cells=[float("inf"), 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0], + top_dimensional_cells=[1, 2, 3, 4, 5, 6, 7, 8, 9], ) + simple_constructor(cub) + +def test_simple_constructor_from_numpy_array(): + cub = CubicalComplex( + numpy_array=np.array([[1, 2, 3], + [4, 5, 6], + [7, 8, 9]]) + ) + simple_constructor(cub) + +def user_case_simple_constructor(cub): assert cub.__is_defined() == True assert cub.__is_persistence_defined() == False assert cub.persistence() == [(1, (0.0, 1.0)), (0, (0.0, float("inf")))] @@ -83,6 +94,20 @@ def test_user_case_simple_constructor(): ) assert other_cub.persistence() == [(1, (0.0, 1.0)), (0, (0.0, float("inf")))] +def test_user_case_simple_constructor_from_top_cells(): + cub = CubicalComplex( + dimensions=[3, 3], + top_dimensional_cells=[float("inf"), 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0], + ) + user_case_simple_constructor(cub) + +def test_user_case_simple_constructor_from_numpy_array(): + cub = CubicalComplex( + numpy_array=np.array([[float("inf"), 0.0, 0.0], + [0.0, 1.0, 0.0], + [0.0, 0.0, 0.0]]) + ) + user_case_simple_constructor(cub) def test_dimension_file_constructor(): # Create test file -- cgit v1.2.3 From b63be266effe24646823acc59fe397021bb13a3e Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Wed, 18 Dec 2019 10:44:17 +0100 Subject: Reuse top_dimensional_cells instead of numpy_array argument to create a cubical --- src/python/doc/cubical_complex_user.rst | 2 +- src/python/gudhi/cubical_complex.pyx | 25 ++++++++++--------- src/python/gudhi/periodic_cubical_complex.pyx | 35 +++++++++++++-------------- src/python/test/test_cubical_complex.py | 12 ++++----- 4 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/python/doc/cubical_complex_user.rst b/src/python/doc/cubical_complex_user.rst index 21806038..d56c8789 100644 --- a/src/python/doc/cubical_complex_user.rst +++ b/src/python/doc/cubical_complex_user.rst @@ -143,7 +143,7 @@ Or it can be defined as follows: from gudhi import PeriodicCubicalComplex as pcc from numpy import array as np_array - periodic_cc = pcc(numpy_array = np_array([[0, 0, 0], [0, 1, 0], [0, 0, 0]]), + periodic_cc = pcc(top_dimensional_cells = np_array([[0, 0, 0], [0, 1, 0], [0, 0, 0]]), periodic_dimensions=[True, False]) result_str = 'Periodic cubical complex is of dimension ' + repr(periodic_cc.dimension()) + ' - ' + \ repr(periodic_cc.num_simplices()) + ' simplices.' diff --git a/src/python/gudhi/cubical_complex.pyx b/src/python/gudhi/cubical_complex.pyx index 2ec0146a..1aa1164c 100644 --- a/src/python/gudhi/cubical_complex.pyx +++ b/src/python/gudhi/cubical_complex.pyx @@ -47,7 +47,7 @@ cdef class CubicalComplex: # Fake constructor that does nothing but documenting the constructor def __init__(self, dimensions=None, top_dimensional_cells=None, - numpy_array=None, perseus_file=''): + perseus_file=''): """CubicalComplex constructor from dimensions and top_dimensional_cells or from a Perseus-style file name. @@ -58,8 +58,9 @@ cdef class CubicalComplex: Or - :param numpy_array: Filtration values in a d-array. - :type numpy_array: numpy ndarray + :param top_dimensional_cells: A multidimensional array of cells + filtration values. + :type top_dimensional_cells: numpy ndarray Or @@ -69,20 +70,20 @@ cdef class CubicalComplex: # The real cython constructor def __cinit__(self, dimensions=None, top_dimensional_cells=None, - numpy_array=None, perseus_file=''): + perseus_file=''): if ((dimensions is not None) and (top_dimensional_cells is not None) - and (numpy_array is None) and (perseus_file == '')): + and (perseus_file == '')): self.thisptr = new Bitmap_cubical_complex_base_interface(dimensions, top_dimensional_cells) - elif ((dimensions is None) and (top_dimensional_cells is None) - and (numpy_array is not None) and (perseus_file == '')): - if isinstance(numpy_array, np.ndarray): - dimensions = list(numpy_array.shape) - top_dimensional_cells = numpy_array.flatten().tolist() + elif ((dimensions is None) and (top_dimensional_cells is not None) + and (perseus_file == '')): + if isinstance(top_dimensional_cells, np.ndarray): + dimensions = list(top_dimensional_cells.shape) + top_dimensional_cells = top_dimensional_cells.flatten().tolist() self.thisptr = new Bitmap_cubical_complex_base_interface(dimensions, top_dimensional_cells) else: - print("numpy_array is not an instance of ndarray. It is a " + type(numpy_array)) + print("top_dimensional_cells is not an instance of ndarray. It is a " + type(top_dimensional_cells)) elif ((dimensions is None) and (top_dimensional_cells is None) - and (numpy_array is None) and (perseus_file != '')): + and (perseus_file != '')): if os.path.isfile(perseus_file): self.thisptr = new Bitmap_cubical_complex_base_interface(str.encode(perseus_file)) else: diff --git a/src/python/gudhi/periodic_cubical_complex.pyx b/src/python/gudhi/periodic_cubical_complex.pyx index 8318b7d3..e623058a 100644 --- a/src/python/gudhi/periodic_cubical_complex.pyx +++ b/src/python/gudhi/periodic_cubical_complex.pyx @@ -47,7 +47,7 @@ cdef class PeriodicCubicalComplex: # Fake constructor that does nothing but documenting the constructor def __init__(self, dimensions=None, top_dimensional_cells=None, - numpy_array=None, periodic_dimensions=None, perseus_file=''): + periodic_dimensions=None, perseus_file=''): """PeriodicCubicalComplex constructor from dimensions and top_dimensional_cells or from a Perseus-style file name. @@ -60,8 +60,9 @@ cdef class PeriodicCubicalComplex: Or - :param numpy_array: Filtration values in a d-array. - :type numpy_array: numpy ndarray + :param top_dimensional_cells: A multidimensional array of cells + filtration values. + :type top_dimensional_cells: numpy ndarray :param periodic_dimensions: A list of top dimensional cells periodicity value. :type periodic_dimensions: list of boolean @@ -73,35 +74,33 @@ cdef class PeriodicCubicalComplex: # The real cython constructor def __cinit__(self, dimensions=None, top_dimensional_cells=None, - numpy_array=None, periodic_dimensions=None, - perseus_file=''): + periodic_dimensions=None, perseus_file=''): if ((dimensions is not None) and (top_dimensional_cells is not None) - and (numpy_array is None) and (periodic_dimensions is not None) - and (perseus_file == '')): + and (periodic_dimensions is not None) and (perseus_file == '')): self.thisptr = new Periodic_cubical_complex_base_interface(dimensions, top_dimensional_cells, periodic_dimensions) - elif ((dimensions is None) and (top_dimensional_cells is None) - and (numpy_array is not None) and (periodic_dimensions is not None) - and (perseus_file == '')): - if isinstance(numpy_array, np.ndarray): - dimensions = list(numpy_array.shape) - top_dimensional_cells = numpy_array.flatten().tolist() + elif ((dimensions is None) and (top_dimensional_cells is not None) + and (periodic_dimensions is not None) and (perseus_file == '')): + if isinstance(top_dimensional_cells, np.ndarray): + dimensions = list(top_dimensional_cells.shape) + top_dimensional_cells = top_dimensional_cells.flatten().tolist() self.thisptr = new Periodic_cubical_complex_base_interface(dimensions, top_dimensional_cells, periodic_dimensions) else: - print("numpy_array is not an instance of ndarray. It is a " + type(numpy_array)) + print("top_dimensional_cells is not an instance of ndarray. It is a " + type(top_dimensional_cells)) elif ((dimensions is None) and (top_dimensional_cells is None) - and (numpy_array is None) and (periodic_dimensions is None) - and (perseus_file != '')): + and (periodic_dimensions is None) and (perseus_file != '')): if os.path.isfile(perseus_file): self.thisptr = new Periodic_cubical_complex_base_interface(str.encode(perseus_file)) else: print("file " + perseus_file + " not found.") else: - print("CubicalComplex can be constructed from dimensions and " - "top_dimensional_cells or from a Perseus-style file name.") + 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.") def __dealloc__(self): if self.thisptr != NULL: diff --git a/src/python/test/test_cubical_complex.py b/src/python/test/test_cubical_complex.py index a37d7821..6d4e0309 100755 --- a/src/python/test/test_cubical_complex.py +++ b/src/python/test/test_cubical_complex.py @@ -77,9 +77,9 @@ def test_simple_constructor_from_top_cells(): def test_simple_constructor_from_numpy_array(): cub = CubicalComplex( - numpy_array=np.array([[1, 2, 3], - [4, 5, 6], - [7, 8, 9]]) + top_dimensional_cells=np.array([[1, 2, 3], + [4, 5, 6], + [7, 8, 9]]) ) simple_constructor(cub) @@ -103,9 +103,9 @@ def test_user_case_simple_constructor_from_top_cells(): def test_user_case_simple_constructor_from_numpy_array(): cub = CubicalComplex( - numpy_array=np.array([[float("inf"), 0.0, 0.0], - [0.0, 1.0, 0.0], - [0.0, 0.0, 0.0]]) + top_dimensional_cells=np.array([[float("inf"), 0.0, 0.0], + [0.0, 1.0, 0.0], + [0.0, 0.0, 0.0]]) ) user_case_simple_constructor(cub) -- cgit v1.2.3 From 32a9c5e4df26e59f5f376e54c05c7bec92012cff Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Wed, 18 Dec 2019 10:57:31 +0100 Subject: use ravel instead of flatten (that makes a copy) and no more converting to a list --- src/python/gudhi/cubical_complex.pyx | 4 ++-- src/python/gudhi/periodic_cubical_complex.pyx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/python/gudhi/cubical_complex.pyx b/src/python/gudhi/cubical_complex.pyx index 1aa1164c..756a9dab 100644 --- a/src/python/gudhi/cubical_complex.pyx +++ b/src/python/gudhi/cubical_complex.pyx @@ -77,8 +77,8 @@ cdef class CubicalComplex: elif ((dimensions is None) and (top_dimensional_cells is not None) and (perseus_file == '')): if isinstance(top_dimensional_cells, np.ndarray): - dimensions = list(top_dimensional_cells.shape) - top_dimensional_cells = top_dimensional_cells.flatten().tolist() + dimensions = top_dimensional_cells.shape + top_dimensional_cells = top_dimensional_cells.ravel(order='C') self.thisptr = new Bitmap_cubical_complex_base_interface(dimensions, top_dimensional_cells) else: print("top_dimensional_cells is not an instance of ndarray. It is a " + type(top_dimensional_cells)) diff --git a/src/python/gudhi/periodic_cubical_complex.pyx b/src/python/gudhi/periodic_cubical_complex.pyx index e623058a..c3d64123 100644 --- a/src/python/gudhi/periodic_cubical_complex.pyx +++ b/src/python/gudhi/periodic_cubical_complex.pyx @@ -83,8 +83,8 @@ cdef class PeriodicCubicalComplex: elif ((dimensions is None) and (top_dimensional_cells is not None) and (periodic_dimensions is not None) and (perseus_file == '')): if isinstance(top_dimensional_cells, np.ndarray): - dimensions = list(top_dimensional_cells.shape) - top_dimensional_cells = top_dimensional_cells.flatten().tolist() + dimensions = top_dimensional_cells.shape + top_dimensional_cells = top_dimensional_cells.ravel(order='C') self.thisptr = new Periodic_cubical_complex_base_interface(dimensions, top_dimensional_cells, periodic_dimensions) -- cgit v1.2.3 From ba406558f707f55b638be92d197ae3039595b29a Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Fri, 20 Dec 2019 16:57:36 +0100 Subject: Fix dimension cell linearization and test connected sublevel sets --- src/python/gudhi/cubical_complex.pyx | 2 +- src/python/gudhi/periodic_cubical_complex.pyx | 2 +- src/python/test/test_cubical_complex.py | 28 ++++++++++++++++++++++++++- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/python/gudhi/cubical_complex.pyx b/src/python/gudhi/cubical_complex.pyx index 756a9dab..04b22921 100644 --- a/src/python/gudhi/cubical_complex.pyx +++ b/src/python/gudhi/cubical_complex.pyx @@ -78,7 +78,7 @@ cdef class CubicalComplex: and (perseus_file == '')): if isinstance(top_dimensional_cells, np.ndarray): dimensions = top_dimensional_cells.shape - top_dimensional_cells = top_dimensional_cells.ravel(order='C') + top_dimensional_cells = top_dimensional_cells.ravel(order='F') self.thisptr = new Bitmap_cubical_complex_base_interface(dimensions, top_dimensional_cells) else: print("top_dimensional_cells is not an instance of ndarray. It is a " + type(top_dimensional_cells)) diff --git a/src/python/gudhi/periodic_cubical_complex.pyx b/src/python/gudhi/periodic_cubical_complex.pyx index c3d64123..1d6f1e59 100644 --- a/src/python/gudhi/periodic_cubical_complex.pyx +++ b/src/python/gudhi/periodic_cubical_complex.pyx @@ -84,7 +84,7 @@ cdef class PeriodicCubicalComplex: and (periodic_dimensions is not None) and (perseus_file == '')): if isinstance(top_dimensional_cells, np.ndarray): dimensions = top_dimensional_cells.shape - top_dimensional_cells = top_dimensional_cells.ravel(order='C') + top_dimensional_cells = top_dimensional_cells.ravel(order='F') self.thisptr = new Periodic_cubical_complex_base_interface(dimensions, top_dimensional_cells, periodic_dimensions) diff --git a/src/python/test/test_cubical_complex.py b/src/python/test/test_cubical_complex.py index 6d4e0309..121da12a 100755 --- a/src/python/test/test_cubical_complex.py +++ b/src/python/test/test_cubical_complex.py @@ -1,4 +1,4 @@ -from gudhi import CubicalComplex +from gudhi import CubicalComplex, PeriodicCubicalComplex import numpy as np """ This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. @@ -121,3 +121,29 @@ def test_dimension_file_constructor(): assert cub.__is_persistence_defined() == True assert cub.betti_numbers() == [1, 0, 0] assert cub.persistent_betti_numbers(0, 1000) == [1, 0, 0] + +def test_connected_sublevel_sets(): + array_cells = np.array([[3, 3], [2, 2], [4, 4]]) + linear_cells = [3, 3, 2, 2, 4, 4] + dimensions = [2, 3] + periodic_dimensions = [False, False] + # with a numpy array version + cub = CubicalComplex(top_dimensional_cells = array_cells) + assert cub.persistence() == [(0, (2.0, float("inf")))] + assert cub.betti_numbers() == [1, 0, 0] + # with vector of dimensions + cub = CubicalComplex(dimensions = dimensions, + top_dimensional_cells = linear_cells) + assert cub.persistence() == [(0, (2.0, float("inf")))] + assert cub.betti_numbers() == [1, 0, 0] + # periodic with a numpy array version + cub = PeriodicCubicalComplex(top_dimensional_cells = array_cells, + periodic_dimensions = periodic_dimensions) + assert cub.persistence() == [(0, (2.0, float("inf")))] + assert cub.betti_numbers() == [1, 0, 0] + # periodic with vector of dimensions + cub = PeriodicCubicalComplex(dimensions = dimensions, + top_dimensional_cells = linear_cells, + periodic_dimensions = periodic_dimensions) + assert cub.persistence() == [(0, (2.0, float("inf")))] + assert cub.betti_numbers() == [1, 0, 0] -- cgit v1.2.3 From d832d3585bf47c48f28d861469730fc47f4956c8 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Tue, 7 Jan 2020 12:24:45 +0100 Subject: Code review: less strict with numpy arrays for cubical ctors. Also accept lists --- src/python/gudhi/cubical_complex.pyx | 14 +++++++------- src/python/gudhi/periodic_cubical_complex.pyx | 18 +++++++++--------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/python/gudhi/cubical_complex.pyx b/src/python/gudhi/cubical_complex.pyx index 04b22921..63911478 100644 --- a/src/python/gudhi/cubical_complex.pyx +++ b/src/python/gudhi/cubical_complex.pyx @@ -60,7 +60,7 @@ cdef class CubicalComplex: :param top_dimensional_cells: A multidimensional array of cells filtration values. - :type top_dimensional_cells: numpy ndarray + :type top_dimensional_cells: numpy ndarray or list of list of double Or @@ -76,12 +76,12 @@ cdef class CubicalComplex: self.thisptr = new Bitmap_cubical_complex_base_interface(dimensions, top_dimensional_cells) elif ((dimensions is None) and (top_dimensional_cells is not None) and (perseus_file == '')): - if isinstance(top_dimensional_cells, np.ndarray): - dimensions = top_dimensional_cells.shape - top_dimensional_cells = top_dimensional_cells.ravel(order='F') - self.thisptr = new Bitmap_cubical_complex_base_interface(dimensions, top_dimensional_cells) - else: - print("top_dimensional_cells is not an instance of ndarray. It is a " + type(top_dimensional_cells)) + top_dimensional_cells = np.array(top_dimensional_cells, + copy = False, + order = 'F') + dimensions = top_dimensional_cells.shape + top_dimensional_cells = top_dimensional_cells.ravel(order='F') + self.thisptr = new Bitmap_cubical_complex_base_interface(dimensions, top_dimensional_cells) elif ((dimensions is None) and (top_dimensional_cells is None) and (perseus_file != '')): if os.path.isfile(perseus_file): diff --git a/src/python/gudhi/periodic_cubical_complex.pyx b/src/python/gudhi/periodic_cubical_complex.pyx index 1d6f1e59..3c0f529b 100644 --- a/src/python/gudhi/periodic_cubical_complex.pyx +++ b/src/python/gudhi/periodic_cubical_complex.pyx @@ -62,7 +62,7 @@ cdef class PeriodicCubicalComplex: :param top_dimensional_cells: A multidimensional array of cells filtration values. - :type top_dimensional_cells: numpy ndarray + :type top_dimensional_cells: numpy ndarray or list of list of double :param periodic_dimensions: A list of top dimensional cells periodicity value. :type periodic_dimensions: list of boolean @@ -82,14 +82,14 @@ cdef class PeriodicCubicalComplex: periodic_dimensions) elif ((dimensions is None) and (top_dimensional_cells is not None) and (periodic_dimensions is not None) and (perseus_file == '')): - if isinstance(top_dimensional_cells, np.ndarray): - dimensions = top_dimensional_cells.shape - top_dimensional_cells = top_dimensional_cells.ravel(order='F') - self.thisptr = new Periodic_cubical_complex_base_interface(dimensions, - top_dimensional_cells, - periodic_dimensions) - else: - print("top_dimensional_cells is not an instance of ndarray. It is a " + type(top_dimensional_cells)) + top_dimensional_cells = np.array(top_dimensional_cells, + copy = False, + order = 'F') + dimensions = top_dimensional_cells.shape + top_dimensional_cells = top_dimensional_cells.ravel(order='F') + self.thisptr = new Periodic_cubical_complex_base_interface(dimensions, + top_dimensional_cells, + periodic_dimensions) elif ((dimensions is None) and (top_dimensional_cells is None) and (periodic_dimensions is None) and (perseus_file != '')): if os.path.isfile(perseus_file): -- cgit v1.2.3 From 82b556c554a60e3b05942ba53300463dc00b8538 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Tue, 7 Jan 2020 12:27:19 +0100 Subject: Code review: use list in examples instead of numpy arrays --- src/python/doc/cubical_complex_user.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/python/doc/cubical_complex_user.rst b/src/python/doc/cubical_complex_user.rst index d56c8789..6fdcd9df 100644 --- a/src/python/doc/cubical_complex_user.rst +++ b/src/python/doc/cubical_complex_user.rst @@ -142,9 +142,7 @@ Or it can be defined as follows: .. testcode:: from gudhi import PeriodicCubicalComplex as pcc - from numpy import array as np_array - periodic_cc = pcc(top_dimensional_cells = np_array([[0, 0, 0], [0, 1, 0], [0, 0, 0]]), - periodic_dimensions=[True, False]) + periodic_cc = pcc(top_dimensional_cells = [[0, 0, 0], [0, 1, 0], [0, 0, 0]] result_str = 'Periodic cubical complex is of dimension ' + repr(periodic_cc.dimension()) + ' - ' + \ repr(periodic_cc.num_simplices()) + ' simplices.' print(result_str) -- cgit v1.2.3 From 44484a8f9242e45ead34cb49226df015c4b6c19a Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Tue, 7 Jan 2020 12:27:43 +0100 Subject: Code review: use list in examples instead of numpy arrays --- src/python/doc/cubical_complex_user.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/python/doc/cubical_complex_user.rst b/src/python/doc/cubical_complex_user.rst index 6fdcd9df..56cf0170 100644 --- a/src/python/doc/cubical_complex_user.rst +++ b/src/python/doc/cubical_complex_user.rst @@ -142,7 +142,8 @@ Or it can be defined as follows: .. testcode:: from gudhi import PeriodicCubicalComplex as pcc - periodic_cc = pcc(top_dimensional_cells = [[0, 0, 0], [0, 1, 0], [0, 0, 0]] + periodic_cc = pcc(top_dimensional_cells = [[0, 0, 0], [0, 1, 0], [0, 0, 0]], + periodic_dimensions=[True, False]) result_str = 'Periodic cubical complex is of dimension ' + repr(periodic_cc.dimension()) + ' - ' + \ repr(periodic_cc.num_simplices()) + ' simplices.' print(result_str) -- cgit v1.2.3 From 6a7a7b6d6d81946dd903f68f525389ab2fd51f71 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Tue, 7 Jan 2020 13:31:18 +0100 Subject: Doc review: anything convertible to a numpy ndarray --- src/python/gudhi/cubical_complex.pyx | 2 +- src/python/gudhi/periodic_cubical_complex.pyx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/python/gudhi/cubical_complex.pyx b/src/python/gudhi/cubical_complex.pyx index 63911478..b7047d4f 100644 --- a/src/python/gudhi/cubical_complex.pyx +++ b/src/python/gudhi/cubical_complex.pyx @@ -60,7 +60,7 @@ cdef class CubicalComplex: :param top_dimensional_cells: A multidimensional array of cells filtration values. - :type top_dimensional_cells: numpy ndarray or list of list of double + :type top_dimensional_cells: anything convertible to a numpy ndarray Or diff --git a/src/python/gudhi/periodic_cubical_complex.pyx b/src/python/gudhi/periodic_cubical_complex.pyx index 3c0f529b..eb96ab5f 100644 --- a/src/python/gudhi/periodic_cubical_complex.pyx +++ b/src/python/gudhi/periodic_cubical_complex.pyx @@ -62,7 +62,7 @@ cdef class PeriodicCubicalComplex: :param top_dimensional_cells: A multidimensional array of cells filtration values. - :type top_dimensional_cells: numpy ndarray or list of list of double + :type top_dimensional_cells: anything convertible to a numpy ndarray :param periodic_dimensions: A list of top dimensional cells periodicity value. :type periodic_dimensions: list of boolean -- cgit v1.2.3