18#ifndef PM_INTRUSIVE_LIST_COLUMN_H
19#define PM_INTRUSIVE_LIST_COLUMN_H
26#include <boost/intrusive/list.hpp>
32namespace persistence_matrix {
45template <
class Master_matrix>
51 using Master = Master_matrix;
52 using Index =
typename Master_matrix::Index;
53 using ID_index =
typename Master_matrix::ID_index;
54 using Dimension =
typename Master_matrix::Dimension;
55 using Field_element =
typename Master_matrix::Element;
56 using Entry =
typename Master_matrix::Matrix_entry;
57 using Column_settings =
typename Master_matrix::Column_settings;
60 using Field_operators =
typename Master_matrix::Field_operators;
61 using Column_support =
62 boost::intrusive::list<Entry,
63 boost::intrusive::constant_time_size<false>,
64 boost::intrusive::base_hook<typename Master_matrix::Base_hook_matrix_list_column> >;
65 using Entry_constructor =
typename Master_matrix::Entry_constructor;
68 using iterator =
typename Column_support::iterator;
69 using const_iterator =
typename Column_support::const_iterator;
70 using reverse_iterator =
typename Column_support::reverse_iterator;
71 using const_reverse_iterator =
typename Column_support::const_reverse_iterator;
74 template <
class Container =
typename Master_matrix::Boundary>
76 template <
class Container =
typename Master_matrix::Boundary,
class Row_container>
78 const Container& nonZeroRowIndices,
79 Row_container* rowContainer,
80 Column_settings* colSettings);
81 template <
class Container =
typename Master_matrix::Boundary>
82 Intrusive_list_column(
const Container& nonZeroChainRowIndices, Dimension dimension, Column_settings* colSettings);
83 template <
class Container =
typename Master_matrix::Boundary,
class Row_container>
85 const Container& nonZeroChainRowIndices,
87 Row_container* rowContainer,
88 Column_settings* colSettings);
90 template <
class Row_container>
93 Row_container* rowContainer,
94 Column_settings* colSettings =
nullptr);
98 std::vector<Field_element> get_content(
int columnLength = -1)
const;
99 bool is_non_zero(ID_index rowIndex)
const;
100 bool is_empty()
const;
101 std::size_t size()
const;
103 template <
class Row_index_map>
104 void reorder(
const Row_index_map& valueMap,
105 [[maybe_unused]] Index columnIndex = Master_matrix::template get_null_value<Index>());
107 void clear(ID_index rowIndex);
109 ID_index get_pivot()
const;
110 Field_element get_pivot_value()
const;
112 iterator begin()
noexcept;
113 const_iterator begin()
const noexcept;
114 iterator end()
noexcept;
115 const_iterator end()
const noexcept;
116 reverse_iterator rbegin()
noexcept;
117 const_reverse_iterator rbegin()
const noexcept;
118 reverse_iterator rend()
noexcept;
119 const_reverse_iterator rend()
const noexcept;
121 template <
class Entry_range>
128 template <
class Entry_range>
132 template <
class Entry_range>
136 void push_back(
const Entry& entry);
139 if (&c1 == &c2)
return true;
141 if constexpr (Master_matrix::Option_list::is_z2) {
142 return c1.column_ == c2.column_;
144 auto it1 = c1.column_.begin();
145 auto it2 = c2.column_.begin();
146 if (c1.column_.size() != c2.column_.size())
return false;
147 while (it1 != c1.column_.end() && it2 != c2.column_.end()) {
148 if (it1->get_row_index() != it2->get_row_index() || it1->get_element() != it2->get_element())
return false;
157 if (&c1 == &c2)
return false;
159 if constexpr (Master_matrix::Option_list::is_z2) {
160 return c1.column_ < c2.column_;
162 auto it1 = c1.column_.begin();
163 auto it2 = c2.column_.begin();
164 while (it1 != c1.column_.end() && it2 != c2.column_.end()) {
165 if (it1->get_row_index() != it2->get_row_index())
return it1->get_row_index() < it2->get_row_index();
166 if (it1->get_element() != it2->get_element())
return it1->get_element() < it2->get_element();
170 return it2 != c2.column_.end();
184 col1.column_.swap(col2.column_);
185 std::swap(col1.operators_, col2.operators_);
186 std::swap(col1.entryPool_, col2.entryPool_);
196 New_cloner(Entry_constructor* entryPool) : entryPool_(entryPool) {};
198 Entry* operator()(
const Entry& clone_this) {
return entryPool_->construct(clone_this); }
200 Entry_constructor* entryPool_;
204 struct Delete_disposer {
205 Delete_disposer() {};
208 void operator()(Entry* delete_this) {
209 if constexpr (Master_matrix::Option_list::has_row_access) col_->unlink(delete_this);
210 col_->entryPool_->destroy(delete_this);
216 Field_operators* operators_;
217 Entry_constructor* entryPool_;
218 Column_support column_;
220 template <
class Column,
class Entry_iterator,
typename F1,
typename F2,
typename F3,
typename F4>
221 friend void _generic_merge_entry_to_column(Column& targetColumn,
222 Entry_iterator& itSource,
223 typename Column::Column_support::iterator& itTarget,
228 bool& pivotIsZeroed);
229 template <
class Column,
class Entry_range,
typename F1,
typename F2,
typename F3,
typename F4,
typename F5>
230 friend bool _generic_add_to_column(
const Entry_range& source,
231 Column& targetColumn,
237 template <
class Column,
class Entry_range>
238 friend bool _add_to_column(
const Entry_range& source, Column& targetColumn);
239 template <
class Column,
class Entry_range>
240 friend bool _multiply_target_and_add_to_column(
const typename Column::Field_element& val,
241 const Entry_range& source,
242 Column& targetColumn);
243 template <
class Column,
class Entry_range>
244 friend bool _multiply_source_and_add_to_column(
const typename Column::Field_element& val,
245 const Entry_range& source,
246 Column& targetColumn);
248 void _delete_entry(iterator& it);
249 Entry* _insert_entry(
const Field_element& value, ID_index rowIndex,
const iterator& position);
250 void _insert_entry(ID_index rowIndex,
const iterator& position);
251 template <
class Entry_range>
252 bool _add(
const Entry_range& column);
253 template <
class Entry_range>
254 bool _multiply_target_and_add(
const Field_element& val,
const Entry_range& column);
255 template <
class Entry_range>
256 bool _multiply_source_and_add(
const Entry_range& column,
const Field_element& val);
259template <
class Master_matrix>
265 entryPool_(colSettings == nullptr ? nullptr : &(colSettings->entryConstructor)),
268 if (colSettings ==
nullptr)
return;
269 if constexpr (!Master_matrix::Option_list::is_z2) {
270 operators_ = &(colSettings->operators);
274template <
class Master_matrix>
275template <
class Container>
276inline Intrusive_list_column<Master_matrix>::Intrusive_list_column(
const Container& nonZeroRowIndices,
277 Column_settings* colSettings)
279 Dim_opt(nonZeroRowIndices.size() == 0 ? 0 : nonZeroRowIndices.size() - 1),
282 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_list_column<Master_matrix>::Intrusive_list_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)),
323 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
324 "Constructor not available for chain columns, please specify the dimension of the chain.");
326 if constexpr (Master_matrix::Option_list::is_z2) {
327 for (ID_index
id : nonZeroRowIndices) {
328 _insert_entry(
id, column_.end());
331 operators_ = &(colSettings->operators);
332 for (
const auto& p : nonZeroRowIndices) {
333 _insert_entry(operators_->get_value(p.second), p.first, column_.end());
338template <
class Master_matrix>
339template <
class Container>
340inline Intrusive_list_column<Master_matrix>::Intrusive_list_column(
const Container& nonZeroRowIndices,
342 Column_settings* colSettings)
346 if constexpr (Master_matrix::Option_list::is_z2) {
347 return nonZeroRowIndices.begin() == nonZeroRowIndices.end()
348 ? Master_matrix::template get_null_value<ID_index>()
349 : *
std::prev(nonZeroRowIndices.end());
351 return nonZeroRowIndices.begin() == nonZeroRowIndices.end()
352 ? Master_matrix::template get_null_value<ID_index>()
353 :
std::prev(nonZeroRowIndices.end())->first;
357 entryPool_(&(colSettings->entryConstructor)),
360 if constexpr (Master_matrix::Option_list::is_z2) {
361 for (ID_index
id : nonZeroRowIndices) {
362 _insert_entry(
id, column_.end());
365 operators_ = &(colSettings->operators);
366 for (
const auto& p : nonZeroRowIndices) {
367 _insert_entry(operators_->get_value(p.second), p.first, column_.end());
372template <
class Master_matrix>
373template <
class Container,
class Row_container>
374inline Intrusive_list_column<Master_matrix>::Intrusive_list_column(Index columnIndex,
375 const Container& nonZeroRowIndices,
377 Row_container* rowContainer,
378 Column_settings* colSettings)
379 : RA_opt(columnIndex, rowContainer),
382 if constexpr (Master_matrix::Option_list::is_z2) {
383 return nonZeroRowIndices.begin() == nonZeroRowIndices.end()
384 ? Master_matrix::template get_null_value<ID_index>()
385 : *
std::prev(nonZeroRowIndices.end());
387 return nonZeroRowIndices.begin() == nonZeroRowIndices.end()
388 ? Master_matrix::template get_null_value<ID_index>()
389 :
std::prev(nonZeroRowIndices.end())->first;
393 entryPool_(&(colSettings->entryConstructor)),
396 if constexpr (Master_matrix::Option_list::is_z2) {
397 for (ID_index
id : nonZeroRowIndices) {
398 _insert_entry(
id, column_.end());
401 operators_ = &(colSettings->operators);
402 for (
const auto& p : nonZeroRowIndices) {
403 _insert_entry(operators_->get_value(p.second), p.first, column_.end());
408template <
class Master_matrix>
409inline Intrusive_list_column<Master_matrix>::Intrusive_list_column(
const Intrusive_list_column& column,
410 Column_settings* colSettings)
412 Dim_opt(static_cast<const Dim_opt&>(column)),
413 Chain_opt(static_cast<const Chain_opt&>(column)),
414 operators_(colSettings == nullptr ? column.operators_ : nullptr),
415 entryPool_(colSettings == nullptr ? column.entryPool_ : &(colSettings->entryConstructor)),
418 static_assert(!Master_matrix::Option_list::has_row_access,
419 "Simple copy constructor not available when row access option enabled. Please specify the new column "
420 "index and the row container.");
421 if constexpr (!Master_matrix::Option_list::is_z2) {
422 if (colSettings !=
nullptr) operators_ = &(colSettings->operators);
425 column_.clone_from(column.column_, New_cloner(entryPool_), Delete_disposer(
this));
428template <
class Master_matrix>
429template <
class Row_container>
430inline Intrusive_list_column<Master_matrix>::Intrusive_list_column(
const Intrusive_list_column& column,
432 Row_container* rowContainer,
433 Column_settings* colSettings)
434 : RA_opt(columnIndex, rowContainer),
435 Dim_opt(static_cast<const Dim_opt&>(column)),
436 Chain_opt(static_cast<const Chain_opt&>(column)),
437 operators_(colSettings == nullptr ? column.operators_ : nullptr),
438 entryPool_(colSettings == nullptr ? column.entryPool_ : &(colSettings->entryConstructor)),
441 if constexpr (!Master_matrix::Option_list::is_z2) {
442 if (colSettings !=
nullptr) operators_ = &(colSettings->operators);
445 for (
const Entry& entry : column.column_) {
446 if constexpr (Master_matrix::Option_list::is_z2) {
447 _insert_entry(entry.get_row_index(), column_.end());
449 _insert_entry(entry.get_element(), entry.get_row_index(), column_.end());
454template <
class Master_matrix>
455inline Intrusive_list_column<Master_matrix>::Intrusive_list_column(Intrusive_list_column&& column) noexcept
456 : RA_opt(std::move(
static_cast<RA_opt&
>(column))),
457 Dim_opt(std::move(
static_cast<Dim_opt&
>(column))),
458 Chain_opt(std::move(
static_cast<Chain_opt&
>(column))),
459 operators_(std::exchange(column.operators_,
nullptr)),
460 entryPool_(std::exchange(column.entryPool_,
nullptr)),
461 column_(std::move(column.column_))
464template <
class Master_matrix>
465inline Intrusive_list_column<Master_matrix>::~Intrusive_list_column()
467 column_.clear_and_dispose(Delete_disposer(
this));
470template <
class Master_matrix>
471inline std::vector<typename Intrusive_list_column<Master_matrix>::Field_element>
472Intrusive_list_column<Master_matrix>::get_content(
int columnLength)
const
474 if (columnLength < 0 && column_.size() > 0)
475 columnLength = column_.back().get_row_index() + 1;
476 else if (columnLength < 0)
477 return std::vector<Field_element>();
479 std::vector<Field_element> container(columnLength);
480 for (
auto it = column_.begin(); it != column_.end() && it->get_row_index() <
static_cast<ID_index
>(columnLength);
482 if constexpr (Master_matrix::Option_list::is_z2) {
483 container[it->get_row_index()] = 1;
485 container[it->get_row_index()] = it->get_element();
491template <
class Master_matrix>
492inline bool Intrusive_list_column<Master_matrix>::is_non_zero(ID_index rowIndex)
const
497 for (
const Entry& entry : column_)
498 if (entry.get_row_index() == rowIndex)
return true;
503template <
class Master_matrix>
504inline bool Intrusive_list_column<Master_matrix>::is_empty()
const
506 return column_.empty();
509template <
class Master_matrix>
510inline std::size_t Intrusive_list_column<Master_matrix>::size()
const
512 return column_.size();
515template <
class Master_matrix>
516template <
class Row_index_map>
517inline void Intrusive_list_column<Master_matrix>::reorder(
const Row_index_map& valueMap,
518 [[maybe_unused]] Index columnIndex)
520 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
521 "Method not available for chain columns.");
523 for (
auto it = column_.begin(); it != column_.end(); ++it) {
524 Entry* entry = &(*it);
525 if constexpr (Master_matrix::Option_list::has_row_access) {
526 RA_opt::unlink(entry);
527 if (columnIndex != Master_matrix::template get_null_value<Index>()) entry->set_column_index(columnIndex);
529 entry->set_row_index(valueMap.at(entry->get_row_index()));
530 if constexpr (Master_matrix::Option_list::has_intrusive_rows && Master_matrix::Option_list::has_row_access)
531 RA_opt::insert_entry(entry->get_row_index(), entry);
535 if constexpr (!Master_matrix::Option_list::has_intrusive_rows && Master_matrix::Option_list::has_row_access) {
536 for (
auto it = column_.begin(); it != column_.end(); ++it) {
537 Entry* entry = &(*it);
538 RA_opt::insert_entry(entry->get_row_index(), entry);
545template <
class Master_matrix>
546inline void Intrusive_list_column<Master_matrix>::clear()
548 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
549 "Method not available for chain columns as a base element should not be empty.");
551 column_.clear_and_dispose(Delete_disposer(
this));
554template <
class Master_matrix>
555inline void Intrusive_list_column<Master_matrix>::clear(ID_index rowIndex)
557 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
558 "Method not available for chain columns.");
560 auto it = column_.begin();
561 while (it != column_.end() && it->get_row_index() != rowIndex) it++;
562 if (it != column_.end()) _delete_entry(it);
565template <
class Master_matrix>
566inline typename Intrusive_list_column<Master_matrix>::ID_index Intrusive_list_column<Master_matrix>::get_pivot()
const
568 static_assert(Master_matrix::isNonBasic,
569 "Method not available for base columns.");
571 if constexpr (Master_matrix::Option_list::is_of_boundary_type) {
572 if (column_.empty())
return Master_matrix::template get_null_value<ID_index>();
573 return column_.back().get_row_index();
575 return Chain_opt::get_pivot();
579template <
class Master_matrix>
580inline typename Intrusive_list_column<Master_matrix>::Field_element
581Intrusive_list_column<Master_matrix>::get_pivot_value()
const
583 static_assert(Master_matrix::isNonBasic,
584 "Method not available for base columns.");
586 if constexpr (Master_matrix::Option_list::is_z2) {
589 if constexpr (Master_matrix::Option_list::is_of_boundary_type) {
590 if (column_.empty())
return 0;
591 return column_.back().get_element();
593 if (Chain_opt::get_pivot() == Master_matrix::template get_null_value<ID_index>())
return Field_element();
594 for (
const Entry& entry : column_) {
595 if (entry.get_row_index() == Chain_opt::get_pivot())
return entry.get_element();
597 return Field_element();
602template <
class Master_matrix>
603inline typename Intrusive_list_column<Master_matrix>::iterator Intrusive_list_column<Master_matrix>::begin() noexcept
605 return column_.begin();
608template <
class Master_matrix>
609inline typename Intrusive_list_column<Master_matrix>::const_iterator Intrusive_list_column<Master_matrix>::begin()
612 return column_.begin();
615template <
class Master_matrix>
616inline typename Intrusive_list_column<Master_matrix>::iterator Intrusive_list_column<Master_matrix>::end() noexcept
618 return column_.end();
621template <
class Master_matrix>
622inline typename Intrusive_list_column<Master_matrix>::const_iterator Intrusive_list_column<Master_matrix>::end()
625 return column_.end();
628template <
class Master_matrix>
629inline typename Intrusive_list_column<Master_matrix>::reverse_iterator
630Intrusive_list_column<Master_matrix>::rbegin() noexcept
632 return column_.rbegin();
635template <
class Master_matrix>
636inline typename Intrusive_list_column<Master_matrix>::const_reverse_iterator
637Intrusive_list_column<Master_matrix>::rbegin() const noexcept
639 return column_.rbegin();
642template <
class Master_matrix>
643inline typename Intrusive_list_column<Master_matrix>::reverse_iterator
644Intrusive_list_column<Master_matrix>::rend() noexcept
646 return column_.rend();
649template <
class Master_matrix>
650inline typename Intrusive_list_column<Master_matrix>::const_reverse_iterator
651Intrusive_list_column<Master_matrix>::rend() const noexcept
653 return column_.rend();
656template <
class Master_matrix>
657template <
class Entry_range>
658inline Intrusive_list_column<Master_matrix>& Intrusive_list_column<Master_matrix>::operator+=(
const Entry_range& column)
660 static_assert((!Master_matrix::isNonBasic || std::is_same_v<Entry_range, Intrusive_list_column>),
661 "For boundary columns, the range has to be a column of same type to help ensure the validity of the "
663 static_assert((!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type),
664 "For chain columns, the given column cannot be constant.");
671template <
class Master_matrix>
672inline Intrusive_list_column<Master_matrix>& Intrusive_list_column<Master_matrix>::operator+=(
673 Intrusive_list_column& column)
675 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
678 Chain_opt::swap_pivots(column);
679 Dim_opt::swap_dimension(column);
688template <
class Master_matrix>
689inline Intrusive_list_column<Master_matrix>& Intrusive_list_column<Master_matrix>::operator*=(
const Field_element& val)
691 if constexpr (Master_matrix::Option_list::is_z2) {
693 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
694 throw std::invalid_argument(
"A chain column should not be multiplied by 0.");
700 Field_element realVal = operators_->get_value(val);
702 if (realVal == Field_operators::get_additive_identity()) {
703 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
704 throw std::invalid_argument(
"A chain column should not be multiplied by 0.");
711 if (realVal == Field_operators::get_multiplicative_identity())
return *
this;
713 for (Entry& entry : column_) {
714 operators_->multiply_inplace(entry.get_element(), realVal);
715 if constexpr (Master_matrix::Option_list::has_row_access) RA_opt::update_entry(entry);
722template <
class Master_matrix>
723template <
class Entry_range>
724inline Intrusive_list_column<Master_matrix>& Intrusive_list_column<Master_matrix>::multiply_target_and_add(
725 const Field_element& val,
726 const Entry_range& column)
728 static_assert((!Master_matrix::isNonBasic || std::is_same_v<Entry_range, Intrusive_list_column>),
729 "For boundary columns, the range has to be a column of same type to help ensure the validity of the "
731 static_assert((!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type),
732 "For chain columns, the given column cannot be constant.");
734 if constexpr (Master_matrix::Option_list::is_z2) {
742 _multiply_target_and_add(val, column);
748template <
class Master_matrix>
749inline Intrusive_list_column<Master_matrix>& Intrusive_list_column<Master_matrix>::multiply_target_and_add(
750 const Field_element& val,
751 Intrusive_list_column& column)
753 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
755 if constexpr (Master_matrix::Option_list::is_z2) {
758 Chain_opt::swap_pivots(column);
759 Dim_opt::swap_dimension(column);
762 throw std::invalid_argument(
"A chain column should not be multiplied by 0.");
765 if (_multiply_target_and_add(val, column)) {
766 Chain_opt::swap_pivots(column);
767 Dim_opt::swap_dimension(column);
771 if constexpr (Master_matrix::Option_list::is_z2) {
779 _multiply_target_and_add(val, column);
786template <
class Master_matrix>
787template <
class Entry_range>
788inline Intrusive_list_column<Master_matrix>& Intrusive_list_column<Master_matrix>::multiply_source_and_add(
789 const Entry_range& column,
790 const Field_element& val)
792 static_assert((!Master_matrix::isNonBasic || std::is_same_v<Entry_range, Intrusive_list_column>),
793 "For boundary columns, the range has to be a column of same type to help ensure the validity of the "
795 static_assert((!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type),
796 "For chain columns, the given column cannot be constant.");
798 if constexpr (Master_matrix::Option_list::is_z2) {
803 _multiply_source_and_add(column, val);
809template <
class Master_matrix>
810inline Intrusive_list_column<Master_matrix>& Intrusive_list_column<Master_matrix>::multiply_source_and_add(
811 Intrusive_list_column& column,
812 const Field_element& val)
814 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
816 if constexpr (Master_matrix::Option_list::is_z2) {
819 Chain_opt::swap_pivots(column);
820 Dim_opt::swap_dimension(column);
824 if (_multiply_source_and_add(column, val)) {
825 Chain_opt::swap_pivots(column);
826 Dim_opt::swap_dimension(column);
830 if constexpr (Master_matrix::Option_list::is_z2) {
835 _multiply_source_and_add(column, val);
842template <
class Master_matrix>
843inline void Intrusive_list_column<Master_matrix>::push_back(
const Entry& entry)
845 static_assert(Master_matrix::Option_list::is_of_boundary_type,
"`push_back` is not available for Chain matrices.");
847 GUDHI_CHECK(entry.get_row_index() > get_pivot(),
"The new row index has to be higher than the current pivot.");
849 if constexpr (Master_matrix::Option_list::is_z2) {
850 _insert_entry(entry.get_row_index(), column_.end());
852 _insert_entry(entry.get_element(), entry.get_row_index(), column_.end());
856template <
class Master_matrix>
857inline Intrusive_list_column<Master_matrix>& Intrusive_list_column<Master_matrix>::operator=(
858 const Intrusive_list_column& other)
860 static_assert(!Master_matrix::Option_list::has_row_access,
"= assignment not enabled with row access option.");
862 Dim_opt::operator=(other);
863 Chain_opt::operator=(other);
866 column_.clear_and_dispose(Delete_disposer(
this));
867 operators_ = other.operators_;
868 entryPool_ = other.entryPool_;
869 column_.clone_from(other.column_, New_cloner(entryPool_), Delete_disposer(
this));
874template <
class Master_matrix>
875inline void Intrusive_list_column<Master_matrix>::_delete_entry(iterator& it)
877 it = column_.erase_and_dispose(it, Delete_disposer(
this));
880template <
class Master_matrix>
881inline typename Intrusive_list_column<Master_matrix>::Entry* Intrusive_list_column<Master_matrix>::_insert_entry(
882 const Field_element& value,
884 const iterator& position)
886 if constexpr (Master_matrix::Option_list::has_row_access) {
887 Entry* newEntry = entryPool_->construct(RA_opt::columnIndex_, rowIndex);
888 newEntry->set_element(value);
889 column_.insert(position, *newEntry);
890 RA_opt::insert_entry(rowIndex, newEntry);
893 Entry* newEntry = entryPool_->construct(rowIndex);
894 newEntry->set_element(value);
895 column_.insert(position, *newEntry);
900template <
class Master_matrix>
901inline void Intrusive_list_column<Master_matrix>::_insert_entry(ID_index rowIndex,
const iterator& position)
903 if constexpr (Master_matrix::Option_list::has_row_access) {
904 Entry* newEntry = entryPool_->construct(RA_opt::columnIndex_, rowIndex);
905 column_.insert(position, *newEntry);
906 RA_opt::insert_entry(rowIndex, newEntry);
908 Entry* newEntry = entryPool_->construct(rowIndex);
909 column_.insert(position, *newEntry);
913template <
class Master_matrix>
914template <
class Entry_range>
915inline bool Intrusive_list_column<Master_matrix>::_add(
const Entry_range& column)
917 return _add_to_column(column, *
this);
920template <
class Master_matrix>
921template <
class Entry_range>
922inline bool Intrusive_list_column<Master_matrix>::_multiply_target_and_add(
const Field_element& val,
923 const Entry_range& column)
925 return _multiply_target_and_add_to_column(val, column, *
this);
928template <
class Master_matrix>
929template <
class Entry_range>
930inline bool Intrusive_list_column<Master_matrix>::_multiply_source_and_add(
const Entry_range& column,
931 const Field_element& val)
933 return _multiply_source_and_add_to_column(val, column, *
this);
947template <
class Master_matrix>
948struct std::hash<
Gudhi::persistence_matrix::Intrusive_list_column<Master_matrix> > {
950 return Gudhi::persistence_matrix::hash_column(column);
Column class following the PersistenceMatrixColumn concept.
Definition: intrusive_list_column.h:49
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