18 #ifndef PM_NAIVE_VECTOR_COLUMN_H
19 #define PM_NAIVE_VECTOR_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::vector<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>;
73 template <
class Container_type =
typename Master_matrix::boundary_type>
75 Column_settings* colSettings);
76 template <
class Container_type =
typename Master_matrix::boundary_type,
class Row_container_type>
78 const Container_type& nonZeroRowIndices,
79 Row_container_type* rowContainer,
80 Column_settings* colSettings);
81 template <
class Container_type =
typename Master_matrix::boundary_type>
83 dimension_type dimension,
84 Column_settings* colSettings);
85 template <
class Container_type =
typename Master_matrix::boundary_type,
class Row_container_type>
87 const Container_type& nonZeroChainRowIndices,
88 dimension_type dimension,
89 Row_container_type* rowContainer,
90 Column_settings* colSettings);
92 Column_settings* colSettings =
nullptr);
93 template <
class Row_container_type>
96 Row_container_type* rowContainer,
97 Column_settings* colSettings =
nullptr);
101 std::vector<Field_element_type> 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 Map_type>
107 void reorder(
const Map_type& valueMap, [[maybe_unused]] index columnIndex = -1);
109 void clear(id_index rowIndex);
111 id_index get_pivot()
const;
112 Field_element_type get_pivot_value()
const;
114 iterator begin() noexcept;
115 const_iterator begin()
const noexcept;
116 iterator end() noexcept;
117 const_iterator end()
const noexcept;
118 reverse_iterator rbegin() noexcept;
119 const_reverse_iterator rbegin()
const noexcept;
120 reverse_iterator rend() noexcept;
121 const_reverse_iterator rend()
const noexcept;
123 template <
class Cell_range>
130 template <
class Cell_range>
131 Naive_vector_column& multiply_target_and_add(
const Field_element_type& val,
const Cell_range& column);
134 template <
class Cell_range>
135 Naive_vector_column& multiply_source_and_add(
const Cell_range& column,
const Field_element_type& val);
139 if (&c1 == &c2)
return true;
140 if (c1.column_.size() != c2.column_.size())
return false;
142 auto it1 = c1.column_.begin();
143 auto it2 = c2.column_.begin();
144 while (it1 != c1.column_.end() && it2 != c2.column_.end()) {
145 if constexpr (Master_matrix::Option_list::is_z2) {
146 if ((*it1)->get_row_index() != (*it2)->get_row_index())
return false;
148 if ((*it1)->get_row_index() != (*it2)->get_row_index() || (*it1)->get_element() != (*it2)->get_element())
157 if (&c1 == &c2)
return false;
159 auto it1 = c1.column_.begin();
160 auto it2 = c2.column_.begin();
161 while (it1 != c1.column_.end() && it2 != c2.column_.end()) {
162 if ((*it1)->get_row_index() != (*it2)->get_row_index())
return (*it1)->get_row_index() < (*it2)->get_row_index();
163 if constexpr (!Master_matrix::Option_list::is_z2) {
164 if ((*it1)->get_element() != (*it2)->get_element())
return (*it1)->get_element() < (*it2)->get_element();
169 return it2 != c2.column_.end();
182 col1.column_.swap(col2.column_);
183 std::swap(col1.operators_, col2.operators_);
184 std::swap(col1.cellPool_, col2.cellPool_);
193 Field_operators* operators_;
194 Cell_constructor* cellPool_;
196 template <
class Column_type,
class Cell_iterator,
typename F1,
typename F2,
typename F3,
typename F4>
197 friend void _generic_merge_cell_to_column(Column_type& targetColumn,
198 Cell_iterator& itSource,
199 typename Column_type::Column_type::iterator& itTarget,
204 bool& pivotIsZeroed);
205 template <
class Column_type,
class Cell_range,
typename F1,
typename F2,
typename F3,
typename F4,
typename F5>
206 friend bool _generic_add_to_column(
const Cell_range& source,
207 Column_type& targetColumn,
214 void _delete_cell(Cell* cell);
215 void _delete_cell(
typename Column_type::iterator& it);
216 Cell* _insert_cell(
const Field_element_type& value, id_index rowIndex, Column_type& column);
217 void _insert_cell(id_index rowIndex, Column_type& column);
218 void _update_cell(
const Field_element_type& value, id_index rowIndex, index position);
219 void _update_cell(id_index rowIndex, index position);
220 template <
class Cell_range>
221 bool _add(
const Cell_range& column);
222 template <
class Cell_range>
223 bool _multiply_target_and_add(
const Field_element_type& val,
const Cell_range& column);
224 template <
class Cell_range>
225 bool _multiply_source_and_add(
const Cell_range& column,
const Field_element_type& val);
228 template <
class Master_matrix>
234 cellPool_(colSettings == nullptr ? nullptr : &(colSettings->cellConstructor))
236 if (operators_ ==
nullptr && cellPool_ ==
nullptr)
return;
237 if constexpr (!Master_matrix::Option_list::is_z2) {
238 operators_ = &(colSettings->operators);
242 template <
class Master_matrix>
243 template <
class Container_type>
244 inline Naive_vector_column<Master_matrix>::Naive_vector_column(
245 const Container_type& nonZeroRowIndices, Column_settings* colSettings)
247 dim_opt(nonZeroRowIndices.size() == 0 ? 0 : nonZeroRowIndices.size() - 1),
249 column_(nonZeroRowIndices.size(), nullptr),
251 cellPool_(&(colSettings->cellConstructor))
253 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
254 "Constructor not available for chain columns, please specify the dimension of the chain.");
257 if constexpr (Master_matrix::Option_list::is_z2) {
258 for (id_index
id : nonZeroRowIndices) {
259 _update_cell(
id, i++);
262 operators_ = &(colSettings->operators);
263 for (
const auto& p : nonZeroRowIndices) {
264 _update_cell(operators_->get_value(p.second), p.first, i++);
269 template <
class Master_matrix>
270 template <
class Container_type,
class Row_container_type>
271 inline Naive_vector_column<Master_matrix>::Naive_vector_column(
273 const Container_type& nonZeroRowIndices,
274 Row_container_type* rowContainer,
275 Column_settings* colSettings)
276 : ra_opt(columnIndex, rowContainer),
277 dim_opt(nonZeroRowIndices.size() == 0 ? 0 : nonZeroRowIndices.size() - 1),
279 if constexpr (Master_matrix::Option_list::is_z2) {
280 return nonZeroRowIndices.begin() == nonZeroRowIndices.end() ? -1 : *std::prev(nonZeroRowIndices.end());
282 return nonZeroRowIndices.begin() == nonZeroRowIndices.end() ? -1 : std::prev(nonZeroRowIndices.end())->first;
285 column_(nonZeroRowIndices.size(),
nullptr),
287 cellPool_(&(colSettings->cellConstructor))
289 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
290 "Constructor not available for chain columns, please specify the dimension of the chain.");
293 if constexpr (Master_matrix::Option_list::is_z2) {
294 for (id_index
id : nonZeroRowIndices) {
295 _update_cell(
id, i++);
298 operators_ = &(colSettings->operators);
299 for (
const auto& p : nonZeroRowIndices) {
300 _update_cell(operators_->get_value(p.second), p.first, i++);
305 template <
class Master_matrix>
306 template <
class Container_type>
307 inline Naive_vector_column<Master_matrix>::Naive_vector_column(
308 const Container_type& nonZeroRowIndices,
309 dimension_type dimension,
310 Column_settings* colSettings)
314 if constexpr (Master_matrix::Option_list::is_z2) {
315 return nonZeroRowIndices.begin() == nonZeroRowIndices.end() ? -1 : *std::prev(nonZeroRowIndices.end());
317 return nonZeroRowIndices.begin() == nonZeroRowIndices.end() ? -1 : std::prev(nonZeroRowIndices.end())->first;
320 column_(nonZeroRowIndices.size(),
nullptr),
322 cellPool_(&(colSettings->cellConstructor))
325 if constexpr (Master_matrix::Option_list::is_z2) {
326 for (id_index
id : nonZeroRowIndices) {
327 _update_cell(
id, i++);
330 operators_ = &(colSettings->operators);
331 for (
const auto& p : nonZeroRowIndices) {
332 _update_cell(operators_->get_value(p.second), p.first, i++);
337 template <
class Master_matrix>
338 template <
class Container_type,
class Row_container_type>
339 inline Naive_vector_column<Master_matrix>::Naive_vector_column(
341 const Container_type& nonZeroRowIndices,
342 dimension_type dimension,
343 Row_container_type* rowContainer,
344 Column_settings* colSettings)
345 : ra_opt(columnIndex, rowContainer),
348 if constexpr (Master_matrix::Option_list::is_z2) {
349 return nonZeroRowIndices.begin() == nonZeroRowIndices.end() ? -1 : *std::prev(nonZeroRowIndices.end());
351 return nonZeroRowIndices.begin() == nonZeroRowIndices.end() ? -1 : std::prev(nonZeroRowIndices.end())->first;
354 column_(nonZeroRowIndices.size(),
nullptr),
356 cellPool_(&(colSettings->cellConstructor))
359 if constexpr (Master_matrix::Option_list::is_z2) {
360 for (id_index
id : nonZeroRowIndices) {
361 _update_cell(
id, i++);
364 operators_ = &(colSettings->operators);
365 for (
const auto& p : nonZeroRowIndices) {
366 _update_cell(operators_->get_value(p.second), p.first, i++);
371 template <
class Master_matrix>
372 inline Naive_vector_column<Master_matrix>::Naive_vector_column(
const Naive_vector_column& column,
373 Column_settings* colSettings)
375 dim_opt(static_cast<const dim_opt&>(column)),
376 chain_opt(static_cast<const chain_opt&>(column)),
377 column_(column.column_.size(), nullptr),
378 operators_(colSettings == nullptr ? column.operators_ : nullptr),
379 cellPool_(colSettings == nullptr ? column.cellPool_ : &(colSettings->cellConstructor))
381 static_assert(!Master_matrix::Option_list::has_row_access,
382 "Simple copy constructor not available when row access option enabled. Please specify the new column "
383 "index and the row container.");
385 if constexpr (!Master_matrix::Option_list::is_z2){
386 if (colSettings !=
nullptr) operators_ = &(colSettings->operators);
390 for (
const Cell* cell : column.column_) {
391 if constexpr (Master_matrix::Option_list::is_z2) {
392 _update_cell(cell->get_row_index(), i++);
394 _update_cell(cell->get_element(), cell->get_row_index(), i++);
399 template <
class Master_matrix>
400 template <
class Row_container_type>
401 inline Naive_vector_column<Master_matrix>::Naive_vector_column(
const Naive_vector_column& column,
403 Row_container_type* rowContainer,
404 Column_settings* colSettings)
405 : ra_opt(columnIndex, rowContainer),
406 dim_opt(static_cast<const dim_opt&>(column)),
407 chain_opt(static_cast<const chain_opt&>(column)),
408 column_(column.column_.size(), nullptr),
409 operators_(colSettings == nullptr ? column.operators_ : nullptr),
410 cellPool_(colSettings == nullptr ? column.cellPool_ : &(colSettings->cellConstructor))
412 if constexpr (!Master_matrix::Option_list::is_z2){
413 if (colSettings !=
nullptr) operators_ = &(colSettings->operators);
417 for (
const Cell* cell : column.column_) {
418 if constexpr (Master_matrix::Option_list::is_z2) {
419 _update_cell(cell->get_row_index(), i++);
421 _update_cell(cell->get_element(), cell->get_row_index(), i++);
426 template <
class Master_matrix>
427 inline Naive_vector_column<Master_matrix>::Naive_vector_column(Naive_vector_column&& column) noexcept
428 : ra_opt(std::move(
static_cast<ra_opt&
>(column))),
429 dim_opt(std::move(
static_cast<dim_opt&
>(column))),
430 chain_opt(std::move(
static_cast<chain_opt&
>(column))),
431 column_(std::move(column.column_)),
432 operators_(std::exchange(column.operators_,
nullptr)),
433 cellPool_(std::exchange(column.cellPool_,
nullptr))
436 template <
class Master_matrix>
437 inline Naive_vector_column<Master_matrix>::~Naive_vector_column()
439 for (
auto* cell : column_) {
444 template <
class Master_matrix>
445 inline std::vector<typename Naive_vector_column<Master_matrix>::Field_element_type>
446 Naive_vector_column<Master_matrix>::get_content(
int columnLength)
const
448 if (columnLength < 0 && column_.size() > 0)
449 columnLength = column_.back()->get_row_index() + 1;
450 else if (columnLength < 0)
451 return std::vector<Field_element_type>();
453 std::vector<Field_element_type> container(columnLength, 0);
454 for (
auto it = column_.begin(); it != column_.end() && (*it)->get_row_index() <
static_cast<id_index
>(columnLength);
456 if constexpr (Master_matrix::Option_list::is_z2) {
457 container[(*it)->get_row_index()] = 1;
459 container[(*it)->get_row_index()] = (*it)->get_element();
465 template <
class Master_matrix>
466 inline bool Naive_vector_column<Master_matrix>::is_non_zero(id_index rowIndex)
const
469 return std::binary_search(column_.begin(), column_.end(), &cell,
470 [](
const Cell* a,
const Cell* b) { return a->get_row_index() < b->get_row_index(); });
473 template <
class Master_matrix>
474 inline bool Naive_vector_column<Master_matrix>::is_empty()
const
476 return column_.empty();
479 template <
class Master_matrix>
480 inline std::size_t Naive_vector_column<Master_matrix>::size()
const
482 return column_.size();
485 template <
class Master_matrix>
486 template <
class Map_type>
487 inline void Naive_vector_column<Master_matrix>::reorder(
const Map_type& valueMap,
488 [[maybe_unused]] index columnIndex)
490 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
491 "Method not available for chain columns.");
493 for (Cell* cell : column_) {
494 if constexpr (Master_matrix::Option_list::has_row_access) {
495 ra_opt::unlink(cell);
496 if (columnIndex !=
static_cast<index
>(-1)) cell->set_column_index(columnIndex);
498 cell->set_row_index(valueMap.at(cell->get_row_index()));
499 if constexpr (Master_matrix::Option_list::has_intrusive_rows && Master_matrix::Option_list::has_row_access)
500 ra_opt::insert_cell(cell->get_row_index(), cell);
504 if constexpr (!Master_matrix::Option_list::has_intrusive_rows && Master_matrix::Option_list::has_row_access) {
505 for (Cell* cell : column_) {
506 ra_opt::insert_cell(cell->get_row_index(), cell);
510 std::sort(column_.begin(), column_.end(), [](
const Cell* c1,
const Cell* c2) { return *c1 < *c2; });
513 template <
class Master_matrix>
514 inline void Naive_vector_column<Master_matrix>::clear()
516 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
517 "Method not available for chain columns as a base element should not be empty.");
519 for (
auto* cell : column_) {
520 if constexpr (Master_matrix::Option_list::has_row_access) ra_opt::unlink(cell);
521 cellPool_->destroy(cell);
527 template <
class Master_matrix>
528 inline void Naive_vector_column<Master_matrix>::clear(id_index rowIndex)
530 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
531 "Method not available for chain columns.");
533 auto it = column_.begin();
534 while (it != column_.end() && (*it)->get_row_index() != rowIndex) ++it;
535 if (it != column_.end()) {
541 template <
class Master_matrix>
542 inline typename Naive_vector_column<Master_matrix>::id_index
543 Naive_vector_column<Master_matrix>::get_pivot()
const
545 static_assert(Master_matrix::isNonBasic,
546 "Method not available for base columns.");
548 if constexpr (Master_matrix::Option_list::is_of_boundary_type) {
549 return column_.empty() ? -1 : column_.back()->get_row_index();
551 return chain_opt::get_pivot();
555 template <
class Master_matrix>
556 inline typename Naive_vector_column<Master_matrix>::Field_element_type
557 Naive_vector_column<Master_matrix>::get_pivot_value()
const
559 static_assert(Master_matrix::isNonBasic,
560 "Method not available for base columns.");
562 if constexpr (Master_matrix::Option_list::is_z2) {
565 if constexpr (Master_matrix::Option_list::is_of_boundary_type) {
566 return column_.empty() ? Field_element_type() : column_.back()->get_element();
568 if (chain_opt::get_pivot() ==
static_cast<id_index
>(-1))
return Field_element_type();
569 for (
const Cell* cell : column_) {
570 if (cell->get_row_index() == chain_opt::get_pivot())
return cell->get_element();
572 return Field_element_type();
577 template <
class Master_matrix>
578 inline typename Naive_vector_column<Master_matrix>::iterator
579 Naive_vector_column<Master_matrix>::begin() noexcept
581 return column_.begin();
584 template <
class Master_matrix>
585 inline typename Naive_vector_column<Master_matrix>::const_iterator
586 Naive_vector_column<Master_matrix>::begin() const noexcept
588 return column_.begin();
591 template <
class Master_matrix>
592 inline typename Naive_vector_column<Master_matrix>::iterator
593 Naive_vector_column<Master_matrix>::end() noexcept
595 return column_.end();
598 template <
class Master_matrix>
599 inline typename Naive_vector_column<Master_matrix>::const_iterator
600 Naive_vector_column<Master_matrix>::end() const noexcept
602 return column_.end();
605 template <
class Master_matrix>
606 inline typename Naive_vector_column<Master_matrix>::reverse_iterator
607 Naive_vector_column<Master_matrix>::rbegin() noexcept
609 return column_.rbegin();
612 template <
class Master_matrix>
613 inline typename Naive_vector_column<Master_matrix>::const_reverse_iterator
614 Naive_vector_column<Master_matrix>::rbegin() const noexcept
616 return column_.rbegin();
619 template <
class Master_matrix>
620 inline typename Naive_vector_column<Master_matrix>::reverse_iterator
621 Naive_vector_column<Master_matrix>::rend() noexcept
623 return column_.rend();
626 template <
class Master_matrix>
627 inline typename Naive_vector_column<Master_matrix>::const_reverse_iterator
628 Naive_vector_column<Master_matrix>::rend() const noexcept
630 return column_.rend();
633 template <
class Master_matrix>
634 template <
class Cell_range>
635 inline Naive_vector_column<Master_matrix>&
636 Naive_vector_column<Master_matrix>::operator+=(
const Cell_range& column)
638 static_assert((!Master_matrix::isNonBasic || std::is_same_v<Cell_range, Naive_vector_column>),
639 "For boundary columns, the range has to be a column of same type to help ensure the validity of the "
641 static_assert((!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type),
642 "For chain columns, the given column cannot be constant.");
649 template <
class Master_matrix>
650 inline Naive_vector_column<Master_matrix>&
651 Naive_vector_column<Master_matrix>::operator+=(Naive_vector_column& column)
653 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
656 chain_opt::swap_pivots(column);
657 dim_opt::swap_dimension(column);
666 template <
class Master_matrix>
667 inline Naive_vector_column<Master_matrix>&
668 Naive_vector_column<Master_matrix>::operator*=(
unsigned int v)
670 if constexpr (Master_matrix::Option_list::is_z2) {
672 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
673 throw std::invalid_argument(
"A chain column should not be multiplied by 0.");
679 Field_element_type val = operators_->get_value(v);
681 if (val == Field_operators::get_additive_identity()) {
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.");
690 if (val == Field_operators::get_multiplicative_identity())
return *
this;
692 for (Cell* cell : column_) {
693 operators_->multiply_inplace(cell->get_element(), val);
694 if constexpr (Master_matrix::Option_list::has_row_access) ra_opt::update_cell(*cell);
701 template <
class Master_matrix>
702 template <
class Cell_range>
703 inline Naive_vector_column<Master_matrix>&
704 Naive_vector_column<Master_matrix>::multiply_target_and_add(
const Field_element_type& val,
705 const Cell_range& column)
707 static_assert((!Master_matrix::isNonBasic || std::is_same_v<Cell_range, Naive_vector_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);
727 template <
class Master_matrix>
728 inline Naive_vector_column<Master_matrix>&
729 Naive_vector_column<Master_matrix>::multiply_target_and_add(
const Field_element_type& val,
730 Naive_vector_column& column)
732 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
734 if constexpr (Master_matrix::Option_list::is_z2) {
737 chain_opt::swap_pivots(column);
738 dim_opt::swap_dimension(column);
741 throw std::invalid_argument(
"A chain column should not be multiplied by 0.");
744 if (_multiply_target_and_add(val, column)) {
745 chain_opt::swap_pivots(column);
746 dim_opt::swap_dimension(column);
750 if constexpr (Master_matrix::Option_list::is_z2) {
758 _multiply_target_and_add(val, column);
765 template <
class Master_matrix>
766 template <
class Cell_range>
767 inline Naive_vector_column<Master_matrix>&
768 Naive_vector_column<Master_matrix>::multiply_source_and_add(
const Cell_range& column,
769 const Field_element_type& val)
771 static_assert((!Master_matrix::isNonBasic || std::is_same_v<Cell_range, Naive_vector_column>),
772 "For boundary columns, the range has to be a column of same type to help ensure the validity of the "
774 static_assert((!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type),
775 "For chain columns, the given column cannot be constant.");
777 if constexpr (Master_matrix::Option_list::is_z2) {
782 _multiply_source_and_add(column, val);
788 template <
class Master_matrix>
789 inline Naive_vector_column<Master_matrix>&
790 Naive_vector_column<Master_matrix>::multiply_source_and_add(Naive_vector_column& column,
791 const Field_element_type& val)
793 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
795 if constexpr (Master_matrix::Option_list::is_z2) {
798 chain_opt::swap_pivots(column);
799 dim_opt::swap_dimension(column);
803 if (_multiply_source_and_add(column, val)) {
804 chain_opt::swap_pivots(column);
805 dim_opt::swap_dimension(column);
809 if constexpr (Master_matrix::Option_list::is_z2) {
814 _multiply_source_and_add(column, val);
821 template <
class Master_matrix>
822 inline Naive_vector_column<Master_matrix>&
823 Naive_vector_column<Master_matrix>::operator=(
const Naive_vector_column& other)
825 static_assert(!Master_matrix::Option_list::has_row_access,
"= assignement not enabled with row access option.");
827 dim_opt::operator=(other);
828 chain_opt::operator=(other);
830 auto tmpPool = cellPool_;
831 cellPool_ = other.cellPool_;
833 while (column_.size() > other.column_.size()) {
834 if (column_.back() ==
nullptr) {
835 if constexpr (Master_matrix::Option_list::has_row_access) ra_opt::unlink(column_.back());
836 tmpPool->destroy(column_.back());
841 column_.resize(other.column_.size(),
nullptr);
843 for (
const Cell* cell : other.column_) {
844 if (column_[i] !=
nullptr) {
845 if constexpr (Master_matrix::Option_list::has_row_access) ra_opt::unlink(column_[i]);
846 tmpPool->destroy(column_[i]);
848 if constexpr (Master_matrix::Option_list::is_z2) {
849 _update_cell(cell->get_row_index(), i++);
851 _update_cell(cell->get_element(), cell->get_row_index(), i++);
855 operators_ = other.operators_;
860 template <
class Master_matrix>
861 inline void Naive_vector_column<Master_matrix>::_delete_cell(Cell* cell)
863 if constexpr (Master_matrix::Option_list::has_row_access) ra_opt::unlink(cell);
864 cellPool_->destroy(cell);
867 template <
class Master_matrix>
868 inline void Naive_vector_column<Master_matrix>::_delete_cell(
typename Column_type::iterator& it)
874 template <
class Master_matrix>
875 inline typename Naive_vector_column<Master_matrix>::Cell* Naive_vector_column<Master_matrix>::_insert_cell(
876 const Field_element_type& value, id_index rowIndex, Column_type& column)
878 if constexpr (Master_matrix::Option_list::has_row_access) {
879 Cell* newCell = cellPool_->construct(ra_opt::columnIndex_, rowIndex);
880 newCell->set_element(value);
881 column.push_back(newCell);
882 ra_opt::insert_cell(rowIndex, newCell);
885 Cell* newCell = cellPool_->construct(rowIndex);
886 column.push_back(newCell);
887 newCell->set_element(value);
892 template <
class Master_matrix>
893 inline void Naive_vector_column<Master_matrix>::_insert_cell(id_index rowIndex, Column_type& column)
895 if constexpr (Master_matrix::Option_list::has_row_access) {
896 Cell* newCell = cellPool_->construct(ra_opt::columnIndex_, rowIndex);
897 column.push_back(newCell);
898 ra_opt::insert_cell(rowIndex, newCell);
900 column.push_back(cellPool_->construct(rowIndex));
904 template <
class Master_matrix>
905 inline void Naive_vector_column<Master_matrix>::_update_cell(
const Field_element_type& value,
909 if constexpr (Master_matrix::Option_list::has_row_access) {
910 Cell* newCell = cellPool_->construct(ra_opt::columnIndex_, rowIndex);
911 newCell->set_element(value);
912 column_[position] = newCell;
913 ra_opt::insert_cell(rowIndex, newCell);
915 column_[position] = cellPool_->construct(rowIndex);
916 column_[position]->set_element(value);
920 template <
class Master_matrix>
921 inline void Naive_vector_column<Master_matrix>::_update_cell(id_index rowIndex, index position)
923 if constexpr (Master_matrix::Option_list::has_row_access) {
924 Cell* newCell = cellPool_->construct(ra_opt::columnIndex_, rowIndex);
925 column_[position] = newCell;
926 ra_opt::insert_cell(rowIndex, newCell);
928 column_[position] = cellPool_->construct(rowIndex);
932 template <
class Master_matrix>
933 template <
class Cell_range>
934 inline bool Naive_vector_column<Master_matrix>::_add(
const Cell_range& column)
936 if (column.begin() == column.end())
return false;
937 if (column_.empty()) {
938 column_.resize(column.size());
940 for (
const Cell& cell : column) {
941 if constexpr (Master_matrix::Option_list::is_z2) {
942 _update_cell(cell.get_row_index(), i++);
944 _update_cell(cell.get_element(), cell.get_row_index(), i++);
950 Column_type newColumn;
951 newColumn.reserve(column_.size() + column.size());
953 auto pivotIsZeroed = _generic_add_to_column(
956 [&](Cell* cellTarget) { newColumn.push_back(cellTarget); },
957 [&](
typename Cell_range::const_iterator& itSource,
958 [[maybe_unused]]
const typename Column_type::iterator& itTarget) {
959 if constexpr (Master_matrix::Option_list::is_z2) {
960 _insert_cell(itSource->get_row_index(), newColumn);
962 _insert_cell(itSource->get_element(), itSource->get_row_index(), newColumn);
965 [&](Field_element_type& targetElement,
typename Cell_range::const_iterator& itSource) {
966 if constexpr (!Master_matrix::Option_list::is_z2)
967 operators_->add_inplace(targetElement, itSource->get_element());
969 [&](Cell* cellTarget) { newColumn.push_back(cellTarget); },
970 [&](
typename Column_type::iterator& itTarget) {
971 while (itTarget != column_.end()) {
972 newColumn.push_back(*itTarget);
977 column_.swap(newColumn);
979 return pivotIsZeroed;
982 template <
class Master_matrix>
983 template <
class Cell_range>
984 inline bool Naive_vector_column<Master_matrix>::_multiply_target_and_add(
const Field_element_type& val,
985 const Cell_range& column)
988 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
989 throw std::invalid_argument(
"A chain column should not be multiplied by 0.");
995 if (column_.empty()) {
996 column_.resize(column.size());
998 for (
const Cell& cell : column) {
999 if constexpr (Master_matrix::Option_list::is_z2) {
1000 _update_cell(cell.get_row_index(), i++);
1002 _update_cell(cell.get_element(), cell.get_row_index(), i++);
1008 Column_type newColumn;
1009 newColumn.reserve(column_.size() + column.size());
1011 auto pivotIsZeroed = _generic_add_to_column(
1014 [&](Cell* cellTarget) {
1015 operators_->multiply_inplace(cellTarget->get_element(), val);
1016 if constexpr (Master_matrix::Option_list::has_row_access) ra_opt::update_cell(*cellTarget);
1017 newColumn.push_back(cellTarget);
1019 [&](
typename Cell_range::const_iterator& itSource,
const typename Column_type::iterator& itTarget) {
1020 _insert_cell(itSource->get_element(), itSource->get_row_index(), newColumn);
1022 [&](Field_element_type& targetElement,
typename Cell_range::const_iterator& itSource) {
1023 operators_->multiply_and_add_inplace_front(targetElement, val, itSource->get_element());
1025 [&](Cell* cellTarget) { newColumn.push_back(cellTarget); },
1026 [&](
typename Column_type::iterator& itTarget) {
1027 while (itTarget != column_.end()) {
1028 operators_->multiply_inplace((*itTarget)->get_element(), val);
1029 if constexpr (Master_matrix::Option_list::has_row_access) ra_opt::update_cell(**itTarget);
1030 newColumn.push_back(*itTarget);
1035 column_.swap(newColumn);
1037 return pivotIsZeroed;
1040 template <
class Master_matrix>
1041 template <
class Cell_range>
1042 inline bool Naive_vector_column<Master_matrix>::_multiply_source_and_add(
const Cell_range& column,
1043 const Field_element_type& val)
1045 if (val == 0u || column.begin() == column.end()) {
1049 Column_type newColumn;
1050 newColumn.reserve(column_.size() + column.size());
1052 auto pivotIsZeroed = _generic_add_to_column(
1054 [&](Cell* cellTarget) { newColumn.push_back(cellTarget); },
1055 [&](
typename Cell_range::const_iterator& itSource,
const typename Column_type::iterator& itTarget) {
1056 Cell* newCell = _insert_cell(itSource->get_element(), itSource->get_row_index(), newColumn);
1057 operators_->multiply_inplace(newCell->get_element(), val);
1058 if constexpr (Master_matrix::Option_list::has_row_access) ra_opt::update_cell(*newCell);
1060 [&](Field_element_type& targetElement,
typename Cell_range::const_iterator& itSource) {
1061 operators_->multiply_and_add_inplace_back(itSource->get_element(), val, targetElement);
1063 [&](Cell* cellTarget) { newColumn.push_back(cellTarget); },
1064 [&](
typename Column_type::iterator& itTarget) {
1065 while (itTarget != column_.end()) {
1066 newColumn.push_back(*itTarget);
1071 column_.swap(newColumn);
1073 return pivotIsZeroed;
1087 template <
class Master_matrix>
1088 struct std::hash<
Gudhi::persistence_matrix::Naive_vector_column<Master_matrix> >
1091 return Gudhi::persistence_matrix::hash_column(column);
Contains the New_cell_constructor and Pool_cell_constructor structures.
Column class following the PersistenceMatrixColumn concept.
Definition: naive_vector_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