18 #ifndef PM_LIST_COLUMN_H
19 #define PM_LIST_COLUMN_H
23 #include <type_traits>
27 #include <boost/iterator/indirect_iterator.hpp>
33 namespace persistence_matrix {
47 template <
class Master_matrix>
53 using Master = Master_matrix;
54 using index =
typename Master_matrix::index;
55 using id_index =
typename Master_matrix::id_index;
56 using dimension_type =
typename Master_matrix::dimension_type;
57 using Field_element_type =
typename Master_matrix::element_type;
58 using Cell =
typename Master_matrix::Cell_type;
59 using Column_settings =
typename Master_matrix::Column_settings;
62 using Field_operators =
typename Master_matrix::Field_operators;
63 using Column_type = std::list<Cell*>;
64 using Cell_constructor =
typename Master_matrix::Cell_constructor;
67 using iterator = boost::indirect_iterator<typename Column_type::iterator>;
68 using const_iterator = boost::indirect_iterator<typename Column_type::const_iterator>;
69 using reverse_iterator = boost::indirect_iterator<typename Column_type::reverse_iterator>;
70 using const_reverse_iterator = boost::indirect_iterator<typename Column_type::const_reverse_iterator>;
72 List_column(Column_settings* colSettings =
nullptr);
73 template <
class Container_type =
typename Master_matrix::boundary_type>
74 List_column(
const Container_type& nonZeroRowIndices, Column_settings* colSettings);
75 template <
class Container_type =
typename Master_matrix::boundary_type,
class Row_container_type>
77 const Container_type& nonZeroRowIndices,
78 Row_container_type* rowContainer,
79 Column_settings* colSettings);
80 template <
class Container_type =
typename Master_matrix::boundary_type>
81 List_column(
const Container_type& nonZeroChainRowIndices,
82 dimension_type dimension,
83 Column_settings* colSettings);
84 template <
class Container_type =
typename Master_matrix::boundary_type,
class Row_container_type>
86 const Container_type& nonZeroChainRowIndices,
87 dimension_type dimension,
88 Row_container_type* rowContainer,
89 Column_settings* colSettings);
91 Column_settings* colSettings =
nullptr);
92 template <
class Row_container_type>
95 Row_container_type* rowContainer,
96 Column_settings* colSettings =
nullptr);
100 std::vector<Field_element_type> get_content(
int columnLength = -1)
const;
101 bool is_non_zero(id_index rowIndex)
const;
102 bool is_empty()
const;
103 std::size_t size()
const;
105 template <
class Map_type>
106 void reorder(
const Map_type& valueMap, [[maybe_unused]] index columnIndex = -1);
108 void clear(id_index rowIndex);
110 id_index get_pivot()
const;
111 Field_element_type get_pivot_value()
const;
113 iterator begin() noexcept;
114 const_iterator begin()
const noexcept;
115 iterator end() noexcept;
116 const_iterator end()
const noexcept;
117 reverse_iterator rbegin() noexcept;
118 const_reverse_iterator rbegin()
const noexcept;
119 reverse_iterator rend() noexcept;
120 const_reverse_iterator rend()
const noexcept;
122 template <
class Cell_range>
129 template <
class Cell_range>
130 List_column& multiply_target_and_add(
const Field_element_type& val,
const Cell_range& column);
133 template <
class Cell_range>
134 List_column& multiply_source_and_add(
const Cell_range& column,
const Field_element_type& val);
138 if (&c1 == &c2)
return true;
140 auto it1 = c1.column_.begin();
141 auto it2 = c2.column_.begin();
142 if (c1.column_.size() != c2.column_.size())
return false;
143 while (it1 != c1.column_.end() && it2 != c2.column_.end()) {
144 if constexpr (Master_matrix::Option_list::is_z2) {
145 if ((*it1)->get_row_index() != (*it2)->get_row_index())
return false;
147 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.cellPool_, col2.cellPool_);
192 Field_operators* operators_;
193 Cell_constructor* cellPool_;
195 template <
class Column_type,
class Cell_iterator,
typename F1,
typename F2,
typename F3,
typename F4>
196 friend void _generic_merge_cell_to_column(Column_type& targetColumn,
197 Cell_iterator& itSource,
198 typename Column_type::Column_type::iterator& itTarget,
203 bool& pivotIsZeroed);
204 template <
class Column_type,
class Cell_range,
typename F1,
typename F2,
typename F3,
typename F4,
typename F5>
205 friend bool _generic_add_to_column(
const Cell_range& source,
206 Column_type& targetColumn,
212 template <
class Column_type,
class Cell_range>
213 friend bool _add_to_column(
const Cell_range& source, Column_type& targetColumn);
214 template <
class Column_type,
class Cell_range>
215 friend bool _multiply_target_and_add_to_column(
const typename Column_type::Field_element_type& val,
216 const Cell_range& source,
217 Column_type& targetColumn);
218 template <
class Column_type,
class Cell_range>
219 friend bool _multiply_source_and_add_to_column(
const typename Column_type::Field_element_type& val,
220 const Cell_range& source,
221 Column_type& targetColumn);
223 void _delete_cell(
typename Column_type::iterator& it);
224 Cell* _insert_cell(
const Field_element_type& value,
226 const typename Column_type::iterator& position);
227 void _insert_cell(id_index rowIndex,
const typename Column_type::iterator& position);
228 void _update_cell(
const Field_element_type& value, id_index rowIndex,
const typename Column_type::iterator& position);
229 void _update_cell(id_index rowIndex,
const typename Column_type::iterator& position);
230 template <
class Cell_range>
231 bool _add(
const Cell_range& column);
232 template <
class Cell_range>
233 bool _multiply_target_and_add(
const Field_element_type& val,
const Cell_range& column);
234 template <
class Cell_range>
235 bool _multiply_source_and_add(
const Cell_range& column,
const Field_element_type& val);
238 template <
class Master_matrix>
244 cellPool_(colSettings == nullptr ? nullptr : &(colSettings->cellConstructor))
246 if (operators_ ==
nullptr && cellPool_ ==
nullptr)
return;
247 if constexpr (!Master_matrix::Option_list::is_z2) {
248 operators_ = &(colSettings->operators);
252 template <
class Master_matrix>
253 template <
class Container_type>
254 inline List_column<Master_matrix>::List_column(
const Container_type& nonZeroRowIndices,
255 Column_settings* colSettings)
257 dim_opt(nonZeroRowIndices.size() == 0 ? 0 : nonZeroRowIndices.size() - 1),
259 column_(nonZeroRowIndices.size()),
261 cellPool_(&(colSettings->cellConstructor))
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_cell(
id, it++);
272 operators_ = &(colSettings->operators);
273 for (
const auto& p : nonZeroRowIndices) {
274 _update_cell(operators_->get_value(p.second), p.first, it++);
279 template <
class Master_matrix>
280 template <
class Container_type,
class Row_container_type>
281 inline List_column<Master_matrix>::List_column(index columnIndex,
282 const Container_type& nonZeroRowIndices,
283 Row_container_type* 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() ? -1 : *std::prev(nonZeroRowIndices.end());
291 return nonZeroRowIndices.begin() == nonZeroRowIndices.end() ? -1 : std::prev(nonZeroRowIndices.end())->first;
294 column_(nonZeroRowIndices.size()),
296 cellPool_(&(colSettings->cellConstructor))
298 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
299 "Constructor not available for chain columns, please specify the dimension of the chain.");
301 auto it = column_.begin();
302 if constexpr (Master_matrix::Option_list::is_z2) {
303 for (id_index
id : nonZeroRowIndices) {
304 _update_cell(
id, it++);
307 operators_ = &(colSettings->operators);
308 for (
const auto& p : nonZeroRowIndices) {
309 _update_cell(operators_->get_value(p.second), p.first, it++);
314 template <
class Master_matrix>
315 template <
class Container_type>
316 inline List_column<Master_matrix>::List_column(
const Container_type& nonZeroRowIndices,
317 dimension_type dimension,
318 Column_settings* colSettings)
322 if constexpr (Master_matrix::Option_list::is_z2) {
323 return nonZeroRowIndices.begin() == nonZeroRowIndices.end() ? -1 : *std::prev(nonZeroRowIndices.end());
325 return nonZeroRowIndices.begin() == nonZeroRowIndices.end() ? -1 : std::prev(nonZeroRowIndices.end())->first;
328 column_(nonZeroRowIndices.size()),
330 cellPool_(&(colSettings->cellConstructor))
332 auto it = column_.begin();
333 if constexpr (Master_matrix::Option_list::is_z2) {
334 for (id_index
id : nonZeroRowIndices) {
335 _update_cell(
id, it++);
338 operators_ = &(colSettings->operators);
339 for (
const auto& p : nonZeroRowIndices) {
340 _update_cell(operators_->get_value(p.second), p.first, it++);
345 template <
class Master_matrix>
346 template <
class Container_type,
class Row_container_type>
347 inline List_column<Master_matrix>::List_column(
349 const Container_type& nonZeroRowIndices,
350 dimension_type dimension,
351 Row_container_type* rowContainer,
352 Column_settings* colSettings)
353 : ra_opt(columnIndex, rowContainer),
356 if constexpr (Master_matrix::Option_list::is_z2) {
357 return nonZeroRowIndices.begin() == nonZeroRowIndices.end() ? -1 : *std::prev(nonZeroRowIndices.end());
359 return nonZeroRowIndices.begin() == nonZeroRowIndices.end() ? -1 : std::prev(nonZeroRowIndices.end())->first;
362 column_(nonZeroRowIndices.size()),
364 cellPool_(&(colSettings->cellConstructor))
366 auto it = column_.begin();
367 if constexpr (Master_matrix::Option_list::is_z2) {
368 for (id_index
id : nonZeroRowIndices) {
369 _update_cell(
id, it++);
372 operators_ = &(colSettings->operators);
373 for (
const auto& p : nonZeroRowIndices) {
374 _update_cell(operators_->get_value(p.second), p.first, it++);
379 template <
class Master_matrix>
380 inline List_column<Master_matrix>::List_column(
const List_column& column,
381 Column_settings* colSettings)
383 dim_opt(static_cast<const dim_opt&>(column)),
384 chain_opt(static_cast<const chain_opt&>(column)),
385 column_(column.column_.size()),
386 operators_(colSettings == nullptr ? column.operators_ : nullptr),
387 cellPool_(colSettings == nullptr ? column.cellPool_ : &(colSettings->cellConstructor))
389 static_assert(!Master_matrix::Option_list::has_row_access,
390 "Simple copy constructor not available when row access option enabled. Please specify the new column "
391 "index and the row container.");
393 if constexpr (!Master_matrix::Option_list::is_z2){
394 if (colSettings !=
nullptr) operators_ = &(colSettings->operators);
397 auto it = column_.begin();
398 for (
const Cell* cell : column.column_) {
399 if constexpr (Master_matrix::Option_list::is_z2) {
400 _update_cell(cell->get_row_index(), it++);
402 _update_cell(cell->get_element(), cell->get_row_index(), it++);
407 template <
class Master_matrix>
408 template <
class Row_container_type>
409 inline List_column<Master_matrix>::List_column(
const List_column& column,
411 Row_container_type* rowContainer,
412 Column_settings* colSettings)
413 : ra_opt(columnIndex, rowContainer),
414 dim_opt(static_cast<const dim_opt&>(column)),
415 chain_opt(static_cast<const chain_opt&>(column)),
416 column_(column.column_.size()),
417 operators_(colSettings == nullptr ? column.operators_ : nullptr),
418 cellPool_(colSettings == nullptr ? column.cellPool_ : &(colSettings->cellConstructor))
420 if constexpr (!Master_matrix::Option_list::is_z2){
421 if (colSettings !=
nullptr) operators_ = &(colSettings->operators);
424 auto it = column_.begin();
425 for (
const Cell* cell : column.column_) {
426 if constexpr (Master_matrix::Option_list::is_z2) {
427 _update_cell(cell->get_row_index(), it++);
429 _update_cell(cell->get_element(), cell->get_row_index(), it++);
434 template <
class Master_matrix>
435 inline List_column<Master_matrix>::List_column(List_column&& column) noexcept
436 : ra_opt(std::move(
static_cast<ra_opt&
>(column))),
437 dim_opt(std::move(
static_cast<dim_opt&
>(column))),
438 chain_opt(std::move(
static_cast<chain_opt&
>(column))),
439 column_(std::move(column.column_)),
440 operators_(std::exchange(column.operators_,
nullptr)),
441 cellPool_(std::exchange(column.cellPool_,
nullptr))
444 template <
class Master_matrix>
445 inline List_column<Master_matrix>::~List_column()
447 for (
auto* cell : column_) {
448 if constexpr (Master_matrix::Option_list::has_row_access) ra_opt::unlink(cell);
449 cellPool_->destroy(cell);
453 template <
class Master_matrix>
454 inline std::vector<typename List_column<Master_matrix>::Field_element_type>
455 List_column<Master_matrix>::get_content(
int columnLength)
const
457 if (columnLength < 0 && column_.size() > 0)
458 columnLength = column_.back()->get_row_index() + 1;
459 else if (columnLength < 0)
460 return std::vector<Field_element_type>();
462 std::vector<Field_element_type> container(columnLength, 0);
463 for (
auto it = column_.begin(); it != column_.end() && (*it)->get_row_index() <
static_cast<id_index
>(columnLength);
465 if constexpr (Master_matrix::Option_list::is_z2) {
466 container[(*it)->get_row_index()] = 1;
468 container[(*it)->get_row_index()] = (*it)->get_element();
474 template <
class Master_matrix>
475 inline bool List_column<Master_matrix>::is_non_zero(id_index rowIndex)
const
480 for (
const Cell* cell : column_)
481 if (cell->get_row_index() == rowIndex)
return true;
486 template <
class Master_matrix>
487 inline bool List_column<Master_matrix>::is_empty()
const
489 return column_.empty();
492 template <
class Master_matrix>
493 inline std::size_t List_column<Master_matrix>::size()
const
495 return column_.size();
498 template <
class Master_matrix>
499 template <
class Map_type>
500 inline void List_column<Master_matrix>::reorder(
const Map_type& valueMap, [[maybe_unused]] index columnIndex)
502 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
503 "Method not available for chain columns.");
505 for (
auto it = column_.begin(); it != column_.end(); ++it) {
507 if constexpr (Master_matrix::Option_list::has_row_access) {
508 ra_opt::unlink(cell);
509 if (columnIndex !=
static_cast<index
>(-1)) cell->set_column_index(columnIndex);
511 cell->set_row_index(valueMap.at(cell->get_row_index()));
512 if constexpr (Master_matrix::Option_list::has_intrusive_rows && Master_matrix::Option_list::has_row_access)
513 ra_opt::insert_cell(cell->get_row_index(), cell);
517 if constexpr (!Master_matrix::Option_list::has_intrusive_rows && Master_matrix::Option_list::has_row_access) {
518 for (
auto it = column_.begin(); it != column_.end(); ++it) {
520 ra_opt::insert_cell(cell->get_row_index(), cell);
524 column_.sort([](
const Cell* c1,
const Cell* c2) {
return *c1 < *c2; });
527 template <
class Master_matrix>
528 inline void List_column<Master_matrix>::clear()
530 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
531 "Method not available for chain columns as a base element should not be empty.");
533 for (
auto* cell : column_) {
534 if constexpr (Master_matrix::Option_list::has_row_access) ra_opt::unlink(cell);
535 cellPool_->destroy(cell);
541 template <
class Master_matrix>
542 inline void List_column<Master_matrix>::clear(id_index rowIndex)
544 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
545 "Method not available for chain columns.");
547 auto it = column_.begin();
548 while (it != column_.end() && (*it)->get_row_index() != rowIndex) it++;
549 if (it != column_.end()) _delete_cell(it);
552 template <
class Master_matrix>
553 inline typename List_column<Master_matrix>::id_index
554 List_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 -1;
561 return column_.back()->get_row_index();
563 return chain_opt::get_pivot();
567 template <
class Master_matrix>
568 inline typename List_column<Master_matrix>::Field_element_type
569 List_column<Master_matrix>::get_pivot_value()
const
571 static_assert(Master_matrix::isNonBasic,
572 "Method not available for base columns.");
574 if constexpr (Master_matrix::Option_list::is_z2) {
577 if constexpr (Master_matrix::Option_list::is_of_boundary_type) {
578 if (column_.empty())
return 0;
579 return column_.back()->get_element();
581 if (chain_opt::get_pivot() ==
static_cast<id_index
>(-1))
return Field_element_type();
582 for (
const Cell* cell : column_) {
583 if (cell->get_row_index() == chain_opt::get_pivot())
return cell->get_element();
585 return Field_element_type();
590 template <
class Master_matrix>
591 inline typename List_column<Master_matrix>::iterator
592 List_column<Master_matrix>::begin() noexcept
594 return column_.begin();
597 template <
class Master_matrix>
598 inline typename List_column<Master_matrix>::const_iterator
599 List_column<Master_matrix>::begin() const noexcept
601 return column_.begin();
604 template <
class Master_matrix>
605 inline typename List_column<Master_matrix>::iterator
606 List_column<Master_matrix>::end() noexcept
608 return column_.end();
611 template <
class Master_matrix>
612 inline typename List_column<Master_matrix>::const_iterator
613 List_column<Master_matrix>::end() const noexcept
615 return column_.end();
618 template <
class Master_matrix>
619 inline typename List_column<Master_matrix>::reverse_iterator
620 List_column<Master_matrix>::rbegin() noexcept
622 return column_.rbegin();
625 template <
class Master_matrix>
626 inline typename List_column<Master_matrix>::const_reverse_iterator
627 List_column<Master_matrix>::rbegin() const noexcept
629 return column_.rbegin();
632 template <
class Master_matrix>
633 inline typename List_column<Master_matrix>::reverse_iterator
634 List_column<Master_matrix>::rend() noexcept
636 return column_.rend();
639 template <
class Master_matrix>
640 inline typename List_column<Master_matrix>::const_reverse_iterator
641 List_column<Master_matrix>::rend() const noexcept
643 return column_.rend();
646 template <
class Master_matrix>
647 template <
class Cell_range>
648 inline List_column<Master_matrix>& List_column<Master_matrix>::operator+=(
649 const Cell_range& column)
651 static_assert((!Master_matrix::isNonBasic || std::is_same_v<Cell_range, List_column>),
652 "For boundary columns, the range has to be a column of same type to help ensure the validity of the "
654 static_assert((!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type),
655 "For chain columns, the given column cannot be constant.");
662 template <
class Master_matrix>
663 inline List_column<Master_matrix>& List_column<Master_matrix>::operator+=(
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);
679 template <
class Master_matrix>
680 inline List_column<Master_matrix>& List_column<Master_matrix>::operator*=(
683 if constexpr (Master_matrix::Option_list::is_z2) {
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.");
692 Field_element_type val = operators_->get_value(v);
695 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
696 throw std::invalid_argument(
"A chain column should not be multiplied by 0.");
703 if (val == 1u)
return *
this;
705 for (Cell* cell : column_) {
706 operators_->multiply_inplace(cell->get_element(), val);
707 if constexpr (Master_matrix::Option_list::has_row_access) ra_opt::update_cell(*cell);
714 template <
class Master_matrix>
715 template <
class Cell_range>
716 inline List_column<Master_matrix>& List_column<Master_matrix>::multiply_target_and_add(
717 const Field_element_type& val,
const Cell_range& column)
719 static_assert((!Master_matrix::isNonBasic || std::is_same_v<Cell_range, List_column>),
720 "For boundary columns, the range has to be a column of same type to help ensure the validity of the "
722 static_assert((!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type),
723 "For chain columns, the given column cannot be constant.");
725 if constexpr (Master_matrix::Option_list::is_z2) {
733 _multiply_target_and_add(val, column);
739 template <
class Master_matrix>
740 inline List_column<Master_matrix>& List_column<Master_matrix>::multiply_target_and_add(
741 const Field_element_type& val, List_column& column)
743 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
745 if constexpr (Master_matrix::Option_list::is_z2) {
748 chain_opt::swap_pivots(column);
749 dim_opt::swap_dimension(column);
752 throw std::invalid_argument(
"A chain column should not be multiplied by 0.");
755 if (_multiply_target_and_add(val, column)) {
756 chain_opt::swap_pivots(column);
757 dim_opt::swap_dimension(column);
761 if constexpr (Master_matrix::Option_list::is_z2) {
769 _multiply_target_and_add(val, column);
776 template <
class Master_matrix>
777 template <
class Cell_range>
778 inline List_column<Master_matrix>& List_column<Master_matrix>::multiply_source_and_add(
779 const Cell_range& column,
const Field_element_type& val)
781 static_assert((!Master_matrix::isNonBasic || std::is_same_v<Cell_range, List_column>),
782 "For boundary columns, the range has to be a column of same type to help ensure the validity of the "
784 static_assert((!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type),
785 "For chain columns, the given column cannot be constant.");
787 if constexpr (Master_matrix::Option_list::is_z2) {
792 _multiply_source_and_add(column, val);
798 template <
class Master_matrix>
799 inline List_column<Master_matrix>& List_column<Master_matrix>::multiply_source_and_add(
800 List_column& column,
const Field_element_type& val)
802 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
804 if constexpr (Master_matrix::Option_list::is_z2) {
807 chain_opt::swap_pivots(column);
808 dim_opt::swap_dimension(column);
812 if (_multiply_source_and_add(column, val)) {
813 chain_opt::swap_pivots(column);
814 dim_opt::swap_dimension(column);
818 if constexpr (Master_matrix::Option_list::is_z2) {
823 _multiply_source_and_add(column, val);
830 template <
class Master_matrix>
831 inline List_column<Master_matrix>& List_column<Master_matrix>::operator=(
const List_column& other)
833 static_assert(!Master_matrix::Option_list::has_row_access,
"= assignement not enabled with row access option.");
835 dim_opt::operator=(other);
836 chain_opt::operator=(other);
838 auto tmpPool = cellPool_;
839 cellPool_ = other.cellPool_;
841 while (column_.size() > other.column_.size()) {
842 if (column_.back() !=
nullptr) {
843 if constexpr (Master_matrix::Option_list::has_row_access) ra_opt::unlink(column_.back());
844 tmpPool->destroy(column_.back());
849 column_.resize(other.column_.size(),
nullptr);
850 auto it = column_.begin();
851 for (
const Cell* cell : other.column_) {
852 if (*it !=
nullptr) {
853 if constexpr (Master_matrix::Option_list::has_row_access) ra_opt::unlink(*it);
854 tmpPool->destroy(*it);
856 if constexpr (Master_matrix::Option_list::is_z2) {
857 _update_cell(cell->get_row_index(), it++);
859 _update_cell(cell->get_element(), cell->get_row_index(), it++);
863 operators_ = other.operators_;
868 template <
class Master_matrix>
869 inline void List_column<Master_matrix>::_delete_cell(
typename Column_type::iterator& it)
871 if constexpr (Master_matrix::Option_list::has_row_access) ra_opt::unlink(*it);
872 cellPool_->destroy(*it);
873 it = column_.erase(it);
876 template <
class Master_matrix>
877 inline typename List_column<Master_matrix>::Cell* List_column<Master_matrix>::_insert_cell(
878 const Field_element_type& value, id_index rowIndex,
const typename Column_type::iterator& position)
880 if constexpr (Master_matrix::Option_list::has_row_access) {
881 Cell* newCell = cellPool_->construct(ra_opt::columnIndex_, rowIndex);
882 newCell->set_element(value);
883 column_.insert(position, newCell);
884 ra_opt::insert_cell(rowIndex, newCell);
887 Cell* newCell = cellPool_->construct(rowIndex);
888 newCell->set_element(value);
889 column_.insert(position, newCell);
894 template <
class Master_matrix>
895 inline void List_column<Master_matrix>::_insert_cell(id_index rowIndex,
896 const typename Column_type::iterator& position)
898 if constexpr (Master_matrix::Option_list::has_row_access) {
899 Cell* newCell = cellPool_->construct(ra_opt::columnIndex_, rowIndex);
900 column_.insert(position, newCell);
901 ra_opt::insert_cell(rowIndex, newCell);
903 Cell* newCell = cellPool_->construct(rowIndex);
904 column_.insert(position, newCell);
908 template <
class Master_matrix>
909 inline void List_column<Master_matrix>::_update_cell(
const Field_element_type& value,
911 const typename Column_type::iterator& position)
913 if constexpr (Master_matrix::Option_list::has_row_access) {
914 *position = cellPool_->construct(ra_opt::columnIndex_, rowIndex);
915 (*position)->set_element(value);
916 ra_opt::insert_cell(rowIndex, *position);
918 *position = cellPool_->construct(rowIndex);
919 (*position)->set_element(value);
923 template <
class Master_matrix>
924 inline void List_column<Master_matrix>::_update_cell(id_index rowIndex,
925 const typename Column_type::iterator& position)
927 if constexpr (Master_matrix::Option_list::has_row_access) {
928 *position = cellPool_->construct(ra_opt::columnIndex_, rowIndex);
929 ra_opt::insert_cell(rowIndex, *position);
931 *position = cellPool_->construct(rowIndex);
935 template <
class Master_matrix>
936 template <
class Cell_range>
937 inline bool List_column<Master_matrix>::_add(
const Cell_range& column)
939 if (column.begin() == column.end())
return false;
940 if (column_.empty()) {
941 column_.resize(column.size());
942 auto it = column_.begin();
943 for (
const Cell& cell : column) {
944 if constexpr (Master_matrix::Option_list::is_z2) {
945 _update_cell(cell.get_row_index(), it++);
947 _update_cell(cell.get_element(), cell.get_row_index(), it++);
953 return _add_to_column(column, *
this);
956 template <
class Master_matrix>
957 template <
class Cell_range>
958 inline bool List_column<Master_matrix>::_multiply_target_and_add(
const Field_element_type& val,
959 const Cell_range& column)
961 return _multiply_target_and_add_to_column(val, column, *
this);
964 template <
class Master_matrix>
965 template <
class Cell_range>
966 inline bool List_column<Master_matrix>::_multiply_source_and_add(
const Cell_range& column,
967 const Field_element_type& val)
969 return _multiply_source_and_add_to_column(val, column, *
this);
983 template <
class Master_matrix>
984 struct std::hash<
Gudhi::persistence_matrix::List_column<Master_matrix> >
987 return Gudhi::persistence_matrix::hash_column(column);
Contains the New_cell_constructor and Pool_cell_constructor structures.
Column class following the PersistenceMatrixColumn concept.
Definition: list_column.h:51
Contains helper methods for column addition and column hasher.
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