18#ifndef PM_SET_COLUMN_H
19#define PM_SET_COLUMN_H
27#include <boost/iterator/indirect_iterator.hpp>
28#include <boost/range/iterator_range_core.hpp>
47template <
class Master_matrix>
48class Set_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;
64 struct EntryPointerComp {
65 bool operator()(
const Entry* c1,
const Entry* c2)
const {
return *c1 < *c2; }
68 using Column_support = std::set<Entry*, EntryPointerComp>;
69 using Entry_constructor =
typename Master_matrix::Entry_constructor;
72 using iterator = boost::indirect_iterator<typename Column_support::iterator>;
73 using const_iterator = boost::indirect_iterator<typename Column_support::const_iterator>;
74 using reverse_iterator = boost::indirect_iterator<typename Column_support::reverse_iterator>;
75 using const_reverse_iterator = boost::indirect_iterator<typename Column_support::const_reverse_iterator>;
76 using Content_range = boost::iterator_range<const_iterator>;
78 Set_column(Column_settings* colSettings =
nullptr);
79 template <
class Container =
typename Master_matrix::Boundary>
80 Set_column(
const Container& nonZeroRowIndices, Column_settings* colSettings);
81 template <
class Container =
typename Master_matrix::Boundary,
class Row_container>
82 Set_column(Index columnIndex,
83 const Container& nonZeroRowIndices,
84 Row_container* rowContainer,
85 Column_settings* colSettings);
86 template <
class Container =
typename Master_matrix::Boundary,
87 class = std::enable_if_t<!std::is_arithmetic_v<Container> > >
88 Set_column(
const Container& nonZeroRowIndices, Dimension dimension, Column_settings* colSettings);
89 template <
class Container =
typename Master_matrix::Boundary,
91 class = std::enable_if_t<!std::is_arithmetic_v<Container> > >
92 Set_column(Index columnIndex,
93 const Container& nonZeroRowIndices,
95 Row_container* rowContainer,
96 Column_settings* colSettings);
97 Set_column(ID_index idx, Dimension dimension, Column_settings* colSettings);
98 Set_column(ID_index idx, Field_element e, Dimension dimension, Column_settings* colSettings);
99 template <
class Row_container>
100 Set_column(Index columnIndex,
103 Row_container* rowContainer,
104 Column_settings* colSettings);
105 template <
class Row_container>
106 Set_column(Index columnIndex,
110 Row_container* rowContainer,
111 Column_settings* colSettings);
112 Set_column(
const Set_column& column, Column_settings* colSettings =
nullptr);
113 template <
class Row_container>
114 Set_column(
const Set_column& column,
116 Row_container* rowContainer,
117 Column_settings* colSettings =
nullptr);
118 Set_column(Set_column&& column)
noexcept;
121 std::vector<Field_element> get_content(
int columnLength = -1)
const;
122 bool is_non_zero(ID_index rowIndex)
const;
123 [[nodiscard]]
bool is_empty()
const;
124 [[nodiscard]] std::size_t size()
const;
126 template <
class Row_index_map>
127 void reorder(
const Row_index_map& valueMap,
128 [[maybe_unused]] Index columnIndex = Master_matrix::template get_null_value<Index>());
130 void clear(ID_index rowIndex);
132 ID_index get_pivot()
const;
133 Field_element get_pivot_value()
const;
135 iterator begin()
noexcept;
136 const_iterator begin()
const noexcept;
137 iterator end()
noexcept;
138 const_iterator end()
const noexcept;
139 reverse_iterator rbegin()
noexcept;
140 const_reverse_iterator rbegin()
const noexcept;
141 reverse_iterator rend()
noexcept;
142 const_reverse_iterator rend()
const noexcept;
144 Content_range get_non_zero_content_range()
const;
146 template <
class Entry_range>
147 Set_column& operator+=(
const Entry_range& column);
148 Set_column& operator+=(Set_column& column);
150 Set_column& operator*=(
const Field_element& v);
153 template <
class Entry_range>
154 Set_column& multiply_target_and_add(
const Field_element& val,
const Entry_range& column);
155 Set_column& multiply_target_and_add(
const Field_element& val, Set_column& column);
157 template <
class Entry_range>
158 Set_column& multiply_source_and_add(
const Entry_range& column,
const Field_element& val);
159 Set_column& multiply_source_and_add(Set_column& column,
const Field_element& val);
161 void push_back(
const Entry& entry);
163 friend bool operator==(
const Set_column& c1,
const Set_column& c2)
165 if (&c1 == &c2)
return true;
166 if (c1.column_.size() != c2.column_.size())
return false;
168 return std::equal(c1.column_.begin(),
172 [](
const Entry* e1,
const Entry* e2) {
173 return e1->get_row_index() == e2->get_row_index() && e1->get_element() == e2->get_element();
177 friend bool operator<(
const Set_column& c1,
const Set_column& c2)
179 if (&c1 == &c2)
return false;
181 return std::lexicographical_compare(c1.column_.begin(),
185 [](
const Entry* e1,
const Entry* e2) {
186 if (e1->get_row_index() != e2->get_row_index())
187 return e1->get_row_index() < e2->get_row_index();
188 if (e1->get_element() != e2->get_element())
189 return e1->get_element() < e2->get_element();
195 Set_column& operator=(
const Set_column& other);
196 Set_column& operator=(Set_column&& other)
noexcept;
198 friend void swap(Set_column& col1, Set_column& col2)
noexcept
200 swap(
static_cast<typename Master_matrix::Row_access_option&
>(col1),
201 static_cast<typename Master_matrix::Row_access_option&
>(col2));
202 swap(
static_cast<typename Master_matrix::Column_dimension_option&
>(col1),
203 static_cast<typename Master_matrix::Column_dimension_option&
>(col2));
204 swap(
static_cast<typename Master_matrix::Chain_column_option&
>(col1),
205 static_cast<typename Master_matrix::Chain_column_option&
>(col2));
206 col1.column_.swap(col2.column_);
207 std::swap(col1.operators_, col2.operators_);
208 std::swap(col1.entryPool_, col2.entryPool_);
212 using RA_opt =
typename Master_matrix::Row_access_option;
213 using Dim_opt =
typename Master_matrix::Column_dimension_option;
214 using Chain_opt =
typename Master_matrix::Chain_column_option;
216 Column_support column_;
217 Field_operators
const* operators_;
218 Entry_constructor* entryPool_;
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(
typename Column_support::iterator& it);
249 Entry* _insert_entry(
const typename Column_support::iterator& position,
251 const Field_element& value);
252 template <
class Entry_range>
253 bool _add(
const Entry_range& column);
254 template <
class Entry_range>
255 bool _multiply_target_and_add(
const Field_element& val,
const Entry_range& column);
256 template <
class Entry_range>
257 bool _multiply_source_and_add(
const Entry_range& column,
const Field_element& val);
260template <
class Master_matrix>
261inline Set_column<Master_matrix>::Set_column(Column_settings* colSettings)
265 operators_(Master_matrix::get_operator_ptr(colSettings)),
266 entryPool_(colSettings == nullptr ? nullptr : &(colSettings->entryConstructor))
269template <
class Master_matrix>
270template <
class Container>
271inline Set_column<Master_matrix>::Set_column(
const Container& nonZeroRowIndices, Column_settings* colSettings)
272 : Set_column(nonZeroRowIndices, nonZeroRowIndices.size() == 0 ? 0 : nonZeroRowIndices.size() - 1, colSettings)
274 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
275 "Constructor not available for chain columns, please specify the dimension of the chain.");
278template <
class Master_matrix>
279template <
class Container,
class Row_container>
280inline Set_column<Master_matrix>::Set_column(Index columnIndex,
281 const Container& nonZeroRowIndices,
282 Row_container* rowContainer,
283 Column_settings* colSettings)
284 : Set_column(columnIndex,
286 nonZeroRowIndices.size() == 0 ? 0 : nonZeroRowIndices.size() - 1,
290 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
291 "Constructor not available for chain columns, please specify the dimension of the chain.");
294template <
class Master_matrix>
295template <
class Container,
class>
296inline Set_column<Master_matrix>::Set_column(
const Container& nonZeroRowIndices,
298 Column_settings* colSettings)
301 Chain_opt(nonZeroRowIndices.begin() == nonZeroRowIndices.end()
302 ? Master_matrix::template get_null_value<ID_index>()
303 : Master_matrix::get_row_index(*std::prev(nonZeroRowIndices.end()))),
304 operators_(Master_matrix::get_operator_ptr(colSettings)),
305 entryPool_(&(colSettings->entryConstructor))
307 for (
const auto&
id : nonZeroRowIndices) {
308 _insert_entry(column_.end(),
309 Master_matrix::get_row_index(
id),
310 Master_matrix::get_coefficient_value(Master_matrix::get_element(
id), operators_));
314template <
class Master_matrix>
315template <
class Container,
class Row_container,
class>
316inline Set_column<Master_matrix>::Set_column(Index columnIndex,
317 const Container& nonZeroRowIndices,
319 Row_container* rowContainer,
320 Column_settings* colSettings)
321 : RA_opt(columnIndex, rowContainer),
323 Chain_opt(nonZeroRowIndices.begin() == nonZeroRowIndices.end()
324 ? Master_matrix::template get_null_value<ID_index>()
325 : Master_matrix::get_row_index(*std::prev(nonZeroRowIndices.end()))),
326 operators_(Master_matrix::get_operator_ptr(colSettings)),
327 entryPool_(&(colSettings->entryConstructor))
329 for (
const auto&
id : nonZeroRowIndices) {
330 _insert_entry(column_.end(),
331 Master_matrix::get_row_index(
id),
332 Master_matrix::get_coefficient_value(Master_matrix::get_element(
id), operators_));
336template <
class Master_matrix>
337inline Set_column<Master_matrix>::Set_column(ID_index idx, Dimension dimension, Column_settings* colSettings)
338 : RA_opt(), Dim_opt(dimension), Chain_opt(idx), operators_(nullptr), entryPool_(&(colSettings->entryConstructor))
340 static_assert(Master_matrix::Option_list::is_z2,
341 "Constructor not available for Zp != Z2. Please specify the coefficient.");
342 _insert_entry(column_.end(), idx, 1);
345template <
class Master_matrix>
346inline Set_column<Master_matrix>::Set_column(ID_index idx,
349 Column_settings* colSettings)
353 operators_(&(colSettings->operators)),
354 entryPool_(&(colSettings->entryConstructor))
356 static_assert(!Master_matrix::Option_list::is_z2,
357 "Constructor not available for Zp == Z2. Please do not specify any coefficient.");
358 _insert_entry(column_.end(), idx, operators_->get_value(e));
361template <
class Master_matrix>
362template <
class Row_container>
363inline Set_column<Master_matrix>::Set_column(Index columnIndex,
366 Row_container* rowContainer,
367 Column_settings* colSettings)
368 : RA_opt(columnIndex, rowContainer),
372 entryPool_(&(colSettings->entryConstructor))
374 static_assert(Master_matrix::Option_list::is_z2,
375 "Constructor not available for Zp != Z2. Please specify the coefficient.");
376 _insert_entry(column_.end(), idx, 1);
379template <
class Master_matrix>
380template <
class Row_container>
381inline Set_column<Master_matrix>::Set_column(Index columnIndex,
385 Row_container* rowContainer,
386 Column_settings* colSettings)
387 : RA_opt(columnIndex, rowContainer),
390 operators_(&(colSettings->operators)),
391 entryPool_(&(colSettings->entryConstructor))
393 static_assert(!Master_matrix::Option_list::is_z2,
394 "Constructor not available for Zp == Z2. Please do not specify any coefficient.");
395 _insert_entry(column_.end(), idx, operators_->get_value(e));
398template <
class Master_matrix>
399inline Set_column<Master_matrix>::Set_column(
const Set_column& column, Column_settings* colSettings)
401 Dim_opt(static_cast<const Dim_opt&>(column)),
402 Chain_opt(static_cast<const Chain_opt&>(column)),
403 operators_(colSettings == nullptr ? column.operators_ : Master_matrix::get_operator_ptr(colSettings)),
404 entryPool_(colSettings == nullptr ? column.entryPool_ : &(colSettings->entryConstructor))
406 static_assert(!Master_matrix::Option_list::has_row_access,
407 "Simple copy constructor not available when row access option enabled. Please specify the new column "
408 "index and the row container.");
410 for (
const Entry* entry : column.column_) {
411 _insert_entry(column_.end(), entry->get_row_index(), entry->get_element());
415template <
class Master_matrix>
416template <
class Row_container>
417inline Set_column<Master_matrix>::Set_column(
const Set_column& column,
419 Row_container* rowContainer,
420 Column_settings* colSettings)
421 : RA_opt(columnIndex, rowContainer),
422 Dim_opt(static_cast<const Dim_opt&>(column)),
423 Chain_opt(static_cast<const Chain_opt&>(column)),
424 operators_(colSettings == nullptr ? column.operators_ : Master_matrix::get_operator_ptr(colSettings)),
425 entryPool_(colSettings == nullptr ? column.entryPool_ : &(colSettings->entryConstructor))
427 for (
const Entry* entry : column.column_) {
428 _insert_entry(column_.end(), entry->get_row_index(), entry->get_element());
432template <
class Master_matrix>
433inline Set_column<Master_matrix>::Set_column(
Set_column&& column) noexcept
434 : RA_opt(std::move(
static_cast<RA_opt&
>(column))),
435 Dim_opt(std::move(
static_cast<Dim_opt&
>(column))),
436 Chain_opt(std::move(
static_cast<Chain_opt&
>(column))),
437 column_(std::move(column.column_)),
438 operators_(std::exchange(column.operators_,
nullptr)),
439 entryPool_(std::exchange(column.entryPool_,
nullptr))
443template <
class Master_matrix>
444inline Set_column<Master_matrix>::~Set_column()
446 for (
auto* entry : column_) {
447 if constexpr (Master_matrix::Option_list::has_row_access) RA_opt::unlink(entry);
448 entryPool_->destroy(entry);
452template <
class Master_matrix>
453inline std::vector<typename Set_column<Master_matrix>::Field_element> Set_column<Master_matrix>::get_content(
454 int columnLength)
const
456 if (columnLength < 0 && column_.size() > 0)
457 columnLength = (*column_.rbegin())->get_row_index() + 1;
458 else if (columnLength < 0)
459 return std::vector<Field_element>();
461 std::vector<Field_element> container(columnLength, 0);
462 for (
auto it = column_.begin(); it != column_.end() && (*it)->get_row_index() <
static_cast<ID_index
>(columnLength);
464 container[(*it)->get_row_index()] = Master_matrix::get_element(**it);
469template <
class Master_matrix>
470inline bool Set_column<Master_matrix>::is_non_zero(ID_index rowIndex)
const
472 Entry entry(rowIndex);
473 return column_.find(&entry) != column_.end();
476template <
class Master_matrix>
477inline bool Set_column<Master_matrix>::is_empty()
const
479 return column_.empty();
482template <
class Master_matrix>
483inline std::size_t Set_column<Master_matrix>::size()
const
485 return column_.size();
488template <
class Master_matrix>
489template <
class Row_index_map>
490inline void Set_column<Master_matrix>::reorder(
const Row_index_map& valueMap, [[maybe_unused]] Index columnIndex)
492 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
493 "Method not available for chain columns.");
495 Column_support newSet;
497 for (
Entry* entry : column_) {
498 if constexpr (Master_matrix::Option_list::has_row_access) {
499 RA_opt::unlink(entry);
500 if (columnIndex != Master_matrix::template get_null_value<Index>()) entry->set_column_index(columnIndex);
502 entry->set_row_index(valueMap.at(entry->get_row_index()));
503 newSet.insert(entry);
504 if constexpr (Master_matrix::Option_list::has_row_access &&
505 Master_matrix::Option_list::has_intrusive_rows)
506 RA_opt::insert_entry(entry->get_row_index(), entry);
510 if constexpr (Master_matrix::Option_list::has_row_access && !Master_matrix::Option_list::has_intrusive_rows) {
511 for (
Entry* entry : newSet) {
512 RA_opt::insert_entry(entry->get_row_index(), entry);
516 column_.swap(newSet);
519template <
class Master_matrix>
520inline void Set_column<Master_matrix>::clear()
522 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
523 "Method not available for chain columns as a base element should not be empty.");
525 for (
auto* entry : column_) {
526 if constexpr (Master_matrix::Option_list::has_row_access) RA_opt::unlink(entry);
527 entryPool_->destroy(entry);
533template <
class Master_matrix>
534inline void Set_column<Master_matrix>::clear(ID_index rowIndex)
536 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
537 "Method not available for chain columns.");
539 auto entry = entryPool_->construct(rowIndex);
540 auto it = column_.find(entry);
541 if (it != column_.end()) {
544 entryPool_->destroy(entry);
547template <
class Master_matrix>
548inline typename Set_column<Master_matrix>::ID_index Set_column<Master_matrix>::get_pivot()
const
550 static_assert(Master_matrix::isNonBasic,
551 "Method not available for base columns.");
553 if constexpr (Master_matrix::Option_list::is_of_boundary_type) {
554 if (column_.empty())
return Master_matrix::template get_null_value<ID_index>();
555 return (*column_.rbegin())->get_row_index();
557 return Chain_opt::_get_pivot();
561template <
class Master_matrix>
562inline typename Set_column<Master_matrix>::Field_element Set_column<Master_matrix>::get_pivot_value()
const
564 static_assert(Master_matrix::isNonBasic,
565 "Method not available for base columns.");
567 if constexpr (Master_matrix::Option_list::is_z2) {
570 if constexpr (Master_matrix::Option_list::is_of_boundary_type) {
571 if (column_.empty())
return 0;
572 return (*column_.rbegin())->get_element();
574 if (Chain_opt::_get_pivot() == Master_matrix::template get_null_value<ID_index>())
return Field_element();
575 for (
const Entry* entry : column_) {
576 if (entry->get_row_index() == Chain_opt::_get_pivot())
return entry->get_element();
578 return Field_element();
583template <
class Master_matrix>
584inline typename Set_column<Master_matrix>::iterator Set_column<Master_matrix>::begin() noexcept
586 return column_.begin();
589template <
class Master_matrix>
590inline typename Set_column<Master_matrix>::const_iterator Set_column<Master_matrix>::begin() const noexcept
592 return column_.begin();
595template <
class Master_matrix>
596inline typename Set_column<Master_matrix>::iterator Set_column<Master_matrix>::end() noexcept
598 return column_.end();
601template <
class Master_matrix>
602inline typename Set_column<Master_matrix>::const_iterator Set_column<Master_matrix>::end() const noexcept
604 return column_.end();
607template <
class Master_matrix>
608inline typename Set_column<Master_matrix>::reverse_iterator Set_column<Master_matrix>::rbegin() noexcept
610 return column_.rbegin();
613template <
class Master_matrix>
614inline typename Set_column<Master_matrix>::const_reverse_iterator Set_column<Master_matrix>::rbegin() const noexcept
616 return column_.rbegin();
619template <
class Master_matrix>
620inline typename Set_column<Master_matrix>::reverse_iterator Set_column<Master_matrix>::rend() noexcept
622 return column_.rend();
625template <
class Master_matrix>
626inline typename Set_column<Master_matrix>::const_reverse_iterator Set_column<Master_matrix>::rend() const noexcept
628 return column_.rend();
631template <
class Master_matrix>
632inline typename Set_column<Master_matrix>::Content_range Set_column<Master_matrix>::get_non_zero_content_range()
const
634 return Content_range(column_.begin(), column_.end());
637template <
class Master_matrix>
638template <
class Entry_range>
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>
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>
671 Field_element val = Master_matrix::get_coefficient_value(v, operators_);
673 if (val == Field_operators::get_additive_identity()) {
674 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
675 throw std::invalid_argument(
"A chain column should not be multiplied by 0.");
682 if (val == Field_operators::get_multiplicative_identity())
return *
this;
686 if constexpr (!Master_matrix::Option_list::is_z2) {
687 for (
Entry* entry : column_) {
688 operators_->multiply_inplace(entry->get_element(), val);
689 if constexpr (Master_matrix::Option_list::has_row_access) RA_opt::update_entry(*entry);
696template <
class Master_matrix>
697template <
class Entry_range>
699 const Entry_range& column)
701 static_assert((!Master_matrix::isNonBasic || std::is_same_v<Entry_range, Set_column>),
702 "For boundary columns, the range has to be a column of same type to help ensure the validity of the "
704 static_assert((!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type),
705 "For chain columns, the given column cannot be constant.");
707 _multiply_target_and_add(Master_matrix::get_coefficient_value(val, operators_), column);
712template <
class Master_matrix>
716 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
718 if (_multiply_target_and_add(Master_matrix::get_coefficient_value(val, operators_), column)) {
719 Chain_opt::_swap_pivots(column);
720 Dim_opt::_swap_dimension(column);
723 _multiply_target_and_add(Master_matrix::get_coefficient_value(val, operators_), column);
729template <
class Master_matrix>
730template <
class Entry_range>
732 const Field_element& val)
734 static_assert((!Master_matrix::isNonBasic || std::is_same_v<Entry_range, Set_column>),
735 "For boundary columns, the range has to be a column of same type to help ensure the validity of the "
737 static_assert((!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type),
738 "For chain columns, the given column cannot be constant.");
740 _multiply_source_and_add(column, Master_matrix::get_coefficient_value(val, operators_));
745template <
class Master_matrix>
747 const Field_element& val)
749 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
751 if (_multiply_source_and_add(column, Master_matrix::get_coefficient_value(val, operators_))) {
752 Chain_opt::_swap_pivots(column);
753 Dim_opt::_swap_dimension(column);
756 _multiply_source_and_add(column, Master_matrix::get_coefficient_value(val, operators_));
762template <
class Master_matrix>
763inline void Set_column<Master_matrix>::push_back(
const Entry& entry)
765 static_assert(Master_matrix::Option_list::is_of_boundary_type,
"`push_back` is not available for Chain matrices.");
767 GUDHI_CHECK(entry.get_row_index() > get_pivot(),
768 std::invalid_argument(
"The new row index has to be higher than the current pivot."));
770 _insert_entry(column_.end(), entry.get_row_index(), entry.get_element());
773template <
class Master_matrix>
776 static_assert(!Master_matrix::Option_list::has_row_access,
"= assignment not enabled with row access option.");
779 if (
this == &other)
return *
this;
781 Dim_opt::operator=(other);
782 Chain_opt::operator=(other);
784 for (
auto* entry : column_) {
785 entryPool_->destroy(entry);
789 entryPool_ = other.entryPool_;
790 operators_ = other.operators_;
792 for (
const Entry* entry : other.column_) {
793 _insert_entry(column_.end(), entry->get_row_index(), entry->get_element());
799template <
class Master_matrix>
802 static_assert(!Master_matrix::Option_list::has_row_access,
"= assignment not enabled with row access option.");
805 if (&column_ == &(other.column_))
return *
this;
807 Dim_opt::operator=(std::move(other));
808 Chain_opt::operator=(std::move(other));
810 for (
auto* entry : column_) {
811 if (entry !=
nullptr) entryPool_->destroy(entry);
814 column_ = std::move(other.column_);
815 operators_ = std::exchange(other.operators_,
nullptr);
816 entryPool_ = std::exchange(other.entryPool_,
nullptr);
821template <
class Master_matrix>
822inline void Set_column<Master_matrix>::_delete_entry(
typename Column_support::iterator& it)
824 if constexpr (Master_matrix::Option_list::has_row_access) RA_opt::unlink(*it);
825 entryPool_->destroy(*it);
826 it = column_.erase(it);
829template <
class Master_matrix>
830inline typename Set_column<Master_matrix>::Entry* Set_column<Master_matrix>::_insert_entry(
831 const typename Column_support::iterator& position,
833 const Field_element& value)
836 if constexpr (Master_matrix::Option_list::has_row_access) {
837 newEntry = entryPool_->construct(RA_opt::get_column_index(), rowIndex);
839 newEntry = entryPool_->construct(rowIndex);
841 newEntry->set_element(value);
842 column_.insert(position, newEntry);
843 if constexpr (Master_matrix::Option_list::has_row_access) RA_opt::insert_entry(rowIndex, newEntry);
847template <
class Master_matrix>
848template <
class Entry_range>
849inline bool Set_column<Master_matrix>::_add(
const Entry_range& column)
851 return _add_to_column(column, *
this);
854template <
class Master_matrix>
855template <
class Entry_range>
856inline bool Set_column<Master_matrix>::_multiply_target_and_add(
const Field_element& val,
const Entry_range& column)
858 return _multiply_target_and_add_to_column(val, column, *
this);
861template <
class Master_matrix>
862template <
class Entry_range>
863inline bool Set_column<Master_matrix>::_multiply_source_and_add(
const Entry_range& column,
const Field_element& val)
865 return _multiply_source_and_add_to_column(val, column, *
this);
879template <
class Master_matrix>
880struct std::hash<
Gudhi::persistence_matrix::Set_column<Master_matrix> > {
883 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
Column class following the PersistenceMatrixColumn concept.
Definition set_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