From a064f5698fedbe13f6c343cb0b82e0f4d72caffb Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Mon, 27 Jan 2020 17:37:31 +0100 Subject: A first naive iterator implementation with yield --- src/python/gudhi/simplex_tree.pxd | 8 +++++++- src/python/gudhi/simplex_tree.pyx | 18 +++++++++--------- src/python/include/Simplex_tree_interface.h | 28 +++++++++++++++++----------- 3 files changed, 33 insertions(+), 21 deletions(-) (limited to 'src/python') diff --git a/src/python/gudhi/simplex_tree.pxd b/src/python/gudhi/simplex_tree.pxd index 96d14079..caf3c459 100644 --- a/src/python/gudhi/simplex_tree.pxd +++ b/src/python/gudhi/simplex_tree.pxd @@ -21,6 +21,9 @@ cdef extern from "Simplex_tree_interface.h" namespace "Gudhi": cdef cppclass Simplex_tree_options_full_featured: pass + cdef cppclass Simplex_tree_simplex_handle "Gudhi::Simplex_tree_interface::Simplex_handle": + pass + cdef cppclass Simplex_tree_interface_full_featured "Gudhi::Simplex_tree_interface": Simplex_tree() double simplex_filtration(vector[int] simplex) @@ -34,7 +37,6 @@ cdef extern from "Simplex_tree_interface.h" namespace "Gudhi": bool find_simplex(vector[int] simplex) bool insert_simplex_and_subfaces(vector[int] simplex, double filtration) - vector[pair[vector[int], double]] get_filtration() vector[pair[vector[int], double]] get_skeleton(int dimension) vector[pair[vector[int], double]] get_star(vector[int] simplex) vector[pair[vector[int], double]] get_cofaces(vector[int] simplex, @@ -43,6 +45,10 @@ 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() + # Iterators over Simplex tree + pair[vector[int], double] get_simplex_filtration(Simplex_tree_simplex_handle f_simplex) + vector[Simplex_tree_simplex_handle].const_iterator get_filtration_iterator_begin() + vector[Simplex_tree_simplex_handle].const_iterator get_filtration_iterator_end() cdef extern from "Persistent_cohomology_interface.h" namespace "Gudhi": cdef cppclass Simplex_tree_persistence_interface "Gudhi::Persistent_cohomology_interface>": diff --git a/src/python/gudhi/simplex_tree.pyx b/src/python/gudhi/simplex_tree.pyx index b18627c4..478139de 100644 --- a/src/python/gudhi/simplex_tree.pyx +++ b/src/python/gudhi/simplex_tree.pyx @@ -7,6 +7,7 @@ # Modification(s): # - YYYY/MM Author: Description of the modification +from cython.operator import dereference, preincrement from libc.stdint cimport intptr_t from numpy import array as np_array cimport simplex_tree @@ -214,15 +215,14 @@ cdef class SimplexTree: :returns: The simplices sorted by increasing filtration values. :rtype: list of tuples(simplex, filtration) """ - cdef vector[pair[vector[int], double]] filtration \ - = self.get_ptr().get_filtration() - ct = [] - for filtered_complex in filtration: - v = [] - for vertex in filtered_complex.first: - v.append(vertex) - ct.append((v, filtered_complex.second)) - return ct + cdef vector[Simplex_tree_simplex_handle].const_iterator it = self.get_ptr().get_filtration_iterator_begin() + cdef vector[Simplex_tree_simplex_handle].const_iterator end = self.get_ptr().get_filtration_iterator_end() + + while True: + yield(self.get_ptr().get_simplex_filtration(dereference(it))) + preincrement(it) + if it == end: + raise StopIteration def get_skeleton(self, dimension): """This function returns the (simplices of the) skeleton of a maximum diff --git a/src/python/include/Simplex_tree_interface.h b/src/python/include/Simplex_tree_interface.h index 06f31341..843966cd 100644 --- a/src/python/include/Simplex_tree_interface.h +++ b/src/python/include/Simplex_tree_interface.h @@ -33,7 +33,8 @@ class Simplex_tree_interface : public Simplex_tree { using Simplex_handle = typename Base::Simplex_handle; using Insertion_result = typename std::pair; using Simplex = std::vector; - using Filtered_simplices = std::vector>; + using Filtered_simplex = std::pair; + using Filtered_simplices = std::vector; public: bool find_simplex(const Simplex& vh) { @@ -82,17 +83,12 @@ class Simplex_tree_interface : public Simplex_tree { Base::initialize_filtration(); } - Filtered_simplices get_filtration() { - Base::initialize_filtration(); - Filtered_simplices filtrations; - for (auto f_simplex : Base::filtration_simplex_range()) { - Simplex simplex; - for (auto vertex : Base::simplex_vertex_range(f_simplex)) { - simplex.insert(simplex.begin(), vertex); - } - filtrations.push_back(std::make_pair(simplex, Base::filtration(f_simplex))); + Filtered_simplex get_simplex_filtration(Simplex_handle f_simplex) { + Simplex simplex; + for (auto vertex : Base::simplex_vertex_range(f_simplex)) { + simplex.insert(simplex.begin(), vertex); } - return filtrations; + return std::make_pair(simplex, Base::filtration(f_simplex)); } Filtered_simplices get_skeleton(int dimension) { @@ -135,6 +131,16 @@ class Simplex_tree_interface : public Simplex_tree { Base::initialize_filtration(); pcoh = new Gudhi::Persistent_cohomology_interface(*this); } + + // Iterator over the simplex tree + typename std::vector::const_iterator get_filtration_iterator_begin() { + Base::initialize_filtration(); + return Base::filtration_simplex_range().begin(); + } + + typename std::vector::const_iterator get_filtration_iterator_end() { + return Base::filtration_simplex_range().end(); + } }; } // namespace Gudhi -- cgit v1.2.3 From ef2c5b53e88321f07ad93496f00dde16dc20f018 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Tue, 28 Jan 2020 11:05:39 +0100 Subject: Code review: rename get_simplex_filtration with get_simplex_and_filtration. Remove exception raise. Fix failed tests. Reword documentation --- .../example/alpha_complex_from_points_example.py | 5 +- .../example/rips_complex_from_points_example.py | 5 +- src/python/example/simplex_tree_example.py | 5 +- src/python/gudhi/simplex_tree.pxd | 2 +- src/python/gudhi/simplex_tree.pyx | 10 +-- src/python/include/Simplex_tree_interface.h | 6 +- src/python/test/test_alpha_complex.py | 50 ++++++------ src/python/test/test_euclidean_witness_complex.py | 46 ++++++----- src/python/test/test_rips_complex.py | 53 +++++++------ src/python/test/test_simplex_tree.py | 90 +++++++++++----------- src/python/test/test_tangential_complex.py | 19 +++-- 11 files changed, 161 insertions(+), 130 deletions(-) (limited to 'src/python') diff --git a/src/python/example/alpha_complex_from_points_example.py b/src/python/example/alpha_complex_from_points_example.py index 844d7a82..465632eb 100755 --- a/src/python/example/alpha_complex_from_points_example.py +++ b/src/python/example/alpha_complex_from_points_example.py @@ -47,7 +47,10 @@ else: print("[4] Not found...") print("dimension=", simplex_tree.dimension()) -print("filtrations=", simplex_tree.get_filtration()) +print("filtrations=") +for simplex_with_filtration in simplex_tree.get_filtration(): + print("(%s, %.2f)" % tuple(simplex_with_filtration)) + print("star([0])=", simplex_tree.get_star([0])) print("coface([0], 1)=", simplex_tree.get_cofaces([0], 1)) diff --git a/src/python/example/rips_complex_from_points_example.py b/src/python/example/rips_complex_from_points_example.py index 59d8a261..c05703c6 100755 --- a/src/python/example/rips_complex_from_points_example.py +++ b/src/python/example/rips_complex_from_points_example.py @@ -22,6 +22,9 @@ rips = gudhi.RipsComplex(points=[[0, 0], [1, 0], [0, 1], [1, 1]], max_edge_lengt simplex_tree = rips.create_simplex_tree(max_dimension=1) -print("filtrations=", simplex_tree.get_filtration()) +print("filtrations=") +for simplex_with_filtration in simplex_tree.get_filtration(): + print("(%s, %.2f)" % tuple(simplex_with_filtration)) + print("star([0])=", simplex_tree.get_star([0])) print("coface([0], 1)=", simplex_tree.get_cofaces([0], 1)) diff --git a/src/python/example/simplex_tree_example.py b/src/python/example/simplex_tree_example.py index 30de00da..7f20c389 100755 --- a/src/python/example/simplex_tree_example.py +++ b/src/python/example/simplex_tree_example.py @@ -39,7 +39,10 @@ else: print("dimension=", st.dimension()) st.initialize_filtration() -print("filtration=", st.get_filtration()) +print("filtration=") +for simplex_with_filtration in st.get_filtration(): + print("(%s, %.2f)" % tuple(simplex_with_filtration)) + print("filtration[1, 2]=", st.filtration([1, 2])) print("filtration[4, 2]=", st.filtration([4, 2])) diff --git a/src/python/gudhi/simplex_tree.pxd b/src/python/gudhi/simplex_tree.pxd index caf3c459..1b0dc881 100644 --- a/src/python/gudhi/simplex_tree.pxd +++ b/src/python/gudhi/simplex_tree.pxd @@ -46,7 +46,7 @@ cdef extern from "Simplex_tree_interface.h" namespace "Gudhi": bool prune_above_filtration(double filtration) bool make_filtration_non_decreasing() # Iterators over Simplex tree - pair[vector[int], double] get_simplex_filtration(Simplex_tree_simplex_handle f_simplex) + pair[vector[int], double] get_simplex_and_filtration(Simplex_tree_simplex_handle f_simplex) vector[Simplex_tree_simplex_handle].const_iterator get_filtration_iterator_begin() vector[Simplex_tree_simplex_handle].const_iterator get_filtration_iterator_end() diff --git a/src/python/gudhi/simplex_tree.pyx b/src/python/gudhi/simplex_tree.pyx index 478139de..22978b6e 100644 --- a/src/python/gudhi/simplex_tree.pyx +++ b/src/python/gudhi/simplex_tree.pyx @@ -209,20 +209,18 @@ cdef class SimplexTree: filtration) def get_filtration(self): - """This function returns a list of all simplices with their given + """This function returns a generator with simplices and their given filtration values. :returns: The simplices sorted by increasing filtration values. - :rtype: list of tuples(simplex, filtration) + :rtype: generator with tuples(simplex, filtration) """ cdef vector[Simplex_tree_simplex_handle].const_iterator it = self.get_ptr().get_filtration_iterator_begin() cdef vector[Simplex_tree_simplex_handle].const_iterator end = self.get_ptr().get_filtration_iterator_end() - while True: - yield(self.get_ptr().get_simplex_filtration(dereference(it))) + while it != end: + yield(self.get_ptr().get_simplex_and_filtration(dereference(it))) preincrement(it) - if it == end: - raise StopIteration def get_skeleton(self, dimension): """This function returns the (simplices of the) skeleton of a maximum diff --git a/src/python/include/Simplex_tree_interface.h b/src/python/include/Simplex_tree_interface.h index 843966cd..c0bbc3d9 100644 --- a/src/python/include/Simplex_tree_interface.h +++ b/src/python/include/Simplex_tree_interface.h @@ -33,8 +33,8 @@ class Simplex_tree_interface : public Simplex_tree { using Simplex_handle = typename Base::Simplex_handle; using Insertion_result = typename std::pair; using Simplex = std::vector; - using Filtered_simplex = std::pair; - using Filtered_simplices = std::vector; + using Simplex_and_filtration = std::pair; + using Filtered_simplices = std::vector; public: bool find_simplex(const Simplex& vh) { @@ -83,7 +83,7 @@ class Simplex_tree_interface : public Simplex_tree { Base::initialize_filtration(); } - Filtered_simplex get_simplex_filtration(Simplex_handle f_simplex) { + Simplex_and_filtration get_simplex_and_filtration(Simplex_handle f_simplex) { Simplex simplex; for (auto vertex : Base::simplex_vertex_range(f_simplex)) { simplex.insert(simplex.begin(), vertex); diff --git a/src/python/test/test_alpha_complex.py b/src/python/test/test_alpha_complex.py index 3761fe16..ceead919 100755 --- a/src/python/test/test_alpha_complex.py +++ b/src/python/test/test_alpha_complex.py @@ -40,19 +40,21 @@ def test_infinite_alpha(): assert simplex_tree.num_simplices() == 11 assert simplex_tree.num_vertices() == 4 - assert simplex_tree.get_filtration() == [ - ([0], 0.0), - ([1], 0.0), - ([2], 0.0), - ([3], 0.0), - ([0, 1], 0.25), - ([0, 2], 0.25), - ([1, 3], 0.25), - ([2, 3], 0.25), - ([1, 2], 0.5), - ([0, 1, 2], 0.5), - ([1, 2, 3], 0.5), - ] + filtration_generator = simplex_tree.get_filtration() + assert(next(filtration_generator) == ([0], 0.0)) + assert(next(filtration_generator) == ([1], 0.0)) + assert(next(filtration_generator) == ([2], 0.0)) + assert(next(filtration_generator) == ([3], 0.0)) + assert(next(filtration_generator) == ([0, 1], 0.25)) + assert(next(filtration_generator) == ([0, 2], 0.25)) + assert(next(filtration_generator) == ([1, 3], 0.25)) + assert(next(filtration_generator) == ([2, 3], 0.25)) + assert(next(filtration_generator) == ([1, 2], 0.5)) + assert(next(filtration_generator) == ([0, 1, 2], 0.5)) + assert(next(filtration_generator) == ([1, 2, 3], 0.5)) + with pytest.raises(StopIteration): + next(filtration_generator) + assert simplex_tree.get_star([0]) == [ ([0], 0.0), ([0, 1], 0.25), @@ -105,16 +107,18 @@ def test_filtered_alpha(): else: assert False - assert simplex_tree.get_filtration() == [ - ([0], 0.0), - ([1], 0.0), - ([2], 0.0), - ([3], 0.0), - ([0, 1], 0.25), - ([0, 2], 0.25), - ([1, 3], 0.25), - ([2, 3], 0.25), - ] + filtration_generator = simplex_tree.get_filtration() + assert(next(filtration_generator) == ([0], 0.0)) + assert(next(filtration_generator) == ([1], 0.0)) + assert(next(filtration_generator) == ([2], 0.0)) + assert(next(filtration_generator) == ([3], 0.0)) + assert(next(filtration_generator) == ([0, 1], 0.25)) + assert(next(filtration_generator) == ([0, 2], 0.25)) + assert(next(filtration_generator) == ([1, 3], 0.25)) + assert(next(filtration_generator) == ([2, 3], 0.25)) + with pytest.raises(StopIteration): + next(filtration_generator) + assert simplex_tree.get_star([0]) == [([0], 0.0), ([0, 1], 0.25), ([0, 2], 0.25)] assert simplex_tree.get_cofaces([0], 1) == [([0, 1], 0.25), ([0, 2], 0.25)] diff --git a/src/python/test/test_euclidean_witness_complex.py b/src/python/test/test_euclidean_witness_complex.py index c18d2484..16ff1ef4 100755 --- a/src/python/test/test_euclidean_witness_complex.py +++ b/src/python/test/test_euclidean_witness_complex.py @@ -9,6 +9,7 @@ """ import gudhi +import pytest __author__ = "Vincent Rouvreau" __copyright__ = "Copyright (C) 2016 Inria" @@ -40,15 +41,16 @@ def test_witness_complex(): assert landmarks[1] == euclidean_witness_complex.get_point(1) assert landmarks[2] == euclidean_witness_complex.get_point(2) - assert simplex_tree.get_filtration() == [ - ([0], 0.0), - ([1], 0.0), - ([0, 1], 0.0), - ([2], 0.0), - ([0, 2], 0.0), - ([1, 2], 0.0), - ([0, 1, 2], 0.0), - ] + filtration_generator = simplex_tree.get_filtration() + assert(next(filtration_generator) == ([0], 0.0)) + assert(next(filtration_generator) == ([1], 0.0)) + assert(next(filtration_generator) == ([0, 1], 0.0)) + assert(next(filtration_generator) == ([2], 0.0)) + assert(next(filtration_generator) == ([0, 2], 0.0)) + assert(next(filtration_generator) == ([1, 2], 0.0)) + assert(next(filtration_generator) == ([0, 1, 2], 0.0)) + with pytest.raises(StopIteration): + next(filtration_generator) def test_empty_euclidean_strong_witness_complex(): @@ -78,18 +80,24 @@ def test_strong_witness_complex(): assert landmarks[1] == euclidean_strong_witness_complex.get_point(1) assert landmarks[2] == euclidean_strong_witness_complex.get_point(2) - assert simplex_tree.get_filtration() == [([0], 0.0), ([1], 0.0), ([2], 0.0)] + filtration_generator = simplex_tree.get_filtration() + assert(next(filtration_generator) == ([0], 0.0)) + assert(next(filtration_generator) == ([1], 0.0)) + assert(next(filtration_generator) == ([2], 0.0)) + with pytest.raises(StopIteration): + next(filtration_generator) simplex_tree = euclidean_strong_witness_complex.create_simplex_tree( max_alpha_square=100.0 ) - assert simplex_tree.get_filtration() == [ - ([0], 0.0), - ([1], 0.0), - ([2], 0.0), - ([1, 2], 15.0), - ([0, 2], 34.0), - ([0, 1], 37.0), - ([0, 1, 2], 37.0), - ] + filtration_generator = simplex_tree.get_filtration() + assert(next(filtration_generator) == ([0], 0.0)) + assert(next(filtration_generator) == ([1], 0.0)) + assert(next(filtration_generator) == ([2], 0.0)) + assert(next(filtration_generator) == ([1, 2], 15.0)) + assert(next(filtration_generator) == ([0, 2], 34.0)) + assert(next(filtration_generator) == ([0, 1], 37.0)) + assert(next(filtration_generator) == ([0, 1, 2], 37.0)) + with pytest.raises(StopIteration): + next(filtration_generator) diff --git a/src/python/test/test_rips_complex.py b/src/python/test/test_rips_complex.py index b02a68e1..bd31c47c 100755 --- a/src/python/test/test_rips_complex.py +++ b/src/python/test/test_rips_complex.py @@ -10,6 +10,7 @@ from gudhi import RipsComplex from math import sqrt +import pytest __author__ = "Vincent Rouvreau" __copyright__ = "Copyright (C) 2016 Inria" @@ -32,18 +33,20 @@ def test_rips_from_points(): assert simplex_tree.num_simplices() == 10 assert simplex_tree.num_vertices() == 4 - assert simplex_tree.get_filtration() == [ - ([0], 0.0), - ([1], 0.0), - ([2], 0.0), - ([3], 0.0), - ([0, 1], 1.0), - ([0, 2], 1.0), - ([1, 3], 1.0), - ([2, 3], 1.0), - ([1, 2], 1.4142135623730951), - ([0, 3], 1.4142135623730951), - ] + filtration_generator = simplex_tree.get_filtration() + assert(next(filtration_generator) == ([0], 0.0)) + assert(next(filtration_generator) == ([1], 0.0)) + assert(next(filtration_generator) == ([2], 0.0)) + assert(next(filtration_generator) == ([3], 0.0)) + assert(next(filtration_generator) == ([0, 1], 1.0)) + assert(next(filtration_generator) == ([0, 2], 1.0)) + assert(next(filtration_generator) == ([1, 3], 1.0)) + assert(next(filtration_generator) == ([2, 3], 1.0)) + assert(next(filtration_generator) == ([1, 2], 1.4142135623730951)) + assert(next(filtration_generator) == ([0, 3], 1.4142135623730951)) + with pytest.raises(StopIteration): + next(filtration_generator) + assert simplex_tree.get_star([0]) == [ ([0], 0.0), ([0, 1], 1.0), @@ -95,18 +98,20 @@ def test_rips_from_distance_matrix(): assert simplex_tree.num_simplices() == 10 assert simplex_tree.num_vertices() == 4 - assert simplex_tree.get_filtration() == [ - ([0], 0.0), - ([1], 0.0), - ([2], 0.0), - ([3], 0.0), - ([0, 1], 1.0), - ([0, 2], 1.0), - ([1, 3], 1.0), - ([2, 3], 1.0), - ([1, 2], 1.4142135623730951), - ([0, 3], 1.4142135623730951), - ] + filtration_generator = simplex_tree.get_filtration() + assert(next(filtration_generator) == ([0], 0.0)) + assert(next(filtration_generator) == ([1], 0.0)) + assert(next(filtration_generator) == ([2], 0.0)) + assert(next(filtration_generator) == ([3], 0.0)) + assert(next(filtration_generator) == ([0, 1], 1.0)) + assert(next(filtration_generator) == ([0, 2], 1.0)) + assert(next(filtration_generator) == ([1, 3], 1.0)) + assert(next(filtration_generator) == ([2, 3], 1.0)) + assert(next(filtration_generator) == ([1, 2], 1.4142135623730951)) + assert(next(filtration_generator) == ([0, 3], 1.4142135623730951)) + with pytest.raises(StopIteration): + next(filtration_generator) + assert simplex_tree.get_star([0]) == [ ([0], 0.0), ([0, 1], 1.0), diff --git a/src/python/test/test_simplex_tree.py b/src/python/test/test_simplex_tree.py index 1822c43b..0f3db7ac 100755 --- a/src/python/test/test_simplex_tree.py +++ b/src/python/test/test_simplex_tree.py @@ -9,6 +9,7 @@ """ from gudhi import SimplexTree +import pytest __author__ = "Vincent Rouvreau" __copyright__ = "Copyright (C) 2016 Inria" @@ -126,55 +127,58 @@ def test_expansion(): assert st.num_vertices() == 7 assert st.num_simplices() == 17 - assert st.get_filtration() == [ - ([2], 0.1), - ([3], 0.1), - ([2, 3], 0.1), - ([0], 0.2), - ([0, 2], 0.2), - ([1], 0.3), - ([0, 1], 0.3), - ([1, 3], 0.4), - ([1, 2], 0.5), - ([5], 0.6), - ([6], 0.6), - ([5, 6], 0.6), - ([4], 0.7), - ([2, 4], 0.7), - ([0, 3], 0.8), - ([4, 6], 0.9), - ([3, 6], 1.0), - ] + + filtration_generator = st.get_filtration() + assert(next(filtration_generator) == ([2], 0.1)) + assert(next(filtration_generator) == ([3], 0.1)) + assert(next(filtration_generator) == ([2, 3], 0.1)) + assert(next(filtration_generator) == ([0], 0.2)) + assert(next(filtration_generator) == ([0, 2], 0.2)) + assert(next(filtration_generator) == ([1], 0.3)) + assert(next(filtration_generator) == ([0, 1], 0.3)) + assert(next(filtration_generator) == ([1, 3], 0.4)) + assert(next(filtration_generator) == ([1, 2], 0.5)) + assert(next(filtration_generator) == ([5], 0.6)) + assert(next(filtration_generator) == ([6], 0.6)) + assert(next(filtration_generator) == ([5, 6], 0.6)) + assert(next(filtration_generator) == ([4], 0.7)) + assert(next(filtration_generator) == ([2, 4], 0.7)) + assert(next(filtration_generator) == ([0, 3], 0.8)) + assert(next(filtration_generator) == ([4, 6], 0.9)) + assert(next(filtration_generator) == ([3, 6], 1.0)) + with pytest.raises(StopIteration): + next(filtration_generator) st.expansion(3) assert st.num_vertices() == 7 assert st.num_simplices() == 22 st.initialize_filtration() - assert st.get_filtration() == [ - ([2], 0.1), - ([3], 0.1), - ([2, 3], 0.1), - ([0], 0.2), - ([0, 2], 0.2), - ([1], 0.3), - ([0, 1], 0.3), - ([1, 3], 0.4), - ([1, 2], 0.5), - ([0, 1, 2], 0.5), - ([1, 2, 3], 0.5), - ([5], 0.6), - ([6], 0.6), - ([5, 6], 0.6), - ([4], 0.7), - ([2, 4], 0.7), - ([0, 3], 0.8), - ([0, 1, 3], 0.8), - ([0, 2, 3], 0.8), - ([0, 1, 2, 3], 0.8), - ([4, 6], 0.9), - ([3, 6], 1.0), - ] + filtration_generator = st.get_filtration() + assert(next(filtration_generator) == ([2], 0.1)) + assert(next(filtration_generator) == ([3], 0.1)) + assert(next(filtration_generator) == ([2, 3], 0.1)) + assert(next(filtration_generator) == ([0], 0.2)) + assert(next(filtration_generator) == ([0, 2], 0.2)) + assert(next(filtration_generator) == ([1], 0.3)) + assert(next(filtration_generator) == ([0, 1], 0.3)) + assert(next(filtration_generator) == ([1, 3], 0.4)) + assert(next(filtration_generator) == ([1, 2], 0.5)) + assert(next(filtration_generator) == ([0, 1, 2], 0.5)) + assert(next(filtration_generator) == ([1, 2, 3], 0.5)) + assert(next(filtration_generator) == ([5], 0.6)) + assert(next(filtration_generator) == ([6], 0.6)) + assert(next(filtration_generator) == ([5, 6], 0.6)) + assert(next(filtration_generator) == ([4], 0.7)) + assert(next(filtration_generator) == ([2, 4], 0.7)) + assert(next(filtration_generator) == ([0, 3], 0.8)) + assert(next(filtration_generator) == ([0, 1, 3], 0.8)) + assert(next(filtration_generator) == ([0, 2, 3], 0.8)) + assert(next(filtration_generator) == ([0, 1, 2, 3], 0.8)) + assert(next(filtration_generator) == ([4, 6], 0.9)) + assert(next(filtration_generator) == ([3, 6], 1.0)) + with pytest.raises(StopIteration): + next(filtration_generator) def test_automatic_dimension(): diff --git a/src/python/test/test_tangential_complex.py b/src/python/test/test_tangential_complex.py index e650e99c..90e2c75b 100755 --- a/src/python/test/test_tangential_complex.py +++ b/src/python/test/test_tangential_complex.py @@ -9,6 +9,7 @@ """ from gudhi import TangentialComplex, SimplexTree +import pytest __author__ = "Vincent Rouvreau" __copyright__ = "Copyright (C) 2016 Inria" @@ -37,14 +38,16 @@ def test_tangential(): assert st.num_simplices() == 6 assert st.num_vertices() == 4 - assert st.get_filtration() == [ - ([0], 0.0), - ([1], 0.0), - ([2], 0.0), - ([0, 2], 0.0), - ([3], 0.0), - ([1, 3], 0.0), - ] + filtration_generator = st.get_filtration() + assert(next(filtration_generator) == ([0], 0.0)) + assert(next(filtration_generator) == ([1], 0.0)) + assert(next(filtration_generator) == ([2], 0.0)) + assert(next(filtration_generator) == ([0, 2], 0.0)) + assert(next(filtration_generator) == ([3], 0.0)) + assert(next(filtration_generator) == ([1, 3], 0.0)) + with pytest.raises(StopIteration): + next(filtration_generator) + assert st.get_cofaces([0], 1) == [([0, 2], 0.0)] assert point_list[0] == tc.get_point(0) -- cgit v1.2.3 From 3253abd27129595f7fcd2be4c2285a93aea98690 Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau <10407034+VincentRouvreau@users.noreply.github.com> Date: Tue, 11 Feb 2020 17:05:08 +0100 Subject: Update src/python/gudhi/simplex_tree.pyx Co-Authored-By: Marc Glisse --- src/python/gudhi/simplex_tree.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/python') diff --git a/src/python/gudhi/simplex_tree.pyx b/src/python/gudhi/simplex_tree.pyx index 22978b6e..308b3d2d 100644 --- a/src/python/gudhi/simplex_tree.pyx +++ b/src/python/gudhi/simplex_tree.pyx @@ -219,7 +219,7 @@ cdef class SimplexTree: cdef vector[Simplex_tree_simplex_handle].const_iterator end = self.get_ptr().get_filtration_iterator_end() while it != end: - yield(self.get_ptr().get_simplex_and_filtration(dereference(it))) + yield self.get_ptr().get_simplex_and_filtration(dereference(it)) preincrement(it) def get_skeleton(self, dimension): -- cgit v1.2.3 From 3ea44646f04648d1a456a0fb9526035101fc17ea Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Tue, 11 Feb 2020 17:20:24 +0100 Subject: Code review: non-optimal way to test filtration generator --- src/python/test/test_alpha_complex.py | 49 ++++++------- src/python/test/test_euclidean_witness_complex.py | 45 +++++------- src/python/test/test_rips_complex.py | 50 +++++++------ src/python/test/test_simplex_tree.py | 88 +++++++++++------------ src/python/test/test_tangential_complex.py | 17 +++-- 5 files changed, 117 insertions(+), 132 deletions(-) (limited to 'src/python') diff --git a/src/python/test/test_alpha_complex.py b/src/python/test/test_alpha_complex.py index ceead919..77121302 100755 --- a/src/python/test/test_alpha_complex.py +++ b/src/python/test/test_alpha_complex.py @@ -40,20 +40,19 @@ def test_infinite_alpha(): assert simplex_tree.num_simplices() == 11 assert simplex_tree.num_vertices() == 4 - filtration_generator = simplex_tree.get_filtration() - assert(next(filtration_generator) == ([0], 0.0)) - assert(next(filtration_generator) == ([1], 0.0)) - assert(next(filtration_generator) == ([2], 0.0)) - assert(next(filtration_generator) == ([3], 0.0)) - assert(next(filtration_generator) == ([0, 1], 0.25)) - assert(next(filtration_generator) == ([0, 2], 0.25)) - assert(next(filtration_generator) == ([1, 3], 0.25)) - assert(next(filtration_generator) == ([2, 3], 0.25)) - assert(next(filtration_generator) == ([1, 2], 0.5)) - assert(next(filtration_generator) == ([0, 1, 2], 0.5)) - assert(next(filtration_generator) == ([1, 2, 3], 0.5)) - with pytest.raises(StopIteration): - next(filtration_generator) + assert list(simplex_tree.get_filtration()) == [ + ([0], 0.0), + ([1], 0.0), + ([2], 0.0), + ([3], 0.0), + ([0, 1], 0.25), + ([0, 2], 0.25), + ([1, 3], 0.25), + ([2, 3], 0.25), + ([1, 2], 0.5), + ([0, 1, 2], 0.5), + ([1, 2, 3], 0.5), + ] assert simplex_tree.get_star([0]) == [ ([0], 0.0), @@ -107,18 +106,16 @@ def test_filtered_alpha(): else: assert False - filtration_generator = simplex_tree.get_filtration() - assert(next(filtration_generator) == ([0], 0.0)) - assert(next(filtration_generator) == ([1], 0.0)) - assert(next(filtration_generator) == ([2], 0.0)) - assert(next(filtration_generator) == ([3], 0.0)) - assert(next(filtration_generator) == ([0, 1], 0.25)) - assert(next(filtration_generator) == ([0, 2], 0.25)) - assert(next(filtration_generator) == ([1, 3], 0.25)) - assert(next(filtration_generator) == ([2, 3], 0.25)) - with pytest.raises(StopIteration): - next(filtration_generator) - + assert list(simplex_tree.get_filtration()) == [ + ([0], 0.0), + ([1], 0.0), + ([2], 0.0), + ([3], 0.0), + ([0, 1], 0.25), + ([0, 2], 0.25), + ([1, 3], 0.25), + ([2, 3], 0.25), + ] assert simplex_tree.get_star([0]) == [([0], 0.0), ([0, 1], 0.25), ([0, 2], 0.25)] assert simplex_tree.get_cofaces([0], 1) == [([0, 1], 0.25), ([0, 2], 0.25)] diff --git a/src/python/test/test_euclidean_witness_complex.py b/src/python/test/test_euclidean_witness_complex.py index 16ff1ef4..47196a2a 100755 --- a/src/python/test/test_euclidean_witness_complex.py +++ b/src/python/test/test_euclidean_witness_complex.py @@ -41,16 +41,15 @@ def test_witness_complex(): assert landmarks[1] == euclidean_witness_complex.get_point(1) assert landmarks[2] == euclidean_witness_complex.get_point(2) - filtration_generator = simplex_tree.get_filtration() - assert(next(filtration_generator) == ([0], 0.0)) - assert(next(filtration_generator) == ([1], 0.0)) - assert(next(filtration_generator) == ([0, 1], 0.0)) - assert(next(filtration_generator) == ([2], 0.0)) - assert(next(filtration_generator) == ([0, 2], 0.0)) - assert(next(filtration_generator) == ([1, 2], 0.0)) - assert(next(filtration_generator) == ([0, 1, 2], 0.0)) - with pytest.raises(StopIteration): - next(filtration_generator) + assert list(simplex_tree.get_filtration()) == [ + ([0], 0.0), + ([1], 0.0), + ([0, 1], 0.0), + ([2], 0.0), + ([0, 2], 0.0), + ([1, 2], 0.0), + ([0, 1, 2], 0.0), + ] def test_empty_euclidean_strong_witness_complex(): @@ -80,24 +79,18 @@ def test_strong_witness_complex(): assert landmarks[1] == euclidean_strong_witness_complex.get_point(1) assert landmarks[2] == euclidean_strong_witness_complex.get_point(2) - filtration_generator = simplex_tree.get_filtration() - assert(next(filtration_generator) == ([0], 0.0)) - assert(next(filtration_generator) == ([1], 0.0)) - assert(next(filtration_generator) == ([2], 0.0)) - with pytest.raises(StopIteration): - next(filtration_generator) + assert list(simplex_tree.get_filtration()) == [([0], 0.0), ([1], 0.0), ([2], 0.0)] simplex_tree = euclidean_strong_witness_complex.create_simplex_tree( max_alpha_square=100.0 ) - filtration_generator = simplex_tree.get_filtration() - assert(next(filtration_generator) == ([0], 0.0)) - assert(next(filtration_generator) == ([1], 0.0)) - assert(next(filtration_generator) == ([2], 0.0)) - assert(next(filtration_generator) == ([1, 2], 15.0)) - assert(next(filtration_generator) == ([0, 2], 34.0)) - assert(next(filtration_generator) == ([0, 1], 37.0)) - assert(next(filtration_generator) == ([0, 1, 2], 37.0)) - with pytest.raises(StopIteration): - next(filtration_generator) + assert list(simplex_tree.get_filtration()) == [ + ([0], 0.0), + ([1], 0.0), + ([2], 0.0), + ([1, 2], 15.0), + ([0, 2], 34.0), + ([0, 1], 37.0), + ([0, 1, 2], 37.0), + ] diff --git a/src/python/test/test_rips_complex.py b/src/python/test/test_rips_complex.py index bd31c47c..f5c086cb 100755 --- a/src/python/test/test_rips_complex.py +++ b/src/python/test/test_rips_complex.py @@ -33,19 +33,18 @@ def test_rips_from_points(): assert simplex_tree.num_simplices() == 10 assert simplex_tree.num_vertices() == 4 - filtration_generator = simplex_tree.get_filtration() - assert(next(filtration_generator) == ([0], 0.0)) - assert(next(filtration_generator) == ([1], 0.0)) - assert(next(filtration_generator) == ([2], 0.0)) - assert(next(filtration_generator) == ([3], 0.0)) - assert(next(filtration_generator) == ([0, 1], 1.0)) - assert(next(filtration_generator) == ([0, 2], 1.0)) - assert(next(filtration_generator) == ([1, 3], 1.0)) - assert(next(filtration_generator) == ([2, 3], 1.0)) - assert(next(filtration_generator) == ([1, 2], 1.4142135623730951)) - assert(next(filtration_generator) == ([0, 3], 1.4142135623730951)) - with pytest.raises(StopIteration): - next(filtration_generator) + assert list(simplex_tree.get_filtration()) == [ + ([0], 0.0), + ([1], 0.0), + ([2], 0.0), + ([3], 0.0), + ([0, 1], 1.0), + ([0, 2], 1.0), + ([1, 3], 1.0), + ([2, 3], 1.0), + ([1, 2], 1.4142135623730951), + ([0, 3], 1.4142135623730951), + ] assert simplex_tree.get_star([0]) == [ ([0], 0.0), @@ -98,19 +97,18 @@ def test_rips_from_distance_matrix(): assert simplex_tree.num_simplices() == 10 assert simplex_tree.num_vertices() == 4 - filtration_generator = simplex_tree.get_filtration() - assert(next(filtration_generator) == ([0], 0.0)) - assert(next(filtration_generator) == ([1], 0.0)) - assert(next(filtration_generator) == ([2], 0.0)) - assert(next(filtration_generator) == ([3], 0.0)) - assert(next(filtration_generator) == ([0, 1], 1.0)) - assert(next(filtration_generator) == ([0, 2], 1.0)) - assert(next(filtration_generator) == ([1, 3], 1.0)) - assert(next(filtration_generator) == ([2, 3], 1.0)) - assert(next(filtration_generator) == ([1, 2], 1.4142135623730951)) - assert(next(filtration_generator) == ([0, 3], 1.4142135623730951)) - with pytest.raises(StopIteration): - next(filtration_generator) + assert list(simplex_tree.get_filtration()) == [ + ([0], 0.0), + ([1], 0.0), + ([2], 0.0), + ([3], 0.0), + ([0, 1], 1.0), + ([0, 2], 1.0), + ([1, 3], 1.0), + ([2, 3], 1.0), + ([1, 2], 1.4142135623730951), + ([0, 3], 1.4142135623730951), + ] assert simplex_tree.get_star([0]) == [ ([0], 0.0), diff --git a/src/python/test/test_simplex_tree.py b/src/python/test/test_simplex_tree.py index 0f3db7ac..fa42f2ac 100755 --- a/src/python/test/test_simplex_tree.py +++ b/src/python/test/test_simplex_tree.py @@ -128,57 +128,55 @@ def test_expansion(): assert st.num_vertices() == 7 assert st.num_simplices() == 17 - filtration_generator = st.get_filtration() - assert(next(filtration_generator) == ([2], 0.1)) - assert(next(filtration_generator) == ([3], 0.1)) - assert(next(filtration_generator) == ([2, 3], 0.1)) - assert(next(filtration_generator) == ([0], 0.2)) - assert(next(filtration_generator) == ([0, 2], 0.2)) - assert(next(filtration_generator) == ([1], 0.3)) - assert(next(filtration_generator) == ([0, 1], 0.3)) - assert(next(filtration_generator) == ([1, 3], 0.4)) - assert(next(filtration_generator) == ([1, 2], 0.5)) - assert(next(filtration_generator) == ([5], 0.6)) - assert(next(filtration_generator) == ([6], 0.6)) - assert(next(filtration_generator) == ([5, 6], 0.6)) - assert(next(filtration_generator) == ([4], 0.7)) - assert(next(filtration_generator) == ([2, 4], 0.7)) - assert(next(filtration_generator) == ([0, 3], 0.8)) - assert(next(filtration_generator) == ([4, 6], 0.9)) - assert(next(filtration_generator) == ([3, 6], 1.0)) - with pytest.raises(StopIteration): - next(filtration_generator) + assert list(st.get_filtration()) == [ + ([2], 0.1), + ([3], 0.1), + ([2, 3], 0.1), + ([0], 0.2), + ([0, 2], 0.2), + ([1], 0.3), + ([0, 1], 0.3), + ([1, 3], 0.4), + ([1, 2], 0.5), + ([5], 0.6), + ([6], 0.6), + ([5, 6], 0.6), + ([4], 0.7), + ([2, 4], 0.7), + ([0, 3], 0.8), + ([4, 6], 0.9), + ([3, 6], 1.0), + ] st.expansion(3) assert st.num_vertices() == 7 assert st.num_simplices() == 22 st.initialize_filtration() - filtration_generator = st.get_filtration() - assert(next(filtration_generator) == ([2], 0.1)) - assert(next(filtration_generator) == ([3], 0.1)) - assert(next(filtration_generator) == ([2, 3], 0.1)) - assert(next(filtration_generator) == ([0], 0.2)) - assert(next(filtration_generator) == ([0, 2], 0.2)) - assert(next(filtration_generator) == ([1], 0.3)) - assert(next(filtration_generator) == ([0, 1], 0.3)) - assert(next(filtration_generator) == ([1, 3], 0.4)) - assert(next(filtration_generator) == ([1, 2], 0.5)) - assert(next(filtration_generator) == ([0, 1, 2], 0.5)) - assert(next(filtration_generator) == ([1, 2, 3], 0.5)) - assert(next(filtration_generator) == ([5], 0.6)) - assert(next(filtration_generator) == ([6], 0.6)) - assert(next(filtration_generator) == ([5, 6], 0.6)) - assert(next(filtration_generator) == ([4], 0.7)) - assert(next(filtration_generator) == ([2, 4], 0.7)) - assert(next(filtration_generator) == ([0, 3], 0.8)) - assert(next(filtration_generator) == ([0, 1, 3], 0.8)) - assert(next(filtration_generator) == ([0, 2, 3], 0.8)) - assert(next(filtration_generator) == ([0, 1, 2, 3], 0.8)) - assert(next(filtration_generator) == ([4, 6], 0.9)) - assert(next(filtration_generator) == ([3, 6], 1.0)) - with pytest.raises(StopIteration): - next(filtration_generator) + assert list(st.get_filtration()) == [ + ([2], 0.1), + ([3], 0.1), + ([2, 3], 0.1), + ([0], 0.2), + ([0, 2], 0.2), + ([1], 0.3), + ([0, 1], 0.3), + ([1, 3], 0.4), + ([1, 2], 0.5), + ([0, 1, 2], 0.5), + ([1, 2, 3], 0.5), + ([5], 0.6), + ([6], 0.6), + ([5, 6], 0.6), + ([4], 0.7), + ([2, 4], 0.7), + ([0, 3], 0.8), + ([0, 1, 3], 0.8), + ([0, 2, 3], 0.8), + ([0, 1, 2, 3], 0.8), + ([4, 6], 0.9), + ([3, 6], 1.0), + ] def test_automatic_dimension(): diff --git a/src/python/test/test_tangential_complex.py b/src/python/test/test_tangential_complex.py index 90e2c75b..fc500c45 100755 --- a/src/python/test/test_tangential_complex.py +++ b/src/python/test/test_tangential_complex.py @@ -38,15 +38,14 @@ def test_tangential(): assert st.num_simplices() == 6 assert st.num_vertices() == 4 - filtration_generator = st.get_filtration() - assert(next(filtration_generator) == ([0], 0.0)) - assert(next(filtration_generator) == ([1], 0.0)) - assert(next(filtration_generator) == ([2], 0.0)) - assert(next(filtration_generator) == ([0, 2], 0.0)) - assert(next(filtration_generator) == ([3], 0.0)) - assert(next(filtration_generator) == ([1, 3], 0.0)) - with pytest.raises(StopIteration): - next(filtration_generator) + assert list(st.get_filtration()) == [ + ([0], 0.0), + ([1], 0.0), + ([2], 0.0), + ([0, 2], 0.0), + ([3], 0.0), + ([1, 3], 0.0), + ] assert st.get_cofaces([0], 1) == [([0, 2], 0.0)] -- cgit v1.2.3 From 79de1437cb2fa0ab69465a2f2feabe09a12056eb Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau <10407034+VincentRouvreau@users.noreply.github.com> Date: Tue, 11 Feb 2020 17:51:40 +0100 Subject: Update src/python/include/Simplex_tree_interface.h Co-Authored-By: Marc Glisse --- src/python/include/Simplex_tree_interface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/python') diff --git a/src/python/include/Simplex_tree_interface.h b/src/python/include/Simplex_tree_interface.h index c0bbc3d9..878919cc 100644 --- a/src/python/include/Simplex_tree_interface.h +++ b/src/python/include/Simplex_tree_interface.h @@ -88,7 +88,7 @@ class Simplex_tree_interface : public Simplex_tree { for (auto vertex : Base::simplex_vertex_range(f_simplex)) { simplex.insert(simplex.begin(), vertex); } - return std::make_pair(simplex, Base::filtration(f_simplex)); + return std::make_pair(std::move(simplex), Base::filtration(f_simplex)); } Filtered_simplices get_skeleton(int dimension) { -- cgit v1.2.3 From 1edb818b38ace05b230319227e60838b796ddfc5 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Thu, 13 Feb 2020 11:08:44 +0100 Subject: simplex tree skeleton iterator --- src/python/gudhi/simplex_tree.pxd | 10 +++++++++- src/python/gudhi/simplex_tree.pyx | 15 ++++++--------- src/python/include/Simplex_tree_interface.h | 23 ++++++++++------------- src/python/test/test_simplex_tree.py | 8 ++++---- 4 files changed, 29 insertions(+), 27 deletions(-) (limited to 'src/python') diff --git a/src/python/gudhi/simplex_tree.pxd b/src/python/gudhi/simplex_tree.pxd index 1b0dc881..66c173a6 100644 --- a/src/python/gudhi/simplex_tree.pxd +++ b/src/python/gudhi/simplex_tree.pxd @@ -24,6 +24,13 @@ cdef extern from "Simplex_tree_interface.h" namespace "Gudhi": cdef cppclass Simplex_tree_simplex_handle "Gudhi::Simplex_tree_interface::Simplex_handle": pass + cdef cppclass Simplex_tree_skeleton_iterator "Gudhi::Simplex_tree_interface::Skeleton_simplex_iterator": + Simplex_tree_skeleton_iterator() + Simplex_tree_simplex_handle& operator*() + Simplex_tree_skeleton_iterator operator++() + bint operator!=(Simplex_tree_skeleton_iterator) + + cdef cppclass Simplex_tree_interface_full_featured "Gudhi::Simplex_tree_interface": Simplex_tree() double simplex_filtration(vector[int] simplex) @@ -37,7 +44,6 @@ cdef extern from "Simplex_tree_interface.h" namespace "Gudhi": bool find_simplex(vector[int] simplex) bool insert_simplex_and_subfaces(vector[int] simplex, double filtration) - vector[pair[vector[int], double]] get_skeleton(int dimension) vector[pair[vector[int], double]] get_star(vector[int] simplex) vector[pair[vector[int], double]] get_cofaces(vector[int] simplex, int dimension) @@ -49,6 +55,8 @@ cdef extern from "Simplex_tree_interface.h" namespace "Gudhi": pair[vector[int], double] get_simplex_and_filtration(Simplex_tree_simplex_handle f_simplex) vector[Simplex_tree_simplex_handle].const_iterator get_filtration_iterator_begin() vector[Simplex_tree_simplex_handle].const_iterator get_filtration_iterator_end() + Simplex_tree_skeleton_iterator get_skeleton_iterator_begin(int dimension) + Simplex_tree_skeleton_iterator get_skeleton_iterator_end(int dimension) cdef extern from "Persistent_cohomology_interface.h" namespace "Gudhi": cdef cppclass Simplex_tree_persistence_interface "Gudhi::Persistent_cohomology_interface>": diff --git a/src/python/gudhi/simplex_tree.pyx b/src/python/gudhi/simplex_tree.pyx index 308b3d2d..efac2d80 100644 --- a/src/python/gudhi/simplex_tree.pyx +++ b/src/python/gudhi/simplex_tree.pyx @@ -231,15 +231,12 @@ cdef class SimplexTree: :returns: The (simplices of the) skeleton of a maximum dimension. :rtype: list of tuples(simplex, filtration) """ - cdef vector[pair[vector[int], double]] skeleton \ - = self.get_ptr().get_skeleton(dimension) - ct = [] - for filtered_simplex in skeleton: - v = [] - for vertex in filtered_simplex.first: - v.append(vertex) - ct.append((v, filtered_simplex.second)) - return ct + cdef Simplex_tree_skeleton_iterator it = self.get_ptr().get_skeleton_iterator_begin(dimension) + cdef Simplex_tree_skeleton_iterator end = self.get_ptr().get_skeleton_iterator_end(dimension) + + while it != end: + yield self.get_ptr().get_simplex_and_filtration(dereference(it)) + preincrement(it) def get_star(self, simplex): """This function returns the star of a given N-simplex. diff --git a/src/python/include/Simplex_tree_interface.h b/src/python/include/Simplex_tree_interface.h index 878919cc..55d5af97 100644 --- a/src/python/include/Simplex_tree_interface.h +++ b/src/python/include/Simplex_tree_interface.h @@ -35,6 +35,7 @@ class Simplex_tree_interface : public Simplex_tree { using Simplex = std::vector; using Simplex_and_filtration = std::pair; using Filtered_simplices = std::vector; + using Skeleton_simplex_iterator = typename Base::Skeleton_simplex_iterator; public: bool find_simplex(const Simplex& vh) { @@ -91,18 +92,6 @@ class Simplex_tree_interface : public Simplex_tree { return std::make_pair(std::move(simplex), Base::filtration(f_simplex)); } - Filtered_simplices get_skeleton(int dimension) { - Filtered_simplices skeletons; - for (auto f_simplex : Base::skeleton_simplex_range(dimension)) { - Simplex simplex; - for (auto vertex : Base::simplex_vertex_range(f_simplex)) { - simplex.insert(simplex.begin(), vertex); - } - skeletons.push_back(std::make_pair(simplex, Base::filtration(f_simplex))); - } - return skeletons; - } - Filtered_simplices get_star(const Simplex& simplex) { Filtered_simplices star; for (auto f_simplex : Base::star_simplex_range(Base::find(simplex))) { @@ -134,13 +123,21 @@ class Simplex_tree_interface : public Simplex_tree { // Iterator over the simplex tree typename std::vector::const_iterator get_filtration_iterator_begin() { - Base::initialize_filtration(); + // Base::initialize_filtration(); already performed in filtration_simplex_range return Base::filtration_simplex_range().begin(); } typename std::vector::const_iterator get_filtration_iterator_end() { return Base::filtration_simplex_range().end(); } + + Skeleton_simplex_iterator get_skeleton_iterator_begin(int dimension) { + return Base::skeleton_simplex_range(dimension).begin(); + } + + Skeleton_simplex_iterator get_skeleton_iterator_end(int dimension) { + return Base::skeleton_simplex_range(dimension).end(); + } }; } // namespace Gudhi diff --git a/src/python/test/test_simplex_tree.py b/src/python/test/test_simplex_tree.py index fa42f2ac..eca3807b 100755 --- a/src/python/test/test_simplex_tree.py +++ b/src/python/test/test_simplex_tree.py @@ -56,7 +56,7 @@ def test_insertion(): assert st.filtration([1]) == 0.0 # skeleton test - assert st.get_skeleton(2) == [ + assert list(st.get_skeleton(2)) == [ ([0, 1, 2], 4.0), ([0, 1], 0.0), ([0, 2], 4.0), @@ -65,7 +65,7 @@ def test_insertion(): ([1], 0.0), ([2], 4.0), ] - assert st.get_skeleton(1) == [ + assert list(st.get_skeleton(1)) == [ ([0, 1], 0.0), ([0, 2], 4.0), ([0], 0.0), @@ -73,12 +73,12 @@ def test_insertion(): ([1], 0.0), ([2], 4.0), ] - assert st.get_skeleton(0) == [([0], 0.0), ([1], 0.0), ([2], 4.0)] + assert list(st.get_skeleton(0)) == [([0], 0.0), ([1], 0.0), ([2], 4.0)] # remove_maximal_simplex test assert st.get_cofaces([0, 1, 2], 1) == [] st.remove_maximal_simplex([0, 1, 2]) - assert st.get_skeleton(2) == [ + assert list(st.get_skeleton(2)) == [ ([0, 1], 0.0), ([0, 2], 4.0), ([0], 0.0), -- cgit v1.2.3 From cbb350d81a8c4acadf31b604aaebde209f462e55 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Wed, 26 Feb 2020 09:32:32 +0100 Subject: Code review: remove import pytest leftovers --- src/python/test/test_euclidean_witness_complex.py | 1 - src/python/test/test_rips_complex.py | 1 - src/python/test/test_simplex_tree.py | 1 - src/python/test/test_tangential_complex.py | 1 - 4 files changed, 4 deletions(-) (limited to 'src/python') diff --git a/src/python/test/test_euclidean_witness_complex.py b/src/python/test/test_euclidean_witness_complex.py index 47196a2a..f3664d39 100755 --- a/src/python/test/test_euclidean_witness_complex.py +++ b/src/python/test/test_euclidean_witness_complex.py @@ -9,7 +9,6 @@ """ import gudhi -import pytest __author__ = "Vincent Rouvreau" __copyright__ = "Copyright (C) 2016 Inria" diff --git a/src/python/test/test_rips_complex.py b/src/python/test/test_rips_complex.py index f5c086cb..b86e7498 100755 --- a/src/python/test/test_rips_complex.py +++ b/src/python/test/test_rips_complex.py @@ -10,7 +10,6 @@ from gudhi import RipsComplex from math import sqrt -import pytest __author__ = "Vincent Rouvreau" __copyright__ = "Copyright (C) 2016 Inria" diff --git a/src/python/test/test_simplex_tree.py b/src/python/test/test_simplex_tree.py index eca3807b..04b26e92 100755 --- a/src/python/test/test_simplex_tree.py +++ b/src/python/test/test_simplex_tree.py @@ -9,7 +9,6 @@ """ from gudhi import SimplexTree -import pytest __author__ = "Vincent Rouvreau" __copyright__ = "Copyright (C) 2016 Inria" diff --git a/src/python/test/test_tangential_complex.py b/src/python/test/test_tangential_complex.py index fc500c45..8668a2e0 100755 --- a/src/python/test/test_tangential_complex.py +++ b/src/python/test/test_tangential_complex.py @@ -9,7 +9,6 @@ """ from gudhi import TangentialComplex, SimplexTree -import pytest __author__ = "Vincent Rouvreau" __copyright__ = "Copyright (C) 2016 Inria" -- cgit v1.2.3 From f85742957276cbd15a2724c86cbc7a8279d62ef9 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Wed, 26 Feb 2020 11:11:32 +0100 Subject: Code review: add some comments about range.begin() and range.end() --- src/python/include/Simplex_tree_interface.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/python') diff --git a/src/python/include/Simplex_tree_interface.h b/src/python/include/Simplex_tree_interface.h index 55d5af97..66ce5afd 100644 --- a/src/python/include/Simplex_tree_interface.h +++ b/src/python/include/Simplex_tree_interface.h @@ -124,18 +124,22 @@ class Simplex_tree_interface : public Simplex_tree { // Iterator over the simplex tree typename std::vector::const_iterator get_filtration_iterator_begin() { // Base::initialize_filtration(); already performed in filtration_simplex_range + // this specific case works because the range is just a pair of iterators - won't work if range was a vector return Base::filtration_simplex_range().begin(); } typename std::vector::const_iterator get_filtration_iterator_end() { + // this specific case works because the range is just a pair of iterators - won't work if range was a vector return Base::filtration_simplex_range().end(); } Skeleton_simplex_iterator get_skeleton_iterator_begin(int dimension) { + // this specific case works because the range is just a pair of iterators - won't work if range was a vector return Base::skeleton_simplex_range(dimension).begin(); } Skeleton_simplex_iterator get_skeleton_iterator_end(int dimension) { + // this specific case works because the range is just a pair of iterators - won't work if range was a vector return Base::skeleton_simplex_range(dimension).end(); } }; -- cgit v1.2.3 From d1d25b4ae8d0f778f0e2b3f98449d7d13e466013 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Tue, 10 Mar 2020 09:04:45 +0100 Subject: Fix example - only fails on OSx --- src/python/example/alpha_complex_from_points_example.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/python') diff --git a/src/python/example/alpha_complex_from_points_example.py b/src/python/example/alpha_complex_from_points_example.py index 465632eb..73faf17c 100755 --- a/src/python/example/alpha_complex_from_points_example.py +++ b/src/python/example/alpha_complex_from_points_example.py @@ -46,6 +46,9 @@ if simplex_tree.find([4]): else: print("[4] Not found...") +# Some insertions, simplex_tree needs to initialize filtrations +simplex_tree.initialize_filtration() + print("dimension=", simplex_tree.dimension()) print("filtrations=") for simplex_with_filtration in simplex_tree.get_filtration(): -- cgit v1.2.3 From 6ed2a97421a223b4ebe31b91f48d779c2209f470 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Mon, 16 Mar 2020 13:38:18 +0100 Subject: Add get_simplices method - contrary to get_filtration method, sort is not performed --- src/Simplex_tree/example/simple_simplex_tree.cpp | 13 +++++++++++-- src/python/example/simplex_tree_example.py | 4 ++++ src/python/gudhi/simplex_tree.pxd | 8 ++++++++ src/python/gudhi/simplex_tree.pyx | 17 ++++++++++++++++- src/python/include/Simplex_tree_interface.h | 11 +++++++++++ src/python/test/test_simplex_tree.py | 12 ++++++++++++ 6 files changed, 62 insertions(+), 3 deletions(-) (limited to 'src/python') diff --git a/src/Simplex_tree/example/simple_simplex_tree.cpp b/src/Simplex_tree/example/simple_simplex_tree.cpp index 4353939f..47ea7e36 100644 --- a/src/Simplex_tree/example/simple_simplex_tree.cpp +++ b/src/Simplex_tree/example/simple_simplex_tree.cpp @@ -166,10 +166,19 @@ int main(int argc, char* const argv[]) { // ++ GENERAL VARIABLE SET std::cout << "********************************************************************\n"; - // Display the Simplex_tree - Can not be done in the middle of 2 inserts std::cout << "* The complex contains " << simplexTree.num_simplices() << " simplices\n"; std::cout << " - dimension " << simplexTree.dimension() << "\n"; - std::cout << "* Iterator on Simplices in the filtration, with [filtration value]:\n"; + std::cout << "* Iterator on simplices, with [filtration value]:\n"; + for (Simplex_tree::Simplex_handle f_simplex : simplexTree.complex_simplex_range()) { + std::cout << " " + << "[" << simplexTree.filtration(f_simplex) << "] "; + for (auto vertex : simplexTree.simplex_vertex_range(f_simplex)) std::cout << "(" << vertex << ")"; + std::cout << std::endl; + } + + std::cout << "********************************************************************\n"; + // Can not be done in the middle of 2 inserts + std::cout << "* Iterator on simplices sorted by filtration values, with [filtration value]:\n"; for (auto f_simplex : simplexTree.filtration_simplex_range()) { std::cout << " " << "[" << simplexTree.filtration(f_simplex) << "] "; diff --git a/src/python/example/simplex_tree_example.py b/src/python/example/simplex_tree_example.py index 7f20c389..34833899 100755 --- a/src/python/example/simplex_tree_example.py +++ b/src/python/example/simplex_tree_example.py @@ -38,6 +38,10 @@ else: print("dimension=", st.dimension()) +print("simplices=") +for simplex_with_filtration in st.get_simplices(): + print("(%s, %.2f)" % tuple(simplex_with_filtration)) + st.initialize_filtration() print("filtration=") for simplex_with_filtration in st.get_filtration(): diff --git a/src/python/gudhi/simplex_tree.pxd b/src/python/gudhi/simplex_tree.pxd index 66c173a6..82f155de 100644 --- a/src/python/gudhi/simplex_tree.pxd +++ b/src/python/gudhi/simplex_tree.pxd @@ -24,6 +24,12 @@ cdef extern from "Simplex_tree_interface.h" namespace "Gudhi": cdef cppclass Simplex_tree_simplex_handle "Gudhi::Simplex_tree_interface::Simplex_handle": pass + cdef cppclass Simplex_tree_simplices_iterator "Gudhi::Simplex_tree_interface::Complex_simplex_iterator": + Simplex_tree_simplices_iterator() + Simplex_tree_simplex_handle& operator*() + Simplex_tree_simplices_iterator operator++() + bint operator!=(Simplex_tree_simplices_iterator) + cdef cppclass Simplex_tree_skeleton_iterator "Gudhi::Simplex_tree_interface::Skeleton_simplex_iterator": Simplex_tree_skeleton_iterator() Simplex_tree_simplex_handle& operator*() @@ -53,6 +59,8 @@ cdef extern from "Simplex_tree_interface.h" namespace "Gudhi": bool make_filtration_non_decreasing() # 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() + Simplex_tree_simplices_iterator get_simplices_iterator_end() vector[Simplex_tree_simplex_handle].const_iterator get_filtration_iterator_begin() vector[Simplex_tree_simplex_handle].const_iterator get_filtration_iterator_end() Simplex_tree_skeleton_iterator get_skeleton_iterator_begin(int dimension) diff --git a/src/python/gudhi/simplex_tree.pyx b/src/python/gudhi/simplex_tree.pyx index efac2d80..c01cc905 100644 --- a/src/python/gudhi/simplex_tree.pyx +++ b/src/python/gudhi/simplex_tree.pyx @@ -208,10 +208,25 @@ cdef class SimplexTree: return self.get_ptr().insert_simplex_and_subfaces(csimplex, filtration) - def get_filtration(self): + def get_simplices(self): """This function returns a generator with simplices and their given filtration values. + :returns: The simplices. + :rtype: generator with tuples(simplex, filtration) + """ + cdef Simplex_tree_simplices_iterator it = self.get_ptr().get_simplices_iterator_begin() + cdef Simplex_tree_simplices_iterator end = self.get_ptr().get_simplices_iterator_end() + cdef Simplex_tree_simplex_handle sh = dereference(it) + + while it != end: + yield self.get_ptr().get_simplex_and_filtration(dereference(it)) + preincrement(it) + + def get_filtration(self): + """This function returns a generator with simplices and their given + filtration values sorted by increasing filtration values. + :returns: The simplices sorted by increasing filtration values. :rtype: generator with tuples(simplex, filtration) """ diff --git a/src/python/include/Simplex_tree_interface.h b/src/python/include/Simplex_tree_interface.h index 66ce5afd..4a7062d6 100644 --- a/src/python/include/Simplex_tree_interface.h +++ b/src/python/include/Simplex_tree_interface.h @@ -36,6 +36,7 @@ class Simplex_tree_interface : public Simplex_tree { using Simplex_and_filtration = std::pair; using Filtered_simplices = std::vector; using Skeleton_simplex_iterator = typename Base::Skeleton_simplex_iterator; + using Complex_simplex_iterator = typename Base::Complex_simplex_iterator; public: bool find_simplex(const Simplex& vh) { @@ -122,6 +123,16 @@ class Simplex_tree_interface : public Simplex_tree { } // Iterator over the simplex tree + Complex_simplex_iterator get_simplices_iterator_begin() { + // this specific case works because the range is just a pair of iterators - won't work if range was a vector + return Base::complex_simplex_range().begin(); + } + + Complex_simplex_iterator get_simplices_iterator_end() { + // this specific case works because the range is just a pair of iterators - won't work if range was a vector + return Base::complex_simplex_range().end(); + } + typename std::vector::const_iterator get_filtration_iterator_begin() { // Base::initialize_filtration(); already performed in filtration_simplex_range // this specific case works because the range is just a pair of iterators - won't work if range was a vector diff --git a/src/python/test/test_simplex_tree.py b/src/python/test/test_simplex_tree.py index 04b26e92..f7848379 100755 --- a/src/python/test/test_simplex_tree.py +++ b/src/python/test/test_simplex_tree.py @@ -249,3 +249,15 @@ def test_make_filtration_non_decreasing(): assert st.filtration([3, 4, 5]) == 2.0 assert st.filtration([3, 4]) == 2.0 assert st.filtration([4, 5]) == 2.0 + +def test_simplices_iterator(): + st = SimplexTree() + + assert st.insert([0, 1, 2], filtration=4.0) == True + assert st.insert([2, 3, 4], filtration=2.0) == True + + for simplex in st.get_simplices(): + print("simplex is: ", simplex[0]) + assert st.find(simplex[0]) == True + print("filtration is: ", simplex[1]) + assert st.filtration(simplex[0]) == simplex[1] -- cgit v1.2.3