18#ifndef PM_LIST_COLUMN_H
19#define PM_LIST_COLUMN_H
27#include <boost/range/iterator_range_core.hpp>
28#include <boost/iterator/indirect_iterator.hpp>
47template <
class Master_matrix>
48class List_column :
public Master_matrix::Row_access_option,
49 public Master_matrix::Column_dimension_option,
50 public Master_matrix::Chain_column_option
53 using Master = Master_matrix;
54 using Index =
typename Master_matrix::Index;
55 using ID_index =
typename Master_matrix::ID_index;
56 using Dimension =
typename Master_matrix::Dimension;
57 using Field_element =
typename Master_matrix::Element;
58 using Entry =
typename Master_matrix::Matrix_entry;
59 using Column_settings =
typename Master_matrix::Column_settings;
62 using Field_operators =
typename Master_matrix::Field_operators;
63 using Column_support = std::list<Entry*>;
64 using Entry_constructor =
typename Master_matrix::Entry_constructor;
67 using iterator = boost::indirect_iterator<typename Column_support::iterator>;
68 using const_iterator = boost::indirect_iterator<typename Column_support::const_iterator>;
69 using reverse_iterator = boost::indirect_iterator<typename Column_support::reverse_iterator>;
70 using const_reverse_iterator = boost::indirect_iterator<typename Column_support::const_reverse_iterator>;
71 using Content_range = boost::iterator_range<const_iterator>;
73 List_column(Column_settings* colSettings =
nullptr);
74 template <
class Container =
typename Master_matrix::Boundary>
75 List_column(
const Container& nonZeroRowIndices, Column_settings* colSettings);
76 template <
class Container =
typename Master_matrix::Boundary,
class Row_container>
77 List_column(Index columnIndex,
78 const Container& nonZeroRowIndices,
79 Row_container* rowContainer,
80 Column_settings* colSettings);
81 template <
class Container =
typename Master_matrix::Boundary,
82 class = std::enable_if_t<!std::is_arithmetic_v<Container> > >
83 List_column(
const Container& nonZeroRowIndices, Dimension dimension, Column_settings* colSettings);
84 template <
class Container =
typename Master_matrix::Boundary,
86 class = std::enable_if_t<!std::is_arithmetic_v<Container> > >
87 List_column(Index columnIndex,
88 const Container& nonZeroRowIndices,
90 Row_container* rowContainer,
91 Column_settings* colSettings);
92 List_column(ID_index idx, Dimension dimension, Column_settings* colSettings);
93 List_column(ID_index idx, Field_element e, Dimension dimension, Column_settings* colSettings);
94 template <
class Row_container>
95 List_column(Index columnIndex,
98 Row_container* rowContainer,
99 Column_settings* colSettings);
100 template <
class Row_container>
101 List_column(Index columnIndex,
105 Row_container* rowContainer,
106 Column_settings* colSettings);
107 List_column(
const List_column& column, Column_settings* colSettings =
nullptr);
108 template <
class Row_container>
109 List_column(
const List_column& column,
111 Row_container* rowContainer,
112 Column_settings* colSettings =
nullptr);
113 List_column(List_column&& column)
noexcept;
116 std::vector<Field_element> get_content(
int columnLength = -1)
const;
117 bool is_non_zero(ID_index rowIndex)
const;
118 [[nodiscard]]
bool is_empty()
const;
119 [[nodiscard]] std::size_t size()
const;
121 template <
class Row_index_map>
122 void reorder(
const Row_index_map& valueMap,
123 [[maybe_unused]] Index columnIndex = Master_matrix::template get_null_value<Index>());
125 void clear(ID_index rowIndex);
127 ID_index get_pivot()
const;
128 Field_element get_pivot_value()
const;
130 iterator begin()
noexcept;
131 const_iterator begin()
const noexcept;
132 iterator end()
noexcept;
133 const_iterator end()
const noexcept;
134 reverse_iterator rbegin()
noexcept;
135 const_reverse_iterator rbegin()
const noexcept;
136 reverse_iterator rend()
noexcept;
137 const_reverse_iterator rend()
const noexcept;
139 Content_range get_non_zero_content_range()
const;
141 template <
class Entry_range>
142 List_column& operator+=(
const Entry_range& column);
143 List_column& operator+=(List_column& column);
145 List_column& operator*=(
const Field_element& v);
148 template <
class Entry_range>
149 List_column& multiply_target_and_add(
const Field_element& val,
const Entry_range& column);
150 List_column& multiply_target_and_add(
const Field_element& val, List_column& column);
152 template <
class Entry_range>
153 List_column& multiply_source_and_add(
const Entry_range& column,
const Field_element& val);
154 List_column& multiply_source_and_add(List_column& column,
const Field_element& val);
156 void push_back(
const Entry& entry);
158 friend bool operator==(
const List_column& c1,
const List_column& c2)
160 if (&c1 == &c2)
return true;
161 if (c1.column_.size() != c2.column_.size())
return false;
163 return std::equal(c1.column_.begin(),
167 [](
const Entry* e1,
const Entry* e2) {
168 return e1->get_row_index() == e2->get_row_index() && e1->get_element() == e2->get_element();
172 friend bool operator<(
const List_column& c1,
const List_column& c2)
174 if (&c1 == &c2)
return false;
176 return std::lexicographical_compare(c1.column_.begin(),
180 [](
const Entry* e1,
const Entry* e2) {
181 if (e1->get_row_index() != e2->get_row_index())
182 return e1->get_row_index() < e2->get_row_index();
183 if (e1->get_element() != e2->get_element())
184 return e1->get_element() < e2->get_element();
190 List_column& operator=(
const List_column& other);
191 List_column& operator=(List_column&& other)
noexcept;
193 friend void swap(List_column& col1, List_column& col2)
noexcept
195 swap(
static_cast<typename Master_matrix::Row_access_option&
>(col1),
196 static_cast<typename Master_matrix::Row_access_option&
>(col2));
197 swap(
static_cast<typename Master_matrix::Column_dimension_option&
>(col1),
198 static_cast<typename Master_matrix::Column_dimension_option&
>(col2));
199 swap(
static_cast<typename Master_matrix::Chain_column_option&
>(col1),
200 static_cast<typename Master_matrix::Chain_column_option&
>(col2));
201 col1.column_.swap(col2.column_);
202 std::swap(col1.operators_, col2.operators_);
203 std::swap(col1.entryPool_, col2.entryPool_);
207 using RA_opt =
typename Master_matrix::Row_access_option;
208 using Dim_opt =
typename Master_matrix::Column_dimension_option;
209 using Chain_opt =
typename Master_matrix::Chain_column_option;
211 Column_support column_;
212 Field_operators
const* operators_;
213 Entry_constructor* entryPool_;
215 template <
class Column,
class Entry_iterator,
typename F1,
typename F2,
typename F3,
typename F4>
216 friend void _generic_merge_entry_to_column(Column& targetColumn,
217 Entry_iterator& itSource,
218 typename Column::Column_support::iterator& itTarget,
223 bool& pivotIsZeroed);
224 template <
class Column,
class Entry_range,
typename F1,
typename F2,
typename F3,
typename F4,
typename F5>
225 friend bool _generic_add_to_column(
const Entry_range& source,
226 Column& targetColumn,
232 template <
class Column,
class Entry_range>
233 friend bool _add_to_column(
const Entry_range& source, Column& targetColumn);
234 template <
class Column,
class Entry_range>
235 friend bool _multiply_target_and_add_to_column(
const typename Column::Field_element& val,
236 const Entry_range& source,
237 Column& targetColumn);
238 template <
class Column,
class Entry_range>
239 friend bool _multiply_source_and_add_to_column(
const typename Column::Field_element& val,
240 const Entry_range& source,
241 Column& targetColumn);
243 void _delete_entry(
typename Column_support::iterator& it);
244 Entry* _insert_entry(
const typename Column_support::iterator& position,
246 const Field_element& value);
247 void _update_entry(
const typename Column_support::iterator& position, ID_index rowIndex,
const Field_element& value);
248 template <
class Entry_range>
249 bool _add(
const Entry_range& column);
250 template <
class Entry_range>
251 bool _multiply_target_and_add(
const Field_element& val,
const Entry_range& column);
252 template <
class Entry_range>
253 bool _multiply_source_and_add(
const Entry_range& column,
const Field_element& val);
256template <
class Master_matrix>
257inline List_column<Master_matrix>::List_column(Column_settings* colSettings)
261 operators_(Master_matrix::get_operator_ptr(colSettings)),
262 entryPool_(colSettings == nullptr ? nullptr : &(colSettings->entryConstructor))
265template <
class Master_matrix>
266template <
class Container>
267inline List_column<Master_matrix>::List_column(
const Container& nonZeroRowIndices, Column_settings* colSettings)
268 : List_column(nonZeroRowIndices, nonZeroRowIndices.size() == 0 ? 0 : nonZeroRowIndices.size() - 1, colSettings)
270 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
271 "Constructor not available for chain columns, please specify the dimension of the chain.");
274template <
class Master_matrix>
275template <
class Container,
class Row_container>
276inline List_column<Master_matrix>::List_column(Index columnIndex,
277 const Container& nonZeroRowIndices,
278 Row_container* rowContainer,
279 Column_settings* colSettings)
280 : List_column(columnIndex,
282 nonZeroRowIndices.size() == 0 ? 0 : nonZeroRowIndices.size() - 1,
286 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
287 "Constructor not available for chain columns, please specify the dimension of the chain.");
290template <
class Master_matrix>
291template <
class Container,
class>
292inline List_column<Master_matrix>::List_column(
const Container& nonZeroRowIndices,
294 Column_settings* colSettings)
297 Chain_opt(nonZeroRowIndices.begin() == nonZeroRowIndices.end()
298 ? Master_matrix::template get_null_value<ID_index>()
299 : Master_matrix::get_row_index(*std::prev(nonZeroRowIndices.end()))),
300 column_(nonZeroRowIndices.size()),
301 operators_(Master_matrix::get_operator_ptr(colSettings)),
302 entryPool_(&(colSettings->entryConstructor))
304 auto it = column_.begin();
305 for (
const auto&
id : nonZeroRowIndices) {
307 Master_matrix::get_row_index(
id),
308 Master_matrix::get_coefficient_value(Master_matrix::get_element(
id), operators_));
312template <
class Master_matrix>
313template <
class Container,
class Row_container,
class>
314inline List_column<Master_matrix>::List_column(Index columnIndex,
315 const Container& nonZeroRowIndices,
317 Row_container* rowContainer,
318 Column_settings* colSettings)
319 : RA_opt(columnIndex, rowContainer),
321 Chain_opt(nonZeroRowIndices.begin() == nonZeroRowIndices.end()
322 ? Master_matrix::template get_null_value<ID_index>()
323 : Master_matrix::get_row_index(*std::prev(nonZeroRowIndices.end()))),
324 column_(nonZeroRowIndices.size()),
325 operators_(Master_matrix::get_operator_ptr(colSettings)),
326 entryPool_(&(colSettings->entryConstructor))
328 auto it = column_.begin();
329 for (
const auto&
id : nonZeroRowIndices) {
331 Master_matrix::get_row_index(
id),
332 Master_matrix::get_coefficient_value(Master_matrix::get_element(
id), operators_));
336template <
class Master_matrix>
337inline List_column<Master_matrix>::List_column(ID_index idx, Dimension dimension, Column_settings* colSettings)
343 entryPool_(&(colSettings->entryConstructor))
345 static_assert(Master_matrix::Option_list::is_z2,
346 "Constructor not available for Zp != Z2. Please specify the coefficient.");
347 _update_entry(column_.begin(), idx, 1);
350template <
class Master_matrix>
351inline List_column<Master_matrix>::List_column(ID_index idx,
354 Column_settings* colSettings)
359 operators_(&(colSettings->operators)),
360 entryPool_(&(colSettings->entryConstructor))
362 static_assert(!Master_matrix::Option_list::is_z2,
363 "Constructor not available for Zp == Z2. Please do not specify any coefficient.");
364 _update_entry(column_.begin(), idx, operators_->get_value(e));
367template <
class Master_matrix>
368template <
class Row_container>
369inline List_column<Master_matrix>::List_column(Index columnIndex,
372 Row_container* rowContainer,
373 Column_settings* colSettings)
374 : RA_opt(columnIndex, rowContainer),
379 entryPool_(&(colSettings->entryConstructor))
381 static_assert(Master_matrix::Option_list::is_z2,
382 "Constructor not available for Zp != Z2. Please specify the coefficient.");
383 _update_entry(column_.begin(), idx, 1);
386template <
class Master_matrix>
387template <
class Row_container>
388inline List_column<Master_matrix>::List_column(Index columnIndex,
392 Row_container* rowContainer,
393 Column_settings* colSettings)
394 : RA_opt(columnIndex, rowContainer),
398 operators_(&(colSettings->operators)),
399 entryPool_(&(colSettings->entryConstructor))
401 static_assert(!Master_matrix::Option_list::is_z2,
402 "Constructor not available for Zp == Z2. Please do not specify any coefficient.");
403 _update_entry(column_.begin(), idx, operators_->get_value(e));
406template <
class Master_matrix>
407inline List_column<Master_matrix>::List_column(
const List_column& column, Column_settings* colSettings)
409 Dim_opt(static_cast<const Dim_opt&>(column)),
410 Chain_opt(static_cast<const Chain_opt&>(column)),
411 column_(column.column_.size()),
412 operators_(colSettings == nullptr ? column.operators_ : Master_matrix::get_operator_ptr(colSettings)),
413 entryPool_(colSettings == nullptr ? column.entryPool_ : &(colSettings->entryConstructor))
415 static_assert(!Master_matrix::Option_list::has_row_access,
416 "Simple copy constructor not available when row access option enabled. Please specify the new column "
417 "index and the row container.");
419 auto it = column_.begin();
420 for (
const Entry* entry : column.column_) {
421 _update_entry(it++, entry->get_row_index(), entry->get_element());
425template <
class Master_matrix>
426template <
class Row_container>
427inline List_column<Master_matrix>::List_column(
const List_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 column_(column.column_.size()),
435 operators_(colSettings == nullptr ? column.operators_ : Master_matrix::get_operator_ptr(colSettings)),
436 entryPool_(colSettings == nullptr ? column.entryPool_ : &(colSettings->entryConstructor))
438 auto it = column_.begin();
439 for (
const Entry* entry : column.column_) {
440 _update_entry(it++, entry->get_row_index(), entry->get_element());
444template <
class Master_matrix>
445inline List_column<Master_matrix>::List_column(
List_column&& column) noexcept
446 : RA_opt(std::move(
static_cast<RA_opt&
>(column))),
447 Dim_opt(std::move(
static_cast<Dim_opt&
>(column))),
448 Chain_opt(std::move(
static_cast<Chain_opt&
>(column))),
449 column_(std::move(column.column_)),
450 operators_(std::exchange(column.operators_,
nullptr)),
451 entryPool_(std::exchange(column.entryPool_,
nullptr))
454template <
class Master_matrix>
455inline List_column<Master_matrix>::~List_column()
457 for (
auto* entry : column_) {
458 if constexpr (Master_matrix::Option_list::has_row_access) RA_opt::unlink(entry);
459 entryPool_->destroy(entry);
463template <
class Master_matrix>
464inline std::vector<typename List_column<Master_matrix>::Field_element> List_column<Master_matrix>::get_content(
465 int columnLength)
const
467 if (columnLength < 0 && column_.size() > 0)
468 columnLength = column_.back()->get_row_index() + 1;
469 else if (columnLength < 0)
470 return std::vector<Field_element>();
472 std::vector<Field_element> container(columnLength, 0);
473 for (
auto it = column_.begin(); it != column_.end() && (*it)->get_row_index() <
static_cast<ID_index
>(columnLength);
475 container[(*it)->get_row_index()] = Master_matrix::get_element(**it);
480template <
class Master_matrix>
481inline bool List_column<Master_matrix>::is_non_zero(ID_index rowIndex)
const
486 for (
const Entry* entry : column_)
487 if (entry->get_row_index() == rowIndex)
return true;
492template <
class Master_matrix>
493inline bool List_column<Master_matrix>::is_empty()
const
495 return column_.empty();
498template <
class Master_matrix>
499inline std::size_t List_column<Master_matrix>::size()
const
501 return column_.size();
504template <
class Master_matrix>
505template <
class Row_index_map>
506inline void List_column<Master_matrix>::reorder(
const Row_index_map& valueMap, [[maybe_unused]] Index columnIndex)
508 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
509 "Method not available for chain columns.");
511 for (
auto it = column_.begin(); it != column_.end(); ++it) {
513 if constexpr (Master_matrix::Option_list::has_row_access) {
514 RA_opt::unlink(entry);
515 if (columnIndex != Master_matrix::template get_null_value<Index>()) entry->set_column_index(columnIndex);
518 if constexpr (Master_matrix::Option_list::has_intrusive_rows && Master_matrix::Option_list::has_row_access)
519 RA_opt::insert_entry(entry->get_row_index(), entry);
523 if constexpr (!Master_matrix::Option_list::has_intrusive_rows && Master_matrix::Option_list::has_row_access) {
524 for (
auto it = column_.begin(); it != column_.end(); ++it) {
526 RA_opt::insert_entry(entry->get_row_index(), entry);
530 column_.sort([](
const Entry* c1,
const Entry* c2) {
return *c1 < *c2; });
533template <
class Master_matrix>
534inline void List_column<Master_matrix>::clear()
536 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
537 "Method not available for chain columns as a base element should not be empty.");
539 for (
auto* entry : column_) {
540 if constexpr (Master_matrix::Option_list::has_row_access) RA_opt::unlink(entry);
541 entryPool_->destroy(entry);
547template <
class Master_matrix>
548inline void List_column<Master_matrix>::clear(ID_index rowIndex)
550 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
551 "Method not available for chain columns.");
553 auto it = column_.begin();
554 while (it != column_.end() && (*it)->get_row_index() != rowIndex) it++;
555 if (it != column_.end()) _delete_entry(it);
558template <
class Master_matrix>
559inline typename List_column<Master_matrix>::ID_index List_column<Master_matrix>::get_pivot()
const
561 static_assert(Master_matrix::isNonBasic,
562 "Method not available for base columns.");
564 if constexpr (Master_matrix::Option_list::is_of_boundary_type) {
565 if (column_.empty())
return Master_matrix::template get_null_value<ID_index>();
566 return column_.back()->get_row_index();
568 return Chain_opt::_get_pivot();
572template <
class Master_matrix>
573inline typename List_column<Master_matrix>::Field_element List_column<Master_matrix>::get_pivot_value()
const
575 static_assert(Master_matrix::isNonBasic,
576 "Method not available for base columns.");
578 if constexpr (Master_matrix::Option_list::is_z2) {
581 if constexpr (Master_matrix::Option_list::is_of_boundary_type) {
582 if (column_.empty())
return 0;
583 return column_.back()->get_element();
585 if (Chain_opt::_get_pivot() == Master_matrix::template get_null_value<ID_index>())
return Field_element();
586 for (
const Entry* entry : column_) {
587 if (entry->get_row_index() == Chain_opt::_get_pivot())
return entry->get_element();
589 return Field_element();
594template <
class Master_matrix>
595inline typename List_column<Master_matrix>::iterator List_column<Master_matrix>::begin() noexcept
597 return column_.begin();
600template <
class Master_matrix>
601inline typename List_column<Master_matrix>::const_iterator List_column<Master_matrix>::begin() const noexcept
603 return column_.begin();
606template <
class Master_matrix>
607inline typename List_column<Master_matrix>::iterator List_column<Master_matrix>::end() noexcept
609 return column_.end();
612template <
class Master_matrix>
613inline typename List_column<Master_matrix>::const_iterator List_column<Master_matrix>::end() const noexcept
615 return column_.end();
618template <
class Master_matrix>
619inline typename List_column<Master_matrix>::reverse_iterator List_column<Master_matrix>::rbegin() noexcept
621 return column_.rbegin();
624template <
class Master_matrix>
625inline typename List_column<Master_matrix>::const_reverse_iterator List_column<Master_matrix>::rbegin() const noexcept
627 return column_.rbegin();
630template <
class Master_matrix>
631inline typename List_column<Master_matrix>::reverse_iterator List_column<Master_matrix>::rend() noexcept
633 return column_.rend();
636template <
class Master_matrix>
637inline typename List_column<Master_matrix>::const_reverse_iterator List_column<Master_matrix>::rend() const noexcept
639 return column_.rend();
642template <
class Master_matrix>
643inline typename List_column<Master_matrix>::Content_range List_column<Master_matrix>::get_non_zero_content_range()
const
645 return Content_range(column_.begin(), column_.end());
648template <
class Master_matrix>
649template <
class Entry_range>
652 static_assert((!Master_matrix::isNonBasic || std::is_same_v<Entry_range, List_column>),
653 "For boundary columns, the range has to be a column of same type to help ensure the validity of the "
655 static_assert((!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type),
656 "For chain columns, the given column cannot be constant.");
663template <
class Master_matrix>
666 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
669 Chain_opt::_swap_pivots(column);
670 Dim_opt::_swap_dimension(column);
679template <
class Master_matrix>
682 Field_element val = Master_matrix::get_coefficient_value(v, operators_);
684 if (val == Field_operators::get_additive_identity()) {
685 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
686 throw std::invalid_argument(
"A chain column should not be multiplied by 0.");
693 if (val == Field_operators::get_multiplicative_identity())
return *
this;
697 if constexpr (!Master_matrix::Option_list::is_z2) {
698 for (
Entry* entry : column_) {
699 operators_->multiply_inplace(entry->get_element(), val);
700 if constexpr (Master_matrix::Option_list::has_row_access) RA_opt::update_entry(*entry);
707template <
class Master_matrix>
708template <
class Entry_range>
710 const Entry_range& column)
712 static_assert((!Master_matrix::isNonBasic || std::is_same_v<Entry_range, List_column>),
713 "For boundary columns, the range has to be a column of same type to help ensure the validity of the "
715 static_assert((!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type),
716 "For chain columns, the given column cannot be constant.");
718 _multiply_target_and_add(Master_matrix::get_coefficient_value(val, operators_), column);
723template <
class Master_matrix>
727 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
729 if (_multiply_target_and_add(Master_matrix::get_coefficient_value(val, operators_), column)) {
730 Chain_opt::_swap_pivots(column);
731 Dim_opt::_swap_dimension(column);
734 _multiply_target_and_add(Master_matrix::get_coefficient_value(val, operators_), column);
740template <
class Master_matrix>
741template <
class Entry_range>
743 const Field_element& val)
745 static_assert((!Master_matrix::isNonBasic || std::is_same_v<Entry_range, List_column>),
746 "For boundary columns, the range has to be a column of same type to help ensure the validity of the "
748 static_assert((!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type),
749 "For chain columns, the given column cannot be constant.");
751 _multiply_source_and_add(column, Master_matrix::get_coefficient_value(val, operators_));
756template <
class Master_matrix>
758 const Field_element& val)
760 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
762 if (_multiply_source_and_add(column, Master_matrix::get_coefficient_value(val, operators_))) {
763 Chain_opt::_swap_pivots(column);
764 Dim_opt::_swap_dimension(column);
767 _multiply_source_and_add(column, Master_matrix::get_coefficient_value(val, operators_));
773template <
class Master_matrix>
774inline void List_column<Master_matrix>::push_back(
const Entry& entry)
776 static_assert(Master_matrix::Option_list::is_of_boundary_type,
"`push_back` is not available for Chain matrices.");
778 GUDHI_CHECK(entry.get_row_index() > get_pivot(),
779 std::invalid_argument(
"The new row index has to be higher than the current pivot."));
781 _insert_entry(column_.end(), entry.get_row_index(), entry.get_element());
784template <
class Master_matrix>
787 static_assert(!Master_matrix::Option_list::has_row_access,
"= assignment not enabled with row access option.");
790 if (
this == &other)
return *
this;
792 Dim_opt::operator=(other);
793 Chain_opt::operator=(other);
795 auto tmpPool = entryPool_;
796 entryPool_ = other.entryPool_;
798 while (column_.size() > other.column_.size()) {
799 if (column_.back() !=
nullptr) {
800 tmpPool->destroy(column_.back());
805 column_.resize(other.column_.size(),
nullptr);
806 auto it = column_.begin();
807 for (
const Entry* entry : other.column_) {
808 if (*it !=
nullptr) {
809 tmpPool->destroy(*it);
811 _update_entry(it++, entry->get_row_index(), entry->get_element());
814 operators_ = other.operators_;
819template <
class Master_matrix>
822 static_assert(!Master_matrix::Option_list::has_row_access,
"= assignment not enabled with row access option.");
825 if (&column_ == &(other.column_))
return *
this;
827 Dim_opt::operator=(std::move(other));
828 Chain_opt::operator=(std::move(other));
830 for (
auto* entry : column_) {
831 if (entry !=
nullptr) entryPool_->destroy(entry);
834 column_ = std::move(other.column_);
835 operators_ = std::exchange(other.operators_,
nullptr);
836 entryPool_ = std::exchange(other.entryPool_,
nullptr);
841template <
class Master_matrix>
842inline void List_column<Master_matrix>::_delete_entry(
typename Column_support::iterator& it)
844 if constexpr (Master_matrix::Option_list::has_row_access) RA_opt::unlink(*it);
845 entryPool_->destroy(*it);
846 it = column_.erase(it);
849template <
class Master_matrix>
850inline typename List_column<Master_matrix>::Entry* List_column<Master_matrix>::_insert_entry(
851 const typename Column_support::iterator& position,
853 const Field_element& value)
856 if constexpr (Master_matrix::Option_list::has_row_access) {
857 newEntry = entryPool_->construct(RA_opt::get_column_index(), rowIndex);
859 newEntry = entryPool_->construct(rowIndex);
861 newEntry->set_element(value);
862 column_.insert(position, newEntry);
863 if constexpr (Master_matrix::Option_list::has_row_access) RA_opt::insert_entry(rowIndex, newEntry);
867template <
class Master_matrix>
868inline void List_column<Master_matrix>::_update_entry(
const typename Column_support::iterator& position,
870 const Field_element& value)
872 if constexpr (Master_matrix::Option_list::has_row_access) {
873 *position = entryPool_->construct(RA_opt::get_column_index(), rowIndex);
875 *position = entryPool_->construct(rowIndex);
877 (*position)->set_element(value);
878 if constexpr (Master_matrix::Option_list::has_row_access) RA_opt::insert_entry(rowIndex, *position);
881template <
class Master_matrix>
882template <
class Entry_range>
883inline bool List_column<Master_matrix>::_add(
const Entry_range& column)
885 if (column.begin() == column.end())
return false;
886 if (column_.empty()) {
887 column_.resize(column.size());
888 auto it = column_.begin();
889 for (
const Entry& entry : column) {
890 _update_entry(it++, entry.get_row_index(), entry.get_element());
895 return _add_to_column(column, *
this);
898template <
class Master_matrix>
899template <
class Entry_range>
900inline bool List_column<Master_matrix>::_multiply_target_and_add(
const Field_element& val,
const Entry_range& column)
902 return _multiply_target_and_add_to_column(val, column, *
this);
905template <
class Master_matrix>
906template <
class Entry_range>
907inline bool List_column<Master_matrix>::_multiply_source_and_add(
const Entry_range& column,
const Field_element& val)
909 return _multiply_source_and_add_to_column(val, column, *
this);
923template <
class Master_matrix>
924struct std::hash<
Gudhi::persistence_matrix::List_column<Master_matrix> > {
927 return Gudhi::persistence_matrix::hash_column(column);
Matrix entry class. Stores by default only the row index it belongs to, but can also store its column...
Definition entry_types.h:163
void set_row_index(ID_index rowIndex)
Sets the row index stored in the entry.
Definition entry_types.h:224
Column class following the PersistenceMatrixColumn concept.
Definition list_column.h:51
Contains helper methods for column addition and column hasher.
Contains different versions of Gudhi::persistence_matrix::Entry factories.
Persistence matrix namespace.
Definition FieldOperators.h:18
Gudhi namespace.
Definition SimplicialComplexForAlpha.h:14