From 865259da1f72582131ba7ad7f820feb9453c8ec9 Mon Sep 17 00:00:00 2001 From: hschreiber Date: Fri, 8 Nov 2024 17:00:00 +0100 Subject: [PATCH] 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;