18#ifndef PM_LIST_COLUMN_H
19#define PM_LIST_COLUMN_H
27#include <boost/iterator/indirect_iterator.hpp>
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 = std::list<Entry*>;
63 using Entry_constructor =
typename Master_matrix::Entry_constructor;
66 using iterator = boost::indirect_iterator<typename Column_support::iterator>;
67 using const_iterator = boost::indirect_iterator<typename Column_support::const_iterator>;
68 using reverse_iterator = boost::indirect_iterator<typename Column_support::reverse_iterator>;
69 using const_reverse_iterator = boost::indirect_iterator<typename Column_support::const_reverse_iterator>;
71 List_column(Column_settings* colSettings =
nullptr);
72 template <
class Container =
typename Master_matrix::Boundary>
73 List_column(
const Container& nonZeroRowIndices, Column_settings* colSettings);
74 template <
class Container =
typename Master_matrix::Boundary,
class Row_container>
76 const Container& nonZeroRowIndices,
77 Row_container* rowContainer,
78 Column_settings* colSettings);
79 template <
class Container =
typename Master_matrix::Boundary>
80 List_column(
const Container& nonZeroChainRowIndices, Dimension dimension, Column_settings* colSettings);
81 template <
class Container =
typename Master_matrix::Boundary,
class Row_container>
83 const Container& nonZeroChainRowIndices,
85 Row_container* rowContainer,
86 Column_settings* colSettings);
88 template <
class Row_container>
91 Row_container* rowContainer,
92 Column_settings* colSettings =
nullptr);
96 std::vector<Field_element> get_content(
int columnLength = -1)
const;
97 bool is_non_zero(ID_index rowIndex)
const;
98 bool is_empty()
const;
99 std::size_t size()
const;
101 template <
class Row_index_map>
102 void reorder(
const Row_index_map& valueMap,
103 [[maybe_unused]] Index columnIndex = Master_matrix::template get_null_value<Index>());
105 void clear(ID_index rowIndex);
107 ID_index get_pivot()
const;
108 Field_element get_pivot_value()
const;
110 iterator begin()
noexcept;
111 const_iterator begin()
const noexcept;
112 iterator end()
noexcept;
113 const_iterator end()
const noexcept;
114 reverse_iterator rbegin()
noexcept;
115 const_reverse_iterator rbegin()
const noexcept;
116 reverse_iterator rend()
noexcept;
117 const_reverse_iterator rend()
const noexcept;
119 template <
class Entry_range>
120 List_column& operator+=(
const Entry_range& column);
126 template <
class Entry_range>
127 List_column& multiply_target_and_add(
const Field_element& val,
const Entry_range& column);
130 template <
class Entry_range>
131 List_column& multiply_source_and_add(
const Entry_range& column,
const Field_element& val);
134 void push_back(
const Entry& entry);
137 if (&c1 == &c2)
return true;
139 auto it1 = c1.column_.begin();
140 auto it2 = c2.column_.begin();
141 if (c1.column_.size() != c2.column_.size())
return false;
142 while (it1 != c1.column_.end() && it2 != c2.column_.end()) {
143 if constexpr (Master_matrix::Option_list::is_z2) {
144 if ((*it1)->get_row_index() != (*it2)->get_row_index())
return false;
146 if ((*it1)->get_row_index() != (*it2)->get_row_index() || (*it1)->get_element() != (*it2)->get_element())
156 if (&c1 == &c2)
return false;
158 auto it1 = c1.column_.begin();
159 auto it2 = c2.column_.begin();
160 while (it1 != c1.column_.end() && it2 != c2.column_.end()) {
161 if ((*it1)->get_row_index() != (*it2)->get_row_index())
return (*it1)->get_row_index() < (*it2)->get_row_index();
162 if constexpr (!Master_matrix::Option_list::is_z2) {
163 if ((*it1)->get_element() != (*it2)->get_element())
return (*it1)->get_element() < (*it2)->get_element();
168 return it2 != c2.column_.end();
181 col1.column_.swap(col2.column_);
182 std::swap(col1.operators_, col2.operators_);
183 std::swap(col1.entryPool_, col2.entryPool_);
191 Column_support column_;
192 Field_operators* operators_;
193 Entry_constructor* entryPool_;
195 template <
class Column,
class Entry_iterator,
typename F1,
typename F2,
typename F3,
typename F4>
196 friend void _generic_merge_entry_to_column(Column& targetColumn,
197 Entry_iterator& itSource,
198 typename Column::Column_support::iterator& itTarget,
203 bool& pivotIsZeroed);
204 template <
class Column,
class Entry_range,
typename F1,
typename F2,
typename F3,
typename F4,
typename F5>
205 friend bool _generic_add_to_column(
const Entry_range& source,
206 Column& targetColumn,
212 template <
class Column,
class Entry_range>
213 friend bool _add_to_column(
const Entry_range& source, Column& targetColumn);
214 template <
class Column,
class Entry_range>
215 friend bool _multiply_target_and_add_to_column(
const typename Column::Field_element& val,
216 const Entry_range& source,
217 Column& targetColumn);
218 template <
class Column,
class Entry_range>
219 friend bool _multiply_source_and_add_to_column(
const typename Column::Field_element& val,
220 const Entry_range& source,
221 Column& targetColumn);
223 void _delete_entry(
typename Column_support::iterator& it);
224 Entry* _insert_entry(
const Field_element& value,
226 const typename Column_support::iterator& position);
227 void _insert_entry(ID_index rowIndex,
const typename Column_support::iterator& position);
228 void _update_entry(
const Field_element& value, ID_index rowIndex,
const typename Column_support::iterator& position);
229 void _update_entry(ID_index rowIndex,
const typename Column_support::iterator& position);
230 template <
class Entry_range>
231 bool _add(
const Entry_range& column);
232 template <
class Entry_range>
233 bool _multiply_target_and_add(
const Field_element& val,
const Entry_range& column);
234 template <
class Entry_range>
235 bool _multiply_source_and_add(
const Entry_range& column,
const Field_element& val);
238template <
class Master_matrix>
244 entryPool_(colSettings == nullptr ? nullptr : &(colSettings->entryConstructor))
246 if (operators_ ==
nullptr && entryPool_ ==
nullptr)
248 if constexpr (!Master_matrix::Option_list::is_z2) {
249 operators_ = &(colSettings->operators);
253template <
class Master_matrix>
254template <
class Container>
255inline List_column<Master_matrix>::List_column(
const Container& nonZeroRowIndices, Column_settings* colSettings)
257 Dim_opt(nonZeroRowIndices.size() == 0 ? 0 : nonZeroRowIndices.size() - 1),
259 column_(nonZeroRowIndices.size()),
261 entryPool_(&(colSettings->entryConstructor))
263 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
264 "Constructor not available for chain columns, please specify the dimension of the chain.");
266 auto it = column_.begin();
267 if constexpr (Master_matrix::Option_list::is_z2) {
268 for (ID_index
id : nonZeroRowIndices) {
269 _update_entry(
id, it++);
272 operators_ = &(colSettings->operators);
273 for (
const auto& p : nonZeroRowIndices) {
274 _update_entry(operators_->get_value(p.second), p.first, it++);
279template <
class Master_matrix>
280template <
class Container,
class Row_container>
281inline List_column<Master_matrix>::List_column(Index columnIndex,
282 const Container& nonZeroRowIndices,
283 Row_container* rowContainer,
284 Column_settings* colSettings)
285 : RA_opt(columnIndex, rowContainer),
286 Dim_opt(nonZeroRowIndices.size() == 0 ? 0 : nonZeroRowIndices.size() - 1),
288 if constexpr (Master_matrix::Option_list::is_z2) {
289 return nonZeroRowIndices.begin() == nonZeroRowIndices.end()
290 ? Master_matrix::template get_null_value<ID_index>()
291 : *
std::prev(nonZeroRowIndices.end());
293 return nonZeroRowIndices.begin() == nonZeroRowIndices.end()
294 ? Master_matrix::template get_null_value<ID_index>()
295 :
std::prev(nonZeroRowIndices.end())->first;
298 column_(nonZeroRowIndices.size()),
300 entryPool_(&(colSettings->entryConstructor))
302 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
303 "Constructor not available for chain columns, please specify the dimension of the chain.");
305 auto it = column_.begin();
306 if constexpr (Master_matrix::Option_list::is_z2) {
307 for (ID_index
id : nonZeroRowIndices) {
308 _update_entry(
id, it++);
311 operators_ = &(colSettings->operators);
312 for (
const auto& p : nonZeroRowIndices) {
313 _update_entry(operators_->get_value(p.second), p.first, it++);
318template <
class Master_matrix>
319template <
class Container>
320inline List_column<Master_matrix>::List_column(
const Container& nonZeroRowIndices,
322 Column_settings* colSettings)
326 if constexpr (Master_matrix::Option_list::is_z2) {
327 return nonZeroRowIndices.begin() == nonZeroRowIndices.end()
328 ? Master_matrix::template get_null_value<ID_index>()
329 : *
std::prev(nonZeroRowIndices.end());
331 return nonZeroRowIndices.begin() == nonZeroRowIndices.end()
332 ? Master_matrix::template get_null_value<ID_index>()
333 :
std::prev(nonZeroRowIndices.end())->first;
336 column_(nonZeroRowIndices.size()),
338 entryPool_(&(colSettings->entryConstructor))
340 auto it = column_.begin();
341 if constexpr (Master_matrix::Option_list::is_z2) {
342 for (ID_index
id : nonZeroRowIndices) {
343 _update_entry(
id, it++);
346 operators_ = &(colSettings->operators);
347 for (
const auto& p : nonZeroRowIndices) {
348 _update_entry(operators_->get_value(p.second), p.first, it++);
353template <
class Master_matrix>
354template <
class Container,
class Row_container>
355inline List_column<Master_matrix>::List_column(Index columnIndex,
356 const Container& nonZeroRowIndices,
358 Row_container* rowContainer,
359 Column_settings* colSettings)
360 : RA_opt(columnIndex, rowContainer),
363 if constexpr (Master_matrix::Option_list::is_z2) {
364 return nonZeroRowIndices.begin() == nonZeroRowIndices.end()
365 ? Master_matrix::template get_null_value<ID_index>()
366 : *
std::prev(nonZeroRowIndices.end());
368 return nonZeroRowIndices.begin() == nonZeroRowIndices.end()
369 ? Master_matrix::template get_null_value<ID_index>()
370 :
std::prev(nonZeroRowIndices.end())->first;
373 column_(nonZeroRowIndices.size()),
375 entryPool_(&(colSettings->entryConstructor))
377 auto it = column_.begin();
378 if constexpr (Master_matrix::Option_list::is_z2) {
379 for (ID_index
id : nonZeroRowIndices) {
380 _update_entry(
id, it++);
383 operators_ = &(colSettings->operators);
384 for (
const auto& p : nonZeroRowIndices) {
385 _update_entry(operators_->get_value(p.second), p.first, it++);
390template <
class Master_matrix>
391inline List_column<Master_matrix>::List_column(
const List_column& column, Column_settings* colSettings)
393 Dim_opt(static_cast<const Dim_opt&>(column)),
394 Chain_opt(static_cast<const Chain_opt&>(column)),
395 column_(column.column_.size()),
396 operators_(colSettings == nullptr ? column.operators_ : nullptr),
397 entryPool_(colSettings == nullptr ? column.entryPool_ : &(colSettings->entryConstructor))
399 static_assert(!Master_matrix::Option_list::has_row_access,
400 "Simple copy constructor not available when row access option enabled. Please specify the new column "
401 "index and the row container.");
403 if constexpr (!Master_matrix::Option_list::is_z2) {
404 if (colSettings !=
nullptr) operators_ = &(colSettings->operators);
407 auto it = column_.begin();
408 for (
const Entry* entry : column.column_) {
409 if constexpr (Master_matrix::Option_list::is_z2) {
410 _update_entry(entry->get_row_index(), it++);
412 _update_entry(entry->get_element(), entry->get_row_index(), it++);
417template <
class Master_matrix>
418template <
class Row_container>
419inline List_column<Master_matrix>::List_column(
const List_column& column,
421 Row_container* rowContainer,
422 Column_settings* colSettings)
423 : RA_opt(columnIndex, rowContainer),
424 Dim_opt(static_cast<const Dim_opt&>(column)),
425 Chain_opt(static_cast<const Chain_opt&>(column)),
426 column_(column.column_.size()),
427 operators_(colSettings == nullptr ? column.operators_ : nullptr),
428 entryPool_(colSettings == nullptr ? column.entryPool_ : &(colSettings->entryConstructor))
430 if constexpr (!Master_matrix::Option_list::is_z2) {
431 if (colSettings !=
nullptr) operators_ = &(colSettings->operators);
434 auto it = column_.begin();
435 for (
const Entry* entry : column.column_) {
436 if constexpr (Master_matrix::Option_list::is_z2) {
437 _update_entry(entry->get_row_index(), it++);
439 _update_entry(entry->get_element(), entry->get_row_index(), it++);
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 if constexpr (Master_matrix::Option_list::is_z2) {
476 container[(*it)->get_row_index()] = 1;
478 container[(*it)->get_row_index()] = (*it)->get_element();
484template <
class Master_matrix>
485inline bool List_column<Master_matrix>::is_non_zero(ID_index rowIndex)
const
490 for (
const Entry* entry : column_)
491 if (entry->get_row_index() == rowIndex)
return true;
496template <
class Master_matrix>
497inline bool List_column<Master_matrix>::is_empty()
const
499 return column_.empty();
502template <
class Master_matrix>
503inline std::size_t List_column<Master_matrix>::size()
const
505 return column_.size();
508template <
class Master_matrix>
509template <
class Row_index_map>
510inline void List_column<Master_matrix>::reorder(
const Row_index_map& valueMap, [[maybe_unused]] Index columnIndex)
512 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
513 "Method not available for chain columns.");
515 for (
auto it = column_.begin(); it != column_.end(); ++it) {
517 if constexpr (Master_matrix::Option_list::has_row_access) {
518 RA_opt::unlink(entry);
519 if (columnIndex != Master_matrix::template get_null_value<Index>()) entry->set_column_index(columnIndex);
521 entry->set_row_index(valueMap.at(entry->get_row_index()));
522 if constexpr (Master_matrix::Option_list::has_intrusive_rows && Master_matrix::Option_list::has_row_access)
523 RA_opt::insert_entry(entry->get_row_index(), entry);
527 if constexpr (!Master_matrix::Option_list::has_intrusive_rows && Master_matrix::Option_list::has_row_access) {
528 for (
auto it = column_.begin(); it != column_.end(); ++it) {
530 RA_opt::insert_entry(entry->get_row_index(), entry);
534 column_.sort([](
const Entry* c1,
const Entry* c2) {
return *c1 < *c2; });
537template <
class Master_matrix>
538inline void List_column<Master_matrix>::clear()
540 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
541 "Method not available for chain columns as a base element should not be empty.");
543 for (
auto* entry : column_) {
544 if constexpr (Master_matrix::Option_list::has_row_access) RA_opt::unlink(entry);
545 entryPool_->destroy(entry);
551template <
class Master_matrix>
552inline void List_column<Master_matrix>::clear(ID_index rowIndex)
554 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
555 "Method not available for chain columns.");
557 auto it = column_.begin();
558 while (it != column_.end() && (*it)->get_row_index() != rowIndex) it++;
559 if (it != column_.end()) _delete_entry(it);
562template <
class Master_matrix>
563inline typename List_column<Master_matrix>::ID_index List_column<Master_matrix>::get_pivot()
const
565 static_assert(Master_matrix::isNonBasic,
566 "Method not available for base columns.");
568 if constexpr (Master_matrix::Option_list::is_of_boundary_type) {
569 if (column_.empty())
return Master_matrix::template get_null_value<ID_index>();
570 return column_.back()->get_row_index();
572 return Chain_opt::get_pivot();
576template <
class Master_matrix>
577inline typename List_column<Master_matrix>::Field_element List_column<Master_matrix>::get_pivot_value()
const
579 static_assert(Master_matrix::isNonBasic,
580 "Method not available for base columns.");
582 if constexpr (Master_matrix::Option_list::is_z2) {
585 if constexpr (Master_matrix::Option_list::is_of_boundary_type) {
586 if (column_.empty())
return 0;
587 return column_.back()->get_element();
589 if (Chain_opt::get_pivot() == Master_matrix::template get_null_value<ID_index>())
return Field_element();
590 for (
const Entry* entry : column_) {
591 if (entry->get_row_index() == Chain_opt::get_pivot())
return entry->get_element();
593 return Field_element();
598template <
class Master_matrix>
599inline typename List_column<Master_matrix>::iterator List_column<Master_matrix>::begin() noexcept
601 return column_.begin();
604template <
class Master_matrix>
605inline typename List_column<Master_matrix>::const_iterator List_column<Master_matrix>::begin() const noexcept
607 return column_.begin();
610template <
class Master_matrix>
611inline typename List_column<Master_matrix>::iterator List_column<Master_matrix>::end() noexcept
613 return column_.end();
616template <
class Master_matrix>
617inline typename List_column<Master_matrix>::const_iterator List_column<Master_matrix>::end() const noexcept
619 return column_.end();
622template <
class Master_matrix>
623inline typename List_column<Master_matrix>::reverse_iterator List_column<Master_matrix>::rbegin() noexcept
625 return column_.rbegin();
628template <
class Master_matrix>
629inline typename List_column<Master_matrix>::const_reverse_iterator List_column<Master_matrix>::rbegin() const noexcept
631 return column_.rbegin();
634template <
class Master_matrix>
635inline typename List_column<Master_matrix>::reverse_iterator List_column<Master_matrix>::rend() noexcept
637 return column_.rend();
640template <
class Master_matrix>
641inline typename List_column<Master_matrix>::const_reverse_iterator List_column<Master_matrix>::rend() const noexcept
643 return column_.rend();
646template <
class Master_matrix>
647template <
class Entry_range>
648inline List_column<Master_matrix>& List_column<Master_matrix>::operator+=(
const Entry_range& column)
650 static_assert((!Master_matrix::isNonBasic || std::is_same_v<Entry_range, List_column>),
651 "For boundary columns, the range has to be a column of same type to help ensure the validity of the "
653 static_assert((!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type),
654 "For chain columns, the given column cannot be constant.");
661template <
class Master_matrix>
662inline List_column<Master_matrix>& List_column<Master_matrix>::operator+=(List_column& column)
664 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
667 Chain_opt::swap_pivots(column);
668 Dim_opt::swap_dimension(column);
677template <
class Master_matrix>
678inline List_column<Master_matrix>& List_column<Master_matrix>::operator*=(
unsigned int v)
680 if constexpr (Master_matrix::Option_list::is_z2) {
682 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
683 throw std::invalid_argument(
"A chain column should not be multiplied by 0.");
689 Field_element val = operators_->get_value(v);
692 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
693 throw std::invalid_argument(
"A chain column should not be multiplied by 0.");
700 if (val == 1u)
return *
this;
702 for (Entry* entry : column_) {
703 operators_->multiply_inplace(entry->get_element(), val);
704 if constexpr (Master_matrix::Option_list::has_row_access) RA_opt::update_entry(*entry);
711template <
class Master_matrix>
712template <
class Entry_range>
713inline List_column<Master_matrix>& List_column<Master_matrix>::multiply_target_and_add(
const Field_element& val,
714 const Entry_range& column)
716 static_assert((!Master_matrix::isNonBasic || std::is_same_v<Entry_range, List_column>),
717 "For boundary columns, the range has to be a column of same type to help ensure the validity of the "
719 static_assert((!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type),
720 "For chain columns, the given column cannot be constant.");
722 if constexpr (Master_matrix::Option_list::is_z2) {
730 _multiply_target_and_add(val, column);
736template <
class Master_matrix>
737inline List_column<Master_matrix>& List_column<Master_matrix>::multiply_target_and_add(
const Field_element& val,
740 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
742 if constexpr (Master_matrix::Option_list::is_z2) {
745 Chain_opt::swap_pivots(column);
746 Dim_opt::swap_dimension(column);
749 throw std::invalid_argument(
"A chain column should not be multiplied by 0.");
752 if (_multiply_target_and_add(val, column)) {
753 Chain_opt::swap_pivots(column);
754 Dim_opt::swap_dimension(column);
758 if constexpr (Master_matrix::Option_list::is_z2) {
766 _multiply_target_and_add(val, column);
773template <
class Master_matrix>
774template <
class Entry_range>
775inline List_column<Master_matrix>& List_column<Master_matrix>::multiply_source_and_add(
const Entry_range& column,
776 const Field_element& val)
778 static_assert((!Master_matrix::isNonBasic || std::is_same_v<Entry_range, List_column>),
779 "For boundary columns, the range has to be a column of same type to help ensure the validity of the "
781 static_assert((!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type),
782 "For chain columns, the given column cannot be constant.");
784 if constexpr (Master_matrix::Option_list::is_z2) {
789 _multiply_source_and_add(column, val);
795template <
class Master_matrix>
796inline List_column<Master_matrix>& List_column<Master_matrix>::multiply_source_and_add(List_column& column,
797 const Field_element& val)
799 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
801 if constexpr (Master_matrix::Option_list::is_z2) {
804 Chain_opt::swap_pivots(column);
805 Dim_opt::swap_dimension(column);
809 if (_multiply_source_and_add(column, val)) {
810 Chain_opt::swap_pivots(column);
811 Dim_opt::swap_dimension(column);
815 if constexpr (Master_matrix::Option_list::is_z2) {
820 _multiply_source_and_add(column, val);
827template <
class Master_matrix>
828inline void List_column<Master_matrix>::push_back(
const Entry& entry)
830 static_assert(Master_matrix::Option_list::is_of_boundary_type,
"`push_back` is not available for Chain matrices.");
832 GUDHI_CHECK(entry.get_row_index() > get_pivot(),
"The new row index has to be higher than the current pivot.");
834 if constexpr (Master_matrix::Option_list::is_z2) {
835 _insert_entry(entry.get_row_index(), column_.end());
837 _insert_entry(entry.get_element(), entry.get_row_index(), column_.end());
841template <
class Master_matrix>
842inline List_column<Master_matrix>& List_column<Master_matrix>::operator=(
const List_column& other)
844 static_assert(!Master_matrix::Option_list::has_row_access,
"= assignment not enabled with row access option.");
846 Dim_opt::operator=(other);
847 Chain_opt::operator=(other);
849 auto tmpPool = entryPool_;
850 entryPool_ = other.entryPool_;
852 while (column_.size() > other.column_.size()) {
853 if (column_.back() !=
nullptr) {
854 if constexpr (Master_matrix::Option_list::has_row_access) RA_opt::unlink(column_.back());
855 tmpPool->destroy(column_.back());
860 column_.resize(other.column_.size(),
nullptr);
861 auto it = column_.begin();
862 for (
const Entry* entry : other.column_) {
863 if (*it !=
nullptr) {
864 if constexpr (Master_matrix::Option_list::has_row_access) RA_opt::unlink(*it);
865 tmpPool->destroy(*it);
867 if constexpr (Master_matrix::Option_list::is_z2) {
868 _update_entry(entry->get_row_index(), it++);
870 _update_entry(entry->get_element(), entry->get_row_index(), it++);
874 operators_ = other.operators_;
879template <
class Master_matrix>
880inline void List_column<Master_matrix>::_delete_entry(
typename Column_support::iterator& it)
882 if constexpr (Master_matrix::Option_list::has_row_access) RA_opt::unlink(*it);
883 entryPool_->destroy(*it);
884 it = column_.erase(it);
887template <
class Master_matrix>
888inline typename List_column<Master_matrix>::Entry* List_column<Master_matrix>::_insert_entry(
889 const Field_element& value,
891 const typename Column_support::iterator& position)
893 if constexpr (Master_matrix::Option_list::has_row_access) {
894 Entry* newEntry = entryPool_->construct(RA_opt::columnIndex_, rowIndex);
895 newEntry->set_element(value);
896 column_.insert(position, newEntry);
897 RA_opt::insert_entry(rowIndex, newEntry);
900 Entry* newEntry = entryPool_->construct(rowIndex);
901 newEntry->set_element(value);
902 column_.insert(position, newEntry);
907template <
class Master_matrix>
908inline void List_column<Master_matrix>::_insert_entry(ID_index rowIndex,
909 const typename Column_support::iterator& position)
911 if constexpr (Master_matrix::Option_list::has_row_access) {
912 Entry* newEntry = entryPool_->construct(RA_opt::columnIndex_, rowIndex);
913 column_.insert(position, newEntry);
914 RA_opt::insert_entry(rowIndex, newEntry);
916 Entry* newEntry = entryPool_->construct(rowIndex);
917 column_.insert(position, newEntry);
921template <
class Master_matrix>
922inline void List_column<Master_matrix>::_update_entry(
const Field_element& value,
924 const typename Column_support::iterator& position)
926 if constexpr (Master_matrix::Option_list::has_row_access) {
927 *position = entryPool_->construct(RA_opt::columnIndex_, rowIndex);
928 (*position)->set_element(value);
929 RA_opt::insert_entry(rowIndex, *position);
931 *position = entryPool_->construct(rowIndex);
932 (*position)->set_element(value);
936template <
class Master_matrix>
937inline void List_column<Master_matrix>::_update_entry(ID_index rowIndex,
938 const typename Column_support::iterator& position)
940 if constexpr (Master_matrix::Option_list::has_row_access) {
941 *position = entryPool_->construct(RA_opt::columnIndex_, rowIndex);
942 RA_opt::insert_entry(rowIndex, *position);
944 *position = entryPool_->construct(rowIndex);
948template <
class Master_matrix>
949template <
class Entry_range>
950inline bool List_column<Master_matrix>::_add(
const Entry_range& column)
952 if (column.begin() == column.end())
return false;
953 if (column_.empty()) {
954 column_.resize(column.size());
955 auto it = column_.begin();
956 for (
const Entry& entry : column) {
957 if constexpr (Master_matrix::Option_list::is_z2) {
958 _update_entry(entry.get_row_index(), it++);
960 _update_entry(entry.get_element(), entry.get_row_index(), it++);
966 return _add_to_column(column, *
this);
969template <
class Master_matrix>
970template <
class Entry_range>
971inline bool List_column<Master_matrix>::_multiply_target_and_add(
const Field_element& val,
const Entry_range& column)
973 return _multiply_target_and_add_to_column(val, column, *
this);
976template <
class Master_matrix>
977template <
class Entry_range>
978inline bool List_column<Master_matrix>::_multiply_source_and_add(
const Entry_range& column,
const Field_element& val)
980 return _multiply_source_and_add_to_column(val, column, *
this);
994template <
class Master_matrix>
995struct std::hash<
Gudhi::persistence_matrix::List_column<Master_matrix> > {
997 return Gudhi::persistence_matrix::hash_column(column);
Column class following the PersistenceMatrixColumn concept.
Definition: list_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