17 #ifndef PM_COLUMN_UTILITIES_H
18 #define PM_COLUMN_UTILITIES_H
26 namespace persistence_matrix {
28 template <
class Cell,
typename Cell_iterator>
29 Cell* _get_cell(
const Cell_iterator& itTarget)
40 template <
class Column_type,
class Cell_iterator,
typename F1,
typename F2,
typename F3,
typename F4>
41 void _generic_merge_cell_to_column(Column_type& targetColumn,
42 Cell_iterator& itSource,
43 typename Column_type::Column_type::iterator& itTarget,
50 typename Column_type::Cell* targetCell = _get_cell<typename Column_type::Cell>(itTarget);
52 if (targetCell->get_row_index() < itSource->get_row_index()) {
53 process_target(targetCell);
55 }
else if (targetCell->get_row_index() > itSource->get_row_index()) {
56 process_source(itSource, itTarget);
59 if constexpr (Column_type::Master::Option_list::is_z2) {
61 if constexpr (Column_type::Master::isNonBasic && !Column_type::Master::Option_list::is_of_boundary_type) {
62 if (targetCell->get_row_index() == targetColumn.get_pivot()) pivotIsZeroed =
true;
64 targetColumn._delete_cell(itTarget);
66 update_target1(targetCell->get_element(), itSource);
67 if (targetCell->get_element() == Column_type::Field_operators::get_additive_identity()) {
68 if constexpr (Column_type::Master::isNonBasic && !Column_type::Master::Option_list::is_of_boundary_type) {
69 if (targetCell->get_row_index() == targetColumn.get_pivot()) pivotIsZeroed =
true;
71 targetColumn._delete_cell(itTarget);
73 update_target2(targetCell);
74 if constexpr (Column_type::Master::Option_list::has_row_access)
75 targetColumn.update_cell(*targetCell);
84 template <
class Column_type,
class Cell_range,
typename F1,
typename F2,
typename F3,
typename F4,
typename F5>
85 bool _generic_add_to_column(
const Cell_range& source,
86 Column_type& targetColumn,
93 bool pivotIsZeroed =
false;
95 auto& target = targetColumn.column_;
96 auto itTarget = target.begin();
97 auto itSource = source.begin();
98 while (itTarget != target.end() && itSource != source.end()) {
99 _generic_merge_cell_to_column(targetColumn, itSource, itTarget,
100 process_target, process_source, update_target1, update_target2,
104 finish_target(itTarget);
106 while (itSource != source.end()) {
107 process_source(itSource, target.end());
111 return pivotIsZeroed;
114 template <
class Column_type,
class Cell_range>
115 bool _add_to_column(
const Cell_range& source, Column_type& targetColumn)
117 return _generic_add_to_column(
119 targetColumn, [&]([[maybe_unused]]
typename Column_type::Cell* cellTarget) {},
120 [&](
typename Cell_range::const_iterator& itSource,
const typename Column_type::Column_type::iterator& itTarget) {
121 if constexpr (Column_type::Master::Option_list::is_z2) {
122 targetColumn._insert_cell(itSource->get_row_index(), itTarget);
124 targetColumn._insert_cell(itSource->get_element(), itSource->get_row_index(), itTarget);
127 [&](
typename Column_type::Field_element_type& targetElement,
typename Cell_range::const_iterator& itSource) {
128 if constexpr (!Column_type::Master::Option_list::is_z2)
129 targetColumn.operators_->add_inplace(targetElement, itSource->get_element());
131 [&]([[maybe_unused]]
typename Column_type::Cell* cellTarget) {},
132 [&]([[maybe_unused]]
typename Column_type::Column_type::iterator& itTarget) {});
135 template <
class Column_type,
class Cell_range>
136 bool _multiply_target_and_add_to_column(
const typename Column_type::Field_element_type& val,
137 const Cell_range& source,
138 Column_type& targetColumn)
141 if constexpr (Column_type::Master::isNonBasic && !Column_type::Master::Option_list::is_of_boundary_type) {
142 throw std::invalid_argument(
"A chain column should not be multiplied by 0.");
145 targetColumn.clear();
149 return _generic_add_to_column(
152 [&](
typename Column_type::Cell* cellTarget) {
153 targetColumn.operators_->multiply_inplace(cellTarget->get_element(), val);
156 if constexpr (Column_type::Master::Option_list::has_row_access)
157 targetColumn.update_cell(*cellTarget);
159 [&](
typename Cell_range::const_iterator& itSource,
const typename Column_type::Column_type::iterator& itTarget) {
160 targetColumn._insert_cell(itSource->get_element(), itSource->get_row_index(), itTarget);
162 [&](
typename Column_type::Field_element_type& targetElement,
typename Cell_range::const_iterator& itSource) {
163 targetColumn.operators_->multiply_and_add_inplace_front(targetElement, val, itSource->get_element());
165 [&]([[maybe_unused]]
typename Column_type::Cell* cellTarget) {},
166 [&](
typename Column_type::Column_type::iterator& itTarget) {
167 while (itTarget != targetColumn.column_.end()) {
168 typename Column_type::Cell* targetCell = _get_cell<typename Column_type::Cell>(itTarget);
169 targetColumn.operators_->multiply_inplace(targetCell->get_element(), val);
170 if constexpr (Column_type::Master::Option_list::has_row_access)
171 targetColumn.update_cell(*targetCell);
177 template <
class Column_type,
class Cell_range>
178 bool _multiply_source_and_add_to_column(
const typename Column_type::Field_element_type& val,
const Cell_range& source,
179 Column_type& targetColumn)
185 return _generic_add_to_column(
187 targetColumn, []([[maybe_unused]]
typename Column_type::Cell* cellTarget) {},
188 [&](
typename Cell_range::const_iterator& itSource,
const typename Column_type::Column_type::iterator& itTarget) {
189 typename Column_type::Cell* cell =
190 targetColumn._insert_cell(itSource->get_element(), itSource->get_row_index(), itTarget);
191 targetColumn.operators_->multiply_inplace(cell->get_element(), val);
192 if constexpr (Column_type::Master::Option_list::has_row_access)
193 targetColumn.update_cell(*cell);
195 [&](
typename Column_type::Field_element_type& targetElement,
typename Cell_range::const_iterator& itSource) {
196 targetColumn.operators_->multiply_and_add_inplace_back(itSource->get_element(), val, targetElement);
198 [&]([[maybe_unused]]
typename Column_type::Cell* cellTarget) {},
199 []([[maybe_unused]]
typename Column_type::Column_type::iterator& itTarget) {});
204 template <
class Column_type>
205 std::size_t hash_column(
const Column_type& column) {
206 std::size_t seed = 0;
207 for (
auto& cell : column) {
208 seed ^= std::hash<unsigned int>()(cell.get_row_index() *
static_cast<unsigned int>(cell.get_element())) +
209 0x9e3779b9 + (seed << 6) + (seed >> 2);
@ INTRUSIVE_LIST
Definition: persistence_matrix_options.h:39
@ INTRUSIVE_SET
Definition: persistence_matrix_options.h:40
Gudhi namespace.
Definition: SimplicialComplexForAlpha.h:14
Contains the options for the matrix template.