17#ifndef PM_CHAIN_MATRIX_H
18#define PM_CHAIN_MATRIX_H
45template <
class Master_matrix>
47 public Master_matrix::Chain_pairing_option,
48 public Master_matrix::Chain_vine_swap_option,
49 public Master_matrix::Chain_representative_cycles_option,
50 public Master_matrix::Matrix_row_access_option,
51 protected std::conditional_t<
52 Master_matrix::Option_list::has_vine_update &&
53 (Master_matrix::Option_list::has_column_pairings ||
54 Master_matrix::Option_list::can_retrieve_representative_cycles),
55 Index_mapper<typename Master_matrix::template Dictionary<typename Master_matrix::Pos_index>>,
59 using Dim_opt =
typename Master_matrix::Matrix_dimension_option;
60 using Pair_opt =
typename Master_matrix::Chain_pairing_option;
61 using Swap_opt =
typename Master_matrix::Chain_vine_swap_option;
62 using Rep_opt =
typename Master_matrix::Chain_representative_cycles_option;
63 using RA_opt =
typename Master_matrix::Matrix_row_access_option;
65 static constexpr bool hasPivotToPosMap_ =
66 Master_matrix::Option_list::has_vine_update && (Master_matrix::Option_list::has_column_pairings ||
67 Master_matrix::Option_list::can_retrieve_representative_cycles);
69 using Pivot_to_pos_mapper_opt =
70 std::conditional_t<hasPivotToPosMap_,
71 Index_mapper<typename Master_matrix::template Dictionary<typename Master_matrix::Pos_index>>,
80 using Column =
typename Master_matrix::Column;
81 using Row =
typename Master_matrix::Row;
83 using Entry =
typename Master_matrix::Matrix_entry;
87 using Boundary =
typename Master_matrix::Boundary;
89 using Index =
typename Master_matrix::Index;
90 using ID_index =
typename Master_matrix::ID_index;
91 using Pos_index =
typename Master_matrix::Pos_index;
92 using Dimension =
typename Master_matrix::Dimension;
127 template <
class Boundary_range = Boundary>
160 template <
typename BirthComparatorFunction,
typename DeathComparatorFunction>
162 const BirthComparatorFunction& birthComparator,
163 const DeathComparatorFunction& deathComparator);
200 template <
typename BirthComparatorFunction,
typename DeathComparatorFunction,
class Boundary_range = Boundary>
203 const BirthComparatorFunction& birthComparator,
204 const DeathComparatorFunction& deathComparator);
227 template <
typename BirthComparatorFunction,
typename DeathComparatorFunction>
230 const BirthComparatorFunction& birthComparator,
231 const DeathComparatorFunction& deathComparator);
272 template <
class Boundary_range = Boundary>
274 const Boundary_range& boundary,
275 Dimension dim = Master_matrix::template get_null_value<Dimension>());
294 template <
class Boundary_range = Boundary>
297 const Boundary_range& boundary,
298 Dimension dim = Master_matrix::template get_null_value<Dimension>());
467 if constexpr (Master_matrix::Option_list::has_matrix_maximal_dimension_access) Dim_opt::_reset();
468 if constexpr (Master_matrix::Option_list::has_column_pairings) Pair_opt::_reset();
469 if constexpr (Master_matrix::Option_list::can_retrieve_representative_cycles) Rep_opt::_reset();
470 if constexpr (hasPivotToPosMap_) Pivot_to_pos_mapper_opt::map_.clear();
472 pivotToColumnIndex_.clear();
475 colSettings_ = colSettings;
492 swap(
static_cast<Dim_opt&
>(matrix1),
static_cast<Dim_opt&
>(matrix2));
493 swap(
static_cast<Pair_opt&
>(matrix1),
static_cast<Pair_opt&
>(matrix2));
494 swap(
static_cast<Swap_opt&
>(matrix1),
static_cast<Swap_opt&
>(matrix2));
495 swap(
static_cast<Rep_opt&
>(matrix1),
static_cast<Rep_opt&
>(matrix2));
496 swap(
static_cast<Pivot_to_pos_mapper_opt&
>(matrix1),
static_cast<Pivot_to_pos_mapper_opt&
>(matrix2));
497 matrix1.matrix_.swap(matrix2.matrix_);
498 matrix1.pivotToColumnIndex_.swap(matrix2.pivotToColumnIndex_);
499 std::swap(matrix1.nextIndex_, matrix2.nextIndex_);
500 std::swap(matrix1.nextPosition_, matrix2.nextPosition_);
501 std::swap(matrix1.colSettings_, matrix2.colSettings_);
503 if constexpr (Master_matrix::Option_list::has_row_access) {
504 swap(
static_cast<RA_opt&
>(matrix1),
static_cast<RA_opt&
>(matrix2));
513 using Column_container =
typename Master_matrix::Column_container;
514 using Dictionary =
typename Master_matrix::template Dictionary<Index>;
515 using Barcode =
typename Master_matrix::Barcode;
516 using Bar_dictionary =
typename Master_matrix::Bar_dictionary;
517 using Tmp_column =
typename std::
518 conditional<Master_matrix::Option_list::is_z2, std::set<ID_index>, std::map<ID_index, Field_element>>::type;
524 Column_container matrix_;
525 Dictionary pivotToColumnIndex_;
530 template <
class Boundary_range>
531 std::vector<Entry_representative> _reduce_boundary(
ID_index cellID,
const Boundary_range& boundary, Dimension dim);
532 void _reduce_by_G(Tmp_column& column, std::vector<Entry_representative>& chainsInH, Index currentIndex);
533 void _reduce_by_F(Tmp_column& column, std::vector<Entry_representative>& chainsInF, Index currentIndex);
534 void _build_from_H(
ID_index cellID, Tmp_column& column, std::vector<Entry_representative>& chainsInH);
535 void _update_largest_death_in_F(
const std::vector<Entry_representative>& chainsInF);
536 void _insert_chain(
const Tmp_column& column, Dimension dimension);
537 void _insert_chain(
const Tmp_column& column, Dimension dimension, Index pair);
538 void _add_to(
const Column& column, Tmp_column& set,
unsigned int coef);
539 template <
typename F>
540 void _add_to(
Column& target, F&& addition);
541 void _remove_last(Index lastIndex);
543 void _add_bar(Dimension dim);
544 template <
class Container>
545 void _container_insert(
const Container& column, Index pos, Dimension dim);
546 template <
class ColumnIterator>
547 void _container_insert(
const ColumnIterator& rep);
549 static void _insert_in(
ID_index cellID, Tmp_column& column);
552template <
class Master_matrix>
554 : Dim_opt(Master_matrix::template get_null_value<
Dimension>()),
559 Pivot_to_pos_mapper_opt(),
562 colSettings_(colSettings)
565template <
class Master_matrix>
566template <
class Boundary_range>
569 : Dim_opt(Master_matrix::template get_null_value<
Dimension>()),
573 RA_opt(orderedBoundaries.size()),
574 Pivot_to_pos_mapper_opt(),
577 colSettings_(colSettings)
579 matrix_.reserve(orderedBoundaries.size());
580 if constexpr (Master_matrix::Option_list::has_map_column_container) {
581 pivotToColumnIndex_.reserve(orderedBoundaries.size());
583 pivotToColumnIndex_.resize(orderedBoundaries.size(), Master_matrix::template get_null_value<Index>());
586 for (
const Boundary_range& b : orderedBoundaries) {
591template <
class Master_matrix>
593 : Dim_opt(Master_matrix::template get_null_value<
Dimension>()),
597 RA_opt(numberOfColumns),
598 Pivot_to_pos_mapper_opt(),
601 colSettings_(colSettings)
603 matrix_.reserve(numberOfColumns);
604 if constexpr (Master_matrix::Option_list::has_map_column_container) {
605 pivotToColumnIndex_.reserve(numberOfColumns);
607 pivotToColumnIndex_.resize(numberOfColumns, Master_matrix::template get_null_value<Index>());
611template <
class Master_matrix>
612template <
typename BirthComparatorFunction,
typename DeathComparatorFunction>
614 const BirthComparatorFunction& birthComparator,
615 const DeathComparatorFunction& deathComparator)
616 : Dim_opt(Master_matrix::template get_null_value<
Dimension>()),
618 Swap_opt(birthComparator, deathComparator),
621 Pivot_to_pos_mapper_opt(),
624 colSettings_(colSettings)
627template <
class Master_matrix>
628template <
typename BirthComparatorFunction,
typename DeathComparatorFunction,
class Boundary_range>
631 const BirthComparatorFunction& birthComparator,
632 const DeathComparatorFunction& deathComparator)
633 : Dim_opt(Master_matrix::template get_null_value<
Dimension>()),
635 Swap_opt(birthComparator, deathComparator),
637 RA_opt(orderedBoundaries.size()),
638 Pivot_to_pos_mapper_opt(),
641 colSettings_(colSettings)
643 matrix_.reserve(orderedBoundaries.size());
644 if constexpr (Master_matrix::Option_list::has_map_column_container) {
645 pivotToColumnIndex_.reserve(orderedBoundaries.size());
647 pivotToColumnIndex_.resize(orderedBoundaries.size(), Master_matrix::template get_null_value<Index>());
649 for (
const Boundary_range& b : orderedBoundaries) {
654template <
class Master_matrix>
655template <
typename BirthComparatorFunction,
typename DeathComparatorFunction>
658 const BirthComparatorFunction& birthComparator,
659 const DeathComparatorFunction& deathComparator)
660 : Dim_opt(Master_matrix::template get_null_value<
Dimension>()),
662 Swap_opt(birthComparator, deathComparator),
664 RA_opt(numberOfColumns),
665 Pivot_to_pos_mapper_opt(),
668 colSettings_(colSettings)
670 matrix_.reserve(numberOfColumns);
671 if constexpr (Master_matrix::Option_list::has_map_column_container) {
672 pivotToColumnIndex_.reserve(numberOfColumns);
674 pivotToColumnIndex_.resize(numberOfColumns, Master_matrix::template get_null_value<Index>());
678template <
class Master_matrix>
680 : Dim_opt(static_cast<const Dim_opt&>(matrixToCopy)),
681 Pair_opt(static_cast<const Pair_opt&>(matrixToCopy)),
682 Swap_opt(static_cast<const Swap_opt&>(matrixToCopy)),
683 Rep_opt(static_cast<const Rep_opt&>(matrixToCopy)),
684 RA_opt(static_cast<const RA_opt&>(matrixToCopy)),
685 Pivot_to_pos_mapper_opt(static_cast<const Pivot_to_pos_mapper_opt&>(matrixToCopy)),
686 pivotToColumnIndex_(matrixToCopy.pivotToColumnIndex_),
687 nextIndex_(matrixToCopy.nextIndex_),
688 nextPosition_(matrixToCopy.nextPosition_),
689 colSettings_(colSettings == nullptr ? matrixToCopy.colSettings_ : colSettings)
691 matrix_.reserve(matrixToCopy.matrix_.size());
692 for (
const auto& cont : matrixToCopy.matrix_) {
693 _container_insert(cont);
697template <
class Master_matrix>
699 : Dim_opt(std::move(
static_cast<Dim_opt&
>(other))),
700 Pair_opt(std::move(
static_cast<Pair_opt&
>(other))),
701 Swap_opt(std::move(
static_cast<Swap_opt&
>(other))),
702 Rep_opt(std::move(
static_cast<Rep_opt&
>(other))),
703 RA_opt(std::move(
static_cast<RA_opt&
>(other))),
704 Pivot_to_pos_mapper_opt(std::move(
static_cast<Pivot_to_pos_mapper_opt&
>(other))),
705 matrix_(std::move(other.matrix_)),
706 pivotToColumnIndex_(std::move(other.pivotToColumnIndex_)),
707 nextIndex_(std::exchange(other.nextIndex_, 0)),
708 nextPosition_(std::exchange(other.nextPosition_, 0)),
709 colSettings_(std::exchange(other.colSettings_,
nullptr))
712template <
class Master_matrix>
713template <
class Boundary_range>
715 const Boundary_range& boundary,
718 return insert_boundary(nextIndex_, boundary, dim);
721template <
class Master_matrix>
722template <
class Boundary_range>
723inline std::vector<typename Master_matrix::Entry_representative>
726 if constexpr (!Master_matrix::Option_list::has_map_column_container) {
727 if (pivotToColumnIndex_.size() <= cellID) {
728 pivotToColumnIndex_.resize((cellID * 2) + 1, Master_matrix::template get_null_value<Index>());
732 if constexpr (hasPivotToPosMap_) {
733 if constexpr (Master_matrix::Option_list::has_map_column_container) {
734 Pivot_to_pos_mapper_opt::map_.try_emplace(cellID, nextPosition_);
736 if (Pivot_to_pos_mapper_opt::map_.size() <= cellID)
737 Pivot_to_pos_mapper_opt::map_.resize(pivotToColumnIndex_.size(),
738 Master_matrix::template get_null_value<Pos_index>());
739 Pivot_to_pos_mapper_opt::map_[cellID] = nextPosition_;
743 if constexpr (Master_matrix::Option_list::has_matrix_maximal_dimension_access) {
744 Dim_opt::_update_up(dim == Master_matrix::template get_null_value<Dimension>()
745 ? (boundary.size() == 0 ? 0 : boundary.size() - 1)
749 return _reduce_boundary(cellID, boundary, dim);
752template <
class Master_matrix>
755 if constexpr (Master_matrix::Option_list::has_map_column_container) {
756 return matrix_.at(columnIndex);
758 return matrix_[columnIndex];
762template <
class Master_matrix>
764 Index columnIndex)
const
766 if constexpr (Master_matrix::Option_list::has_map_column_container) {
767 return matrix_.at(columnIndex);
769 return matrix_[columnIndex];
773template <
class Master_matrix>
776 static_assert(Master_matrix::Option_list::has_removable_columns,
777 "'remove_maximal_cell' is not implemented for the chosen options.");
778 static_assert(Master_matrix::Option_list::has_map_column_container && Master_matrix::Option_list::has_vine_update &&
779 Master_matrix::Option_list::has_column_pairings,
780 "'remove_maximal_cell' is not implemented for the chosen options.");
784 const auto& pivotToPosition = Pivot_to_pos_mapper_opt::map_;
785 auto it = pivotToPosition.find(cellID);
786 if (it == pivotToPosition.end())
return;
788 Index startIndex = pivotToColumnIndex_.at(cellID);
790 if (startPos != nextPosition_ - 1) {
791 std::vector<Index> colToSwap;
792 colToSwap.reserve(matrix_.size());
794 for (
auto& p : pivotToPosition) {
795 if (p.second > startPos) colToSwap.push_back(pivotToColumnIndex_.at(p.first));
797 std::sort(colToSwap.begin(), colToSwap.end(), [&](
Index c1,
Index c2) {
798 return pivotToPosition.at(get_pivot(c1)) < pivotToPosition.at(get_pivot(c2));
801 for (
Index i : colToSwap) {
802 startIndex = Swap_opt::vine_swap(startIndex, i);
806 _remove_last(startIndex);
809template <
class Master_matrix>
811 const std::vector<ID_index>& columnsToSwap)
813 static_assert(Master_matrix::Option_list::has_removable_columns,
814 "'remove_maximal_cell' is not implemented for the chosen options.");
815 static_assert(Master_matrix::Option_list::has_map_column_container && Master_matrix::Option_list::has_vine_update,
816 "'remove_maximal_cell' is not implemented for the chosen options.");
820 Index startIndex = pivotToColumnIndex_.at(cellID);
823 startIndex = Swap_opt::vine_swap(startIndex, pivotToColumnIndex_.at(i));
826 _remove_last(startIndex);
829template <
class Master_matrix>
832 static_assert(Master_matrix::Option_list::has_removable_columns,
833 "'remove_last' is not implemented for the chosen options.");
834 static_assert(Master_matrix::Option_list::has_map_column_container || !Master_matrix::Option_list::has_vine_update,
835 "'remove_last' is not implemented for the chosen options.");
837 if (nextIndex_ == 0 || matrix_.empty())
return;
839 if constexpr (Master_matrix::Option_list::has_vine_update) {
846 for (
auto& p : pivotToColumnIndex_) {
847 if (p.first > pivot) {
852 _remove_last(colIndex);
854 _remove_last(nextIndex_ - 1);
858template <
class Master_matrix>
861 if constexpr (Master_matrix::Option_list::has_map_column_container) {
862 return matrix_.size();
868template <
class Master_matrix>
870 Index columnIndex)
const
872 return get_column(columnIndex).get_dimension();
875template <
class Master_matrix>
879 _add_to(col, [&]() { col +=
get_column(sourceColumnIndex); });
882template <
class Master_matrix>
885 Index targetColumnIndex)
888 _add_to(col, [&]() { col.multiply_target_and_add(coefficient,
get_column(sourceColumnIndex)); });
891template <
class Master_matrix>
893 Index sourceColumnIndex,
894 Index targetColumnIndex)
897 _add_to(col, [&]() { col.multiply_source_and_add(
get_column(sourceColumnIndex), coefficient); });
900template <
class Master_matrix>
903 return !
get_column(columnIndex).is_non_zero(rowIndex);
906template <
class Master_matrix>
912template <
class Master_matrix>
916 if constexpr (Master_matrix::Option_list::has_map_column_container) {
917 return pivotToColumnIndex_.at(cellID);
919 return pivotToColumnIndex_[cellID];
923template <
class Master_matrix>
929template <
class Master_matrix>
932 if (
this == &other)
return *
this;
934 Dim_opt::operator=(other);
935 Swap_opt::operator=(other);
936 Pair_opt::operator=(other);
937 Rep_opt::operator=(other);
938 Pivot_to_pos_mapper_opt::operator=(other);
940 pivotToColumnIndex_ = other.pivotToColumnIndex_;
941 nextIndex_ = other.nextIndex_;
942 nextPosition_ = other.nextPosition_;
943 colSettings_ = other.colSettings_;
945 matrix_.reserve(other.matrix_.size());
946 for (
const auto& cont : other.matrix_) {
947 _container_insert(cont);
953template <
class Master_matrix>
956 if (
this == &other)
return *
this;
958 Dim_opt::operator=(std::move(other));
959 Pair_opt::operator=(std::move(other));
960 Swap_opt::operator=(std::move(other));
961 Rep_opt::operator=(std::move(other));
962 RA_opt::operator=(std::move(other));
963 Pivot_to_pos_mapper_opt::operator=(std::move(other));
964 matrix_ = std::move(other.matrix_);
965 pivotToColumnIndex_ = std::move(other.pivotToColumnIndex_);
966 nextIndex_ = std::exchange(other.nextIndex_, 0);
967 nextPosition_ = std::exchange(other.nextPosition_, 0);
968 colSettings_ = std::exchange(other.colSettings_,
nullptr);
973template <
class Master_matrix>
974inline void Chain_matrix<Master_matrix>::print()
const
976 std::cout <<
"Column Matrix:\n";
977 if constexpr (!Master_matrix::Option_list::has_map_column_container) {
978 for (ID_index i = 0; i < pivotToColumnIndex_.size(); ++i) {
979 Index pos = pivotToColumnIndex_[i];
980 if (pos != Master_matrix::template get_null_value<Index>()) {
981 const Column& col = matrix_[pos];
982 for (
const auto& entry : col) {
983 std::cout << entry.get_row_index() <<
" ";
985 std::cout <<
"(" << i <<
", " << pos <<
")\n";
988 if constexpr (Master_matrix::Option_list::has_row_access) {
990 std::cout <<
"Row Matrix:\n";
991 for (ID_index i = 0; i < pivotToColumnIndex_.size(); ++i) {
992 Index pos = pivotToColumnIndex_[i];
993 if (pos != Master_matrix::template get_null_value<Index>()) {
994 const Row& row = RA_opt::get_row(pos);
995 for (
const auto& entry : row) {
996 std::cout << entry.get_column_index() <<
" ";
998 std::cout <<
"(" << i <<
", " << pos <<
")\n";
1003 for (
const auto& p : pivotToColumnIndex_) {
1004 const Column& col = matrix_.at(p.second);
1005 for (
const auto& entry : col) {
1006 std::cout << entry.get_row_index() <<
" ";
1008 std::cout <<
"(" << p.first <<
", " << p.second <<
")\n";
1010 if constexpr (Master_matrix::Option_list::has_row_access) {
1012 std::cout <<
"Row Matrix:\n";
1013 for (
const auto& p : pivotToColumnIndex_) {
1014 const Row& row = RA_opt::get_row(p.first);
1015 for (
const auto& entry : row) {
1016 std::cout << entry.get_column_index() <<
" ";
1018 std::cout <<
"(" << p.first <<
", " << p.second <<
")\n";
1025template <
class Master_matrix>
1026template <
class Boundary_range>
1027inline std::vector<typename Master_matrix::Entry_representative>
1030 Tmp_column column(boundary.begin(), boundary.end());
1031 if (dim == Master_matrix::template get_null_value<Dimension>())
1032 dim = boundary.begin() == boundary.end() ? 0 : boundary.size() - 1;
1033 std::vector<Entry_representative> chainsInH;
1034 std::vector<Entry_representative> chainsInF;
1036 auto get_last = [&column]() {
1037 if constexpr (Master_matrix::Option_list::is_z2)
1038 return *(column.rbegin());
1040 return column.rbegin()->first;
1043 if (boundary.begin() == boundary.end()) {
1044 _insert_in(cellID, column);
1045 _insert_chain(column, dim);
1049 Index currentIndex = get_column_with_pivot(get_last());
1051 while (get_column(currentIndex).is_paired()) {
1052 _reduce_by_G(column, chainsInH, currentIndex);
1054 if (column.empty()) {
1056 _build_from_H(cellID, column, chainsInH);
1058 _insert_chain(column, dim);
1062 currentIndex = get_column_with_pivot(get_last());
1065 while (!column.empty()) {
1066 currentIndex = get_column_with_pivot(get_last());
1068 if (!get_column(currentIndex).is_paired()) {
1070 _reduce_by_F(column, chainsInF, currentIndex);
1072 _reduce_by_G(column, chainsInH, currentIndex);
1076 _update_largest_death_in_F(chainsInF);
1079 _build_from_H(cellID, column, chainsInH);
1082 _insert_chain(column, dim, Master_matrix::get_row_index(chainsInF[0]));
1087template <
class Master_matrix>
1089 std::vector<Entry_representative>& chainsInH,
1092 Column& col = get_column(currentIndex);
1093 if constexpr (Master_matrix::Option_list::is_z2) {
1094 _add_to(col, column, 1U);
1095 chainsInH.push_back(col.get_paired_chain_index());
1097 Field_element coef = col.get_pivot_value();
1098 auto& operators = colSettings_->operators;
1099 coef = operators.get_inverse(coef);
1100 operators.multiply_inplace(coef, operators.get_characteristic() - column.rbegin()->second);
1102 _add_to(col, column, coef);
1103 chainsInH.emplace_back(col.get_paired_chain_index(), coef);
1107template <
class Master_matrix>
1109 std::vector<Entry_representative>& chainsInF,
1112 Column& col = get_column(currentIndex);
1113 if constexpr (Master_matrix::Option_list::is_z2) {
1114 _add_to(col, column, 1U);
1115 chainsInF.push_back(currentIndex);
1117 Field_element coef = col.get_pivot_value();
1118 auto& operators = colSettings_->operators;
1119 coef = operators.get_inverse(coef);
1120 operators.multiply_inplace(coef, operators.get_characteristic() - column.rbegin()->second);
1122 _add_to(col, column, coef);
1123 chainsInF.emplace_back(currentIndex, operators.get_characteristic() - coef);
1127template <
class Master_matrix>
1130 std::vector<Entry_representative>& chainsInH)
1132 _insert_in(cellID, column);
1134 for (
const auto& idx_h : chainsInH) {
1135 _add_to(get_column(Master_matrix::get_row_index(idx_h)), column, Master_matrix::get_element(idx_h));
1139template <
class Master_matrix>
1142 Index toUpdate = Master_matrix::get_row_index(chainsInF[0]);
1143 if constexpr (Master_matrix::Option_list::is_z2) {
1144 for (
auto other_col_it = chainsInF.begin() + 1; other_col_it != chainsInF.end(); ++other_col_it) {
1145 add_to(*other_col_it, toUpdate);
1148 get_column(toUpdate) *= Master_matrix::get_element(chainsInF[0]);
1149 for (
auto other_col_it = chainsInF.begin() + 1; other_col_it != chainsInF.end(); ++other_col_it) {
1150 multiply_source_and_add_to(
1151 Master_matrix::get_element(*other_col_it), Master_matrix::get_row_index(*other_col_it), toUpdate);
1156template <
class Master_matrix>
1159 _container_insert(column, nextIndex_, dimension);
1160 _add_bar(dimension);
1165template <
class Master_matrix>
1170 Pos_index pairPos = pair;
1172 _container_insert(column, nextIndex_, dimension);
1174 get_column(nextIndex_).assign_paired_chain(pair);
1175 auto& pairCol = get_column(pair);
1176 pairCol.assign_paired_chain(nextIndex_);
1178 if constexpr (Master_matrix::Option_list::has_column_pairings && Master_matrix::Option_list::has_vine_update) {
1179 pairPos = Pivot_to_pos_mapper_opt::map_[pairCol.get_pivot()];
1182 _update_barcode(pairPos);
1187template <
class Master_matrix>
1190 [[maybe_unused]]
unsigned int coef)
1192 if constexpr (Master_matrix::Option_list::is_z2) {
1193 std::pair<typename std::set<Index>::iterator,
bool> res_insert;
1194 for (
const Entry& entry : column) {
1195 res_insert = set.insert(entry.get_row_index());
1196 if (!res_insert.second) {
1197 set.erase(res_insert.first);
1201 auto& operators = colSettings_->operators;
1202 for (
const Entry& entry : column) {
1203 auto res = set.emplace(entry.get_row_index(), entry.get_element());
1205 operators.multiply_inplace(res.first->second, coef);
1207 operators.multiply_and_add_inplace_back(entry.get_element(), coef, res.first->second);
1208 if (res.first->second == Field_operators::get_additive_identity()) {
1209 set.erase(res.first);
1216template <
class Master_matrix>
1217template <
typename F>
1220 auto pivot = target.get_pivot();
1221 std::forward<F>(addition)();
1223 if (pivot != target.get_pivot()) {
1224 if constexpr (Master_matrix::Option_list::has_map_column_container) {
1225 std::swap(pivotToColumnIndex_.at(pivot), pivotToColumnIndex_.at(target.get_pivot()));
1227 std::swap(pivotToColumnIndex_[pivot], pivotToColumnIndex_[target.get_pivot()]);
1232template <
class Master_matrix>
1235 static_assert(Master_matrix::Option_list::has_removable_columns,
1236 "'_remove_last' is not implemented for the chosen options.");
1237 static_assert(Master_matrix::Option_list::has_map_column_container || !Master_matrix::Option_list::has_vine_update,
1238 "'_remove_last' is not implemented for the chosen options.");
1242 if constexpr (Master_matrix::Option_list::has_map_column_container) {
1243 auto itToErase = matrix_.find(lastIndex);
1244 Column& colToErase = itToErase->second;
1245 pivot = colToErase.get_pivot();
1247 if constexpr (Master_matrix::Option_list::has_matrix_maximal_dimension_access) {
1248 Dim_opt::_update_down(colToErase.get_dimension());
1251 if (colToErase.is_paired()) matrix_.at(colToErase.get_paired_chain_index()).unassign_paired_chain();
1252 pivotToColumnIndex_.erase(pivot);
1253 matrix_.erase(itToErase);
1255 GUDHI_CHECK(lastIndex == nextIndex_ - 1 && nextIndex_ == matrix_.size(),
1256 std::logic_error(
"Chain_matrix::_remove_last - Indexation problem."));
1258 Column& colToErase = matrix_[lastIndex];
1259 pivot = colToErase.get_pivot();
1261 if constexpr (Master_matrix::Option_list::has_matrix_maximal_dimension_access) {
1262 Dim_opt::_update_down(colToErase.get_dimension());
1265 if (colToErase.is_paired()) matrix_.at(colToErase.get_paired_chain_index()).unassign_paired_chain();
1266 pivotToColumnIndex_[pivot] = Master_matrix::template get_null_value<Index>();
1271 if constexpr (!Master_matrix::Option_list::has_vine_update) {
1276 if constexpr (Master_matrix::Option_list::has_column_pairings) {
1277 Pair_opt::_erase_bar(nextPosition_);
1279 if constexpr (hasPivotToPosMap_) {
1280 Pivot_to_pos_mapper_opt::map_.erase(pivot);
1283 if constexpr (Master_matrix::Option_list::has_row_access) {
1285 RA_opt::get_row(pivot).size() == 0,
1286 std::invalid_argument(
1287 "Chain_matrix::_remove_last - Column asked to be removed does not corresponds to a maximal simplex."));
1288 if constexpr (Master_matrix::Option_list::has_removable_rows) {
1289 RA_opt::erase_empty_row(pivot);
1294template <
class Master_matrix>
1297 if constexpr (Master_matrix::Option_list::has_column_pairings) {
1298 Pair_opt::_update_barcode(birth, nextPosition_);
1303template <
class Master_matrix>
1306 if constexpr (Master_matrix::Option_list::has_column_pairings) {
1307 Pair_opt::_add_bar(dim, nextPosition_);
1312template <
class Master_matrix>
1313template <
class Container>
1316 ID_index pivot = Master_matrix::get_row_index(*(column.rbegin()));
1318 if constexpr (Master_matrix::Option_list::has_map_column_container) {
1319 pivotToColumnIndex_.try_emplace(pivot, pos);
1320 if constexpr (Master_matrix::Option_list::has_row_access) {
1321 matrix_.try_emplace(pos, Column(pos, column, dim, RA_opt::_get_rows_ptr(), colSettings_));
1323 matrix_.try_emplace(pos, Column(column, dim, colSettings_));
1326 if constexpr (Master_matrix::Option_list::has_row_access) {
1327 matrix_.emplace_back(pos, column, dim, RA_opt::_get_rows_ptr(), colSettings_);
1329 matrix_.emplace_back(column, dim, colSettings_);
1331 pivotToColumnIndex_[pivot] = pos;
1335template <
class Master_matrix>
1336template <
class ColumnIterator>
1339 if constexpr (Master_matrix::Option_list::has_map_column_container) {
1340 const auto& col = rep.second;
1341 if constexpr (Master_matrix::Option_list::has_row_access) {
1342 matrix_.try_emplace(rep.first, Column(col, col.get_column_index(), RA_opt::_get_rows_ptr(), colSettings_));
1344 matrix_.try_emplace(rep.first, Column(col, colSettings_));
1347 if constexpr (Master_matrix::Option_list::has_row_access) {
1348 matrix_.emplace_back(rep, rep.get_column_index(), RA_opt::_get_rows_ptr(), colSettings_);
1350 matrix_.emplace_back(rep, colSettings_);
1355template <
class Master_matrix>
1358 if constexpr (Master_matrix::Option_list::is_z2)
1359 column.insert(cellID);
1361 column.emplace(cellID, 1);
Contains the Gudhi::persistence_matrix::Id_to_index_overlay class.
Matrix structure storing a compatible base of a filtered chain complex. See zigzag....
Definition Chain_matrix.h:57
void remove_maximal_cell(ID_index cellID)
Only available if PersistenceMatrixOptions::has_removable_columns and PersistenceMatrixOptions::has_v...
Definition Chain_matrix.h:774
Chain_matrix(const std::vector< Boundary_range > &orderedBoundaries, Column_settings *colSettings)
Constructs a new matrix from the given ranges of Matrix::Entry_representative. Each range corresponds...
Definition Chain_matrix.h:567
Chain_matrix(const Chain_matrix &matrixToCopy, Column_settings *colSettings=nullptr)
Copy constructor. If colSettings is not a null pointer, its value is kept instead of the one in the c...
Definition Chain_matrix.h:679
std::vector< Entry_representative > insert_boundary(const Boundary_range &boundary, Dimension dim=Master_matrix::template get_null_value< Dimension >())
Inserts at the end of the matrix a new ordered column corresponding to the given boundary....
Column & get_column(Index columnIndex)
Returns the column at the given MatIdx index. The type of the column depends on the chosen options,...
Definition Chain_matrix.h:753
void reset(Column_settings *colSettings)
Resets the matrix to an empty matrix.
Definition Chain_matrix.h:465
void remove_maximal_cell(ID_index cellID, const std::vector< ID_index > &columnsToSwap)
Only available if PersistenceMatrixOptions::has_removable_columns, PersistenceMatrixOptions::has_vine...
Definition Chain_matrix.h:810
typename Matrix< PersistenceMatrixOptions >::Index Index
Definition Chain_matrix.h:89
void multiply_source_and_add_to(const Field_element &coefficient, Index sourceColumnIndex, Index targetColumnIndex)
Multiplies the source column with the coefficient before adding it to the target column....
Definition Chain_matrix.h:892
typename Matrix< PersistenceMatrixOptions >::Pos_index Pos_index
Definition Chain_matrix.h:91
bool is_zero_entry(Index columnIndex, ID_index rowIndex) const
Indicates if the entry at given coordinates has value zero.
Definition Chain_matrix.h:901
Chain_matrix(unsigned int numberOfColumns, Column_settings *colSettings, const BirthComparatorFunction &birthComparator, const DeathComparatorFunction &deathComparator)
Constructs a new empty matrix and reserves space for the given number of columns.
Definition Chain_matrix.h:656
Chain_matrix(Chain_matrix &&other) noexcept
Move constructor.
Definition Chain_matrix.h:698
typename Matrix< PersistenceMatrixOptions >::Entry_constructor Entry_constructor
Definition Chain_matrix.h:84
void multiply_target_and_add_to(Index sourceColumnIndex, const Field_element &coefficient, Index targetColumnIndex)
Multiplies the target column with the coefficient and then adds the source column to it....
Definition Chain_matrix.h:883
Index get_column_with_pivot(ID_index cellID) const
Returns the column with given row index as pivot. Assumes that the pivot exists.
Definition Chain_matrix.h:913
Chain_matrix & operator=(Chain_matrix &&other) noexcept
Move assign operator.
Definition Chain_matrix.h:954
Chain_matrix(Column_settings *colSettings)
Constructs an empty matrix. Only available if PersistenceMatrixOptions::has_column_pairings is true o...
Definition Chain_matrix.h:553
Chain_matrix(unsigned int numberOfColumns, Column_settings *colSettings)
Constructs a new empty matrix and reserves space for the given number of columns. Only available if P...
Definition Chain_matrix.h:592
typename Matrix< PersistenceMatrixOptions >::Row Row
Definition Chain_matrix.h:81
typename Matrix< PersistenceMatrixOptions >::Field_operators Field_operators
Definition Chain_matrix.h:78
typename Matrix< PersistenceMatrixOptions >::Element Field_element
Definition Chain_matrix.h:79
void add_to(Index sourceColumnIndex, Index targetColumnIndex)
Adds column at sourceColumnIndex onto the column at targetColumnIndex in the matrix.
Definition Chain_matrix.h:876
ID_index get_pivot(Index columnIndex)
Returns the row index of the pivot of the given column.
Definition Chain_matrix.h:924
typename Matrix< PersistenceMatrixOptions >::Entry_representative Entry_representative
Definition Chain_matrix.h:88
bool is_zero_column(Index columnIndex)
Indicates if the column at given index has value zero. Note that if the matrix is valid,...
Definition Chain_matrix.h:907
Chain_matrix(Column_settings *colSettings, const BirthComparatorFunction &birthComparator, const DeathComparatorFunction &deathComparator)
Constructs an empty matrix and stores the given comparators.
Definition Chain_matrix.h:613
Index get_number_of_columns() const
Returns the current number of columns in the matrix.
Definition Chain_matrix.h:859
Chain_matrix(const std::vector< Boundary_range > &orderedBoundaries, Column_settings *colSettings, const BirthComparatorFunction &birthComparator, const DeathComparatorFunction &deathComparator)
Constructs a new matrix from the given ranges of Matrix::Entry_representative. Each range corresponds...
Definition Chain_matrix.h:629
std::vector< Entry_representative > insert_boundary(ID_index cellID, const Boundary_range &boundary, Dimension dim=Master_matrix::template get_null_value< Dimension >())
It does the same as the other version, but allows the boundary cells to be identified without restric...
Dimension get_column_dimension(Index columnIndex) const
Returns the dimension of the given column.
Definition Chain_matrix.h:869
void remove_last()
Only available if PersistenceMatrixOptions::has_removable_columns is true and, if PersistenceMatrixOp...
Definition Chain_matrix.h:830
friend void swap(Chain_matrix &matrix1, Chain_matrix &matrix2) noexcept
Swap operator.
Definition Chain_matrix.h:490
typename Matrix< PersistenceMatrixOptions >::ID_index ID_index
Definition Chain_matrix.h:90
typename Matrix< PersistenceMatrixOptions >::Column Column
Definition Chain_matrix.h:80
typename Matrix< PersistenceMatrixOptions >::Matrix_entry Entry
Definition Chain_matrix.h:83
typename Matrix< PersistenceMatrixOptions >::Dimension Dimension
Definition Chain_matrix.h:92
Chain_matrix & operator=(const Chain_matrix &other)
Assign operator.
Definition Chain_matrix.h:930
typename Matrix< PersistenceMatrixOptions >::Boundary Boundary
Definition Chain_matrix.h:87
typename Matrix< PersistenceMatrixOptions >::Column_settings Column_settings
Definition Chain_matrix.h:85
const Column & get_column(Index columnIndex) const
Returns the column at the given MatIdx index. The type of the column depends on the chosen options,...
Definition Chain_matrix.h:763
Matrix entry class. Stores by default only the row index it belongs to, but can also store its column...
Definition entry_types.h:163
Overlay for non-basic matrices replacing all input and output MatIdx indices of the original methods ...
Definition Id_to_index_overlay.h:42
std::enable_if_t< std::is_integral_v< Integer_index > > multiply_target_and_add_to(Integer_index sourceColumnIndex, int coefficient, Integer_index targetColumnIndex)
Dimension get_column_dimension(Index columnIndex) const
Index get_column_with_pivot(ID_index cellIndex) const
std::enable_if_t< std::is_integral_v< Integer_index > > multiply_source_and_add_to(int coefficient, Integer_index sourceColumnIndex, Integer_index targetColumnIndex)
ID_index get_pivot(Index columnIndex)
Returned_column & get_column(Index columnIndex)
typename Chain_rep_cycles_options::Dimension Dimension
Definition Matrix.h:153
bool is_zero_entry(Index columnIndex, ID_index rowIndex)
typename Chain_rep_cycles_options::Index Index
Definition Matrix.h:150
Matrix & operator=(Matrix other) &
Insertion_return insert_boundary(const Boundary_range &boundary, Dimension dim=Matrix::get_null_value< Dimension >())
bool is_zero_column(Index columnIndex)
std::conditional_t< Chain_rep_cycles_options::column_type==Column_types::HEAP, Matrix_heap_column, std::conditional_t< Chain_rep_cycles_options::column_type==Column_types::LIST, Matrix_list_column, std::conditional_t< Chain_rep_cycles_options::column_type==Column_types::SET, Matrix_set_column, std::conditional_t< Chain_rep_cycles_options::column_type==Column_types::UNORDERED_SET, Matrix_unordered_set_column, std::conditional_t< Chain_rep_cycles_options::column_type==Column_types::VECTOR, Matrix_vector_column, std::conditional_t< Chain_rep_cycles_options::column_type==Column_types::INTRUSIVE_LIST, Matrix_intrusive_list_column, std::conditional_t< Chain_rep_cycles_options::column_type==Column_types::NAIVE_VECTOR, Matrix_naive_vector_column, std::conditional_t< Chain_rep_cycles_options::column_type==Column_types::SMALL_VECTOR, Matrix_small_vector_column, Matrix_intrusive_set_column > > > > > > > > Column
Definition Matrix.h:359
typename Chain_rep_cycles_options::Index ID_index
Definition Matrix.h:151
Index get_number_of_columns() const
std::enable_if_t< std::is_integral_v< Integer_index > > add_to(Integer_index sourceColumnIndex, Integer_index targetColumnIndex)
void remove_maximal_cell(Index columnIndex)
Contains the Gudhi::persistence_matrix::Index_mapper class and Gudhi::persistence_matrix::Dummy_index...
Persistence matrix namespace.
Definition FieldOperators.h:18
Gudhi namespace.
Definition SimplicialComplexForAlpha.h:14