18#ifndef PM_INTRUSIVE_SET_COLUMN_H
19#define PM_INTRUSIVE_SET_COLUMN_H
26#include <boost/intrusive/set.hpp>
28#include <gudhi/Debug_utils.h>
33namespace persistence_matrix {
46template <
class Master_matrix>
52 using Master = Master_matrix;
53 using Index =
typename Master_matrix::Index;
54 using ID_index =
typename Master_matrix::ID_index;
55 using Dimension =
typename Master_matrix::Dimension;
56 using Field_element =
typename Master_matrix::Element;
57 using Entry =
typename Master_matrix::Matrix_entry;
58 using Column_settings =
typename Master_matrix::Column_settings;
61 using Field_operators =
typename Master_matrix::Field_operators;
62 using Column_support =
63 boost::intrusive::set<Entry,
64 boost::intrusive::constant_time_size<false>,
65 boost::intrusive::base_hook<typename Master_matrix::Base_hook_matrix_set_column> >;
66 using Entry_constructor =
typename Master_matrix::Entry_constructor;
69 using iterator =
typename Column_support::iterator;
70 using const_iterator =
typename Column_support::const_iterator;
71 using reverse_iterator =
typename Column_support::reverse_iterator;
72 using const_reverse_iterator =
typename Column_support::const_reverse_iterator;
75 template <
class Container =
typename Master_matrix::Boundary>
77 template <
class Container =
typename Master_matrix::Boundary,
class Row_container>
79 const Container& nonZeroRowIndices,
80 Row_container* rowContainer,
81 Column_settings* colSettings);
82 template <
class Container =
typename Master_matrix::Boundary>
83 Intrusive_set_column(
const Container& nonZeroChainRowIndices, Dimension dimension, Column_settings* colSettings);
84 template <
class Container =
typename Master_matrix::Boundary,
class Row_container>
86 const Container& nonZeroChainRowIndices,
88 Row_container* rowContainer,
89 Column_settings* colSettings);
91 template <
class Row_container>
94 Row_container* rowContainer,
95 Column_settings* colSettings =
nullptr);
99 std::vector<Field_element> get_content(
int columnLength = -1)
const;
100 bool is_non_zero(ID_index rowIndex)
const;
101 bool is_empty()
const;
102 std::size_t size()
const;
104 template <
class Row_index_map>
105 void reorder(
const Row_index_map& valueMap,
106 [[maybe_unused]] Index columnIndex = Master_matrix::template get_null_value<Index>());
108 void clear(ID_index rowIndex);
110 ID_index get_pivot()
const;
111 Field_element get_pivot_value()
const;
113 iterator begin()
noexcept;
114 const_iterator begin()
const noexcept;
115 iterator end()
noexcept;
116 const_iterator end()
const noexcept;
117 reverse_iterator rbegin()
noexcept;
118 const_reverse_iterator rbegin()
const noexcept;
119 reverse_iterator rend()
noexcept;
120 const_reverse_iterator rend()
const noexcept;
122 template <
class Entry_range>
129 template <
class Entry_range>
130 Intrusive_set_column& multiply_target_and_add(
const Field_element& val,
const Entry_range& column);
133 template <
class Entry_range>
134 Intrusive_set_column& multiply_source_and_add(
const Entry_range& column,
const Field_element& val);
137 void push_back(
const Entry& entry);
140 if (&c1 == &c2)
return true;
142 if constexpr (Master_matrix::Option_list::is_z2) {
143 return c1.column_ == c2.column_;
145 auto it1 = c1.column_.begin();
146 auto it2 = c2.column_.begin();
147 if (c1.column_.size() != c2.column_.size())
return false;
148 while (it1 != c1.column_.end() && it2 != c2.column_.end()) {
149 if (it1->get_row_index() != it2->get_row_index() || it1->get_element() != it2->get_element())
return false;
158 if (&c1 == &c2)
return false;
160 if constexpr (Master_matrix::Option_list::is_z2) {
161 return c1.column_ < c2.column_;
163 auto it1 = c1.column_.begin();
164 auto it2 = c2.column_.begin();
165 while (it1 != c1.column_.end() && it2 != c2.column_.end()) {
166 if (it1->get_row_index() != it2->get_row_index())
return it1->get_row_index() < it2->get_row_index();
167 if (it1->get_element() != it2->get_element())
return it1->get_element() < it2->get_element();
171 return it2 != c2.column_.end();
185 col1.column_.swap(col2.column_);
186 std::swap(col1.operators_, col2.operators_);
187 std::swap(col1.entryPool_, col2.entryPool_);
197 New_cloner(Entry_constructor* entryPool) : entryPool_(entryPool) {};
199 Entry* operator()(
const Entry& clone_this) {
return entryPool_->construct(clone_this); }
201 Entry_constructor* entryPool_;
205 struct Delete_disposer {
206 Delete_disposer() {};
209 void operator()(Entry* delete_this) {
210 if constexpr (Master_matrix::Option_list::has_row_access) col_->unlink(delete_this);
211 col_->entryPool_->destroy(delete_this);
217 Column_support column_;
218 Field_operators* operators_;
219 Entry_constructor* entryPool_;
221 template <
class Column,
class Entry_iterator,
typename F1,
typename F2,
typename F3,
typename F4>
222 friend void _generic_merge_entry_to_column(Column& targetColumn,
223 Entry_iterator& itSource,
224 typename Column::Column_support::iterator& itTarget,
229 bool& pivotIsZeroed);
230 template <
class Column,
class Entry_range,
typename F1,
typename F2,
typename F3,
typename F4,
typename F5>
231 friend bool _generic_add_to_column(
const Entry_range& source,
232 Column& targetColumn,
238 template <
class Column,
class Entry_range>
239 friend bool _add_to_column(
const Entry_range& source, Column& targetColumn);
240 template <
class Column,
class Entry_range>
241 friend bool _multiply_target_and_add_to_column(
const typename Column::Field_element& val,
242 const Entry_range& source,
243 Column& targetColumn);
244 template <
class Column,
class Entry_range>
245 friend bool _multiply_source_and_add_to_column(
const typename Column::Field_element& val,
246 const Entry_range& source,
247 Column& targetColumn);
249 void _delete_entry(iterator& it);
250 Entry* _insert_entry(
const Field_element& value, ID_index rowIndex,
const iterator& position);
251 void _insert_entry(ID_index rowIndex,
const iterator& position);
252 template <
class Entry_range>
253 bool _add(
const Entry_range& column);
254 template <
class Entry_range>
255 bool _multiply_target_and_add(
const Field_element& val,
const Entry_range& column);
256 template <
class Entry_range>
257 bool _multiply_source_and_add(
const Entry_range& column,
const Field_element& val);
260template <
class Master_matrix>
266 entryPool_(colSettings == nullptr ? nullptr : &(colSettings->entryConstructor))
268 if (operators_ ==
nullptr && entryPool_ ==
nullptr)
270 if constexpr (!Master_matrix::Option_list::is_z2) {
271 operators_ = &(colSettings->operators);
275template <
class Master_matrix>
276template <
class Container>
277inline Intrusive_set_column<Master_matrix>::Intrusive_set_column(
const Container& nonZeroRowIndices,
278 Column_settings* colSettings)
280 Dim_opt(nonZeroRowIndices.size() == 0 ? 0 : nonZeroRowIndices.size() - 1),
283 entryPool_(&(colSettings->entryConstructor))
285 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
286 "Constructor not available for chain columns, please specify the dimension of the chain.");
288 if constexpr (Master_matrix::Option_list::is_z2) {
289 for (ID_index
id : nonZeroRowIndices) {
290 _insert_entry(
id, column_.end());
293 operators_ = &(colSettings->operators);
294 for (
const auto& p : nonZeroRowIndices) {
295 _insert_entry(operators_->get_value(p.second), p.first, column_.end());
300template <
class Master_matrix>
301template <
class Container,
class Row_container>
302inline Intrusive_set_column<Master_matrix>::Intrusive_set_column(Index columnIndex,
303 const Container& nonZeroRowIndices,
304 Row_container* rowContainer,
305 Column_settings* colSettings)
306 : RA_opt(columnIndex, rowContainer),
307 Dim_opt(nonZeroRowIndices.size() == 0 ? 0 : nonZeroRowIndices.size() - 1),
309 if constexpr (Master_matrix::Option_list::is_z2) {
310 return nonZeroRowIndices.begin() == nonZeroRowIndices.end()
311 ? Master_matrix::template get_null_value<ID_index>()
312 : *
std::prev(nonZeroRowIndices.end());
314 return nonZeroRowIndices.begin() == nonZeroRowIndices.end()
315 ? Master_matrix::template get_null_value<ID_index>()
316 :
std::prev(nonZeroRowIndices.end())->first;
320 entryPool_(&(colSettings->entryConstructor))
322 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
323 "Constructor not available for chain columns, please specify the dimension of the chain.");
325 if constexpr (Master_matrix::Option_list::is_z2) {
326 for (ID_index
id : nonZeroRowIndices) {
327 _insert_entry(
id, column_.end());
330 operators_ = &(colSettings->operators);
331 for (
const auto& p : nonZeroRowIndices) {
332 _insert_entry(operators_->get_value(p.second), p.first, column_.end());
337template <
class Master_matrix>
338template <
class Container>
339inline Intrusive_set_column<Master_matrix>::Intrusive_set_column(
const Container& nonZeroRowIndices,
341 Column_settings* colSettings)
345 if constexpr (Master_matrix::Option_list::is_z2) {
346 return nonZeroRowIndices.begin() == nonZeroRowIndices.end()
347 ? Master_matrix::template get_null_value<ID_index>()
348 : *
std::prev(nonZeroRowIndices.end());
350 return nonZeroRowIndices.begin() == nonZeroRowIndices.end()
351 ? Master_matrix::template get_null_value<ID_index>()
352 :
std::prev(nonZeroRowIndices.end())->first;
356 entryPool_(&(colSettings->entryConstructor))
358 if constexpr (Master_matrix::Option_list::is_z2) {
359 for (ID_index
id : nonZeroRowIndices) {
360 _insert_entry(
id, column_.end());
363 operators_ = &(colSettings->operators);
364 for (
const auto& p : nonZeroRowIndices) {
365 _insert_entry(operators_->get_value(p.second), p.first, column_.end());
370template <
class Master_matrix>
371template <
class Container,
class Row_container>
372inline Intrusive_set_column<Master_matrix>::Intrusive_set_column(Index columnIndex,
373 const Container& nonZeroRowIndices,
375 Row_container* rowContainer,
376 Column_settings* colSettings)
377 : RA_opt(columnIndex, rowContainer),
380 if constexpr (Master_matrix::Option_list::is_z2) {
381 return nonZeroRowIndices.begin() == nonZeroRowIndices.end()
382 ? Master_matrix::template get_null_value<ID_index>()
383 : *
std::prev(nonZeroRowIndices.end());
385 return nonZeroRowIndices.begin() == nonZeroRowIndices.end()
386 ? Master_matrix::template get_null_value<ID_index>()
387 :
std::prev(nonZeroRowIndices.end())->first;
391 entryPool_(&(colSettings->entryConstructor))
393 if constexpr (Master_matrix::Option_list::is_z2) {
394 for (ID_index
id : nonZeroRowIndices) {
395 _insert_entry(
id, column_.end());
398 operators_ = &(colSettings->operators);
399 for (
const auto& p : nonZeroRowIndices) {
400 _insert_entry(operators_->get_value(p.second), p.first, column_.end());
405template <
class Master_matrix>
406inline Intrusive_set_column<Master_matrix>::Intrusive_set_column(
const Intrusive_set_column& column,
407 Column_settings* colSettings)
409 Dim_opt(static_cast<const Dim_opt&>(column)),
410 Chain_opt(static_cast<const Chain_opt&>(column)),
411 operators_(colSettings == nullptr ? column.operators_ : nullptr),
412 entryPool_(colSettings == nullptr ? column.entryPool_ : &(colSettings->entryConstructor))
414 static_assert(!Master_matrix::Option_list::has_row_access,
415 "Simple copy constructor not available when row access option enabled. Please specify the new column "
416 "index and the row container.");
418 if constexpr (!Master_matrix::Option_list::is_z2) {
419 if (colSettings !=
nullptr) operators_ = &(colSettings->operators);
422 column_.clone_from(column.column_, New_cloner(entryPool_), Delete_disposer(
this));
425template <
class Master_matrix>
426template <
class Row_container>
427inline Intrusive_set_column<Master_matrix>::Intrusive_set_column(
const Intrusive_set_column& column,
429 Row_container* rowContainer,
430 Column_settings* colSettings)
431 : RA_opt(columnIndex, rowContainer),
432 Dim_opt(static_cast<const Dim_opt&>(column)),
433 Chain_opt(static_cast<const Chain_opt&>(column)),
434 operators_(colSettings == nullptr ? column.operators_ : nullptr),
435 entryPool_(colSettings == nullptr ? column.entryPool_ : &(colSettings->entryConstructor))
437 if constexpr (!Master_matrix::Option_list::is_z2) {
438 if (colSettings !=
nullptr) operators_ = &(colSettings->operators);
441 for (
const Entry& entry : column.column_) {
442 if constexpr (Master_matrix::Option_list::is_z2) {
443 _insert_entry(entry.get_row_index(), column_.end());
445 _insert_entry(entry.get_element(), entry.get_row_index(), column_.end());
450template <
class Master_matrix>
451inline Intrusive_set_column<Master_matrix>::Intrusive_set_column(Intrusive_set_column&& column) noexcept
452 : RA_opt(std::move(
static_cast<RA_opt&
>(column))),
453 Dim_opt(std::move(
static_cast<Dim_opt&
>(column))),
454 Chain_opt(std::move(
static_cast<Chain_opt&
>(column))),
455 column_(std::move(column.column_)),
456 operators_(std::exchange(column.operators_,
nullptr)),
457 entryPool_(std::exchange(column.entryPool_,
nullptr))
460template <
class Master_matrix>
461inline Intrusive_set_column<Master_matrix>::~Intrusive_set_column()
463 column_.clear_and_dispose(Delete_disposer(
this));
466template <
class Master_matrix>
467inline std::vector<typename Intrusive_set_column<Master_matrix>::Field_element>
468Intrusive_set_column<Master_matrix>::get_content(
int columnLength)
const
470 if (columnLength < 0 && column_.size() > 0)
471 columnLength = column_.rbegin()->get_row_index() + 1;
472 else if (columnLength < 0)
473 return std::vector<Field_element>();
475 std::vector<Field_element> container(columnLength);
476 for (
auto it = column_.begin(); it != column_.end() && it->get_row_index() <
static_cast<ID_index
>(columnLength);
478 if constexpr (Master_matrix::Option_list::is_z2) {
479 container[it->get_row_index()] = 1;
481 container[it->get_row_index()] = it->get_element();
487template <
class Master_matrix>
488inline bool Intrusive_set_column<Master_matrix>::is_non_zero(ID_index rowIndex)
const
490 return column_.find(Entry(rowIndex)) != column_.end();
493template <
class Master_matrix>
494inline bool Intrusive_set_column<Master_matrix>::is_empty()
const
496 return column_.empty();
499template <
class Master_matrix>
500inline std::size_t Intrusive_set_column<Master_matrix>::size()
const
502 return column_.size();
505template <
class Master_matrix>
506template <
class Row_index_map>
507inline void Intrusive_set_column<Master_matrix>::reorder(
const Row_index_map& valueMap,
508 [[maybe_unused]] Index columnIndex)
510 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
511 "Method not available for chain columns.");
513 Column_support newSet;
515 if constexpr (Master_matrix::Option_list::has_row_access) {
516 for (
auto it = column_.begin(); it != column_.end();) {
517 Entry* newEntry = entryPool_->construct(
518 columnIndex == Master_matrix::template get_null_value<Index>() ? RA_opt::columnIndex_ : columnIndex,
519 valueMap.at(it->get_row_index()));
520 if constexpr (!Master_matrix::Option_list::is_z2) {
521 newEntry->set_element(it->get_element());
523 newSet.insert(newSet.end(), *newEntry);
525 if constexpr (Master_matrix::Option_list::has_intrusive_rows)
526 RA_opt::insert_entry(newEntry->get_row_index(), newEntry);
530 if constexpr (!Master_matrix::Option_list::has_intrusive_rows) {
531 for (Entry& entry : newSet) {
532 RA_opt::insert_entry(entry.get_row_index(), &entry);
536 for (
auto it = column_.begin(); it != column_.end();) {
537 Entry* newEntry = entryPool_->construct(valueMap.at(it->get_row_index()));
538 if constexpr (!Master_matrix::Option_list::is_z2) {
539 newEntry->set_element(it->get_element());
541 newSet.insert(newSet.end(), *newEntry);
546 column_.swap(newSet);
549template <
class Master_matrix>
550inline void Intrusive_set_column<Master_matrix>::clear()
552 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
553 "Method not available for chain columns as a base element should not be empty.");
555 column_.clear_and_dispose(Delete_disposer(
this));
558template <
class Master_matrix>
559inline void Intrusive_set_column<Master_matrix>::clear(ID_index rowIndex)
561 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
562 "Method not available for chain columns.");
564 auto it = column_.find(Entry(rowIndex));
565 if (it != column_.end()) {
570template <
class Master_matrix>
571inline typename Intrusive_set_column<Master_matrix>::ID_index Intrusive_set_column<Master_matrix>::get_pivot()
const
573 static_assert(Master_matrix::isNonBasic,
574 "Method not available for base columns.");
576 if constexpr (Master_matrix::Option_list::is_of_boundary_type) {
577 if (column_.empty())
return Master_matrix::template get_null_value<ID_index>();
578 return column_.rbegin()->get_row_index();
580 return Chain_opt::get_pivot();
584template <
class Master_matrix>
585inline typename Intrusive_set_column<Master_matrix>::Field_element
586Intrusive_set_column<Master_matrix>::get_pivot_value()
const
588 static_assert(Master_matrix::isNonBasic,
589 "Method not available for base columns.");
591 if constexpr (Master_matrix::Option_list::is_z2) {
594 if constexpr (Master_matrix::Option_list::is_of_boundary_type) {
595 if (column_.empty())
return 0;
596 return column_.rbegin()->get_element();
598 if (Chain_opt::get_pivot() == Master_matrix::template get_null_value<ID_index>())
return 0;
599 auto it = column_.find(Entry(Chain_opt::get_pivot()));
600 GUDHI_CHECK(it != column_.end(),
601 "Intrusive_set_column::get_pivot_value - Pivot not found only if the column was misused.");
602 return it->get_element();
607template <
class Master_matrix>
608inline typename Intrusive_set_column<Master_matrix>::iterator Intrusive_set_column<Master_matrix>::begin() noexcept
610 return column_.begin();
613template <
class Master_matrix>
614inline typename Intrusive_set_column<Master_matrix>::const_iterator Intrusive_set_column<Master_matrix>::begin()
617 return column_.begin();
620template <
class Master_matrix>
621inline typename Intrusive_set_column<Master_matrix>::iterator Intrusive_set_column<Master_matrix>::end() noexcept
623 return column_.end();
626template <
class Master_matrix>
627inline typename Intrusive_set_column<Master_matrix>::const_iterator Intrusive_set_column<Master_matrix>::end()
630 return column_.end();
633template <
class Master_matrix>
634inline typename Intrusive_set_column<Master_matrix>::reverse_iterator
635Intrusive_set_column<Master_matrix>::rbegin() noexcept
637 return column_.rbegin();
640template <
class Master_matrix>
641inline typename Intrusive_set_column<Master_matrix>::const_reverse_iterator
642Intrusive_set_column<Master_matrix>::rbegin() const noexcept
644 return column_.rbegin();
647template <
class Master_matrix>
648inline typename Intrusive_set_column<Master_matrix>::reverse_iterator
649Intrusive_set_column<Master_matrix>::rend() noexcept
651 return column_.rend();
654template <
class Master_matrix>
655inline typename Intrusive_set_column<Master_matrix>::const_reverse_iterator Intrusive_set_column<Master_matrix>::rend()
658 return column_.rend();
661template <
class Master_matrix>
662template <
class Entry_range>
663inline Intrusive_set_column<Master_matrix>& Intrusive_set_column<Master_matrix>::operator+=(
const Entry_range& column)
665 static_assert((!Master_matrix::isNonBasic || std::is_same_v<Entry_range, Intrusive_set_column>),
666 "For boundary columns, the range has to be a column of same type to help ensure the validity of the "
668 static_assert((!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type),
669 "For chain columns, the given column cannot be constant.");
676template <
class Master_matrix>
677inline Intrusive_set_column<Master_matrix>& Intrusive_set_column<Master_matrix>::operator+=(
678 Intrusive_set_column& column)
680 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
683 Chain_opt::swap_pivots(column);
684 Dim_opt::swap_dimension(column);
693template <
class Master_matrix>
694inline Intrusive_set_column<Master_matrix>& Intrusive_set_column<Master_matrix>::operator*=(
unsigned int v)
696 if constexpr (Master_matrix::Option_list::is_z2) {
698 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
699 throw std::invalid_argument(
"A chain column should not be multiplied by 0.");
705 Field_element val = operators_->get_value(v);
707 if (val == Field_operators::get_additive_identity()) {
708 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
709 throw std::invalid_argument(
"A chain column should not be multiplied by 0.");
716 if (val == Field_operators::get_multiplicative_identity())
return *
this;
718 for (Entry& entry : column_) {
719 operators_->multiply_inplace(entry.get_element(), val);
720 if constexpr (Master_matrix::Option_list::has_row_access) RA_opt::update_entry(entry);
727template <
class Master_matrix>
728template <
class Entry_range>
729inline Intrusive_set_column<Master_matrix>& Intrusive_set_column<Master_matrix>::multiply_target_and_add(
730 const Field_element& val,
731 const Entry_range& column)
733 static_assert((!Master_matrix::isNonBasic || std::is_same_v<Entry_range, Intrusive_set_column>),
734 "For boundary columns, the range has to be a column of same type to help ensure the validity of the "
736 static_assert((!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type),
737 "For chain columns, the given column cannot be constant.");
739 if constexpr (Master_matrix::Option_list::is_z2) {
747 _multiply_target_and_add(val, column);
753template <
class Master_matrix>
754inline Intrusive_set_column<Master_matrix>& Intrusive_set_column<Master_matrix>::multiply_target_and_add(
755 const Field_element& val,
756 Intrusive_set_column& column)
758 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
760 if constexpr (Master_matrix::Option_list::is_z2) {
763 Chain_opt::swap_pivots(column);
764 Dim_opt::swap_dimension(column);
767 throw std::invalid_argument(
"A chain column should not be multiplied by 0.");
770 if (_multiply_target_and_add(val, column)) {
771 Chain_opt::swap_pivots(column);
772 Dim_opt::swap_dimension(column);
776 if constexpr (Master_matrix::Option_list::is_z2) {
784 _multiply_target_and_add(val, column);
791template <
class Master_matrix>
792template <
class Entry_range>
793inline Intrusive_set_column<Master_matrix>& Intrusive_set_column<Master_matrix>::multiply_source_and_add(
794 const Entry_range& column,
795 const Field_element& val)
797 static_assert((!Master_matrix::isNonBasic || std::is_same_v<Entry_range, Intrusive_set_column>),
798 "For boundary columns, the range has to be a column of same type to help ensure the validity of the "
800 static_assert((!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type),
801 "For chain columns, the given column cannot be constant.");
803 if constexpr (Master_matrix::Option_list::is_z2) {
808 _multiply_source_and_add(column, val);
814template <
class Master_matrix>
815inline Intrusive_set_column<Master_matrix>& Intrusive_set_column<Master_matrix>::multiply_source_and_add(
816 Intrusive_set_column& column,
817 const Field_element& val)
819 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
821 if constexpr (Master_matrix::Option_list::is_z2) {
824 Chain_opt::swap_pivots(column);
825 Dim_opt::swap_dimension(column);
829 if (_multiply_source_and_add(column, val)) {
830 Chain_opt::swap_pivots(column);
831 Dim_opt::swap_dimension(column);
835 if constexpr (Master_matrix::Option_list::is_z2) {
840 _multiply_source_and_add(column, val);
847template <
class Master_matrix>
848inline void Intrusive_set_column<Master_matrix>::push_back(
const Entry& entry)
850 static_assert(Master_matrix::Option_list::is_of_boundary_type,
"`push_back` is not available for Chain matrices.");
852 GUDHI_CHECK(entry.get_row_index() > get_pivot(),
"The new row index has to be higher than the current pivot.");
854 if constexpr (Master_matrix::Option_list::is_z2) {
855 _insert_entry(entry.get_row_index(), column_.end());
857 _insert_entry(entry.get_element(), entry.get_row_index(), column_.end());
861template <
class Master_matrix>
862inline Intrusive_set_column<Master_matrix>& Intrusive_set_column<Master_matrix>::operator=(
863 const Intrusive_set_column& other)
865 static_assert(!Master_matrix::Option_list::has_row_access,
"= assignment not enabled with row access option.");
867 Dim_opt::operator=(other);
868 Chain_opt::operator=(other);
871 column_.clear_and_dispose(Delete_disposer(
this));
872 operators_ = other.operators_;
873 entryPool_ = other.entryPool_;
874 column_.clone_from(other.column_, New_cloner(entryPool_), Delete_disposer(
this));
879template <
class Master_matrix>
880inline void Intrusive_set_column<Master_matrix>::_delete_entry(iterator& it)
882 it = column_.erase_and_dispose(it, Delete_disposer(
this));
885template <
class Master_matrix>
886inline typename Intrusive_set_column<Master_matrix>::Entry* Intrusive_set_column<Master_matrix>::_insert_entry(
887 const Field_element& value,
889 const iterator& position)
891 if constexpr (Master_matrix::Option_list::has_row_access) {
892 Entry* newEntry = entryPool_->construct(RA_opt::columnIndex_, rowIndex);
893 newEntry->set_element(value);
894 column_.insert(position, *newEntry);
895 RA_opt::insert_entry(rowIndex, newEntry);
898 Entry* newEntry = entryPool_->construct(rowIndex);
899 newEntry->set_element(value);
900 column_.insert(position, *newEntry);
905template <
class Master_matrix>
906inline void Intrusive_set_column<Master_matrix>::_insert_entry(ID_index rowIndex,
const iterator& position)
908 if constexpr (Master_matrix::Option_list::has_row_access) {
909 Entry* newEntry = entryPool_->construct(RA_opt::columnIndex_, rowIndex);
910 column_.insert(position, *newEntry);
911 RA_opt::insert_entry(rowIndex, newEntry);
913 Entry* newEntry = entryPool_->construct(rowIndex);
914 column_.insert(position, *newEntry);
918template <
class Master_matrix>
919template <
class Entry_range>
920inline bool Intrusive_set_column<Master_matrix>::_add(
const Entry_range& column)
922 return _add_to_column(column, *
this);
925template <
class Master_matrix>
926template <
class Entry_range>
927inline bool Intrusive_set_column<Master_matrix>::_multiply_target_and_add(
const Field_element& val,
928 const Entry_range& column)
930 return _multiply_target_and_add_to_column(val, column, *
this);
933template <
class Master_matrix>
934template <
class Entry_range>
935inline bool Intrusive_set_column<Master_matrix>::_multiply_source_and_add(
const Entry_range& column,
936 const Field_element& val)
938 return _multiply_source_and_add_to_column(val, column, *
this);
952template <
class Master_matrix>
953struct std::hash<
Gudhi::persistence_matrix::Intrusive_set_column<Master_matrix> > {
955 return Gudhi::persistence_matrix::hash_column(column);
Column class following the PersistenceMatrixColumn concept.
Definition: intrusive_set_column.h:50
Contains helper methods for column addition and column hasher.
Contains different versions of Gudhi::persistence_matrix::Entry factories.
Chain_column_extra_properties Chain_column_option
If PersistenceMatrixOptions::is_of_boundary_type is false, and, PersistenceMatrixOptions::has_column_...
Definition: PersistenceMatrixColumn.h:45
Row_access Row_access_option
If PersistenceMatrixOptions::has_row_access is true, then Row_access. Otherwise Dummy_row_access....
Definition: PersistenceMatrixColumn.h:28
Column_dimension_holder Column_dimension_option
If PersistenceMatrixOptions::has_column_pairings or PersistenceMatrixOptions::has_vine_update or Pers...
Definition: PersistenceMatrixColumn.h:36
Gudhi namespace.
Definition: SimplicialComplexForAlpha.h:14