18#ifndef PM_SET_COLUMN_H
19#define PM_SET_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;
63 struct EntryPointerComp {
64 bool operator()(
const Entry* c1,
const Entry* c2)
const {
return *c1 < *c2; }
67 using Column_support = std::set<Entry*, EntryPointerComp>;
68 using Entry_constructor =
typename Master_matrix::Entry_constructor;
71 using iterator = boost::indirect_iterator<typename Column_support::iterator>;
72 using const_iterator = boost::indirect_iterator<typename Column_support::const_iterator>;
73 using reverse_iterator = boost::indirect_iterator<typename Column_support::reverse_iterator>;
74 using const_reverse_iterator = boost::indirect_iterator<typename Column_support::const_reverse_iterator>;
76 Set_column(Column_settings* colSettings =
nullptr);
77 template <
class Container =
typename Master_matrix::Boundary>
78 Set_column(
const Container& nonZeroRowIndices, Column_settings* colSettings);
79 template <
class Container =
typename Master_matrix::Boundary,
class Row_container>
81 const Container& nonZeroRowIndices,
82 Row_container* rowContainer,
83 Column_settings* colSettings);
84 template <
class Container =
typename Master_matrix::Boundary>
85 Set_column(
const Container& nonZeroChainRowIndices, Dimension dimension, Column_settings* colSettings);
86 template <
class Container =
typename Master_matrix::Boundary,
class Row_container>
88 const Container& nonZeroChainRowIndices,
90 Row_container* rowContainer,
91 Column_settings* colSettings);
93 template <
class Row_container>
96 Row_container* rowContainer,
97 Column_settings* colSettings =
nullptr);
101 std::vector<Field_element> get_content(
int columnLength = -1)
const;
102 bool is_non_zero(ID_index rowIndex)
const;
103 bool is_empty()
const;
104 std::size_t size()
const;
106 template <
class Row_index_map>
107 void reorder(
const Row_index_map& valueMap,
108 [[maybe_unused]] Index columnIndex = Master_matrix::template get_null_value<Index>());
110 void clear(ID_index rowIndex);
112 ID_index get_pivot()
const;
113 Field_element get_pivot_value()
const;
115 iterator begin()
noexcept;
116 const_iterator begin()
const noexcept;
117 iterator end()
noexcept;
118 const_iterator end()
const noexcept;
119 reverse_iterator rbegin()
noexcept;
120 const_reverse_iterator rbegin()
const noexcept;
121 reverse_iterator rend()
noexcept;
122 const_reverse_iterator rend()
const noexcept;
124 template <
class Entry_range>
125 Set_column& operator+=(
const Entry_range& column);
131 template <
class Entry_range>
132 Set_column& multiply_target_and_add(
const Field_element& val,
const Entry_range& column);
135 template <
class Entry_range>
136 Set_column& multiply_source_and_add(
const Entry_range& column,
const Field_element& val);
139 void push_back(
const Entry& entry);
142 if (&c1 == &c2)
return true;
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 constexpr (Master_matrix::Option_list::is_z2) {
149 if ((*it1)->get_row_index() != (*it2)->get_row_index())
return false;
151 if ((*it1)->get_row_index() != (*it2)->get_row_index() || (*it1)->get_element() != (*it2)->get_element())
161 if (&c1 == &c2)
return false;
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 constexpr (!Master_matrix::Option_list::is_z2) {
168 if ((*it1)->get_element() != (*it2)->get_element())
return (*it1)->get_element() < (*it2)->get_element();
173 return it2 != c2.column_.end();
186 col1.column_.swap(col2.column_);
187 std::swap(col1.operators_, col2.operators_);
188 std::swap(col1.entryPool_, col2.entryPool_);
196 Column_support column_;
197 Field_operators* operators_;
198 Entry_constructor* entryPool_;
200 template <
class Column,
class Entry_iterator,
typename F1,
typename F2,
typename F3,
typename F4>
201 friend void _generic_merge_entry_to_column(Column& targetColumn,
202 Entry_iterator& itSource,
203 typename Column::Column_support::iterator& itTarget,
208 bool& pivotIsZeroed);
209 template <
class Column,
class Entry_range,
typename F1,
typename F2,
typename F3,
typename F4,
typename F5>
210 friend bool _generic_add_to_column(
const Entry_range& source,
211 Column& targetColumn,
217 template <
class Column,
class Entry_range>
218 friend bool _add_to_column(
const Entry_range& source, Column& targetColumn);
219 template <
class Column,
class Entry_range>
220 friend bool _multiply_target_and_add_to_column(
const typename Column::Field_element& val,
221 const Entry_range& source,
222 Column& targetColumn);
223 template <
class Column,
class Entry_range>
224 friend bool _multiply_source_and_add_to_column(
const typename Column::Field_element& val,
225 const Entry_range& source,
226 Column& targetColumn);
228 void _delete_entry(
typename Column_support::iterator& it);
229 Entry* _insert_entry(
const Field_element& value,
231 const typename Column_support::iterator& position);
232 void _insert_entry(ID_index rowIndex,
const typename Column_support::iterator& position);
233 template <
class Entry_range>
234 bool _add(
const Entry_range& column);
235 template <
class Entry_range>
236 bool _multiply_target_and_add(
const Field_element& val,
const Entry_range& column);
237 template <
class Entry_range>
238 bool _multiply_source_and_add(
const Entry_range& column,
const Field_element& val);
241template <
class Master_matrix>
247 entryPool_(colSettings == nullptr ? nullptr : &(colSettings->entryConstructor))
249 if (operators_ ==
nullptr && entryPool_ ==
nullptr)
251 if constexpr (!Master_matrix::Option_list::is_z2) {
252 operators_ = &(colSettings->operators);
256template <
class Master_matrix>
257template <
class Container>
258inline Set_column<Master_matrix>::Set_column(
const Container& nonZeroRowIndices, Column_settings* colSettings)
260 Dim_opt(nonZeroRowIndices.size() == 0 ? 0 : nonZeroRowIndices.size() - 1),
263 entryPool_(&(colSettings->entryConstructor))
265 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
266 "Constructor not available for chain columns, please specify the dimension of the chain.");
268 if constexpr (Master_matrix::Option_list::is_z2) {
269 for (ID_index
id : nonZeroRowIndices) {
270 _insert_entry(
id, column_.end());
273 operators_ = &(colSettings->operators);
274 for (
const auto& p : nonZeroRowIndices) {
275 _insert_entry(operators_->get_value(p.second), p.first, column_.end());
280template <
class Master_matrix>
281template <
class Container,
class Row_container>
282inline Set_column<Master_matrix>::Set_column(Index columnIndex,
283 const Container& nonZeroRowIndices,
284 Row_container* rowContainer,
285 Column_settings* colSettings)
286 : RA_opt(columnIndex, rowContainer),
287 Dim_opt(nonZeroRowIndices.size() == 0 ? 0 : nonZeroRowIndices.size() - 1),
289 if constexpr (Master_matrix::Option_list::is_z2) {
290 return nonZeroRowIndices.begin() == nonZeroRowIndices.end()
291 ? Master_matrix::template get_null_value<ID_index>()
292 : *
std::prev(nonZeroRowIndices.end());
294 return nonZeroRowIndices.begin() == nonZeroRowIndices.end()
295 ? Master_matrix::template get_null_value<ID_index>()
296 :
std::prev(nonZeroRowIndices.end())->first;
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 if constexpr (Master_matrix::Option_list::is_z2) {
306 for (ID_index
id : nonZeroRowIndices) {
307 _insert_entry(
id, column_.end());
310 operators_ = &(colSettings->operators);
311 for (
const auto& p : nonZeroRowIndices) {
312 _insert_entry(operators_->get_value(p.second), p.first, column_.end());
317template <
class Master_matrix>
318template <
class Container>
319inline Set_column<Master_matrix>::Set_column(
const Container& nonZeroRowIndices,
321 Column_settings* colSettings)
325 if constexpr (Master_matrix::Option_list::is_z2) {
326 return nonZeroRowIndices.begin() == nonZeroRowIndices.end()
327 ? Master_matrix::template get_null_value<ID_index>()
328 : *
std::prev(nonZeroRowIndices.end());
330 return nonZeroRowIndices.begin() == nonZeroRowIndices.end()
331 ? Master_matrix::template get_null_value<ID_index>()
332 :
std::prev(nonZeroRowIndices.end())->first;
336 entryPool_(&(colSettings->entryConstructor))
338 if constexpr (Master_matrix::Option_list::is_z2) {
339 for (ID_index
id : nonZeroRowIndices) {
340 _insert_entry(
id, column_.end());
343 operators_ = &(colSettings->operators);
344 for (
const auto& p : nonZeroRowIndices) {
345 _insert_entry(operators_->get_value(p.second), p.first, column_.end());
350template <
class Master_matrix>
351template <
class Container,
class Row_container>
352inline Set_column<Master_matrix>::Set_column(Index columnIndex,
353 const Container& nonZeroRowIndices,
355 Row_container* rowContainer,
356 Column_settings* colSettings)
357 : RA_opt(columnIndex, rowContainer),
360 if constexpr (Master_matrix::Option_list::is_z2) {
361 return nonZeroRowIndices.begin() == nonZeroRowIndices.end()
362 ? Master_matrix::template get_null_value<ID_index>()
363 : *
std::prev(nonZeroRowIndices.end());
365 return nonZeroRowIndices.begin() == nonZeroRowIndices.end()
366 ? Master_matrix::template get_null_value<ID_index>()
367 :
std::prev(nonZeroRowIndices.end())->first;
371 entryPool_(&(colSettings->entryConstructor))
373 if constexpr (Master_matrix::Option_list::is_z2) {
374 for (ID_index
id : nonZeroRowIndices) {
375 _insert_entry(
id, column_.end());
378 operators_ = &(colSettings->operators);
379 for (
const auto& p : nonZeroRowIndices) {
380 _insert_entry(operators_->get_value(p.second), p.first, column_.end());
385template <
class Master_matrix>
386inline Set_column<Master_matrix>::Set_column(
const Set_column& column, Column_settings* colSettings)
388 Dim_opt(static_cast<const Dim_opt&>(column)),
389 Chain_opt(static_cast<const Chain_opt&>(column)),
390 operators_(colSettings == nullptr ? column.operators_ : nullptr),
391 entryPool_(colSettings == nullptr ? column.entryPool_ : &(colSettings->entryConstructor))
393 static_assert(!Master_matrix::Option_list::has_row_access,
394 "Simple copy constructor not available when row access option enabled. Please specify the new column "
395 "index and the row container.");
397 if constexpr (!Master_matrix::Option_list::is_z2) {
398 if (colSettings !=
nullptr) operators_ = &(colSettings->operators);
401 for (
const Entry* entry : column.column_) {
402 if constexpr (Master_matrix::Option_list::is_z2) {
403 _insert_entry(entry->get_row_index(), column_.end());
405 _insert_entry(entry->get_element(), entry->get_row_index(), column_.end());
410template <
class Master_matrix>
411template <
class Row_container>
412inline Set_column<Master_matrix>::Set_column(
const Set_column& column,
414 Row_container* rowContainer,
415 Column_settings* colSettings)
416 : RA_opt(columnIndex, rowContainer),
417 Dim_opt(static_cast<const Dim_opt&>(column)),
418 Chain_opt(static_cast<const Chain_opt&>(column)),
419 operators_(colSettings == nullptr ? column.operators_ : nullptr),
420 entryPool_(colSettings == nullptr ? column.entryPool_ : &(colSettings->entryConstructor))
422 if constexpr (!Master_matrix::Option_list::is_z2) {
423 if (colSettings !=
nullptr) operators_ = &(colSettings->operators);
426 for (
const Entry* entry : column.column_) {
427 if constexpr (Master_matrix::Option_list::is_z2) {
428 _insert_entry(entry->get_row_index(), column_.end());
430 _insert_entry(entry->get_element(), entry->get_row_index(), column_.end());
435template <
class Master_matrix>
436inline Set_column<Master_matrix>::Set_column(Set_column&& column) noexcept
437 : RA_opt(std::move(
static_cast<RA_opt&
>(column))),
438 Dim_opt(std::move(
static_cast<Dim_opt&
>(column))),
439 Chain_opt(std::move(
static_cast<Chain_opt&
>(column))),
440 column_(std::move(column.column_)),
441 operators_(std::exchange(column.operators_,
nullptr)),
442 entryPool_(std::exchange(column.entryPool_,
nullptr))
445template <
class Master_matrix>
446inline Set_column<Master_matrix>::~Set_column()
448 for (
auto* entry : column_) {
449 if constexpr (Master_matrix::Option_list::has_row_access) RA_opt::unlink(entry);
450 entryPool_->destroy(entry);
454template <
class Master_matrix>
455inline std::vector<typename Set_column<Master_matrix>::Field_element> Set_column<Master_matrix>::get_content(
456 int columnLength)
const
458 if (columnLength < 0 && column_.size() > 0)
459 columnLength = (*column_.rbegin())->get_row_index() + 1;
460 else if (columnLength < 0)
461 return std::vector<Field_element>();
463 std::vector<Field_element> container(columnLength, 0);
464 for (
auto it = column_.begin(); it != column_.end() && (*it)->get_row_index() <
static_cast<ID_index
>(columnLength);
466 if constexpr (Master_matrix::Option_list::is_z2) {
467 container[(*it)->get_row_index()] = 1;
469 container[(*it)->get_row_index()] = (*it)->get_element();
475template <
class Master_matrix>
476inline bool Set_column<Master_matrix>::is_non_zero(ID_index rowIndex)
const
478 Entry entry(rowIndex);
479 return column_.find(&entry) != column_.end();
482template <
class Master_matrix>
483inline bool Set_column<Master_matrix>::is_empty()
const
485 return column_.empty();
488template <
class Master_matrix>
489inline std::size_t Set_column<Master_matrix>::size()
const
491 return column_.size();
494template <
class Master_matrix>
495template <
class Row_index_map>
496inline void Set_column<Master_matrix>::reorder(
const Row_index_map& valueMap, [[maybe_unused]] Index columnIndex)
498 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
499 "Method not available for chain columns.");
501 Column_support newSet;
503 for (Entry* entry : column_) {
504 if constexpr (Master_matrix::Option_list::has_row_access) {
505 RA_opt::unlink(entry);
506 if (columnIndex != Master_matrix::template get_null_value<Index>()) entry->set_column_index(columnIndex);
508 entry->set_row_index(valueMap.at(entry->get_row_index()));
509 newSet.insert(entry);
510 if constexpr (Master_matrix::Option_list::has_row_access &&
511 Master_matrix::Option_list::has_intrusive_rows)
512 RA_opt::insert_entry(entry->get_row_index(), entry);
516 if constexpr (Master_matrix::Option_list::has_row_access && !Master_matrix::Option_list::has_intrusive_rows) {
517 for (Entry* entry : newSet) {
518 RA_opt::insert_entry(entry->get_row_index(), entry);
522 column_.swap(newSet);
525template <
class Master_matrix>
526inline void Set_column<Master_matrix>::clear()
528 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
529 "Method not available for chain columns as a base element should not be empty.");
531 for (
auto* entry : column_) {
532 if constexpr (Master_matrix::Option_list::has_row_access) RA_opt::unlink(entry);
533 entryPool_->destroy(entry);
539template <
class Master_matrix>
540inline void Set_column<Master_matrix>::clear(ID_index rowIndex)
542 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
543 "Method not available for chain columns.");
545 auto entry = entryPool_->construct(rowIndex);
546 auto it = column_.find(entry);
547 if (it != column_.end()) {
550 entryPool_->destroy(entry);
553template <
class Master_matrix>
554inline typename Set_column<Master_matrix>::ID_index Set_column<Master_matrix>::get_pivot()
const
556 static_assert(Master_matrix::isNonBasic,
557 "Method not available for base columns.");
559 if constexpr (Master_matrix::Option_list::is_of_boundary_type) {
560 if (column_.empty())
return Master_matrix::template get_null_value<ID_index>();
561 return (*column_.rbegin())->get_row_index();
563 return Chain_opt::get_pivot();
567template <
class Master_matrix>
568inline typename Set_column<Master_matrix>::Field_element Set_column<Master_matrix>::get_pivot_value()
const
570 static_assert(Master_matrix::isNonBasic,
571 "Method not available for base columns.");
573 if constexpr (Master_matrix::Option_list::is_z2) {
576 if constexpr (Master_matrix::Option_list::is_of_boundary_type) {
577 if (column_.empty())
return 0;
578 return (*column_.rbegin())->get_element();
580 if (Chain_opt::get_pivot() == Master_matrix::template get_null_value<ID_index>())
return Field_element();
581 for (
const Entry* entry : column_) {
582 if (entry->get_row_index() == Chain_opt::get_pivot())
return entry->get_element();
584 return Field_element();
589template <
class Master_matrix>
590inline typename Set_column<Master_matrix>::iterator Set_column<Master_matrix>::begin() noexcept
592 return column_.begin();
595template <
class Master_matrix>
596inline typename Set_column<Master_matrix>::const_iterator Set_column<Master_matrix>::begin() const noexcept
598 return column_.begin();
601template <
class Master_matrix>
602inline typename Set_column<Master_matrix>::iterator Set_column<Master_matrix>::end() noexcept
604 return column_.end();
607template <
class Master_matrix>
608inline typename Set_column<Master_matrix>::const_iterator Set_column<Master_matrix>::end() const noexcept
610 return column_.end();
613template <
class Master_matrix>
614inline typename Set_column<Master_matrix>::reverse_iterator Set_column<Master_matrix>::rbegin() noexcept
616 return column_.rbegin();
619template <
class Master_matrix>
620inline typename Set_column<Master_matrix>::const_reverse_iterator Set_column<Master_matrix>::rbegin() const noexcept
622 return column_.rbegin();
625template <
class Master_matrix>
626inline typename Set_column<Master_matrix>::reverse_iterator Set_column<Master_matrix>::rend() noexcept
628 return column_.rend();
631template <
class Master_matrix>
632inline typename Set_column<Master_matrix>::const_reverse_iterator Set_column<Master_matrix>::rend() const noexcept
634 return column_.rend();
637template <
class Master_matrix>
638template <
class Entry_range>
639inline Set_column<Master_matrix>& Set_column<Master_matrix>::operator+=(
const Entry_range& column)
641 static_assert((!Master_matrix::isNonBasic || std::is_same_v<Entry_range, Set_column>),
642 "For boundary columns, the range has to be a column of same type to help ensure the validity of the "
644 static_assert((!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type),
645 "For chain columns, the given column cannot be constant.");
652template <
class Master_matrix>
653inline Set_column<Master_matrix>& Set_column<Master_matrix>::operator+=(Set_column& column)
655 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
658 Chain_opt::swap_pivots(column);
659 Dim_opt::swap_dimension(column);
668template <
class Master_matrix>
669inline Set_column<Master_matrix>& Set_column<Master_matrix>::operator*=(
unsigned int v)
671 if constexpr (Master_matrix::Option_list::is_z2) {
673 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
674 throw std::invalid_argument(
"A chain column should not be multiplied by 0.");
680 Field_element val = operators_->get_value(v);
682 if (val == Field_operators::get_additive_identity()) {
683 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
684 throw std::invalid_argument(
"A chain column should not be multiplied by 0.");
691 if (val == Field_operators::get_multiplicative_identity())
return *
this;
693 for (Entry* entry : column_) {
694 operators_->multiply_inplace(entry->get_element(), val);
695 if constexpr (Master_matrix::Option_list::has_row_access) RA_opt::update_entry(*entry);
702template <
class Master_matrix>
703template <
class Entry_range>
704inline Set_column<Master_matrix>& Set_column<Master_matrix>::multiply_target_and_add(
const Field_element& val,
705 const Entry_range& column)
707 static_assert((!Master_matrix::isNonBasic || std::is_same_v<Entry_range, Set_column>),
708 "For boundary columns, the range has to be a column of same type to help ensure the validity of the "
710 static_assert((!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type),
711 "For chain columns, the given column cannot be constant.");
713 if constexpr (Master_matrix::Option_list::is_z2) {
721 _multiply_target_and_add(val, column);
727template <
class Master_matrix>
728inline Set_column<Master_matrix>& Set_column<Master_matrix>::multiply_target_and_add(
const Field_element& val,
731 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
733 if constexpr (Master_matrix::Option_list::is_z2) {
736 Chain_opt::swap_pivots(column);
737 Dim_opt::swap_dimension(column);
740 throw std::invalid_argument(
"A chain column should not be multiplied by 0.");
743 if (_multiply_target_and_add(val, column)) {
744 Chain_opt::swap_pivots(column);
745 Dim_opt::swap_dimension(column);
749 if constexpr (Master_matrix::Option_list::is_z2) {
757 _multiply_target_and_add(val, column);
764template <
class Master_matrix>
765template <
class Entry_range>
766inline Set_column<Master_matrix>& Set_column<Master_matrix>::multiply_source_and_add(
const Entry_range& column,
767 const Field_element& val)
769 static_assert((!Master_matrix::isNonBasic || std::is_same_v<Entry_range, Set_column>),
770 "For boundary columns, the range has to be a column of same type to help ensure the validity of the "
772 static_assert((!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type),
773 "For chain columns, the given column cannot be constant.");
775 if constexpr (Master_matrix::Option_list::is_z2) {
780 _multiply_source_and_add(column, val);
786template <
class Master_matrix>
787inline Set_column<Master_matrix>& Set_column<Master_matrix>::multiply_source_and_add(Set_column& column,
788 const Field_element& val)
790 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
792 if constexpr (Master_matrix::Option_list::is_z2) {
795 Chain_opt::swap_pivots(column);
796 Dim_opt::swap_dimension(column);
800 if (_multiply_source_and_add(column, val)) {
801 Chain_opt::swap_pivots(column);
802 Dim_opt::swap_dimension(column);
806 if constexpr (Master_matrix::Option_list::is_z2) {
811 _multiply_source_and_add(column, val);
818template <
class Master_matrix>
819inline void Set_column<Master_matrix>::push_back(
const Entry& entry)
821 static_assert(Master_matrix::Option_list::is_of_boundary_type,
"`push_back` is not available for Chain matrices.");
823 GUDHI_CHECK(entry.get_row_index() > get_pivot(),
"The new row index has to be higher than the current pivot.");
825 if constexpr (Master_matrix::Option_list::is_z2) {
826 _insert_entry(entry.get_row_index(), column_.end());
828 _insert_entry(entry.get_element(), entry.get_row_index(), column_.end());
832template <
class Master_matrix>
833inline Set_column<Master_matrix>& Set_column<Master_matrix>::operator=(
const Set_column& other)
835 static_assert(!Master_matrix::Option_list::has_row_access,
"= assignment not enabled with row access option.");
837 Dim_opt::operator=(other);
838 Chain_opt::operator=(other);
840 for (
auto* entry : column_) {
841 if constexpr (Master_matrix::Option_list::has_row_access) RA_opt::unlink(entry);
842 entryPool_->destroy(entry);
846 entryPool_ = other.entryPool_;
847 operators_ = other.operators_;
849 for (
const Entry* entry : other.column_) {
850 if constexpr (Master_matrix::Option_list::is_z2) {
851 _insert_entry(entry->get_row_index(), column_.end());
853 _insert_entry(entry->get_element(), entry->get_row_index(), column_.end());
860template <
class Master_matrix>
861inline void Set_column<Master_matrix>::_delete_entry(
typename Column_support::iterator& it)
863 if constexpr (Master_matrix::Option_list::has_row_access) RA_opt::unlink(*it);
864 entryPool_->destroy(*it);
865 it = column_.erase(it);
868template <
class Master_matrix>
869inline typename Set_column<Master_matrix>::Entry* Set_column<Master_matrix>::_insert_entry(
870 const Field_element& value,
872 const typename Column_support::iterator& position)
874 if constexpr (Master_matrix::Option_list::has_row_access) {
875 Entry* newEntry = entryPool_->construct(RA_opt::columnIndex_, rowIndex);
876 newEntry->set_element(value);
877 column_.insert(position, newEntry);
878 RA_opt::insert_entry(rowIndex, newEntry);
881 Entry* newEntry = entryPool_->construct(rowIndex);
882 newEntry->set_element(value);
883 column_.insert(position, newEntry);
888template <
class Master_matrix>
889inline void Set_column<Master_matrix>::_insert_entry(ID_index rowIndex,
890 const typename Column_support::iterator& position)
892 if constexpr (Master_matrix::Option_list::has_row_access) {
893 Entry* newEntry = entryPool_->construct(RA_opt::columnIndex_, rowIndex);
894 column_.insert(position, newEntry);
895 RA_opt::insert_entry(rowIndex, newEntry);
897 Entry* newEntry = entryPool_->construct(rowIndex);
898 column_.insert(position, newEntry);
902template <
class Master_matrix>
903template <
class Entry_range>
904inline bool Set_column<Master_matrix>::_add(
const Entry_range& column)
906 return _add_to_column(column, *
this);
909template <
class Master_matrix>
910template <
class Entry_range>
911inline bool Set_column<Master_matrix>::_multiply_target_and_add(
const Field_element& val,
const Entry_range& column)
913 return _multiply_target_and_add_to_column(val, column, *
this);
916template <
class Master_matrix>
917template <
class Entry_range>
918inline bool Set_column<Master_matrix>::_multiply_source_and_add(
const Entry_range& column,
const Field_element& val)
920 return _multiply_source_and_add_to_column(val, column, *
this);
934template <
class Master_matrix>
935struct std::hash<
Gudhi::persistence_matrix::Set_column<Master_matrix> > {
937 return Gudhi::persistence_matrix::hash_column(column);
Column class following the PersistenceMatrixColumn concept.
Definition: 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