Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/GUDHI/gudhi-devel into Ex…
Browse files Browse the repository at this point in the history
…act_SW
  • Loading branch information
MathieuCarriere committed Feb 6, 2025
2 parents a4c069e + 86cb9b1 commit 5664cdf
Show file tree
Hide file tree
Showing 17 changed files with 331 additions and 149 deletions.
9 changes: 7 additions & 2 deletions src/Persistence_matrix/include/gudhi/Matrix.h
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,8 @@ class Matrix {
using Matrix_heap_column = Heap_column<Matrix<PersistenceMatrixOptions> >;
using Matrix_list_column = List_column<Matrix<PersistenceMatrixOptions> >;
using Matrix_vector_column = Vector_column<Matrix<PersistenceMatrixOptions> >;
using Matrix_naive_vector_column = Naive_vector_column<Matrix<PersistenceMatrixOptions> >;
using Matrix_naive_vector_column = Naive_std_vector_column<Matrix<PersistenceMatrixOptions> >;
using Matrix_small_vector_column = Naive_small_vector_column<Matrix<PersistenceMatrixOptions> >;
using Matrix_set_column = Set_column<Matrix<PersistenceMatrixOptions> >;
using Matrix_unordered_set_column = Unordered_set_column<Matrix<PersistenceMatrixOptions> >;
using Matrix_intrusive_list_column = Intrusive_list_column<Matrix<PersistenceMatrixOptions> >;
Expand Down Expand Up @@ -353,7 +354,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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 Master_matrix>
class Heap_column : public Master_matrix::Column_dimension_option, public Master_matrix::Chain_column_option
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 Master_matrix>
class Intrusive_list_column : public Master_matrix::Row_access_option,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 Master_matrix>
class Intrusive_set_column : public Master_matrix::Row_access_option,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 Master_matrix>
class List_column : public Master_matrix::Row_access_option,
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -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 Master_matrix>
class Set_column : public Master_matrix::Row_access_option,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,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 Master_matrix>
class Unordered_set_column : public Master_matrix::Row_access_option,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 Master_matrix>
class Vector_column : public Master_matrix::Row_access_option,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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>. */
Expand Down
16 changes: 10 additions & 6 deletions src/Persistence_matrix/test/pm_column_tests_boost_type_lists.h
Original file line number Diff line number Diff line change
Expand Up @@ -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::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;
Expand Down Expand Up @@ -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<col_type, Unordered_set_column<typename col_type::Master> >;
} else if constexpr (col_type::Master::Option_list::column_type == Column_types::NAIVE_VECTOR) {
return !std::is_same_v<col_type, Naive_vector_column<typename col_type::Master> >;
return !std::is_same_v<col_type, Naive_std_vector_column<typename col_type::Master> >;
} else if constexpr (col_type::Master::Option_list::column_type == Column_types::SMALL_VECTOR) {
return !std::is_same_v<col_type, Naive_small_vector_column<typename col_type::Master> >;
} else if constexpr (col_type::Master::Option_list::column_type == Column_types::VECTOR) {
return !std::is_same_v<col_type, Vector_column<typename col_type::Master> >;
} else if constexpr (col_type::Master::Option_list::column_type == Column_types::HEAP) {
Expand All @@ -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_intrusive_list, ct_intrusive_set, ct_list, ct_set, ct_heap,
ct_unordered_set, ct_vector, ct_naive_vector>;
ct_unordered_set, ct_vector, ct_naive_vector, ct_small_vector>;
using row_col_type_list = boost::mp11::mp_list<ct_intrusive_list, ct_intrusive_set, ct_list, ct_set, ct_unordered_set,
ct_vector, ct_naive_vector>;
ct_vector, ct_naive_vector, ct_small_vector>;
//...and add the column name here.
using column_list = mp_list_q<Intrusive_list_column, Intrusive_set_column, List_column, Set_column,
Unordered_set_column, Naive_vector_column, Vector_column, Heap_column>;
using column_list =
mp_list_q<Intrusive_list_column, Intrusive_set_column, List_column, Set_column, Unordered_set_column,
Naive_std_vector_column, Naive_small_vector_column, Vector_column, Heap_column>;
using c_matrix_type_list = mp_list_q<Column_mini_matrix>;

template <typename option_name_list, typename bool_is_z2, typename col_t, typename bool_has_row, typename bool_rem_row,
Expand Down
4 changes: 4 additions & 0 deletions src/Persistence_matrix/test/pm_common_boost_type_lists.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ struct ct_naive_vector {
static constexpr const Column_types t = Column_types::NAIVE_VECTOR;
};

struct ct_small_vector {
static constexpr const Column_types t = Column_types::SMALL_VECTOR;
};

struct true_value {
static constexpr const bool t = true;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ class matrix_non_validity {
// users. But in case real changes were made to this module, it would be better to test at least once with all column
// types as below:
// using col_type_list = boost::mp11::mp_list<ct_intrusive_list, ct_intrusive_set, ct_list, ct_set, ct_heap,
// ct_unordered_set, ct_vector, ct_naive_vector>;
// ct_unordered_set, ct_vector, ct_naive_vector, ct_small_vector>;
#ifdef PM_TEST_INTR_LIST
using col_type_list = boost::mp11::mp_list<ct_intrusive_list>;
#else
Expand All @@ -162,6 +162,9 @@ using col_type_list = boost::mp11::mp_list<ct_unordered_set>;
#ifdef PM_TEST_NAIVE_VECTOR
using col_type_list = boost::mp11::mp_list<ct_naive_vector>;
#else
#ifdef PM_TEST_SMALL_VECTOR
using col_type_list = boost::mp11::mp_list<ct_small_vector>;
#else
using col_type_list = boost::mp11::mp_list<ct_vector>;
#endif
#endif
Expand All @@ -170,6 +173,7 @@ using col_type_list = boost::mp11::mp_list<ct_vector>;
#endif
#endif
#endif
#endif

using matrix_type_list = mp_list_q<Matrix>;

Expand Down
59 changes: 47 additions & 12 deletions src/Simplex_tree/include/gudhi/Simplex_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
* - 2024/10 Hannah Schreiber: Const version of the Simplex_tree
* - YYYY/MM Author: Description of the modification
*/
Expand Down Expand Up @@ -106,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
* <a target="_blank" href="https://en.cppreference.com/w/cpp/language/default_initialization">default-initialization
* </a> behaviour, which may mean an indeterminate value. */
typedef typename Get_simplex_data_type<Options>::type Simplex_data;
/** \brief Type for the vertex handle.
*
Expand Down Expand Up @@ -438,15 +443,18 @@ 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;
#endif // DEBUG_TRACES
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) {
Expand All @@ -465,7 +473,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;
Expand All @@ -480,7 +490,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) {
Expand Down Expand Up @@ -513,7 +524,21 @@ class Simplex_tree {
for (auto& map_el : root_.members()) {
map_el.second.assign_children(&root_);
}
rec_copy<Options::store_key>(
// Specific for optional data
if constexpr (!std::is_same_v<Simplex_data, No_simplex_data>) {
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<Options::store_key, true>(
&root_, &root_source, [](const Filtration_value& fil) -> const Filtration_value& { return fil; });
}

Expand All @@ -537,11 +562,11 @@ class Simplex_tree {
}
}

rec_copy<OtherSimplexTreeOptions::store_key>(&root_, &root_source, translate_filtration_value);
rec_copy<OtherSimplexTreeOptions::store_key, false>(&root_, &root_source, translate_filtration_value);
}

/** \brief depth first search, inserts simplices when reaching a leaf. */
template<bool store_key, typename OtherSiblings, typename F>
template<bool store_key, bool copy_simplex_data, typename OtherSiblings, typename F>
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) {
Expand All @@ -552,18 +577,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 optional data
if constexpr (copy_simplex_data && !std::is_same_v<Simplex_data, No_simplex_data>) {
new_it->second.data() = child.second.data();
}
}
rec_copy<store_key>(newsib, sh_source->second.children(), translate_filtration_value);
rec_copy<store_key, copy_simplex_data>(newsib, sh_source->second.children(), translate_filtration_value);
sh->second.assign_children(newsib);
}
}
Expand Down Expand Up @@ -616,7 +646,9 @@ class Simplex_tree {
public:
template<typename> 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 comparison.
*/
template<class OtherSimplexTreeOptions>
bool operator==(const Simplex_tree<OtherSimplexTreeOptions>& st2) const {
if ((null_vertex_ != st2.null_vertex_) ||
Expand Down Expand Up @@ -2562,6 +2594,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 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) */
Expand Down Expand Up @@ -2630,6 +2664,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 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"));
Expand Down
4 changes: 4 additions & 0 deletions src/Simplex_tree/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,9 @@ 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)

add_executable_with_targets(Simplex_tree_constness_test_unit simplex_tree_constness_unit_test.cpp TBB::tbb)
gudhi_add_boost_test(Simplex_tree_constness_test_unit)

Loading

0 comments on commit 5664cdf

Please sign in to comment.