17#ifndef PM_COLUMN_UTILITIES_H
18#define PM_COLUMN_UTILITIES_H
28template <
class Entry,
typename Entry_iterator>
29Entry* _get_entry(
const Entry_iterator& itTarget)
40template <
class Column,
class Entry_iterator,
typename F1,
typename F2,
typename F3,
typename F4>
41void _generic_merge_entry_to_column(Column& targetColumn,
42 Entry_iterator& itSource,
43 typename Column::Column_support::iterator& itTarget,
46 [[maybe_unused]] F3&& update_target1,
47 [[maybe_unused]] F4&& update_target2,
50 typename Column::Entry* targetEntry = _get_entry<typename Column::Entry>(itTarget);
52 if (targetEntry->get_row_index() < itSource->get_row_index()) {
53 std::forward<F1>(process_target)(targetEntry);
55 }
else if (targetEntry->get_row_index() > itSource->get_row_index()) {
56 std::forward<F2>(process_source)(itSource, itTarget);
59 if constexpr (Column::Master::Option_list::is_z2) {
61 if constexpr (Column::Master::isNonBasic && !Column::Master::Option_list::is_of_boundary_type) {
62 if (targetEntry->get_row_index() == targetColumn.get_pivot()) pivotIsZeroed =
true;
64 targetColumn._delete_entry(itTarget);
66 std::forward<F3>(update_target1)(targetEntry->get_element(), itSource);
67 if (targetEntry->get_element() == Column::Field_operators::get_additive_identity()) {
68 if constexpr (Column::Master::isNonBasic && !Column::Master::Option_list::is_of_boundary_type) {
69 if (targetEntry->get_row_index() == targetColumn.get_pivot()) pivotIsZeroed =
true;
71 targetColumn._delete_entry(itTarget);
73 std::forward<F4>(update_target2)(targetEntry);
74 if constexpr (Column::Master::Option_list::has_row_access) targetColumn.update_entry(*targetEntry);
83template <
class Column,
class Entry_range,
typename F1,
typename F2,
typename F3,
typename F4,
typename F5>
84bool _generic_add_to_column(
const Entry_range& source,
92 bool pivotIsZeroed =
false;
94 auto& target = targetColumn.column_;
95 auto itTarget = target.begin();
96 auto itSource = source.begin();
97 while (itTarget != target.end() && itSource != source.end()) {
98 _generic_merge_entry_to_column(targetColumn,
101 std::forward<F1>(process_target),
102 std::forward<F2>(process_source),
103 std::forward<F3>(update_target1),
104 std::forward<F4>(update_target2),
108 std::forward<F5>(finish_target)(itTarget);
110 while (itSource != source.end()) {
111 std::forward<F2>(process_source)(itSource, target.end());
115 return pivotIsZeroed;
118template <
class Column,
class Entry_range>
119bool _add_to_column(
const Entry_range& source, Column& targetColumn)
121 return _generic_add_to_column(
124 [&]([[maybe_unused]]
typename Column::Entry* entryTarget) {},
125 [&](
typename Entry_range::const_iterator& itSource,
const typename Column::Column_support::iterator& itTarget) {
126 targetColumn._insert_entry(itTarget, itSource->get_row_index(), itSource->get_element());
128 [&](
typename Column::Field_element& targetElement,
typename Entry_range::const_iterator& itSource) {
129 if constexpr (!Column::Master::Option_list::is_z2)
130 targetColumn.operators_->add_inplace(targetElement, itSource->get_element());
132 [&]([[maybe_unused]]
typename Column::Entry* entryTarget) {},
133 [&]([[maybe_unused]]
typename Column::Column_support::iterator& itTarget) {});
136template <
class Column,
class Entry_range>
137bool _multiply_target_and_add_to_column(
const typename Column::Field_element& val,
138 const Entry_range& source,
139 Column& targetColumn)
141 if (val == Column::Field_operators::get_additive_identity()) {
142 if constexpr (Column::Master::isNonBasic && !Column::Master::Option_list::is_of_boundary_type) {
144 throw std::invalid_argument(
"A chain column should not be multiplied by 0.");
146 targetColumn.clear();
147 return _add_to_column(source, targetColumn);
151 if (val == Column::Field_operators::get_multiplicative_identity()) {
152 return _add_to_column(source, targetColumn);
155 if constexpr (!Column::Master::Option_list::is_z2) {
156 return _generic_add_to_column(
159 [&](
typename Column::Entry* entryTarget) {
160 targetColumn.operators_->multiply_inplace(entryTarget->get_element(), val);
163 if constexpr (Column::Master::Option_list::has_row_access) targetColumn.update_entry(*entryTarget);
165 [&](
typename Entry_range::const_iterator& itSource,
const typename Column::Column_support::iterator& itTarget) {
166 targetColumn._insert_entry(itTarget, itSource->get_row_index(), itSource->get_element());
168 [&](
typename Column::Field_element& targetElement,
typename Entry_range::const_iterator& itSource) {
169 targetColumn.operators_->multiply_and_add_inplace_front(targetElement, val, itSource->get_element());
171 [&]([[maybe_unused]]
typename Column::Entry* entryTarget) {},
172 [&](
typename Column::Column_support::iterator& itTarget) {
173 while (itTarget != targetColumn.column_.end()) {
174 typename Column::Entry* targetEntry = _get_entry<typename Column::Entry>(itTarget);
175 targetColumn.operators_->multiply_inplace(targetEntry->get_element(), val);
176 if constexpr (Column::Master::Option_list::has_row_access) targetColumn.update_entry(*targetEntry);
185template <
class Column,
class Entry_range>
186bool _multiply_source_and_add_to_column(
const typename Column::Field_element& val,
187 const Entry_range& source,
188 Column& targetColumn)
190 if (val == Column::Field_operators::get_additive_identity()) {
194 if (val == Column::Field_operators::get_multiplicative_identity()) {
195 return _add_to_column(source, targetColumn);
198 if constexpr (!Column::Master::Option_list::is_z2) {
199 return _generic_add_to_column(
202 []([[maybe_unused]]
typename Column::Entry* entryTarget) {},
203 [&](
typename Entry_range::const_iterator& itSource,
const typename Column::Column_support::iterator& itTarget) {
204 typename Column::Entry* entry =
205 targetColumn._insert_entry(itTarget, itSource->get_row_index(), itSource->get_element());
206 targetColumn.operators_->multiply_inplace(entry->get_element(), val);
207 if constexpr (Column::Master::Option_list::has_row_access) targetColumn.update_entry(*entry);
209 [&](
typename Column::Field_element& targetElement,
typename Entry_range::const_iterator& itSource) {
210 targetColumn.operators_->multiply_and_add_inplace_back(itSource->get_element(), val, targetElement);
212 [&]([[maybe_unused]]
typename Column::Entry* entryTarget) {},
213 []([[maybe_unused]]
typename Column::Column_support::iterator& itTarget) {});
221template <
class Column>
222std::size_t hash_column(
const Column& column)
224 std::size_t seed = 0;
225 for (
auto& entry : column) {
226 seed ^= std::hash<unsigned int>()(entry.get_row_index() *
static_cast<unsigned int>(entry.get_element())) +
227 0x9e3779b9 + (seed << 6) + (seed >> 2);
Matrix entry class. Stores by default only the row index it belongs to, but can also store its column...
Definition entry_types.h:163
@ INTRUSIVE_SET
Definition persistence_matrix_options.h:44
@ INTRUSIVE_LIST
Definition persistence_matrix_options.h:43
Persistence matrix namespace.
Definition FieldOperators.h:18
Gudhi namespace.
Definition SimplicialComplexForAlpha.h:14
Contains the options for the matrix template.