From 49d24a5e4cd1f45e66f44fc27a6ff2b0268d8eb0 Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau Date: Fri, 25 Oct 2024 17:53:52 +0200 Subject: [PATCH 01/15] Copy data when Simplex_tree has the same options. No copy for transforming constructor --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 107 +++++++++++------- src/Simplex_tree/test/CMakeLists.txt | 3 + .../test/simplex_tree_unit_test.cpp | 25 +--- 3 files changed, 71 insertions(+), 64 deletions(-) diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index 45a955dd87..c0935889d4 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -61,7 +61,7 @@ namespace Gudhi { -/** \addtogroup simplex_tree +/** \addtogroup simplex_tree * @{ */ @@ -280,12 +280,12 @@ class Simplex_tree { typedef Simplex_tree_complex_simplex_iterator Complex_simplex_iterator; /** \brief Range over the simplices of the simplicial complex. */ typedef boost::iterator_range Complex_simplex_range; - /** \brief Iterator over the simplices of the skeleton of the simplicial complex, for a given + /** \brief Iterator over the simplices of the skeleton of the simplicial complex, for a given * dimension. * * 'value_type' is Simplex_handle. */ typedef Simplex_tree_skeleton_simplex_iterator Skeleton_simplex_iterator; - /** \brief Range over the simplices of the skeleton of the simplicial complex, for a given + /** \brief Range over the simplices of the skeleton of the simplicial complex, for a given * dimension. */ typedef boost::iterator_range Skeleton_simplex_range; /** \brief Range over the simplices of the simplicial complex, ordered by the filtration. */ @@ -299,7 +299,7 @@ class Simplex_tree { /** \name Range and iterator methods * @{ */ - /** \brief Returns a range over the vertices of the simplicial complex. + /** \brief Returns a range over the vertices of the simplicial complex. * The order is increasing according to < on Vertex_handles.*/ Complex_vertex_range complex_vertex_range() { return Complex_vertex_range( @@ -418,7 +418,7 @@ class Simplex_tree { * are already implicitly convertible if the concept of @ref SimplexTreeOptions is respected (note that there is * an eventual loss of precision or an undefined behaviour if a value is converted into a new type too small to * contain it). Any extra data (@ref Simplex_data) stored in the simplices are ignored in the copy for now. - * + * * @tparam OtherSimplexTreeOptions Options of the given simplex tree. * @tparam F Method taking an OtherSimplexTreeOptions::Filtration_value as input and returning an * Options::Filtration_value. @@ -509,7 +509,21 @@ class Simplex_tree { for (auto& map_el : root_.members()) { map_el.second.assign_children(&root_); } - rec_copy( + // Specific for optionnal data + if constexpr (!std::is_same_v) { + auto dst_iter = root_.members().begin(); + auto src_iter = root_source.members().begin(); + + while(dst_iter != root_.members().end() || src_iter != root_source.members().end()) { + dst_iter->second.data() = src_iter->second.data(); + dst_iter++; + src_iter++; + } + // Check in debug mode members data were copied + assert(dst_iter == root_.members().end()); + assert(src_iter == root_source.members().end()); + } + rec_copy( &root_, &root_source, [](const Filtration_value& fil) -> const Filtration_value& { return fil; }); } @@ -533,11 +547,11 @@ class Simplex_tree { } } - rec_copy(&root_, &root_source, translate_filtration_value); + rec_copy(&root_, &root_source, translate_filtration_value); } /** \brief depth first search, inserts simplices when reaching a leaf. */ - template + template void rec_copy(Siblings *sib, OtherSiblings *sib_source, F&& translate_filtration_value) { auto sh_source = sib_source->members().begin(); for (auto sh = sib->members().begin(); sh != sib->members().end(); ++sh, ++sh_source) { @@ -548,18 +562,23 @@ class Simplex_tree { newsib->members_.reserve(sh_source->second.children()->members().size()); } for (auto & child : sh_source->second.children()->members()){ + Dictionary_it new_it{}; if constexpr (store_key && Options::store_key) { - newsib->members_.emplace_hint( + new_it = newsib->members_.emplace_hint( newsib->members_.end(), child.first, Node(newsib, translate_filtration_value(child.second.filtration()), child.second.key())); } else { - newsib->members_.emplace_hint(newsib->members_.end(), + new_it = newsib->members_.emplace_hint(newsib->members_.end(), child.first, Node(newsib, translate_filtration_value(child.second.filtration()))); } + // Specific for optionnal data + if constexpr (copy_data && !std::is_same_v) { + new_it->second.data() = child.second.data(); + } } - rec_copy(newsib, sh_source->second.children(), translate_filtration_value); + rec_copy(newsib, sh_source->second.children(), translate_filtration_value); sh->second.assign_children(newsib); } } @@ -758,7 +777,7 @@ class Simplex_tree { /** * @brief Returns the dimension of the given sibling simplices. - * + * * @param curr_sib Pointer to the sibling container. * @return Height of the siblings in the tree (root counts as zero to make the height correspond to the dimension). */ @@ -918,7 +937,7 @@ class Simplex_tree { * we assign this simplex with the new value 'filtration', and set the Simplex_handle field of the * output pair to the Simplex_handle of the simplex. Otherwise, we set the Simplex_handle part to * null_simplex. - * + * */ template > std::pair insert_simplex_raw(const RandomVertexHandleRange& simplex, @@ -1229,7 +1248,7 @@ class Simplex_tree { * \param simplex represent the simplex of which we search the star * \return Vector of Simplex_tree::Simplex_handle (empty vector if no star found) when * SimplexTreeOptions::link_nodes_by_label is false. - * + * * Simplex_tree::Simplex_handle range for an optimized search for the star of a simplex when * SimplexTreeOptions::link_nodes_by_label is true. */ @@ -1243,7 +1262,7 @@ class Simplex_tree { * cofaces (equivalent of star function) * \return Vector of Simplex_tree::Simplex_handle (empty vector if no cofaces found) when * SimplexTreeOptions::link_nodes_by_label is false. - * + * * Simplex_tree::Simplex_handle range for an optimized search for the coface of a simplex when * SimplexTreeOptions::link_nodes_by_label is true. */ @@ -1452,7 +1471,7 @@ class Simplex_tree { * @brief Adds a new vertex or a new edge in a flag complex, as well as all * simplices of its star, defined to maintain the property * of the complex to be a flag complex, truncated at dimension dim_max. - * To insert a new edge, the two given vertex handles have to correspond + * To insert a new edge, the two given vertex handles have to correspond * to the two end points of the edge. To insert a new vertex, the handles * have to be twice the same and correspond to the number you want assigned * to it. I.e., to insert vertex \f$i\f$, give \f$u = v = i\f$. @@ -1460,7 +1479,7 @@ class Simplex_tree { * the simplex tree, so the behaviour is undefined if called on an existing * edge. Also, the vertices of an edge have to be inserted before the edge. * - * @param[in] u,v Vertex_handle representing the new edge + * @param[in] u,v Vertex_handle representing the new edge * (@p v != @p u) or the new vertex (@p v == @p u). * @param[in] fil Filtration value of the edge. * @param[in] dim_max Maximal dimension of the expansion. @@ -1478,8 +1497,8 @@ class Simplex_tree { * filtration values, the method `make_filtration_non_decreasing()` has to be * called at the end of the insertions to restore the intended filtration. * Note that even then, an edge has to be inserted after its vertices. - * @warning The method assumes that the given edge or vertex was not already - * contained in the simplex tree, so the behaviour is undefined if called on + * @warning The method assumes that the given edge or vertex was not already + * contained in the simplex tree, so the behaviour is undefined if called on * an existing simplex. */ void insert_edge_as_flag( Vertex_handle u @@ -2084,7 +2103,7 @@ class Simplex_tree { bool prune_above_dimension(int dimension) { if (dimension >= dimension_) return false; - + bool modified = false; if (dimension < 0) { if (num_vertices() > 0) { @@ -2185,17 +2204,17 @@ class Simplex_tree { } } - /** \brief Retrieve the original filtration value for a given simplex in the Simplex_tree. Since the + /** \brief Retrieve the original filtration value for a given simplex in the Simplex_tree. Since the * computation of extended persistence requires modifying the filtration values, this function can be used * to recover the original values. Moreover, computing extended persistence requires adding new simplices * in the Simplex_tree. Hence, this function also outputs the type of each simplex. It can be either UP (which means * that the simplex was present originally, and is thus part of the ascending extended filtration), DOWN (which means * that the simplex is the cone of an original simplex, and is thus part of the descending extended filtration) or * EXTRA (which means the simplex is the cone point). See the definition of Extended_simplex_type. Note that if the simplex type is DOWN, the original filtration value - * is set to be the original filtration value of the corresponding (not coned) original simplex. + * is set to be the original filtration value of the corresponding (not coned) original simplex. * \pre This function should be called only if `extend_filtration()` has been called first! * \post The output filtration value is supposed to be the same, but might be a little different, than the - * original filtration value, due to the internal transformation (scaling to [-2,-1]) that is + * original filtration value, due to the internal transformation (scaling to [-2,-1]) that is * performed on the original filtration values during the computation of extended persistence. * @param[in] f Filtration value of the simplex in the extended (i.e., modified) filtration. * @param[in] efd Structure containing the minimum and maximum values of the original filtration. This the output of `extend_filtration()`. @@ -2215,12 +2234,12 @@ class Simplex_tree { return p; }; - /** \brief Extend filtration for computing extended persistence. - * This function only uses the filtration values at the 0-dimensional simplices, - * and computes the extended persistence diagram induced by the lower-star filtration - * computed with these values. - * \post Note that after calling this function, the filtration - * values are actually modified. The function `decode_extended_filtration()` + /** \brief Extend filtration for computing extended persistence. + * This function only uses the filtration values at the 0-dimensional simplices, + * and computes the extended persistence diagram induced by the lower-star filtration + * computed with these values. + * \post Note that after calling this function, the filtration + * values are actually modified. The function `decode_extended_filtration()` * retrieves the original values and outputs the extended simplex type. * @exception std::invalid_argument In debug mode if the Simplex tree contains a vertex with the largest * Vertex_handle, as this method requires to create an extra vertex internally. @@ -2241,7 +2260,7 @@ class Simplex_tree { maxval = std::max(maxval, f); maxvert = std::max(sh->first, maxvert); } - + GUDHI_CHECK(maxvert < std::numeric_limits::max(), std::invalid_argument("Simplex_tree contains a vertex with the largest Vertex_handle")); maxvert++; @@ -2280,7 +2299,7 @@ class Simplex_tree { // Automatically assign good values for simplices this->make_filtration_non_decreasing(); - // Return the filtration data + // Return the filtration data return Extended_filtration_data(minval, maxval); } @@ -2398,14 +2417,14 @@ class Simplex_tree { //decltype(testPtr) = boost::intrusive::compact_rbtree_node* decltype(testPtr) sh_ptr = decltype(testPtr)((const char*)(&node) - shift); //shifts from node to pointer - //decltype(testIIt) = + //decltype(testIIt) = //boost::intrusive::tree_iterator< // boost::intrusive::bhtraits< // boost::container::base_node< // std::pair>, // boost::container::dtl::intrusive_tree_hook, true>, - // boost::intrusive::rbtree_node_traits, - // boost::intrusive::normal_link, + // boost::intrusive::rbtree_node_traits, + // boost::intrusive::normal_link, // boost::intrusive::dft_tag, // 3>, // false> @@ -2482,9 +2501,9 @@ class Simplex_tree { public: /** @private @brief Returns the serialization required buffer size. - * + * * @return The exact serialization required size in number of bytes. - * + * * @warning It is meant to return the same size with the same SimplexTreeOptions and on a computer with the same * architecture. */ @@ -2497,14 +2516,14 @@ class Simplex_tree { #endif // DEBUG_TRACES return buffer_byte_size; } - + /** @private @brief Serialize the Simplex tree - Flatten it in a user given array of char - * + * * @param[in] buffer An array of char allocated with enough space (cf. Gudhi::simplex_tree::get_serialization_size) * @param[in] buffer_size The buffer size. - * + * * @exception std::invalid_argument If serialization does not match exactly the buffer_size value. - * + * * @warning Serialize/Deserialize is not portable. It is meant to be read in a Simplex_tree with the same * SimplexTreeOptions and on a computer with the same architecture. */ @@ -2565,16 +2584,16 @@ class Simplex_tree { public: /** @private @brief Deserialize the array of char (flatten version of the tree) to initialize a Simplex tree. * It is the user's responsibility to provide an 'empty' Simplex_tree, there is no guarantee otherwise. - * + * * @param[in] buffer A pointer on a buffer that contains a serialized Simplex_tree. * @param[in] buffer_size The size of the buffer. - * + * * @exception std::invalid_argument In case the deserialization does not finish at the correct buffer_size. * @exception std::logic_error In debug mode, if the Simplex_tree is not 'empty'. - * + * * @warning Serialize/Deserialize is not portable. It is meant to be read in a Simplex_tree with the same * SimplexTreeOptions and on a computer with the same architecture. - * + * */ void deserialize(const char* buffer, const std::size_t buffer_size) { GUDHI_CHECK(num_vertices() == 0, std::logic_error("Simplex_tree::deserialize - Simplex_tree must be empty")); diff --git a/src/Simplex_tree/test/CMakeLists.txt b/src/Simplex_tree/test/CMakeLists.txt index 5f441b338b..55160603af 100644 --- a/src/Simplex_tree/test/CMakeLists.txt +++ b/src/Simplex_tree/test/CMakeLists.txt @@ -29,3 +29,6 @@ gudhi_add_boost_test(Simplex_tree_edge_expansion_unit_test) add_executable_with_targets(Simplex_tree_extended_filtration_test_unit simplex_tree_extended_filtration_unit_test.cpp TBB::tbb) gudhi_add_boost_test(Simplex_tree_extended_filtration_test_unit) + +add_executable_with_targets(Simplex_tree_data_test_unit simplex_tree_data_unit_test.cpp TBB::tbb) +gudhi_add_boost_test(Simplex_tree_data_test_unit) diff --git a/src/Simplex_tree/test/simplex_tree_unit_test.cpp b/src/Simplex_tree/test/simplex_tree_unit_test.cpp index d0dc0140ec..31f6296ab0 100644 --- a/src/Simplex_tree/test/simplex_tree_unit_test.cpp +++ b/src/Simplex_tree/test/simplex_tree_unit_test.cpp @@ -498,7 +498,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(NSimplexAndSubfaces_tree_insertion, typeST, list_o BOOST_CHECK(vertex == SimplexVector6[position]); position++; } - + /* Inserted simplex: */ /* 1 6 */ /* o---o */ @@ -818,7 +818,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(copy_move_on_simplex_tree, typeST, list_of_tested_ std::clog << "Printing st - address = " << &st << std::endl; - // Copy constructor + // Copy constructor typeST st_copy = st; std::clog << "Printing a copy of st - address = " << &st_copy << std::endl; @@ -827,7 +827,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(copy_move_on_simplex_tree, typeST, list_of_tested_ // Check there is a new simplex tree reference BOOST_CHECK(&st != &st_copy); - // Move constructor + // Move constructor typeST st_move = std::move(st); std::clog << "Printing a move of st - address = " << &st_move << std::endl; @@ -836,14 +836,14 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(copy_move_on_simplex_tree, typeST, list_of_tested_ // Check there is a new simplex tree reference BOOST_CHECK(&st_move != &st_copy); BOOST_CHECK(&st_move != &st); - + typeST st_empty; // Check st has been emptied by the move BOOST_CHECK(st == st_empty); BOOST_CHECK(st.dimension() == -1); BOOST_CHECK(st.num_simplices() == 0); BOOST_CHECK(st.num_vertices() == (size_t)0); - + std::clog << "Printing st once again- address = " << &st << std::endl; } @@ -1227,18 +1227,3 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(for_each_simplex_skip_iteration, typeST, list_of_t BOOST_CHECK(num_simplices_by_dim_until_two[0] == num_simplices_by_dim[0]); BOOST_CHECK(num_simplices_by_dim_until_two[1] == num_simplices_by_dim[1]); } - -struct Options_with_int_data : Simplex_tree_options_minimal { - typedef int Simplex_data; -}; - -BOOST_AUTO_TEST_CASE(simplex_data) { - Simplex_tree st; - st.insert_simplex_and_subfaces({0, 1}); - st.insert_simplex_and_subfaces({2, 1}); - st.insert_simplex_and_subfaces({0, 2}); - st.simplex_data(st.find({0, 1})) = 5; - st.expansion(3); - st.simplex_data(st.find({0, 1, 2})) = 4; - BOOST_CHECK(st.simplex_data(st.find({0, 1})) == 5); -} From 9ba4aa9de314cea6b4726be56e0b788509367ddf Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau Date: Fri, 25 Oct 2024 17:55:47 +0200 Subject: [PATCH 02/15] test was splitted and forgotten --- .../test/simplex_tree_data_unit_test.cpp | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 src/Simplex_tree/test/simplex_tree_data_unit_test.cpp diff --git a/src/Simplex_tree/test/simplex_tree_data_unit_test.cpp b/src/Simplex_tree/test/simplex_tree_data_unit_test.cpp new file mode 100644 index 0000000000..cc74220dac --- /dev/null +++ b/src/Simplex_tree/test/simplex_tree_data_unit_test.cpp @@ -0,0 +1,78 @@ +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. + * Author(s): Marc Glisse, Vincent Rouvreau + * + * Copyright (C) 2024 Inria + * + * Modification(s): + * - 2024/11 Vincent Rouvreau: Move data test from simplex_tree_unit_test + * - YYYY/MM Author: Description of the modification + */ + +#include +#include + +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_MODULE "simplex_tree_data" +#include + +#include "gudhi/Simplex_tree.h" + +using namespace Gudhi; + +struct Options_with_int_data : Simplex_tree_options_minimal { + typedef int Simplex_data; +}; + +BOOST_AUTO_TEST_CASE(simplex_data) { + Simplex_tree st; + st.insert_simplex_and_subfaces({0, 1}); + st.insert_simplex_and_subfaces({2, 1}); + st.insert_simplex_and_subfaces({0, 2}); + st.simplex_data(st.find({0, 1})) = 5; + st.expansion(3); + st.simplex_data(st.find({0, 1, 2})) = 4; + BOOST_CHECK(st.simplex_data(st.find({0, 1})) == 5); +} + +struct Options_with_string_data : Simplex_tree_options_full_featured { + using Simplex_data = std::string; +}; + +BOOST_AUTO_TEST_CASE(simplex_data_copy) { + Simplex_tree stree; + stree.insert_simplex_and_subfaces({0, 1}, 1.); + stree.simplex_data(stree.find({0, 1})) = "{0, 1}"; + // vertices have a specific algorithm, so let's test one data on a vertex + stree.simplex_data(stree.find({0})) = "{0}"; + stree.insert_simplex_and_subfaces({2, 1}, 2.); + stree.simplex_data(stree.find({1, 2})) = "{1, 2}"; + stree.insert_simplex_and_subfaces({0, 2}, 3.); + stree.simplex_data(stree.find({0, 2})) = "{0, 2}"; + std::clog << "Iterator on stree:\n"; + for (auto simplex : stree.complex_simplex_range()) { + std::clog << "("; + for (auto vertex : stree.simplex_vertex_range(simplex)) { + std::clog << vertex << " "; + } + std::clog << ") filtration=" << stree.filtration(simplex) << " - data='" << stree.simplex_data(simplex) << "'\n"; + } + Simplex_tree stree_copy(stree); + std::clog << "\nIterator on copy:\n"; + for (auto simplex : stree_copy.complex_simplex_range()) { + std::vector::Vertex_handle> vec_of_vertices {}; + std::clog << "("; + for (auto vertex : stree_copy.simplex_vertex_range(simplex)) { + std::clog << vertex << " "; + vec_of_vertices.push_back(vertex); + } + std::clog << ")"; + auto sh = stree.find(vec_of_vertices); + BOOST_CHECK(sh != stree.null_simplex()); + std::clog << " filtration=" << stree_copy.filtration(simplex) << " versus " << stree.filtration(sh); + std::clog << " - data='" << stree_copy.simplex_data(simplex) << "' versus '" << stree.simplex_data(sh) << "'\n"; + BOOST_CHECK(stree_copy.filtration(simplex) == stree.filtration(sh)); + BOOST_CHECK(stree_copy.simplex_data(simplex) == stree.simplex_data(sh)); + } + +} From 3c0dc0362ac9e90727cb421b330e86050c331e66 Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau Date: Tue, 5 Nov 2024 11:11:39 +0100 Subject: [PATCH 03/15] Add some tests and rename copy_data as copy_simplex_data --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 21 ++++--- .../test/simplex_tree_data_unit_test.cpp | 60 +++++++++++++------ 2 files changed, 57 insertions(+), 24 deletions(-) diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index c0935889d4..76f9351799 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -11,6 +11,7 @@ * - 2023/05 Hannah Schreiber: Factorization of expansion methods * - 2023/08 Hannah Schreiber (& Clément Maria): Add possibility of stable simplex handles. * - 2024/08 Hannah Schreiber: Addition of customizable copy constructor. + * - 2024/08 Marc Glisse: Allow storing custom data in simplices. * - YYYY/MM Author: Description of the modification */ @@ -434,7 +435,9 @@ class Simplex_tree { copy_from(complex_source, translate_filtration_value); } - /** \brief User-defined copy constructor reproduces the whole tree structure. */ + /** \brief User-defined copy constructor reproduces the whole tree structure including extra data (@ref Simplex_data) + * stored in the simplices. + */ Simplex_tree(const Simplex_tree& complex_source) { #ifdef DEBUG_TRACES std::clog << "Simplex_tree copy constructor" << std::endl; @@ -442,7 +445,8 @@ class Simplex_tree { copy_from(complex_source); } - /** \brief User-defined move constructor relocates the whole tree structure. + /** \brief User-defined move constructor relocates the whole tree structure including extra data (@ref Simplex_data) + * stored in the simplices. * \exception std::invalid_argument In debug mode, if the complex_source is invalid. */ Simplex_tree(Simplex_tree && complex_source) { @@ -461,7 +465,9 @@ class Simplex_tree { root_members_recursive_deletion(); } - /** \brief User-defined copy assignment reproduces the whole tree structure. */ + /** \brief User-defined copy assignment reproduces the whole tree structure including extra data (@ref Simplex_data) + * stored in the simplices. + */ Simplex_tree& operator= (const Simplex_tree& complex_source) { #ifdef DEBUG_TRACES std::clog << "Simplex_tree copy assignment" << std::endl; @@ -476,7 +482,8 @@ class Simplex_tree { return *this; } - /** \brief User-defined move assignment relocates the whole tree structure. + /** \brief User-defined move assignment relocates the whole tree structure including extra data (@ref Simplex_data) + * stored in the simplices. * \exception std::invalid_argument In debug mode, if the complex_source is invalid. */ Simplex_tree& operator=(Simplex_tree&& complex_source) { @@ -551,7 +558,7 @@ class Simplex_tree { } /** \brief depth first search, inserts simplices when reaching a leaf. */ - template + template void rec_copy(Siblings *sib, OtherSiblings *sib_source, F&& translate_filtration_value) { auto sh_source = sib_source->members().begin(); for (auto sh = sib->members().begin(); sh != sib->members().end(); ++sh, ++sh_source) { @@ -574,11 +581,11 @@ class Simplex_tree { Node(newsib, translate_filtration_value(child.second.filtration()))); } // Specific for optionnal data - if constexpr (copy_data && !std::is_same_v) { + if constexpr (copy_simplex_data && !std::is_same_v) { new_it->second.data() = child.second.data(); } } - rec_copy(newsib, sh_source->second.children(), translate_filtration_value); + rec_copy(newsib, sh_source->second.children(), translate_filtration_value); sh->second.assign_children(newsib); } } diff --git a/src/Simplex_tree/test/simplex_tree_data_unit_test.cpp b/src/Simplex_tree/test/simplex_tree_data_unit_test.cpp index cc74220dac..5bf5c6175d 100644 --- a/src/Simplex_tree/test/simplex_tree_data_unit_test.cpp +++ b/src/Simplex_tree/test/simplex_tree_data_unit_test.cpp @@ -11,6 +11,7 @@ #include #include +#include // for std::move #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MODULE "simplex_tree_data" @@ -39,6 +40,25 @@ struct Options_with_string_data : Simplex_tree_options_full_featured { using Simplex_data = std::string; }; +template +void test_filtration_and_additionnal_data(Simplex_tree_source stree, Simplex_tree_copy stree_copy) { + for (auto simplex : stree_copy.complex_simplex_range()) { + std::vector vec_of_vertices {}; + std::clog << "("; + for (auto vertex : stree_copy.simplex_vertex_range(simplex)) { + std::clog << vertex << " "; + vec_of_vertices.push_back(vertex); + } + std::clog << ")"; + auto sh = stree.find(vec_of_vertices); + BOOST_CHECK(sh != stree.null_simplex()); + std::clog << " filtration=" << stree_copy.filtration(simplex) << " versus " << stree.filtration(sh); + std::clog << " - data='" << stree_copy.simplex_data(simplex) << "' versus '" << stree.simplex_data(sh) << "'\n"; + BOOST_CHECK(stree_copy.filtration(simplex) == stree.filtration(sh)); + BOOST_CHECK(stree_copy.simplex_data(simplex) == stree.simplex_data(sh)); + } +} + BOOST_AUTO_TEST_CASE(simplex_data_copy) { Simplex_tree stree; stree.insert_simplex_and_subfaces({0, 1}, 1.); @@ -57,22 +77,28 @@ BOOST_AUTO_TEST_CASE(simplex_data_copy) { } std::clog << ") filtration=" << stree.filtration(simplex) << " - data='" << stree.simplex_data(simplex) << "'\n"; } - Simplex_tree stree_copy(stree); - std::clog << "\nIterator on copy:\n"; - for (auto simplex : stree_copy.complex_simplex_range()) { - std::vector::Vertex_handle> vec_of_vertices {}; - std::clog << "("; - for (auto vertex : stree_copy.simplex_vertex_range(simplex)) { - std::clog << vertex << " "; - vec_of_vertices.push_back(vertex); - } - std::clog << ")"; - auto sh = stree.find(vec_of_vertices); - BOOST_CHECK(sh != stree.null_simplex()); - std::clog << " filtration=" << stree_copy.filtration(simplex) << " versus " << stree.filtration(sh); - std::clog << " - data='" << stree_copy.simplex_data(simplex) << "' versus '" << stree.simplex_data(sh) << "'\n"; - BOOST_CHECK(stree_copy.filtration(simplex) == stree.filtration(sh)); - BOOST_CHECK(stree_copy.simplex_data(simplex) == stree.simplex_data(sh)); + { + Simplex_tree stree_copy(stree); + std::clog << "\nIterator on copy constructor:\n"; + test_filtration_and_additionnal_data(stree, stree_copy); + } + { + Simplex_tree stree_copy = stree; + std::clog << "\nIterator on copy assignment:\n"; + test_filtration_and_additionnal_data(stree, stree_copy); + } + { + // Needs to copy first for not to lose the original one + Simplex_tree stree_copy = stree; + Simplex_tree stree_moved(std::move(stree_copy)); + std::clog << "\nIterator on move constructor:\n"; + test_filtration_and_additionnal_data(stree, stree_moved); + } + { + // Needs to copy first for not to lose the original one + Simplex_tree stree_copy = stree; + Simplex_tree stree_moved = std::move(stree_copy); + std::clog << "\nIterator on move assignment:\n"; + test_filtration_and_additionnal_data(stree, stree_moved); } - } From c5cddc30f35b3e4c410241ca7a03aabdc55f1363 Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau Date: Thu, 7 Nov 2024 10:24:30 +0100 Subject: [PATCH 04/15] Add a non really satisfying test for transformer constructor and data --- .../test/simplex_tree_data_unit_test.cpp | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/Simplex_tree/test/simplex_tree_data_unit_test.cpp b/src/Simplex_tree/test/simplex_tree_data_unit_test.cpp index 5bf5c6175d..061e4f136a 100644 --- a/src/Simplex_tree/test/simplex_tree_data_unit_test.cpp +++ b/src/Simplex_tree/test/simplex_tree_data_unit_test.cpp @@ -33,6 +33,14 @@ BOOST_AUTO_TEST_CASE(simplex_data) { st.simplex_data(st.find({0, 1})) = 5; st.expansion(3); st.simplex_data(st.find({0, 1, 2})) = 4; + for (auto simplex : st.complex_simplex_range()) { + std::clog << "("; + for (auto vertex : st.simplex_vertex_range(simplex)) { + std::clog << vertex << " "; + } + std::clog << ")"; + std::clog << " filtration=" << st.filtration(simplex) << " - data='" << st.simplex_data(simplex) << "'\n"; + } BOOST_CHECK(st.simplex_data(st.find({0, 1})) == 5); } @@ -101,4 +109,35 @@ BOOST_AUTO_TEST_CASE(simplex_data_copy) { std::clog << "\nIterator on move assignment:\n"; test_filtration_and_additionnal_data(stree, stree_moved); } + { + auto trans = [](const typename Simplex_tree::Filtration_value& fil) + -> Simplex_tree::Filtration_value { + // spoiler: Options_with_int_data does not store filtrations + if constexpr(Options_with_int_data::store_filtration) + return fil; + else + return {}; + }; + Simplex_tree stree_copy(stree, trans); + std::clog << "\nIterator on transformer copy constructor:\n"; + Simplex_tree::Filtration_value default_filtration_value{}; + Simplex_tree::Simplex_data default_data_value{}; + for (auto simplex : stree_copy.complex_simplex_range()) { + std::vector::Vertex_handle> vec_of_vertices {}; + std::clog << "("; + for (auto vertex : stree_copy.simplex_vertex_range(simplex)) { + std::clog << vertex << " "; + vec_of_vertices.push_back(vertex); + } + std::clog << ")"; + auto sh = stree.find(vec_of_vertices); + BOOST_CHECK(sh != stree.null_simplex()); + std::clog << " filtration=" << stree_copy.filtration(simplex) << " versus " << stree.filtration(sh); + std::clog << " - data='" << stree_copy.simplex_data(simplex) << "' versus '" << stree.simplex_data(sh) << "'\n"; + BOOST_CHECK(stree_copy.filtration(simplex) == default_filtration_value); + // With transformer constructors, simplex_data is not copied and not initialized, so we cannot test it + // I just keep it in comment if we find something smarter + // BOOST_CHECK(stree_copy.simplex_data(simplex) == default_data_value); + } + } } From 7ce085d8333fa309c0111aae35aa2fa44d115d9a Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau Date: Thu, 7 Nov 2024 10:25:21 +0100 Subject: [PATCH 05/15] Add more details for comparison operator and serialization --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index 76f9351799..566803d5d4 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -638,7 +638,9 @@ class Simplex_tree { public: template friend class Simplex_tree; - /** \brief Checks if two simplex trees are equal. */ + /** \brief Checks if two simplex trees are equal. Any extra data (@ref Simplex_data) stored in the simplices are + * ignored in the coomparison + */ template bool operator==(Simplex_tree& st2) { if ((null_vertex_ != st2.null_vertex_) || @@ -2533,6 +2535,8 @@ class Simplex_tree { * * @warning Serialize/Deserialize is not portable. It is meant to be read in a Simplex_tree with the same * SimplexTreeOptions and on a computer with the same architecture. + * + * Serialize/Deserialize ignore any extra data (@ref Simplex_data) stored in the simplices for now. */ /* Let's take the following simplicial complex as example: */ /* (vertices are represented as letters to ease the understanding) */ @@ -2601,6 +2605,7 @@ class Simplex_tree { * @warning Serialize/Deserialize is not portable. It is meant to be read in a Simplex_tree with the same * SimplexTreeOptions and on a computer with the same architecture. * + * Serialize/Deserialize ignore any extra data (@ref Simplex_data) stored in the simplices for now. */ void deserialize(const char* buffer, const std::size_t buffer_size) { GUDHI_CHECK(num_vertices() == 0, std::logic_error("Simplex_tree::deserialize - Simplex_tree must be empty")); From 48a03027a2761c5ba30b6b70ebeb17b868ae337b Mon Sep 17 00:00:00 2001 From: hschreiber Date: Fri, 8 Nov 2024 11:51:59 +0100 Subject: [PATCH 06/15] doc --- .../include/gudhi/Persistence_matrix/columns/heap_column.h | 1 - .../gudhi/Persistence_matrix/columns/intrusive_list_column.h | 1 - .../gudhi/Persistence_matrix/columns/intrusive_set_column.h | 1 - .../include/gudhi/Persistence_matrix/columns/list_column.h | 1 - .../gudhi/Persistence_matrix/columns/naive_vector_column.h | 1 - .../include/gudhi/Persistence_matrix/columns/set_column.h | 1 - .../gudhi/Persistence_matrix/columns/unordered_set_column.h | 1 - 7 files changed, 7 deletions(-) diff --git a/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/heap_column.h b/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/heap_column.h index e195dfea4e..7b0edda3f4 100644 --- a/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/heap_column.h +++ b/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/heap_column.h @@ -45,7 +45,6 @@ namespace persistence_matrix { * row index. Additionally, the given entry range added into the heap does not need to be somehow ordered. * * @tparam Master_matrix An instantiation of @ref Matrix from which all types and options are deduced. - * @tparam Entry_constructor Factory of @ref Entry classes. */ template class Heap_column : public Master_matrix::Column_dimension_option, public Master_matrix::Chain_column_option diff --git a/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/intrusive_list_column.h b/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/intrusive_list_column.h index 0f5aaa8325..3581eee6a9 100644 --- a/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/intrusive_list_column.h +++ b/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/intrusive_list_column.h @@ -41,7 +41,6 @@ namespace persistence_matrix { * are stored uniquely in the underlying container. * * @tparam Master_matrix An instantiation of @ref Matrix from which all types and options are deduced. - * @tparam Entry_constructor Factory of @ref Entry classes. */ template class Intrusive_list_column : public Master_matrix::Row_access_option, diff --git a/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/intrusive_set_column.h b/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/intrusive_set_column.h index 994a5014d1..14532954a2 100644 --- a/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/intrusive_set_column.h +++ b/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/intrusive_set_column.h @@ -42,7 +42,6 @@ namespace persistence_matrix { * are stored uniquely in the underlying container. * * @tparam Master_matrix An instantiation of @ref Matrix from which all types and options are deduced. - * @tparam Entry_constructor Factory of @ref Entry classes. */ template class Intrusive_set_column : public Master_matrix::Row_access_option, diff --git a/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/list_column.h b/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/list_column.h index 658541f973..fca1bb6735 100644 --- a/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/list_column.h +++ b/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/list_column.h @@ -42,7 +42,6 @@ namespace persistence_matrix { * are stored uniquely in the underlying container. * * @tparam Master_matrix An instantiation of @ref Matrix from which all types and options are deduced. - * @tparam Entry_constructor Factory of @ref Entry classes. */ template class List_column : public Master_matrix::Row_access_option, diff --git a/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/naive_vector_column.h b/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/naive_vector_column.h index e99d37b7e2..3626b9ae9d 100644 --- a/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/naive_vector_column.h +++ b/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/naive_vector_column.h @@ -42,7 +42,6 @@ namespace persistence_matrix { * are stored uniquely in the underlying container. * * @tparam Master_matrix An instantiation of @ref Matrix from which all types and options are deduced. - * @tparam Entry_constructor Factory of @ref Entry classes. */ template class Naive_vector_column : public Master_matrix::Row_access_option, diff --git a/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/set_column.h b/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/set_column.h index 6f69c53c96..366ec98504 100644 --- a/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/set_column.h +++ b/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/set_column.h @@ -42,7 +42,6 @@ namespace persistence_matrix { * are stored uniquely in the underlying container. * * @tparam Master_matrix An instantiation of @ref Matrix from which all types and options are deduced. - * @tparam Entry_constructor Factory of @ref Entry classes. */ template class Set_column : public Master_matrix::Row_access_option, diff --git a/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/unordered_set_column.h b/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/unordered_set_column.h index b63adcbac4..c637051875 100644 --- a/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/unordered_set_column.h +++ b/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/unordered_set_column.h @@ -60,7 +60,6 @@ struct EntryPointerEq * also does not need to be ordered (contrary to most other column types). * * @tparam Master_matrix An instantiation of @ref Matrix from which all types and options are deduced. - * @tparam Entry_constructor Factory of @ref Entry classes. */ template class Unordered_set_column : public Master_matrix::Row_access_option, From 7d1df66e30c4a7ac5f760ee694152336be004a73 Mon Sep 17 00:00:00 2001 From: hschreiber Date: Fri, 8 Nov 2024 12:01:15 +0100 Subject: [PATCH 07/15] doc --- .../include/gudhi/Persistence_matrix/columns/vector_column.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/vector_column.h b/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/vector_column.h index f6a7da8e84..7b22597d5f 100644 --- a/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/vector_column.h +++ b/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/vector_column.h @@ -44,7 +44,6 @@ namespace persistence_matrix { * On the other hand, two entries will never have the same row index. * * @tparam Master_matrix An instantiation of @ref Matrix from which all types and options are deduced. - * @tparam Entry_constructor Factory of @ref Entry classes. */ template class Vector_column : public Master_matrix::Row_access_option, From 865259da1f72582131ba7ad7f820feb9453c8ec9 Mon Sep 17 00:00:00 2001 From: hschreiber Date: Fri, 8 Nov 2024 17:00:00 +0100 Subject: [PATCH 08/15] add small vector column to matrix module --- src/Persistence_matrix/include/gudhi/Matrix.h | 9 +- .../columns/naive_vector_column.h | 197 +++++++++--------- .../gudhi/persistence_matrix_options.h | 2 + .../test/pm_column_tests_boost_type_lists.h | 16 +- .../test/pm_common_boost_type_lists.h | 4 + .../test/pm_matrix_tests_boost_type_lists.h | 6 +- 6 files changed, 130 insertions(+), 104 deletions(-) diff --git a/src/Persistence_matrix/include/gudhi/Matrix.h b/src/Persistence_matrix/include/gudhi/Matrix.h index d917bddc80..2ff8b46d41 100644 --- a/src/Persistence_matrix/include/gudhi/Matrix.h +++ b/src/Persistence_matrix/include/gudhi/Matrix.h @@ -313,7 +313,8 @@ class Matrix { using Matrix_heap_column = Heap_column >; using Matrix_list_column = List_column >; using Matrix_vector_column = Vector_column >; - using Matrix_naive_vector_column = Naive_vector_column >; + using Matrix_naive_vector_column = STD_naive_vector_column >; + using Matrix_small_vector_column = Small_naive_vector_column >; using Matrix_set_column = Set_column >; using Matrix_unordered_set_column = Unordered_set_column >; using Matrix_intrusive_list_column = Intrusive_list_column >; @@ -345,7 +346,11 @@ class Matrix { typename std::conditional< PersistenceMatrixOptions::column_type == Column_types::NAIVE_VECTOR, Matrix_naive_vector_column, - Matrix_intrusive_set_column + typename std::conditional< + PersistenceMatrixOptions::column_type == Column_types::SMALL_VECTOR, + Matrix_small_vector_column, + Matrix_intrusive_set_column + >::type >::type >::type >::type diff --git a/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/naive_vector_column.h b/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/naive_vector_column.h index 3626b9ae9d..710987a374 100644 --- a/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/naive_vector_column.h +++ b/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/naive_vector_column.h @@ -25,6 +25,7 @@ #include //std::swap, std::move & std::exchange #include +#include #include #include @@ -43,7 +44,7 @@ namespace persistence_matrix { * * @tparam Master_matrix An instantiation of @ref Matrix from which all types and options are deduced. */ -template +template class Naive_vector_column : public Master_matrix::Row_access_option, public Master_matrix::Column_dimension_option, public Master_matrix::Chain_column_option @@ -59,7 +60,7 @@ class Naive_vector_column : public Master_matrix::Row_access_option, private: using Field_operators = typename Master_matrix::Field_operators; - using Column_support = std::vector; + using Column_support = Support; using Entry_constructor = typename Master_matrix::Entry_constructor; public: @@ -223,7 +224,13 @@ class Naive_vector_column : public Master_matrix::Row_access_option, }; template -inline Naive_vector_column::Naive_vector_column(Column_settings* colSettings) +using STD_naive_vector_column = Naive_vector_column >; +template +using Small_naive_vector_column = + Naive_vector_column >; + +template +inline Naive_vector_column::Naive_vector_column(Column_settings* colSettings) : RA_opt(), Dim_opt(), Chain_opt(), @@ -236,9 +243,9 @@ inline Naive_vector_column::Naive_vector_column(Column_settings* } } -template +template template -inline Naive_vector_column::Naive_vector_column(const Container& nonZeroRowIndices, +inline Naive_vector_column::Naive_vector_column(const Container& nonZeroRowIndices, Column_settings* colSettings) : RA_opt(), Dim_opt(nonZeroRowIndices.size() == 0 ? 0 : nonZeroRowIndices.size() - 1), @@ -263,9 +270,9 @@ inline Naive_vector_column::Naive_vector_column(const Container& } } -template +template template -inline Naive_vector_column::Naive_vector_column(Index columnIndex, +inline Naive_vector_column::Naive_vector_column(Index columnIndex, const Container& nonZeroRowIndices, Row_container* rowContainer, Column_settings* colSettings) @@ -298,9 +305,9 @@ inline Naive_vector_column::Naive_vector_column(Index columnIndex } } -template +template template -inline Naive_vector_column::Naive_vector_column(const Container& nonZeroRowIndices, +inline Naive_vector_column::Naive_vector_column(const Container& nonZeroRowIndices, Dimension dimension, Column_settings* colSettings) : RA_opt(), @@ -329,9 +336,9 @@ inline Naive_vector_column::Naive_vector_column(const Container& } } -template +template template -inline Naive_vector_column::Naive_vector_column(Index columnIndex, +inline Naive_vector_column::Naive_vector_column(Index columnIndex, const Container& nonZeroRowIndices, Dimension dimension, Row_container* rowContainer, @@ -362,8 +369,8 @@ inline Naive_vector_column::Naive_vector_column(Index columnIndex } } -template -inline Naive_vector_column::Naive_vector_column(const Naive_vector_column& column, +template +inline Naive_vector_column::Naive_vector_column(const Naive_vector_column& column, Column_settings* colSettings) : RA_opt(), Dim_opt(static_cast(column)), @@ -390,9 +397,9 @@ inline Naive_vector_column::Naive_vector_column(const Naive_vecto } } -template +template template -inline Naive_vector_column::Naive_vector_column(const Naive_vector_column& column, +inline Naive_vector_column::Naive_vector_column(const Naive_vector_column& column, Index columnIndex, Row_container* rowContainer, Column_settings* colSettings) @@ -417,8 +424,8 @@ inline Naive_vector_column::Naive_vector_column(const Naive_vecto } } -template -inline Naive_vector_column::Naive_vector_column(Naive_vector_column&& column) noexcept +template +inline Naive_vector_column::Naive_vector_column(Naive_vector_column&& column) noexcept : RA_opt(std::move(static_cast(column))), Dim_opt(std::move(static_cast(column))), Chain_opt(std::move(static_cast(column))), @@ -427,17 +434,17 @@ inline Naive_vector_column::Naive_vector_column(Naive_vector_colu entryPool_(std::exchange(column.entryPool_, nullptr)) {} -template -inline Naive_vector_column::~Naive_vector_column() +template +inline Naive_vector_column::~Naive_vector_column() { for (auto* entry : column_) { _delete_entry(entry); } } -template -inline std::vector::Field_element> -Naive_vector_column::get_content(int columnLength) const +template +inline std::vector::Field_element> +Naive_vector_column::get_content(int columnLength) const { if (columnLength < 0 && column_.size() > 0) columnLength = column_.back()->get_row_index() + 1; @@ -456,29 +463,29 @@ Naive_vector_column::get_content(int columnLength) const return container; } -template -inline bool Naive_vector_column::is_non_zero(ID_index rowIndex) const +template +inline bool Naive_vector_column::is_non_zero(ID_index rowIndex) const { Entry entry(rowIndex); return std::binary_search(column_.begin(), column_.end(), &entry, [](const Entry* a, const Entry* b) { return a->get_row_index() < b->get_row_index(); }); } -template -inline bool Naive_vector_column::is_empty() const +template +inline bool Naive_vector_column::is_empty() const { return column_.empty(); } -template -inline std::size_t Naive_vector_column::size() const +template +inline std::size_t Naive_vector_column::size() const { return column_.size(); } -template +template template -inline void Naive_vector_column::reorder(const Row_index_map& valueMap, +inline void Naive_vector_column::reorder(const Row_index_map& valueMap, [[maybe_unused]] Index columnIndex) { static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type, @@ -504,8 +511,8 @@ inline void Naive_vector_column::reorder(const Row_index_map& val std::sort(column_.begin(), column_.end(), [](const Entry* c1, const Entry* c2) { return *c1 < *c2; }); } -template -inline void Naive_vector_column::clear() +template +inline void Naive_vector_column::clear() { static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type, "Method not available for chain columns as a base element should not be empty."); @@ -518,8 +525,8 @@ inline void Naive_vector_column::clear() column_.clear(); } -template -inline void Naive_vector_column::clear(ID_index rowIndex) +template +inline void Naive_vector_column::clear(ID_index rowIndex) { static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type, "Method not available for chain columns."); @@ -532,8 +539,8 @@ inline void Naive_vector_column::clear(ID_index rowIndex) } } -template -inline typename Naive_vector_column::ID_index Naive_vector_column::get_pivot() const +template +inline typename Naive_vector_column::ID_index Naive_vector_column::get_pivot() const { static_assert(Master_matrix::isNonBasic, "Method not available for base columns."); // could technically be, but is the notion useful then? @@ -545,8 +552,8 @@ inline typename Naive_vector_column::ID_index Naive_vector_column } } -template -inline typename Naive_vector_column::Field_element Naive_vector_column::get_pivot_value() +template +inline typename Naive_vector_column::Field_element Naive_vector_column::get_pivot_value() const { static_assert(Master_matrix::isNonBasic, @@ -567,63 +574,63 @@ inline typename Naive_vector_column::Field_element Naive_vector_c } } -template -inline typename Naive_vector_column::iterator Naive_vector_column::begin() noexcept +template +inline typename Naive_vector_column::iterator Naive_vector_column::begin() noexcept { return column_.begin(); } -template -inline typename Naive_vector_column::const_iterator Naive_vector_column::begin() +template +inline typename Naive_vector_column::const_iterator Naive_vector_column::begin() const noexcept { return column_.begin(); } -template -inline typename Naive_vector_column::iterator Naive_vector_column::end() noexcept +template +inline typename Naive_vector_column::iterator Naive_vector_column::end() noexcept { return column_.end(); } -template -inline typename Naive_vector_column::const_iterator Naive_vector_column::end() +template +inline typename Naive_vector_column::const_iterator Naive_vector_column::end() const noexcept { return column_.end(); } -template -inline typename Naive_vector_column::reverse_iterator -Naive_vector_column::rbegin() noexcept +template +inline typename Naive_vector_column::reverse_iterator +Naive_vector_column::rbegin() noexcept { return column_.rbegin(); } -template -inline typename Naive_vector_column::const_reverse_iterator Naive_vector_column::rbegin() +template +inline typename Naive_vector_column::const_reverse_iterator Naive_vector_column::rbegin() const noexcept { return column_.rbegin(); } -template -inline typename Naive_vector_column::reverse_iterator -Naive_vector_column::rend() noexcept +template +inline typename Naive_vector_column::reverse_iterator +Naive_vector_column::rend() noexcept { return column_.rend(); } -template -inline typename Naive_vector_column::const_reverse_iterator Naive_vector_column::rend() +template +inline typename Naive_vector_column::const_reverse_iterator Naive_vector_column::rend() const noexcept { return column_.rend(); } -template +template template -inline Naive_vector_column& Naive_vector_column::operator+=(const Entry_range& column) +inline Naive_vector_column& Naive_vector_column::operator+=(const Entry_range& column) { static_assert((!Master_matrix::isNonBasic || std::is_same_v), "For boundary columns, the range has to be a column of same type to help ensure the validity of the " @@ -636,8 +643,8 @@ inline Naive_vector_column& Naive_vector_column::o return *this; } -template -inline Naive_vector_column& Naive_vector_column::operator+=(Naive_vector_column& column) +template +inline Naive_vector_column& Naive_vector_column::operator+=(Naive_vector_column& column) { if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) { // assumes that the addition never zeros out this column. @@ -652,8 +659,8 @@ inline Naive_vector_column& Naive_vector_column::o return *this; } -template -inline Naive_vector_column& Naive_vector_column::operator*=(unsigned int v) +template +inline Naive_vector_column& Naive_vector_column::operator*=(unsigned int v) { if constexpr (Master_matrix::Option_list::is_z2) { if (v % 2 == 0) { @@ -686,9 +693,9 @@ inline Naive_vector_column& Naive_vector_column::o return *this; } -template +template template -inline Naive_vector_column& Naive_vector_column::multiply_target_and_add( +inline Naive_vector_column& Naive_vector_column::multiply_target_and_add( const Field_element& val, const Entry_range& column) { static_assert((!Master_matrix::isNonBasic || std::is_same_v), @@ -711,8 +718,8 @@ inline Naive_vector_column& Naive_vector_column::m return *this; } -template -inline Naive_vector_column& Naive_vector_column::multiply_target_and_add( +template +inline Naive_vector_column& Naive_vector_column::multiply_target_and_add( const Field_element& val, Naive_vector_column& column) { if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) { @@ -748,9 +755,9 @@ inline Naive_vector_column& Naive_vector_column::m return *this; } -template +template template -inline Naive_vector_column& Naive_vector_column::multiply_source_and_add( +inline Naive_vector_column& Naive_vector_column::multiply_source_and_add( const Entry_range& column, const Field_element& val) { static_assert((!Master_matrix::isNonBasic || std::is_same_v), @@ -770,8 +777,8 @@ inline Naive_vector_column& Naive_vector_column::m return *this; } -template -inline Naive_vector_column& Naive_vector_column::multiply_source_and_add( +template +inline Naive_vector_column& Naive_vector_column::multiply_source_and_add( Naive_vector_column& column, const Field_element& val) { if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) { @@ -802,8 +809,8 @@ inline Naive_vector_column& Naive_vector_column::m return *this; } -template -inline void Naive_vector_column::push_back(const Entry& entry) +template +inline void Naive_vector_column::push_back(const Entry& entry) { static_assert(Master_matrix::Option_list::is_of_boundary_type, "`push_back` is not available for Chain matrices."); @@ -816,8 +823,8 @@ inline void Naive_vector_column::push_back(const Entry& entry) } } -template -inline Naive_vector_column& Naive_vector_column::operator=( +template +inline Naive_vector_column& Naive_vector_column::operator=( const Naive_vector_column& other) { static_assert(!Master_matrix::Option_list::has_row_access, "= assignment not enabled with row access option."); @@ -855,22 +862,22 @@ inline Naive_vector_column& Naive_vector_column::o return *this; } -template -inline void Naive_vector_column::_delete_entry(Entry* entry) +template +inline void Naive_vector_column::_delete_entry(Entry* entry) { if constexpr (Master_matrix::Option_list::has_row_access) RA_opt::unlink(entry); entryPool_->destroy(entry); } -template -inline void Naive_vector_column::_delete_entry(typename Column_support::iterator& it) +template +inline void Naive_vector_column::_delete_entry(typename Column_support::iterator& it) { _delete_entry(*it); ++it; } -template -inline typename Naive_vector_column::Entry* Naive_vector_column::_insert_entry( +template +inline typename Naive_vector_column::Entry* Naive_vector_column::_insert_entry( const Field_element& value, ID_index rowIndex, Column_support& column) { if constexpr (Master_matrix::Option_list::has_row_access) { @@ -887,8 +894,8 @@ inline typename Naive_vector_column::Entry* Naive_vector_column -inline void Naive_vector_column::_insert_entry(ID_index rowIndex, Column_support& column) +template +inline void Naive_vector_column::_insert_entry(ID_index rowIndex, Column_support& column) { if constexpr (Master_matrix::Option_list::has_row_access) { Entry* newEntry = entryPool_->construct(RA_opt::columnIndex_, rowIndex); @@ -899,8 +906,8 @@ inline void Naive_vector_column::_insert_entry(ID_index rowIndex, } } -template -inline void Naive_vector_column::_update_entry(const Field_element& value, +template +inline void Naive_vector_column::_update_entry(const Field_element& value, ID_index rowIndex, Index position) { @@ -915,8 +922,8 @@ inline void Naive_vector_column::_update_entry(const Field_elemen } } -template -inline void Naive_vector_column::_update_entry(ID_index rowIndex, Index position) +template +inline void Naive_vector_column::_update_entry(ID_index rowIndex, Index position) { if constexpr (Master_matrix::Option_list::has_row_access) { Entry* newEntry = entryPool_->construct(RA_opt::columnIndex_, rowIndex); @@ -927,9 +934,9 @@ inline void Naive_vector_column::_update_entry(ID_index rowIndex, } } -template +template template -inline bool Naive_vector_column::_add(const Entry_range& column) +inline bool Naive_vector_column::_add(const Entry_range& column) { if (column.begin() == column.end()) return false; if (column_.empty()) { // chain should never enter here. @@ -977,9 +984,9 @@ inline bool Naive_vector_column::_add(const Entry_range& column) return pivotIsZeroed; } -template +template template -inline bool Naive_vector_column::_multiply_target_and_add(const Field_element& val, +inline bool Naive_vector_column::_multiply_target_and_add(const Field_element& val, const Entry_range& column) { if (val == 0u) { @@ -1035,9 +1042,9 @@ inline bool Naive_vector_column::_multiply_target_and_add(const F return pivotIsZeroed; } -template +template template -inline bool Naive_vector_column::_multiply_source_and_add(const Entry_range& column, +inline bool Naive_vector_column::_multiply_source_and_add(const Entry_range& column, const Field_element& val) { if (val == 0u || column.begin() == column.end()) { @@ -1083,9 +1090,9 @@ inline bool Naive_vector_column::_multiply_source_and_add(const E * @tparam Master_matrix Template parameter of @ref Gudhi::persistence_matrix::Naive_vector_column. * @tparam Entry_constructor Template parameter of @ref Gudhi::persistence_matrix::Naive_vector_column. */ -template -struct std::hash > { - std::size_t operator()(const Gudhi::persistence_matrix::Naive_vector_column& column) const { +template +struct std::hash > { + std::size_t operator()(const Gudhi::persistence_matrix::Naive_vector_column& column) const { return Gudhi::persistence_matrix::hash_column(column); } }; diff --git a/src/Persistence_matrix/include/gudhi/persistence_matrix_options.h b/src/Persistence_matrix/include/gudhi/persistence_matrix_options.h index 58f7bc117c..0d7c83785c 100644 --- a/src/Persistence_matrix/include/gudhi/persistence_matrix_options.h +++ b/src/Persistence_matrix/include/gudhi/persistence_matrix_options.h @@ -35,6 +35,8 @@ enum class Column_types { VECTOR, /**< @ref Vector_column "": Underlying container is a std::vector<@ref Entry*> with a lazy removal method. */ NAIVE_VECTOR, /**< @ref Naive_vector_column "": Underlying container is a std::vector<@ref Entry*>. */ + SMALL_VECTOR, /**< @ref Naive_vector_column "": Underlying container is a + boost::container::small_vector<@ref Entry*, 8>. */ UNORDERED_SET, /**< @ref Unordered_set_column "": Underlying container is a std::unordered_set<@ref Entry*>. */ INTRUSIVE_LIST, /**< @ref Intrusive_list_column "": Underlying container is a boost::intrusive::list<@ref Entry>. */ INTRUSIVE_SET /**< @ref Intrusive_set_column "": Underlying container is a boost::intrusive::set<@ref Entry>. */ diff --git a/src/Persistence_matrix/test/pm_column_tests_boost_type_lists.h b/src/Persistence_matrix/test/pm_column_tests_boost_type_lists.h index 1f4b28b349..dbccb01e72 100644 --- a/src/Persistence_matrix/test/pm_column_tests_boost_type_lists.h +++ b/src/Persistence_matrix/test/pm_column_tests_boost_type_lists.h @@ -30,7 +30,8 @@ using Gudhi::persistence_matrix::Heap_column; using Gudhi::persistence_matrix::Intrusive_list_column; using Gudhi::persistence_matrix::Intrusive_set_column; using Gudhi::persistence_matrix::List_column; -using Gudhi::persistence_matrix::Naive_vector_column; +using Gudhi::persistence_matrix::STD_naive_vector_column; +using Gudhi::persistence_matrix::Small_naive_vector_column; using Gudhi::persistence_matrix::Set_column; using Gudhi::persistence_matrix::Unordered_set_column; using Gudhi::persistence_matrix::Vector_column; @@ -65,7 +66,9 @@ class column_non_validity { } else if constexpr (col_type::Master::Option_list::column_type == Column_types::UNORDERED_SET) { return !std::is_same_v >; } else if constexpr (col_type::Master::Option_list::column_type == Column_types::NAIVE_VECTOR) { - return !std::is_same_v >; + return !std::is_same_v >; + } else if constexpr (col_type::Master::Option_list::column_type == Column_types::SMALL_VECTOR) { + return !std::is_same_v >; } else if constexpr (col_type::Master::Option_list::column_type == Column_types::VECTOR) { return !std::is_same_v >; } else if constexpr (col_type::Master::Option_list::column_type == Column_types::HEAP) { @@ -81,12 +84,13 @@ class column_non_validity { // if a new column type is implemented, create a `ct_*` structure for it and add it to this list... using col_type_list = boost::mp11::mp_list; + ct_unordered_set, ct_vector, ct_naive_vector, ct_small_vector>; using row_col_type_list = boost::mp11::mp_list; + ct_vector, ct_naive_vector, ct_small_vector>; //...and add the column name here. -using column_list = mp_list_q; +using column_list = + mp_list_q; using c_matrix_type_list = mp_list_q; template ; +// ct_unordered_set, ct_vector, ct_naive_vector, ct_small_vector>; #ifdef PM_TEST_INTR_LIST using col_type_list = boost::mp11::mp_list; #else @@ -162,6 +162,9 @@ using col_type_list = boost::mp11::mp_list; #ifdef PM_TEST_NAIVE_VECTOR using col_type_list = boost::mp11::mp_list; #else +#ifdef PM_TEST_SMALL_VECTOR +using col_type_list = boost::mp11::mp_list; +#else using col_type_list = boost::mp11::mp_list; #endif #endif @@ -170,6 +173,7 @@ using col_type_list = boost::mp11::mp_list; #endif #endif #endif +#endif using matrix_type_list = mp_list_q; From 17fa435d666cab9f7a12eb7e9b3aac787eba6f63 Mon Sep 17 00:00:00 2001 From: hschreiber Date: Tue, 12 Nov 2024 17:51:25 +0100 Subject: [PATCH 09/15] name change for naive vector columns --- src/Persistence_matrix/include/gudhi/Matrix.h | 4 ++-- .../Persistence_matrix/columns/naive_vector_column.h | 4 ++-- .../test/pm_column_tests_boost_type_lists.h | 10 +++++----- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Persistence_matrix/include/gudhi/Matrix.h b/src/Persistence_matrix/include/gudhi/Matrix.h index 2ff8b46d41..19ebd34f88 100644 --- a/src/Persistence_matrix/include/gudhi/Matrix.h +++ b/src/Persistence_matrix/include/gudhi/Matrix.h @@ -313,8 +313,8 @@ class Matrix { using Matrix_heap_column = Heap_column >; using Matrix_list_column = List_column >; using Matrix_vector_column = Vector_column >; - using Matrix_naive_vector_column = STD_naive_vector_column >; - using Matrix_small_vector_column = Small_naive_vector_column >; + using Matrix_naive_vector_column = Naive_std_vector_column >; + using Matrix_small_vector_column = Naive_small_vector_column >; using Matrix_set_column = Set_column >; using Matrix_unordered_set_column = Unordered_set_column >; using Matrix_intrusive_list_column = Intrusive_list_column >; diff --git a/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/naive_vector_column.h b/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/naive_vector_column.h index 710987a374..d14a150ae6 100644 --- a/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/naive_vector_column.h +++ b/src/Persistence_matrix/include/gudhi/Persistence_matrix/columns/naive_vector_column.h @@ -224,9 +224,9 @@ class Naive_vector_column : public Master_matrix::Row_access_option, }; template -using STD_naive_vector_column = Naive_vector_column >; +using Naive_std_vector_column = Naive_vector_column >; template -using Small_naive_vector_column = +using Naive_small_vector_column = Naive_vector_column >; template diff --git a/src/Persistence_matrix/test/pm_column_tests_boost_type_lists.h b/src/Persistence_matrix/test/pm_column_tests_boost_type_lists.h index dbccb01e72..c015eaa70b 100644 --- a/src/Persistence_matrix/test/pm_column_tests_boost_type_lists.h +++ b/src/Persistence_matrix/test/pm_column_tests_boost_type_lists.h @@ -30,8 +30,8 @@ using Gudhi::persistence_matrix::Heap_column; using Gudhi::persistence_matrix::Intrusive_list_column; using Gudhi::persistence_matrix::Intrusive_set_column; using Gudhi::persistence_matrix::List_column; -using Gudhi::persistence_matrix::STD_naive_vector_column; -using Gudhi::persistence_matrix::Small_naive_vector_column; +using Gudhi::persistence_matrix::Naive_std_vector_column; +using Gudhi::persistence_matrix::Naive_small_vector_column; using Gudhi::persistence_matrix::Set_column; using Gudhi::persistence_matrix::Unordered_set_column; using Gudhi::persistence_matrix::Vector_column; @@ -66,9 +66,9 @@ class column_non_validity { } else if constexpr (col_type::Master::Option_list::column_type == Column_types::UNORDERED_SET) { return !std::is_same_v >; } else if constexpr (col_type::Master::Option_list::column_type == Column_types::NAIVE_VECTOR) { - return !std::is_same_v >; + return !std::is_same_v >; } else if constexpr (col_type::Master::Option_list::column_type == Column_types::SMALL_VECTOR) { - return !std::is_same_v >; + return !std::is_same_v >; } else if constexpr (col_type::Master::Option_list::column_type == Column_types::VECTOR) { return !std::is_same_v >; } else if constexpr (col_type::Master::Option_list::column_type == Column_types::HEAP) { @@ -90,7 +90,7 @@ using row_col_type_list = boost::mp11::mp_list; + Naive_std_vector_column, Naive_small_vector_column, Vector_column, Heap_column>; using c_matrix_type_list = mp_list_q; template Date: Thu, 14 Nov 2024 08:55:40 +0100 Subject: [PATCH 10/15] doc review: typo Co-authored-by: hschreiber <48448038+hschreiber@users.noreply.github.com> --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index 566803d5d4..39e0d41395 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -639,7 +639,7 @@ class Simplex_tree { template friend class Simplex_tree; /** \brief Checks if two simplex trees are equal. Any extra data (@ref Simplex_data) stored in the simplices are - * ignored in the coomparison + * ignored in the comparison. */ template bool operator==(Simplex_tree& st2) { From 59ce648275f09c980056da51371fed8fb5bd480f Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau <10407034+VincentRouvreau@users.noreply.github.com> Date: Thu, 14 Nov 2024 08:55:54 +0100 Subject: [PATCH 11/15] doc review: typo Co-authored-by: hschreiber <48448038+hschreiber@users.noreply.github.com> --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index 39e0d41395..731898dd0c 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -2605,7 +2605,7 @@ class Simplex_tree { * @warning Serialize/Deserialize is not portable. It is meant to be read in a Simplex_tree with the same * SimplexTreeOptions and on a computer with the same architecture. * - * Serialize/Deserialize ignore any extra data (@ref Simplex_data) stored in the simplices for now. + * Serialize/Deserialize ignores any extra data (@ref Simplex_data) stored in the simplices for now. */ void deserialize(const char* buffer, const std::size_t buffer_size) { GUDHI_CHECK(num_vertices() == 0, std::logic_error("Simplex_tree::deserialize - Simplex_tree must be empty")); From 5b3e30e768b006db0f4256b6b7b233727e97497a Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau <10407034+VincentRouvreau@users.noreply.github.com> Date: Thu, 14 Nov 2024 08:56:09 +0100 Subject: [PATCH 12/15] doc review: typo Co-authored-by: hschreiber <48448038+hschreiber@users.noreply.github.com> --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index 731898dd0c..1ee893402c 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -2536,7 +2536,7 @@ class Simplex_tree { * @warning Serialize/Deserialize is not portable. It is meant to be read in a Simplex_tree with the same * SimplexTreeOptions and on a computer with the same architecture. * - * Serialize/Deserialize ignore any extra data (@ref Simplex_data) stored in the simplices for now. + * Serialize/Deserialize ignores any extra data (@ref Simplex_data) stored in the simplices for now. */ /* Let's take the following simplicial complex as example: */ /* (vertices are represented as letters to ease the understanding) */ From 961919a8f52247a914bd4bfcf3f8a969ace7bbe0 Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau Date: Tue, 4 Feb 2025 15:14:45 +0100 Subject: [PATCH 13/15] code review: add default-initialization for extra dat in doc --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index 25053fd7c6..07ed208c8e 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -107,7 +107,11 @@ class Simplex_tree { * * Must be an integer type. */ typedef typename Options::Simplex_key Simplex_key; - /** \brief Extra data stored in each simplex. */ + /** \brief Extra data stored in each simplex. + * + * When extra data type is defined by the user, the extra data gets a + * default-initialization + * , which may mean an indeterminate value. */ typedef typename Get_simplex_data_type::type Simplex_data; /** \brief Type for the vertex handle. * From 20635d75f4d69e3661d2ee0da890538ff7a14675 Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau Date: Tue, 4 Feb 2025 15:26:16 +0100 Subject: [PATCH 14/15] bad commit --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index 07ed208c8e..e653dedfc5 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -111,7 +111,7 @@ class Simplex_tree { * * When extra data type is defined by the user, the extra data gets a * default-initialization - * , which may mean an indeterminate value. */ + * behaviour, which may mean an indeterminate value. */ typedef typename Get_simplex_data_type::type Simplex_data; /** \brief Type for the vertex handle. * From 72bbb885a646b2daa3b91c0288348d207b4d93f3 Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau Date: Tue, 4 Feb 2025 15:30:26 +0100 Subject: [PATCH 15/15] code review: typo (codespell ok on the rest of the code) --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index e653dedfc5..794a1662e5 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -524,7 +524,7 @@ class Simplex_tree { for (auto& map_el : root_.members()) { map_el.second.assign_children(&root_); } - // Specific for optionnal data + // Specific for optional data if constexpr (!std::is_same_v) { auto dst_iter = root_.members().begin(); auto src_iter = root_source.members().begin(); @@ -588,7 +588,7 @@ class Simplex_tree { child.first, Node(newsib, translate_filtration_value(child.second.filtration()))); } - // Specific for optionnal data + // Specific for optional data if constexpr (copy_simplex_data && !std::is_same_v) { new_it->second.data() = child.second.data(); }