summaryrefslogtreecommitdiff
path: root/src/cython
diff options
context:
space:
mode:
authorvrouvrea <vrouvrea@636b058d-ea47-450e-bf9e-a15bfbe3eedb>2016-06-23 09:49:03 +0000
committervrouvrea <vrouvrea@636b058d-ea47-450e-bf9e-a15bfbe3eedb>2016-06-23 09:49:03 +0000
commit8cb574ec24253e908960e00d950f2b319aabf793 (patch)
tree7dbf15c2798904f809fc508a91950c7c12439088 /src/cython
parent0d7729ea665cd2d3c4cabe02fde9c82ea8d86a97 (diff)
Cubical complex unitary tests
Using pytest because of unittest bug on __function in cython git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/ST_cythonize@1332 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: bbb829104ddb14173cdb066c40e73273fac0c720
Diffstat (limited to 'src/cython')
-rw-r--r--src/cython/Makefile2
-rw-r--r--src/cython/src/cython/cubical_complex.pyx42
-rwxr-xr-xsrc/cython/test/test_cubical_complex.py78
-rwxr-xr-xsrc/cython/test/test_witness_complex.py12
4 files changed, 119 insertions, 15 deletions
diff --git a/src/cython/Makefile b/src/cython/Makefile
index 75adbf3a..fdf4956c 100644
--- a/src/cython/Makefile
+++ b/src/cython/Makefile
@@ -6,6 +6,8 @@ test:
python test/test_mini_simplex_tree.py
python test/test_rips_complex.py
python test/test_alpha_complex.py
+ python test/test_witness_complex.py
+ python -m pytest test/test_cubical_complex.py
example:
python example/simplex_tree_example.py
diff --git a/src/cython/src/cython/cubical_complex.pyx b/src/cython/src/cython/cubical_complex.pyx
index 98f0526a..375d2e0c 100644
--- a/src/cython/src/cython/cubical_complex.pyx
+++ b/src/cython/src/cython/cubical_complex.pyx
@@ -2,6 +2,7 @@ from cython cimport numeric
from libcpp.vector cimport vector
from libcpp.utility cimport pair
from libcpp.string cimport string
+import os
"""This file is part of the Gudhi Library. The Gudhi library
(Geometric Understanding in Higher Dimensions) is a generic C++
@@ -52,7 +53,8 @@ cdef class CubicalComplex:
cdef Cubical_complex_persistence_interface * pcohptr
- def __cinit__(self, dimensions=None, top_dimensional_cells=None, perseus_file=''):
+ def __cinit__(self, dimensions=None, top_dimensional_cells=None,
+ perseus_file=''):
"""CubicalComplex constructor from dimensions and
top_dimensional_cells or from a perseus file style name.
@@ -61,11 +63,20 @@ cdef class CubicalComplex:
top_dimensional_cells (list): A list of top dimensional cells.
perseus_file (string): A perseus file style name.
"""
- if dimensions is not None:
- if top_dimensional_cells is not None:
- self.thisptr = new Bitmap_cubical_complex_base_interface(dimensions, top_dimensional_cells)
+ if (((dimensions is not None) or (top_dimensional_cells is not None)) and
+ (perseus_file is not '')):
+ print("CubicalComplex can be constructed from dimensions and "
+ "top_dimensional_cells or from a perseus file style name.")
else:
- self.thisptr = new Bitmap_cubical_complex_base_interface(perseus_file)
+ if dimensions is not None:
+ if top_dimensional_cells is not None:
+ self.thisptr = new Bitmap_cubical_complex_base_interface(dimensions, top_dimensional_cells)
+ else:
+ if perseus_file is not '':
+ if os.path.isfile(perseus_file):
+ self.thisptr = new Bitmap_cubical_complex_base_interface(perseus_file)
+ else:
+ print("file " + perseus_file + " not found.")
def __dealloc__(self):
if self.thisptr != NULL:
@@ -73,6 +84,12 @@ cdef class CubicalComplex:
if self.pcohptr != NULL:
del self.pcohptr
+ def __is_defined(self):
+ return self.thisptr != NULL
+
+ def __is_persistence_defined(self):
+ return self.pcohptr != NULL
+
def persistence(self, homology_coeff_field=11, min_persistence=0):
"""This function returns the persistence of the simplicial complex.
@@ -88,7 +105,8 @@ cdef class CubicalComplex:
"""
if self.pcohptr != NULL:
del self.pcohptr
- self.pcohptr = new Cubical_complex_persistence_interface(self.thisptr)
+ if self.thisptr != NULL:
+ self.pcohptr = new Cubical_complex_persistence_interface(self.thisptr)
cdef vector[pair[int, pair[double, double]]] persistence_result
if self.pcohptr != NULL:
persistence_result = self.pcohptr.get_persistence(homology_coeff_field, min_persistence)
@@ -98,13 +116,13 @@ cdef class CubicalComplex:
"""This function returns the Betti numbers of the simplicial complex.
:returns: list of int -- The Betti numbers ([B0, B1, ..., Bn]).
+
+ :warning: betti_numbers function requires persistence function to be
+ launched first.
"""
cdef vector[int] bn_result
if self.pcohptr != NULL:
bn_result = self.pcohptr.betti_numbers()
- else:
- print("betti_numbers function requires persistence function"
- " to be launched first.")
return bn_result
def persistent_betti_numbers(self, from_value, to_value):
@@ -120,11 +138,11 @@ cdef class CubicalComplex:
:returns: list of int -- The persistent Betti numbers ([B0, B1, ...,
Bn]).
+
+ :warning: betti_numbers function requires persistence function to be
+ launched first.
"""
cdef vector[int] pbn_result
if self.pcohptr != NULL:
pbn_result = self.pcohptr.persistent_betti_numbers(<double>from_value, <double>to_value)
- else:
- print("persistent_betti_numbers function requires persistence function"
- " to be launched first.")
return pbn_result
diff --git a/src/cython/test/test_cubical_complex.py b/src/cython/test/test_cubical_complex.py
new file mode 100755
index 00000000..9f5847f9
--- /dev/null
+++ b/src/cython/test/test_cubical_complex.py
@@ -0,0 +1,78 @@
+from gudhi import CubicalComplex
+
+"""This file is part of the Gudhi Library. The Gudhi library
+ (Geometric Understanding in Higher Dimensions) is a generic C++
+ library for computational topology.
+
+ Author(s): Vincent Rouvreau
+
+ Copyright (C) 2016 INRIA
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+"""
+
+__author__ = "Vincent Rouvreau"
+__copyright__ = "Copyright (C) 2016 INRIA"
+__license__ = "GPL v3"
+
+
+def test_empty_constructor():
+ # Try to create an empty CubicalComplex
+ cub = CubicalComplex()
+ assert cub.__is_defined() == False
+ assert cub.__is_persistence_defined() == False
+
+def test_non_existing_perseus_file_constructor():
+ # Try to open a non existing file
+ cub = CubicalComplex(perseus_file='pouetpouettralala.toubiloubabdou')
+ assert cub.__is_defined() == False
+ assert cub.__is_persistence_defined() == False
+
+def test_dimension_or_perseus_file_constructor():
+ # CubicalComplex can be constructed from dimensions and
+ # top_dimensional_cells OR from a perseus file style name.
+ cub = CubicalComplex(dimensions=[3, 3],
+ top_dimensional_cells = [1,2,3,4,5,6,7,8,9],
+ perseus_file='../data/bitmap/CubicalOneSphere.txt')
+ assert cub.__is_defined() == False
+ assert cub.__is_persistence_defined() == False
+
+ cub = CubicalComplex(top_dimensional_cells = [1,2,3,4,5,6,7,8,9],
+ perseus_file='../data/bitmap/CubicalOneSphere.txt')
+ assert cub.__is_defined() == False
+ assert cub.__is_persistence_defined() == False
+
+ cub = CubicalComplex(dimensions=[3, 3],
+ perseus_file='../data/bitmap/CubicalOneSphere.txt')
+ assert cub.__is_defined() == False
+ assert cub.__is_persistence_defined() == False
+
+def test_dimension_constructor():
+ cub = CubicalComplex(dimensions=[3, 3],
+ top_dimensional_cells = [1,2,3,4,5,6,7,8,9])
+ assert cub.__is_defined() == True
+ assert cub.__is_persistence_defined() == False
+ assert cub.persistence() == [(1, (0.0, 100.0)), (0, (0.0, 1.8446744073709552e+19))]
+ assert cub.__is_persistence_defined() == True
+ assert cub.betti_numbers() == [1, 0]
+ assert cub.persistent_betti_numbers(0, 1000) == [0, 0]
+
+def test_dimension_constructor():
+ cub = CubicalComplex(perseus_file='../data/bitmap/CubicalOneSphere.txt')
+ assert cub.__is_defined() == True
+ assert cub.__is_persistence_defined() == False
+ assert cub.persistence() == [(1, (0.0, 100.0)), (0, (0.0, 1.8446744073709552e+19))]
+ assert cub.__is_persistence_defined() == True
+ assert cub.betti_numbers() == [1, 0]
+ assert cub.persistent_betti_numbers(0, 1000) == [1, 0]
diff --git a/src/cython/test/test_witness_complex.py b/src/cython/test/test_witness_complex.py
index f9bbe077..2891935d 100755
--- a/src/cython/test/test_witness_complex.py
+++ b/src/cython/test/test_witness_complex.py
@@ -31,11 +31,13 @@ __license__ = "GPL v3"
class TestWitnessComplex(unittest.TestCase):
- def test_infinite_alpha(self):
+ def test_witness_complex(self):
point_list = [[0, 0], [1, 0], [0, 1], [1, 1]]
witness = gudhi.WitnessComplex(points=point_list,
number_of_landmarks=10)
+ # FIXME: Remove this line
+ witness.set_dimension(2)
self.assertEqual(witness.num_simplices(), 13)
self.assertEqual(witness.num_vertices(), 10)
@@ -46,8 +48,12 @@ class TestWitnessComplex(unittest.TestCase):
([1, 2], 0.0), ([3], 0.0), ([4], 0.0), ([3, 4], 0.0),
([5], 0.0), ([6], 0.0), ([7], 0.0), ([8], 0.0),
([9], 0.0)])
- self.assertEqual(witness.get_star_tree([0]), [])
- self.assertEqual(witness.get_coface_tree([0], 1), [])
+
+ self.assertEqual(witness.get_coface_tree([2], 1),
+ [([0, 2], 0.0), ([1, 2], 0.0)])
+ self.assertEqual(witness.get_star_tree([2]),
+ [([0, 2], 0.0), ([1, 2], 0.0), ([2], 0.0)])
+
if __name__ == '__main__':
unittest.main()