18 #ifndef PM_INTRUSIVE_SET_COLUMN_H
19 #define PM_INTRUSIVE_SET_COLUMN_H
23 #include <type_traits>
26 #include <boost/intrusive/set.hpp>
28 #include <gudhi/Debug_utils.h>
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;
64 boost::intrusive::set<Cell,
65 boost::intrusive::constant_time_size<false>,
66 boost::intrusive::base_hook<typename Master_matrix::base_hook_matrix_set_column> >;
67 using Cell_constructor =
typename Master_matrix::Cell_constructor;
70 using iterator =
typename Column_type::iterator;
71 using const_iterator =
typename Column_type::const_iterator;
72 using reverse_iterator =
typename Column_type::reverse_iterator;
73 using const_reverse_iterator =
typename Column_type::const_reverse_iterator;
76 template <
class Container_type =
typename Master_matrix::boundary_type>
78 Column_settings* colSettings);
79 template <
class Container_type =
typename Master_matrix::boundary_type,
class Row_container_type>
81 const Container_type& nonZeroRowIndices,
82 Row_container_type* rowContainer,
83 Column_settings* colSettings);
84 template <
class Container_type =
typename Master_matrix::boundary_type>
86 dimension_type dimension,
87 Column_settings* colSettings);
88 template <
class Container_type =
typename Master_matrix::boundary_type,
class Row_container_type>
90 const Container_type& nonZeroChainRowIndices,
91 dimension_type dimension,
92 Row_container_type* rowContainer,
93 Column_settings* colSettings);
95 Column_settings* colSettings =
nullptr);
96 template <
class Row_container_type>
99 Row_container_type* rowContainer,
100 Column_settings* colSettings =
nullptr);
104 std::vector<Field_element_type> get_content(
int columnLength = -1)
const;
105 bool is_non_zero(id_index rowIndex)
const;
106 bool is_empty()
const;
107 std::size_t size()
const;
109 template <
class Map_type>
110 void reorder(
const Map_type& valueMap, [[maybe_unused]] index columnIndex = -1);
112 void clear(id_index rowIndex);
114 id_index get_pivot()
const;
115 Field_element_type get_pivot_value()
const;
117 iterator begin() noexcept;
118 const_iterator begin()
const noexcept;
119 iterator end() noexcept;
120 const_iterator end()
const noexcept;
121 reverse_iterator rbegin() noexcept;
122 const_reverse_iterator rbegin()
const noexcept;
123 reverse_iterator rend() noexcept;
124 const_reverse_iterator rend()
const noexcept;
126 template <
class Cell_range>
133 template <
class Cell_range>
134 Intrusive_set_column& multiply_target_and_add(
const Field_element_type& val,
const Cell_range& column);
137 template <
class Cell_range>
138 Intrusive_set_column& multiply_source_and_add(
const Cell_range& column,
const Field_element_type& val);
142 if (&c1 == &c2)
return true;
144 if constexpr (Master_matrix::Option_list::is_z2) {
145 return c1.column_ == c2.column_;
147 auto it1 = c1.column_.begin();
148 auto it2 = c2.column_.begin();
149 if (c1.column_.size() != c2.column_.size())
return false;
150 while (it1 != c1.column_.end() && it2 != c2.column_.end()) {
151 if (it1->get_row_index() != it2->get_row_index() || it1->get_element() != it2->get_element())
return false;
159 if (&c1 == &c2)
return false;
161 if constexpr (Master_matrix::Option_list::is_z2) {
162 return c1.column_ < c2.column_;
164 auto it1 = c1.column_.begin();
165 auto it2 = c2.column_.begin();
166 while (it1 != c1.column_.end() && it2 != c2.column_.end()) {
167 if (it1->get_row_index() != it2->get_row_index())
return it1->get_row_index() < it2->get_row_index();
168 if (it1->get_element() != it2->get_element())
return it1->get_element() < it2->get_element();
172 return it2 != c2.column_.end();
186 col1.column_.swap(col2.column_);
187 std::swap(col1.operators_, col2.operators_);
188 std::swap(col1.cellPool_, col2.cellPool_);
198 new_cloner(Cell_constructor* cellPool) : cellPool_(cellPool){};
200 Cell* operator()(
const Cell& clone_this) {
return cellPool_->construct(clone_this); }
202 Cell_constructor* cellPool_;
206 struct delete_disposer {
210 void operator()(Cell* delete_this) {
211 if constexpr (Master_matrix::Option_list::has_row_access) col_->unlink(delete_this);
212 col_->cellPool_->destroy(delete_this);
219 Field_operators* operators_;
220 Cell_constructor* cellPool_;
222 template <
class Column_type,
class Cell_iterator,
typename F1,
typename F2,
typename F3,
typename F4>
223 friend void _generic_merge_cell_to_column(Column_type& targetColumn,
224 Cell_iterator& itSource,
225 typename Column_type::Column_type::iterator& itTarget,
230 bool& pivotIsZeroed);
231 template <
class Column_type,
class Cell_range,
typename F1,
typename F2,
typename F3,
typename F4,
typename F5>
232 friend bool _generic_add_to_column(
const Cell_range& source,
233 Column_type& targetColumn,
239 template <
class Column_type,
class Cell_range>
240 friend bool _add_to_column(
const Cell_range& source, Column_type& targetColumn);
241 template <
class Column_type,
class Cell_range>
242 friend bool _multiply_target_and_add_to_column(
const typename Column_type::Field_element_type& val,
243 const Cell_range& source,
244 Column_type& targetColumn);
245 template <
class Column_type,
class Cell_range>
246 friend bool _multiply_source_and_add_to_column(
const typename Column_type::Field_element_type& val,
247 const Cell_range& source,
248 Column_type& targetColumn);
250 void _delete_cell(iterator& it);
251 Cell* _insert_cell(
const Field_element_type& value, id_index rowIndex,
const iterator& position);
252 void _insert_cell(id_index rowIndex,
const iterator& position);
253 template <
class Cell_range>
254 bool _add(
const Cell_range& column);
255 template <
class Cell_range>
256 bool _multiply_target_and_add(
const Field_element_type& val,
const Cell_range& column);
257 template <
class Cell_range>
258 bool _multiply_source_and_add(
const Cell_range& column,
const Field_element_type& val);
261 template <
class Master_matrix>
267 cellPool_(colSettings == nullptr ? nullptr : &(colSettings->cellConstructor))
269 if (operators_ ==
nullptr && cellPool_ ==
nullptr)
return;
270 if constexpr (!Master_matrix::Option_list::is_z2) {
271 operators_ = &(colSettings->operators);
275 template <
class Master_matrix>
276 template <
class Container_type>
277 inline Intrusive_set_column<Master_matrix>::Intrusive_set_column(
278 const Container_type& nonZeroRowIndices, Column_settings* colSettings)
280 dim_opt(nonZeroRowIndices.size() == 0 ? 0 : nonZeroRowIndices.size() - 1),
283 cellPool_(&(colSettings->cellConstructor))
285 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
286 "Constructor not available for chain columns, please specify the dimension of the chain.");
288 if constexpr (Master_matrix::Option_list::is_z2) {
289 for (id_index
id : nonZeroRowIndices) {
290 _insert_cell(
id, column_.end());
293 operators_ = &(colSettings->operators);
294 for (
const auto& p : nonZeroRowIndices) {
295 _insert_cell(operators_->get_value(p.second), p.first, column_.end());
300 template <
class Master_matrix>
301 template <
class Container_type,
class Row_container_type>
302 inline Intrusive_set_column<Master_matrix>::Intrusive_set_column(
304 const Container_type& nonZeroRowIndices,
305 Row_container_type* rowContainer,
306 Column_settings* colSettings)
307 : ra_opt(columnIndex, rowContainer),
308 dim_opt(nonZeroRowIndices.size() == 0 ? 0 : nonZeroRowIndices.size() - 1),
310 if constexpr (Master_matrix::Option_list::is_z2) {
311 return nonZeroRowIndices.begin() == nonZeroRowIndices.end() ? -1 : *std::prev(nonZeroRowIndices.end());
313 return nonZeroRowIndices.begin() == nonZeroRowIndices.end() ? -1 : std::prev(nonZeroRowIndices.end())->first;
317 cellPool_(&(colSettings->cellConstructor))
319 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
320 "Constructor not available for chain columns, please specify the dimension of the chain.");
322 if constexpr (Master_matrix::Option_list::is_z2) {
323 for (id_index
id : nonZeroRowIndices) {
324 _insert_cell(
id, column_.end());
327 operators_ = &(colSettings->operators);
328 for (
const auto& p : nonZeroRowIndices) {
329 _insert_cell(operators_->get_value(p.second), p.first, column_.end());
334 template <
class Master_matrix>
335 template <
class Container_type>
336 inline Intrusive_set_column<Master_matrix>::Intrusive_set_column(
337 const Container_type& nonZeroRowIndices,
338 dimension_type dimension,
339 Column_settings* colSettings)
343 if constexpr (Master_matrix::Option_list::is_z2) {
344 return nonZeroRowIndices.begin() == nonZeroRowIndices.end() ? -1 : *std::prev(nonZeroRowIndices.end());
346 return nonZeroRowIndices.begin() == nonZeroRowIndices.end() ? -1 : std::prev(nonZeroRowIndices.end())->first;
350 cellPool_(&(colSettings->cellConstructor))
352 if constexpr (Master_matrix::Option_list::is_z2) {
353 for (id_index
id : nonZeroRowIndices) {
354 _insert_cell(
id, column_.end());
357 operators_ = &(colSettings->operators);
358 for (
const auto& p : nonZeroRowIndices) {
359 _insert_cell(operators_->get_value(p.second), p.first, column_.end());
364 template <
class Master_matrix>
365 template <
class Container_type,
class Row_container_type>
366 inline Intrusive_set_column<Master_matrix>::Intrusive_set_column(
368 const Container_type& nonZeroRowIndices,
369 dimension_type dimension,
370 Row_container_type* rowContainer,
371 Column_settings* colSettings)
372 : ra_opt(columnIndex, rowContainer),
375 if constexpr (Master_matrix::Option_list::is_z2) {
376 return nonZeroRowIndices.begin() == nonZeroRowIndices.end() ? -1 : *std::prev(nonZeroRowIndices.end());
378 return nonZeroRowIndices.begin() == nonZeroRowIndices.end() ? -1 : std::prev(nonZeroRowIndices.end())->first;
382 cellPool_(&(colSettings->cellConstructor))
384 if constexpr (Master_matrix::Option_list::is_z2) {
385 for (id_index
id : nonZeroRowIndices) {
386 _insert_cell(
id, column_.end());
389 operators_ = &(colSettings->operators);
390 for (
const auto& p : nonZeroRowIndices) {
391 _insert_cell(operators_->get_value(p.second), p.first, column_.end());
396 template <
class Master_matrix>
397 inline Intrusive_set_column<Master_matrix>::Intrusive_set_column(
const Intrusive_set_column& column,
398 Column_settings* colSettings)
400 dim_opt(static_cast<const dim_opt&>(column)),
401 chain_opt(static_cast<const chain_opt&>(column)),
402 operators_(colSettings == nullptr ? column.operators_ : nullptr),
403 cellPool_(colSettings == nullptr ? column.cellPool_ : &(colSettings->cellConstructor))
405 static_assert(!Master_matrix::Option_list::has_row_access,
406 "Simple copy constructor not available when row access option enabled. Please specify the new column "
407 "index and the row container.");
409 if constexpr (!Master_matrix::Option_list::is_z2){
410 if (colSettings !=
nullptr) operators_ = &(colSettings->operators);
413 column_.clone_from(column.column_, new_cloner(cellPool_), delete_disposer(
this));
416 template <
class Master_matrix>
417 template <
class Row_container_type>
418 inline Intrusive_set_column<Master_matrix>::Intrusive_set_column(
const Intrusive_set_column& column,
420 Row_container_type* rowContainer,
421 Column_settings* colSettings)
422 : ra_opt(columnIndex, rowContainer),
423 dim_opt(static_cast<const dim_opt&>(column)),
424 chain_opt(static_cast<const chain_opt&>(column)),
425 operators_(colSettings == nullptr ? column.operators_ : nullptr),
426 cellPool_(colSettings == nullptr ? column.cellPool_ : &(colSettings->cellConstructor))
428 if constexpr (!Master_matrix::Option_list::is_z2){
429 if (colSettings !=
nullptr) operators_ = &(colSettings->operators);
432 for (
const Cell& cell : column.column_) {
433 if constexpr (Master_matrix::Option_list::is_z2) {
434 _insert_cell(cell.get_row_index(), column_.end());
436 _insert_cell(cell.get_element(), cell.get_row_index(), column_.end());
441 template <
class Master_matrix>
442 inline Intrusive_set_column<Master_matrix>::Intrusive_set_column(
443 Intrusive_set_column&& column) noexcept
444 : ra_opt(std::move(
static_cast<ra_opt&
>(column))),
445 dim_opt(std::move(
static_cast<dim_opt&
>(column))),
446 chain_opt(std::move(
static_cast<chain_opt&
>(column))),
447 column_(std::move(column.column_)),
448 operators_(std::exchange(column.operators_,
nullptr)),
449 cellPool_(std::exchange(column.cellPool_,
nullptr))
452 template <
class Master_matrix>
453 inline Intrusive_set_column<Master_matrix>::~Intrusive_set_column()
455 column_.clear_and_dispose(delete_disposer(
this));
458 template <
class Master_matrix>
459 inline std::vector<typename Intrusive_set_column<Master_matrix>::Field_element_type>
460 Intrusive_set_column<Master_matrix>::get_content(
int columnLength)
const
462 if (columnLength < 0 && column_.size() > 0)
463 columnLength = column_.rbegin()->get_row_index() + 1;
464 else if (columnLength < 0)
465 return std::vector<Field_element_type>();
467 std::vector<Field_element_type> container(columnLength);
468 for (
auto it = column_.begin(); it != column_.end() && it->get_row_index() <
static_cast<id_index
>(columnLength);
470 if constexpr (Master_matrix::Option_list::is_z2) {
471 container[it->get_row_index()] = 1;
473 container[it->get_row_index()] = it->get_element();
479 template <
class Master_matrix>
480 inline bool Intrusive_set_column<Master_matrix>::is_non_zero(id_index rowIndex)
const
482 return column_.find(Cell(rowIndex)) != column_.end();
485 template <
class Master_matrix>
486 inline bool Intrusive_set_column<Master_matrix>::is_empty()
const
488 return column_.empty();
491 template <
class Master_matrix>
492 inline std::size_t Intrusive_set_column<Master_matrix>::size()
const
494 return column_.size();
497 template <
class Master_matrix>
498 template <
class Map_type>
499 inline void Intrusive_set_column<Master_matrix>::reorder(
const Map_type& valueMap,
500 [[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.");
507 if constexpr (Master_matrix::Option_list::has_row_access) {
508 for (
auto it = column_.begin(); it != column_.end();) {
509 Cell* newCell = cellPool_->construct(columnIndex ==
static_cast<index
>(-1) ?
510 ra_opt::columnIndex_ : columnIndex,
511 valueMap.at(it->get_row_index()));
512 if constexpr (!Master_matrix::Option_list::is_z2) {
513 newCell->set_element(it->get_element());
515 newSet.insert(newSet.end(), *newCell);
517 if constexpr (Master_matrix::Option_list::has_intrusive_rows)
518 ra_opt::insert_cell(newCell->get_row_index(), newCell);
522 if constexpr (!Master_matrix::Option_list::has_intrusive_rows) {
523 for (Cell& cell : newSet) {
524 ra_opt::insert_cell(cell.get_row_index(), &cell);
528 for (
auto it = column_.begin(); it != column_.end();) {
529 Cell* newCell = cellPool_->construct(valueMap.at(it->get_row_index()));
530 if constexpr (!Master_matrix::Option_list::is_z2) {
531 newCell->set_element(it->get_element());
533 newSet.insert(newSet.end(), *newCell);
538 column_.swap(newSet);
541 template <
class Master_matrix>
542 inline void Intrusive_set_column<Master_matrix>::clear()
544 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
545 "Method not available for chain columns as a base element should not be empty.");
547 column_.clear_and_dispose(delete_disposer(
this));
550 template <
class Master_matrix>
551 inline void Intrusive_set_column<Master_matrix>::clear(id_index rowIndex)
553 static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
554 "Method not available for chain columns.");
556 auto it = column_.find(Cell(rowIndex));
557 if (it != column_.end()) {
562 template <
class Master_matrix>
563 inline typename Intrusive_set_column<Master_matrix>::id_index
564 Intrusive_set_column<Master_matrix>::get_pivot()
const
566 static_assert(Master_matrix::isNonBasic,
567 "Method not available for base columns.");
569 if constexpr (Master_matrix::Option_list::is_of_boundary_type) {
570 if (column_.empty())
return -1;
571 return column_.rbegin()->get_row_index();
573 return chain_opt::get_pivot();
577 template <
class Master_matrix>
578 inline typename Intrusive_set_column<Master_matrix>::Field_element_type
579 Intrusive_set_column<Master_matrix>::get_pivot_value()
const
581 static_assert(Master_matrix::isNonBasic,
582 "Method not available for base columns.");
584 if constexpr (Master_matrix::Option_list::is_z2) {
587 if constexpr (Master_matrix::Option_list::is_of_boundary_type) {
588 if (column_.empty())
return 0;
589 return column_.rbegin()->get_element();
591 if (chain_opt::get_pivot() ==
static_cast<id_index
>(-1))
return 0;
592 auto it = column_.find(Cell(chain_opt::get_pivot()));
593 GUDHI_CHECK(it != column_.end(),
594 "Intrusive_set_column::get_pivot_value - Pivot not found only if the column was misused.");
595 return it->get_element();
600 template <
class Master_matrix>
601 inline typename Intrusive_set_column<Master_matrix>::iterator
602 Intrusive_set_column<Master_matrix>::begin() noexcept
604 return column_.begin();
607 template <
class Master_matrix>
608 inline typename Intrusive_set_column<Master_matrix>::const_iterator
609 Intrusive_set_column<Master_matrix>::begin() const noexcept
611 return column_.begin();
614 template <
class Master_matrix>
615 inline typename Intrusive_set_column<Master_matrix>::iterator
616 Intrusive_set_column<Master_matrix>::end() noexcept
618 return column_.end();
621 template <
class Master_matrix>
622 inline typename Intrusive_set_column<Master_matrix>::const_iterator
623 Intrusive_set_column<Master_matrix>::end() const noexcept
625 return column_.end();
628 template <
class Master_matrix>
629 inline typename Intrusive_set_column<Master_matrix>::reverse_iterator
630 Intrusive_set_column<Master_matrix>::rbegin() noexcept
632 return column_.rbegin();
635 template <
class Master_matrix>
636 inline typename Intrusive_set_column<Master_matrix>::const_reverse_iterator
637 Intrusive_set_column<Master_matrix>::rbegin() const noexcept
639 return column_.rbegin();
642 template <
class Master_matrix>
643 inline typename Intrusive_set_column<Master_matrix>::reverse_iterator
644 Intrusive_set_column<Master_matrix>::rend() noexcept
646 return column_.rend();
649 template <
class Master_matrix>
650 inline typename Intrusive_set_column<Master_matrix>::const_reverse_iterator
651 Intrusive_set_column<Master_matrix>::rend() const noexcept
653 return column_.rend();
656 template <
class Master_matrix>
657 template <
class Cell_range>
658 inline Intrusive_set_column<Master_matrix>&
659 Intrusive_set_column<Master_matrix>::operator+=(
const Cell_range& column)
661 static_assert((!Master_matrix::isNonBasic || std::is_same_v<Cell_range, Intrusive_set_column>),
662 "For boundary columns, the range has to be a column of same type to help ensure the validity of the "
664 static_assert((!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type),
665 "For chain columns, the given column cannot be constant.");
672 template <
class Master_matrix>
673 inline Intrusive_set_column<Master_matrix>&
674 Intrusive_set_column<Master_matrix>::operator+=(Intrusive_set_column& column)
676 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
679 chain_opt::swap_pivots(column);
680 dim_opt::swap_dimension(column);
689 template <
class Master_matrix>
690 inline Intrusive_set_column<Master_matrix>&
691 Intrusive_set_column<Master_matrix>::operator*=(
unsigned int v)
693 if constexpr (Master_matrix::Option_list::is_z2) {
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.");
702 Field_element_type val = operators_->get_value(v);
704 if (val == Field_operators::get_additive_identity()) {
705 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
706 throw std::invalid_argument(
"A chain column should not be multiplied by 0.");
713 if (val == Field_operators::get_multiplicative_identity())
return *
this;
715 for (Cell& cell : column_) {
716 operators_->multiply_inplace(cell.get_element(), val);
717 if constexpr (Master_matrix::Option_list::has_row_access) ra_opt::update_cell(cell);
724 template <
class Master_matrix>
725 template <
class Cell_range>
726 inline Intrusive_set_column<Master_matrix>&
727 Intrusive_set_column<Master_matrix>::multiply_target_and_add(
const Field_element_type& val,
728 const Cell_range& column)
730 static_assert((!Master_matrix::isNonBasic || std::is_same_v<Cell_range, Intrusive_set_column>),
731 "For boundary columns, the range has to be a column of same type to help ensure the validity of the "
733 static_assert((!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type),
734 "For chain columns, the given column cannot be constant.");
736 if constexpr (Master_matrix::Option_list::is_z2) {
744 _multiply_target_and_add(val, column);
750 template <
class Master_matrix>
751 inline Intrusive_set_column<Master_matrix>&
752 Intrusive_set_column<Master_matrix>::multiply_target_and_add(
const Field_element_type& val,
753 Intrusive_set_column& column)
755 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
757 if constexpr (Master_matrix::Option_list::is_z2) {
760 chain_opt::swap_pivots(column);
761 dim_opt::swap_dimension(column);
764 throw std::invalid_argument(
"A chain column should not be multiplied by 0.");
767 if (_multiply_target_and_add(val, column)) {
768 chain_opt::swap_pivots(column);
769 dim_opt::swap_dimension(column);
773 if constexpr (Master_matrix::Option_list::is_z2) {
781 _multiply_target_and_add(val, column);
788 template <
class Master_matrix>
789 template <
class Cell_range>
790 inline Intrusive_set_column<Master_matrix>&
791 Intrusive_set_column<Master_matrix>::multiply_source_and_add(
const Cell_range& column,
792 const Field_element_type& val)
794 static_assert((!Master_matrix::isNonBasic || std::is_same_v<Cell_range, Intrusive_set_column>),
795 "For boundary columns, the range has to be a column of same type to help ensure the validity of the "
797 static_assert((!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type),
798 "For chain columns, the given column cannot be constant.");
800 if constexpr (Master_matrix::Option_list::is_z2) {
805 _multiply_source_and_add(column, val);
811 template <
class Master_matrix>
812 inline Intrusive_set_column<Master_matrix>&
813 Intrusive_set_column<Master_matrix>::multiply_source_and_add(Intrusive_set_column& column,
814 const Field_element_type& val)
816 if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
818 if constexpr (Master_matrix::Option_list::is_z2) {
821 chain_opt::swap_pivots(column);
822 dim_opt::swap_dimension(column);
826 if (_multiply_source_and_add(column, val)) {
827 chain_opt::swap_pivots(column);
828 dim_opt::swap_dimension(column);
832 if constexpr (Master_matrix::Option_list::is_z2) {
837 _multiply_source_and_add(column, val);
844 template <
class Master_matrix>
845 inline Intrusive_set_column<Master_matrix>&
846 Intrusive_set_column<Master_matrix>::operator=(
const Intrusive_set_column& other)
848 static_assert(!Master_matrix::Option_list::has_row_access,
"= assignement not enabled with row access option.");
850 dim_opt::operator=(other);
851 chain_opt::operator=(other);
854 column_.clear_and_dispose(delete_disposer(
this));
855 operators_ = other.operators_;
856 cellPool_ = other.cellPool_;
857 column_.clone_from(other.column_, new_cloner(cellPool_), delete_disposer(
this));
862 template <
class Master_matrix>
863 inline void Intrusive_set_column<Master_matrix>::_delete_cell(iterator& it)
865 it = column_.erase_and_dispose(it, delete_disposer(
this));
868 template <
class Master_matrix>
869 inline typename Intrusive_set_column<Master_matrix>::Cell* Intrusive_set_column<Master_matrix>::_insert_cell(
870 const Field_element_type& value, id_index rowIndex,
const iterator& position)
872 if constexpr (Master_matrix::Option_list::has_row_access) {
873 Cell* newCell = cellPool_->construct(ra_opt::columnIndex_, rowIndex);
874 newCell->set_element(value);
875 column_.insert(position, *newCell);
876 ra_opt::insert_cell(rowIndex, newCell);
879 Cell* newCell = cellPool_->construct(rowIndex);
880 newCell->set_element(value);
881 column_.insert(position, *newCell);
886 template <
class Master_matrix>
887 inline void Intrusive_set_column<Master_matrix>::_insert_cell(id_index rowIndex,
888 const iterator& position)
890 if constexpr (Master_matrix::Option_list::has_row_access) {
891 Cell* newCell = cellPool_->construct(ra_opt::columnIndex_, rowIndex);
892 column_.insert(position, *newCell);
893 ra_opt::insert_cell(rowIndex, newCell);
895 Cell* newCell = cellPool_->construct(rowIndex);
896 column_.insert(position, *newCell);
900 template <
class Master_matrix>
901 template <
class Cell_range>
902 inline bool Intrusive_set_column<Master_matrix>::_add(
const Cell_range& column)
904 return _add_to_column(column, *
this);
907 template <
class Master_matrix>
908 template <
class Cell_range>
909 inline bool Intrusive_set_column<Master_matrix>::_multiply_target_and_add(
const Field_element_type& val,
910 const Cell_range& column)
912 return _multiply_target_and_add_to_column(val, column, *
this);
915 template <
class Master_matrix>
916 template <
class Cell_range>
917 inline bool Intrusive_set_column<Master_matrix>::_multiply_source_and_add(
const Cell_range& column,
918 const Field_element_type& val)
920 return _multiply_source_and_add_to_column(val, column, *
this);
935 template <
class Master_matrix>
936 struct std::hash<
Gudhi::persistence_matrix::Intrusive_set_column<Master_matrix> >
939 return Gudhi::persistence_matrix::hash_column(column);
Contains the New_cell_constructor and Pool_cell_constructor structures.
Column class following the PersistenceMatrixColumn concept.
Definition: intrusive_set_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