17#ifndef PM_CHAIN_MATRIX_H
18#define PM_CHAIN_MATRIX_H
46template <
class Master_matrix>
48 public Master_matrix::Chain_pairing_option,
49 public Master_matrix::Chain_vine_swap_option,
50 public Master_matrix::Chain_representative_cycles_option,
51 public Master_matrix::Matrix_row_access_option,
52 protected std::conditional_t<
53 Master_matrix::Option_list::has_vine_update &&
54 (Master_matrix::Option_list::has_column_pairings ||
55 Master_matrix::Option_list::can_retrieve_representative_cycles),
56 Index_mapper<typename Master_matrix::template Dictionary<typename Master_matrix::Pos_index>>,
60 using Dim_opt =
typename Master_matrix::Matrix_dimension_option;
61 using Pair_opt =
typename Master_matrix::Chain_pairing_option;
62 using Swap_opt =
typename Master_matrix::Chain_vine_swap_option;
63 using Rep_opt =
typename Master_matrix::Chain_representative_cycles_option;
64 using RA_opt =
typename Master_matrix::Matrix_row_access_option;
66 static constexpr bool hasPivotToPosMap_ =
67 Master_matrix::Option_list::has_vine_update && (Master_matrix::Option_list::has_column_pairings ||
68 Master_matrix::Option_list::can_retrieve_representative_cycles);
70 using Pivot_to_pos_mapper_opt =
71 std::conditional_t<hasPivotToPosMap_,
72 Index_mapper<typename Master_matrix::template Dictionary<typename Master_matrix::Pos_index>>,
81 using Column =
typename Master_matrix::Column;
82 using Row =
typename Master_matrix::Row;
84 using Entry =
typename Master_matrix::Matrix_entry;
88 using Boundary =
typename Master_matrix::Boundary;
90 using Index =
typename Master_matrix::Index;
91 using ID_index =
typename Master_matrix::ID_index;
92 using Pos_index =
typename Master_matrix::Pos_index;
93 using Dimension =
typename Master_matrix::Dimension;
128 template <
class Boundary_range = Boundary>
161 template <
typename BirthComparatorFunction,
typename DeathComparatorFunction>
163 const BirthComparatorFunction& birthComparator,
164 const DeathComparatorFunction& deathComparator);
201 template <
typename BirthComparatorFunction,
typename DeathComparatorFunction,
class Boundary_range = Boundary>
204 const BirthComparatorFunction& birthComparator,
205 const DeathComparatorFunction& deathComparator);
228 template <
typename BirthComparatorFunction,
typename DeathComparatorFunction>
231 const BirthComparatorFunction& birthComparator,
232 const DeathComparatorFunction& deathComparator);
273 template <
class Boundary_range = Boundary>
275 const Boundary_range& boundary,
276 Dimension dim = Master_matrix::template get_null_value<Dimension>());
295 template <
class Boundary_range = Boundary>
298 const Boundary_range& boundary,
299 Dimension dim = Master_matrix::template get_null_value<Dimension>());
318 template <
class Boundary_range = Boundary>
321 const Boundary_range& boundary,
322 Dimension dim = Master_matrix::template get_null_value<Dimension>());
342 template <
class Boundary_range = Boundary>
346 const Boundary_range& boundary,
347 Dimension dim = Master_matrix::template get_null_value<Dimension>());
517 if constexpr (Master_matrix::Option_list::has_matrix_maximal_dimension_access) Dim_opt::_reset();
518 if constexpr (Master_matrix::Option_list::has_column_pairings) Pair_opt::_reset();
519 if constexpr (Master_matrix::Option_list::can_retrieve_representative_cycles) Rep_opt::_reset();
520 if constexpr (hasPivotToPosMap_) Pivot_to_pos_mapper_opt::map_.clear();
522 pivotToColumnIndex_.clear();
525 colSettings_ = colSettings;
542 swap(
static_cast<Dim_opt&
>(matrix1),
static_cast<Dim_opt&
>(matrix2));
543 swap(
static_cast<Pair_opt&
>(matrix1),
static_cast<Pair_opt&
>(matrix2));
544 swap(
static_cast<Swap_opt&
>(matrix1),
static_cast<Swap_opt&
>(matrix2));
545 swap(
static_cast<Rep_opt&
>(matrix1),
static_cast<Rep_opt&
>(matrix2));
546 swap(
static_cast<Pivot_to_pos_mapper_opt&
>(matrix1),
static_cast<Pivot_to_pos_mapper_opt&
>(matrix2));
547 matrix1.matrix_.swap(matrix2.matrix_);
548 matrix1.pivotToColumnIndex_.swap(matrix2.pivotToColumnIndex_);
549 std::swap(matrix1.nextIndex_, matrix2.nextIndex_);
550 std::swap(matrix1.nextPosition_, matrix2.nextPosition_);
551 std::swap(matrix1.colSettings_, matrix2.colSettings_);
553 if constexpr (Master_matrix::Option_list::has_row_access) {
554 swap(
static_cast<RA_opt&
>(matrix1),
static_cast<RA_opt&
>(matrix2));
564 using Column_container =
typename Master_matrix::Column_container;
565 using Dictionary =
typename Master_matrix::template Dictionary<Index>;
566 using Barcode =
typename Master_matrix::Barcode;
567 using Bar_dictionary =
typename Master_matrix::Bar_dictionary;
568 using Tmp_column =
typename std::
569 conditional<Master_matrix::Option_list::is_z2, std::set<ID_index>, std::map<ID_index, Field_element>>::type;
575 Column_container matrix_;
576 Dictionary pivotToColumnIndex_;
581 template <
class Boundary_range>
582 std::vector<Entry_representative> _reduce_boundary(
ID_index cellID,
const Boundary_range& boundary, Dimension dim);
583 void _reduce_by_G(Tmp_column& column, std::vector<Entry_representative>& chainsInH, Index currentIndex);
584 void _reduce_by_F(Tmp_column& column, std::vector<Entry_representative>& chainsInF, Index currentIndex);
585 void _build_from_H(
ID_index cellID, Tmp_column& column, std::vector<Entry_representative>& chainsInH);
586 void _update_largest_death_in_F(
const std::vector<Entry_representative>& chainsInF);
587 void _insert_chain(
const Tmp_column& column, Dimension dimension);
588 void _insert_chain(
const Tmp_column& column, Dimension dimension, Index pair);
589 void _add_to(
const Column& column, Tmp_column& set,
unsigned int coef);
590 template <
typename F>
591 void _add_to(
Column& target, F&& addition);
592 void _remove_last(Index lastIndex);
594 void _add_bar(Dimension dim);
595 template <
class Container>
596 void _container_insert(
const Container& column, Index pos, Dimension dim);
597 template <
class ColumnIterator>
598 void _container_insert(
const ColumnIterator& rep);
600 static void _insert_in(
ID_index cellID, Tmp_column& column);
603template <
class Master_matrix>
605 : Dim_opt(Master_matrix::template get_null_value<
Dimension>()),
610 Pivot_to_pos_mapper_opt(),
613 colSettings_(colSettings)
616template <
class Master_matrix>
617template <
class Boundary_range>
620 : Dim_opt(Master_matrix::template get_null_value<
Dimension>()),
624 RA_opt(orderedBoundaries.size()),
625 Pivot_to_pos_mapper_opt(),
628 colSettings_(colSettings)
630 matrix_.reserve(orderedBoundaries.size());
631 if constexpr (Master_matrix::Option_list::has_map_column_container) {
632 pivotToColumnIndex_.reserve(orderedBoundaries.size());
634 pivotToColumnIndex_.resize(orderedBoundaries.size(), Master_matrix::template get_null_value<Index>());
637 for (
const Boundary_range& b : orderedBoundaries) {
642template <
class Master_matrix>
644 : Dim_opt(Master_matrix::template get_null_value<
Dimension>()),
648 RA_opt(numberOfColumns),
649 Pivot_to_pos_mapper_opt(),
652 colSettings_(colSettings)
654 matrix_.reserve(numberOfColumns);
655 if constexpr (Master_matrix::Option_list::has_map_column_container) {
656 pivotToColumnIndex_.reserve(numberOfColumns);
658 pivotToColumnIndex_.resize(numberOfColumns, Master_matrix::template get_null_value<Index>());
662template <
class Master_matrix>
663template <
typename BirthComparatorFunction,
typename DeathComparatorFunction>
665 const BirthComparatorFunction& birthComparator,
666 const DeathComparatorFunction& deathComparator)
667 : Dim_opt(Master_matrix::template get_null_value<
Dimension>()),
669 Swap_opt(birthComparator, deathComparator),
672 Pivot_to_pos_mapper_opt(),
675 colSettings_(colSettings)
678template <
class Master_matrix>
679template <
typename BirthComparatorFunction,
typename DeathComparatorFunction,
class Boundary_range>
682 const BirthComparatorFunction& birthComparator,
683 const DeathComparatorFunction& deathComparator)
684 : Dim_opt(Master_matrix::template get_null_value<
Dimension>()),
686 Swap_opt(birthComparator, deathComparator),
688 RA_opt(orderedBoundaries.size()),
689 Pivot_to_pos_mapper_opt(),
692 colSettings_(colSettings)
694 matrix_.reserve(orderedBoundaries.size());
695 if constexpr (Master_matrix::Option_list::has_map_column_container) {
696 pivotToColumnIndex_.reserve(orderedBoundaries.size());
698 pivotToColumnIndex_.resize(orderedBoundaries.size(), Master_matrix::template get_null_value<Index>());
700 for (
const Boundary_range& b : orderedBoundaries) {
705template <
class Master_matrix>
706template <
typename BirthComparatorFunction,
typename DeathComparatorFunction>
709 const BirthComparatorFunction& birthComparator,
710 const DeathComparatorFunction& deathComparator)
711 : Dim_opt(Master_matrix::template get_null_value<
Dimension>()),
713 Swap_opt(birthComparator, deathComparator),
715 RA_opt(numberOfColumns),
716 Pivot_to_pos_mapper_opt(),
719 colSettings_(colSettings)
721 matrix_.reserve(numberOfColumns);
722 if constexpr (Master_matrix::Option_list::has_map_column_container) {
723 pivotToColumnIndex_.reserve(numberOfColumns);
725 pivotToColumnIndex_.resize(numberOfColumns, Master_matrix::template get_null_value<Index>());
729template <
class Master_matrix>
731 : Dim_opt(static_cast<const Dim_opt&>(matrixToCopy)),
732 Pair_opt(static_cast<const Pair_opt&>(matrixToCopy)),
733 Swap_opt(static_cast<const Swap_opt&>(matrixToCopy)),
734 Rep_opt(static_cast<const Rep_opt&>(matrixToCopy)),
735 RA_opt(static_cast<const RA_opt&>(matrixToCopy)),
736 Pivot_to_pos_mapper_opt(static_cast<const Pivot_to_pos_mapper_opt&>(matrixToCopy)),
737 pivotToColumnIndex_(matrixToCopy.pivotToColumnIndex_),
738 nextIndex_(matrixToCopy.nextIndex_),
739 nextPosition_(matrixToCopy.nextPosition_),
740 colSettings_(colSettings == nullptr ? matrixToCopy.colSettings_ : colSettings)
742 matrix_.reserve(matrixToCopy.matrix_.size());
743 for (
const auto& cont : matrixToCopy.matrix_) {
744 _container_insert(cont);
748template <
class Master_matrix>
750 : Dim_opt(std::move(
static_cast<Dim_opt&
>(other))),
751 Pair_opt(std::move(
static_cast<Pair_opt&
>(other))),
752 Swap_opt(std::move(
static_cast<Swap_opt&
>(other))),
753 Rep_opt(std::move(
static_cast<Rep_opt&
>(other))),
754 RA_opt(std::move(
static_cast<RA_opt&
>(other))),
755 Pivot_to_pos_mapper_opt(std::move(
static_cast<Pivot_to_pos_mapper_opt&
>(other))),
756 matrix_(std::move(other.matrix_)),
757 pivotToColumnIndex_(std::move(other.pivotToColumnIndex_)),
758 nextIndex_(std::exchange(other.nextIndex_, 0)),
759 nextPosition_(std::exchange(other.nextPosition_, 0)),
760 colSettings_(std::exchange(other.colSettings_,
nullptr))
763template <
class Master_matrix>
764template <
class Boundary_range>
766 const Boundary_range& boundary,
769 return insert_boundary(nextIndex_, boundary, dim);
772template <
class Master_matrix>
773template <
class Boundary_range>
774inline std::vector<typename Master_matrix::Entry_representative>
777 if constexpr (!Master_matrix::Option_list::has_map_column_container) {
778 if (pivotToColumnIndex_.size() <= cellID) {
779 pivotToColumnIndex_.resize((cellID * 2) + 1, Master_matrix::template get_null_value<Index>());
783 if constexpr (hasPivotToPosMap_) {
784 if constexpr (Master_matrix::Option_list::has_map_column_container) {
785 Pivot_to_pos_mapper_opt::map_.try_emplace(cellID, nextPosition_);
787 if (Pivot_to_pos_mapper_opt::map_.size() <= cellID)
788 Pivot_to_pos_mapper_opt::map_.resize(pivotToColumnIndex_.size(),
789 Master_matrix::template get_null_value<Pos_index>());
790 Pivot_to_pos_mapper_opt::map_[cellID] = nextPosition_;
794 if constexpr (Master_matrix::Option_list::has_matrix_maximal_dimension_access) {
795 Dim_opt::_update_up(dim == Master_matrix::template get_null_value<Dimension>()
796 ? (boundary.size() == 0 ? 0 : boundary.size() - 1)
800 return _reduce_boundary(cellID, boundary, dim);
803template <
class Master_matrix>
804template <
class Boundary_range>
805inline std::vector<typename Master_matrix::Entry_representative>
808 return insert_maximal_cell(columnIndex, nextIndex_, boundary, dim);
811template <
class Master_matrix>
812template <
class Boundary_range>
816 const Boundary_range& boundary,
820 Master_matrix::Option_list::has_vine_update && (Master_matrix::Option_list::has_column_pairings ||
821 Master_matrix::Option_list::can_retrieve_representative_cycles),
822 "'insert_maximal_cell' is not implemented for the chosen options.");
824 GUDHI_CHECK(columnIndex >= 0, std::invalid_argument(
"Indices have to be positive."));
826 auto chainsInF = insert_boundary(cellID, boundary, dim);
828 const auto& pivotToPosition = Pivot_to_pos_mapper_opt::map_;
829 Pos_index startPos = nextPosition_ - 1;
830 Index startIndex = pivotToColumnIndex_[cellID];
832 if (startPos > columnIndex) {
833 std::vector<Index> colToSwap;
834 colToSwap.reserve(pivotToPosition.size());
840 if constexpr (Master_matrix::Option_list::has_map_column_container) {
841 for (
auto& p : pivotToPosition) {
842 if (p.second >= columnIndex && p.second < startPos) colToSwap.push_back(pivotToColumnIndex_.at(p.first));
844 std::sort(colToSwap.begin(), colToSwap.end(), [&](Index c1, Index c2) {
845 return pivotToPosition.at(get_pivot(c1)) > pivotToPosition.at(get_pivot(c2));
848 for (Index i = 0; i < pivotToPosition.size(); ++i) {
849 if (pivotToPosition[i] >= columnIndex && pivotToPosition[i] < startPos)
850 colToSwap.push_back(pivotToColumnIndex_[i]);
852 std::sort(colToSwap.begin(), colToSwap.end(), [&](Index c1, Index c2) {
853 return pivotToPosition[get_pivot(c1)] > pivotToPosition[get_pivot(c2)];
857 for (Index i : colToSwap) {
858 startIndex = Swap_opt::vine_swap(i, startIndex) == startIndex ? i : startIndex;
865template <
class Master_matrix>
868 if constexpr (Master_matrix::Option_list::has_map_column_container) {
869 return matrix_.at(columnIndex);
871 return matrix_[columnIndex];
875template <
class Master_matrix>
877 Index columnIndex)
const
879 if constexpr (Master_matrix::Option_list::has_map_column_container) {
880 return matrix_.at(columnIndex);
882 return matrix_[columnIndex];
886template <
class Master_matrix>
890 Master_matrix::Option_list::has_removable_columns && Master_matrix::Option_list::has_map_column_container,
891 "'remove_maximal_cell' is not implemented for the chosen options.");
893 Master_matrix::Option_list::has_vine_update && (Master_matrix::Option_list::has_column_pairings ||
894 Master_matrix::Option_list::can_retrieve_representative_cycles),
895 "'remove_maximal_cell' is not implemented for the chosen options.");
899 const auto& pivotToPosition = Pivot_to_pos_mapper_opt::map_;
900 auto it = pivotToPosition.find(cellID);
901 if (it == pivotToPosition.end())
return;
903 Index startIndex = pivotToColumnIndex_.at(cellID);
905 if (startPos != nextPosition_ - 1) {
906 std::vector<Index> colToSwap;
907 colToSwap.reserve(matrix_.size());
909 for (
auto& p : pivotToPosition) {
910 if (p.second > startPos) colToSwap.push_back(pivotToColumnIndex_.at(p.first));
912 std::sort(colToSwap.begin(), colToSwap.end(), [&](
Index c1,
Index c2) {
913 return pivotToPosition.at(get_pivot(c1)) < pivotToPosition.at(get_pivot(c2));
916 for (
Index i : colToSwap) {
917 startIndex = Swap_opt::vine_swap(startIndex, i);
921 _remove_last(startIndex);
924template <
class Master_matrix>
926 const std::vector<ID_index>& columnsToSwap)
928 static_assert(Master_matrix::Option_list::has_removable_columns,
929 "'remove_maximal_cell' is not implemented for the chosen options.");
930 static_assert(Master_matrix::Option_list::has_map_column_container && Master_matrix::Option_list::has_vine_update,
931 "'remove_maximal_cell' is not implemented for the chosen options.");
935 Index startIndex = pivotToColumnIndex_.at(cellID);
938 startIndex = Swap_opt::vine_swap(startIndex, pivotToColumnIndex_.at(i));
941 _remove_last(startIndex);
944template <
class Master_matrix>
947 static_assert(Master_matrix::Option_list::has_removable_columns,
948 "'remove_last' is not implemented for the chosen options.");
949 static_assert(Master_matrix::Option_list::has_map_column_container || !Master_matrix::Option_list::has_vine_update,
950 "'remove_last' is not implemented for the chosen options.");
952 if (nextIndex_ == 0 || matrix_.empty())
return;
954 if constexpr (Master_matrix::Option_list::has_vine_update) {
961 for (
auto& p : pivotToColumnIndex_) {
962 if (p.first > pivot) {
967 _remove_last(colIndex);
969 _remove_last(nextIndex_ - 1);
973template <
class Master_matrix>
976 if constexpr (Master_matrix::Option_list::has_map_column_container) {
977 return matrix_.size();
983template <
class Master_matrix>
985 Index columnIndex)
const
987 return get_column(columnIndex).get_dimension();
990template <
class Master_matrix>
994 _add_to(col, [&]() { col +=
get_column(sourceColumnIndex); });
997template <
class Master_matrix>
1000 Index targetColumnIndex)
1003 _add_to(col, [&]() { col.multiply_target_and_add(coefficient,
get_column(sourceColumnIndex)); });
1006template <
class Master_matrix>
1008 Index sourceColumnIndex,
1009 Index targetColumnIndex)
1012 _add_to(col, [&]() { col.multiply_source_and_add(
get_column(sourceColumnIndex), coefficient); });
1015template <
class Master_matrix>
1018 return !
get_column(columnIndex).is_non_zero(rowIndex);
1021template <
class Master_matrix>
1027template <
class Master_matrix>
1031 if constexpr (Master_matrix::Option_list::has_map_column_container) {
1032 return pivotToColumnIndex_.at(cellID);
1034 return pivotToColumnIndex_[cellID];
1038template <
class Master_matrix>
1044template <
class Master_matrix>
1047 if (
this == &other)
return *
this;
1049 Dim_opt::operator=(other);
1050 Swap_opt::operator=(other);
1051 Pair_opt::operator=(other);
1052 Rep_opt::operator=(other);
1053 Pivot_to_pos_mapper_opt::operator=(other);
1055 pivotToColumnIndex_ = other.pivotToColumnIndex_;
1056 nextIndex_ = other.nextIndex_;
1057 nextPosition_ = other.nextPosition_;
1058 colSettings_ = other.colSettings_;
1060 matrix_.reserve(other.matrix_.size());
1061 for (
const auto& cont : other.matrix_) {
1062 _container_insert(cont);
1068template <
class Master_matrix>
1071 if (
this == &other)
return *
this;
1073 Dim_opt::operator=(std::move(other));
1074 Pair_opt::operator=(std::move(other));
1075 Swap_opt::operator=(std::move(other));
1076 Rep_opt::operator=(std::move(other));
1077 RA_opt::operator=(std::move(other));
1078 Pivot_to_pos_mapper_opt::operator=(std::move(other));
1079 matrix_ = std::move(other.matrix_);
1080 pivotToColumnIndex_ = std::move(other.pivotToColumnIndex_);
1081 nextIndex_ = std::exchange(other.nextIndex_, 0);
1082 nextPosition_ = std::exchange(other.nextPosition_, 0);
1083 colSettings_ = std::exchange(other.colSettings_,
nullptr);
1088template <
class Master_matrix>
1089inline void Chain_matrix<Master_matrix>::print()
const
1091 std::cout <<
"Column Matrix:\n";
1092 if constexpr (!Master_matrix::Option_list::has_map_column_container) {
1093 for (ID_index i = 0; i < pivotToColumnIndex_.size(); ++i) {
1094 Index pos = pivotToColumnIndex_[i];
1095 if (pos != Master_matrix::template get_null_value<Index>()) {
1096 const Column& col = matrix_[pos];
1097 for (
const auto& entry : col) {
1098 std::cout << entry.get_row_index() <<
" ";
1100 std::cout <<
"(" << i <<
", " << pos <<
")\n";
1103 if constexpr (Master_matrix::Option_list::has_row_access) {
1105 std::cout <<
"Row Matrix:\n";
1106 for (ID_index i = 0; i < pivotToColumnIndex_.size(); ++i) {
1107 Index pos = pivotToColumnIndex_[i];
1108 if (pos != Master_matrix::template get_null_value<Index>()) {
1109 const Row& row = RA_opt::get_row(pos);
1110 for (
const auto& entry : row) {
1111 std::cout << entry.get_column_index() <<
" ";
1113 std::cout <<
"(" << i <<
", " << pos <<
")\n";
1118 for (
const auto& p : pivotToColumnIndex_) {
1119 const Column& col = matrix_.at(p.second);
1120 for (
const auto& entry : col) {
1121 std::cout << entry.get_row_index() <<
" ";
1123 std::cout <<
"(" << p.first <<
", " << p.second <<
")\n";
1125 if constexpr (Master_matrix::Option_list::has_row_access) {
1127 std::cout <<
"Row Matrix:\n";
1128 for (
const auto& p : pivotToColumnIndex_) {
1129 const Row& row = RA_opt::get_row(p.first);
1130 for (
const auto& entry : row) {
1131 std::cout << entry.get_column_index() <<
" ";
1133 std::cout <<
"(" << p.first <<
", " << p.second <<
")\n";
1140template <
class Master_matrix>
1141template <
class Boundary_range>
1142inline std::vector<typename Master_matrix::Entry_representative>
1145 Tmp_column column(boundary.begin(), boundary.end());
1146 if (dim == Master_matrix::template get_null_value<Dimension>())
1147 dim = boundary.begin() == boundary.end() ? 0 : boundary.size() - 1;
1148 std::vector<Entry_representative> chainsInH;
1149 std::vector<Entry_representative> chainsInF;
1151 auto get_last = [&column]() {
1152 if constexpr (Master_matrix::Option_list::is_z2)
1153 return *(column.rbegin());
1155 return column.rbegin()->first;
1158 if (boundary.begin() == boundary.end()) {
1159 _insert_in(cellID, column);
1160 _insert_chain(column, dim);
1164 Index currentIndex = get_column_with_pivot(get_last());
1166 while (get_column(currentIndex).is_paired()) {
1167 _reduce_by_G(column, chainsInH, currentIndex);
1169 if (column.empty()) {
1171 _build_from_H(cellID, column, chainsInH);
1173 _insert_chain(column, dim);
1177 currentIndex = get_column_with_pivot(get_last());
1180 while (!column.empty()) {
1181 currentIndex = get_column_with_pivot(get_last());
1183 if (!get_column(currentIndex).is_paired()) {
1185 _reduce_by_F(column, chainsInF, currentIndex);
1187 _reduce_by_G(column, chainsInH, currentIndex);
1191 _update_largest_death_in_F(chainsInF);
1194 _build_from_H(cellID, column, chainsInH);
1197 _insert_chain(column, dim, Master_matrix::get_row_index(chainsInF[0]));
1202template <
class Master_matrix>
1204 std::vector<Entry_representative>& chainsInH,
1207 Column& col = get_column(currentIndex);
1208 if constexpr (Master_matrix::Option_list::is_z2) {
1209 _add_to(col, column, 1U);
1210 chainsInH.push_back(col.get_paired_chain_index());
1212 Field_element coef = col.get_pivot_value();
1213 auto& operators = colSettings_->operators;
1214 coef = operators.get_inverse(coef);
1215 operators.multiply_inplace(coef, operators.get_characteristic() - column.rbegin()->second);
1217 _add_to(col, column, coef);
1218 chainsInH.emplace_back(col.get_paired_chain_index(), coef);
1222template <
class Master_matrix>
1224 std::vector<Entry_representative>& chainsInF,
1227 Column& col = get_column(currentIndex);
1228 if constexpr (Master_matrix::Option_list::is_z2) {
1229 _add_to(col, column, 1U);
1230 chainsInF.push_back(currentIndex);
1232 Field_element coef = col.get_pivot_value();
1233 auto& operators = colSettings_->operators;
1234 coef = operators.get_inverse(coef);
1235 operators.multiply_inplace(coef, operators.get_characteristic() - column.rbegin()->second);
1237 _add_to(col, column, coef);
1238 chainsInF.emplace_back(currentIndex, operators.get_characteristic() - coef);
1242template <
class Master_matrix>
1245 std::vector<Entry_representative>& chainsInH)
1247 _insert_in(cellID, column);
1249 for (
const auto& idx_h : chainsInH) {
1250 _add_to(get_column(Master_matrix::get_row_index(idx_h)), column, Master_matrix::get_element(idx_h));
1254template <
class Master_matrix>
1257 Index toUpdate = Master_matrix::get_row_index(chainsInF[0]);
1258 if constexpr (Master_matrix::Option_list::is_z2) {
1259 for (
auto other_col_it = chainsInF.begin() + 1; other_col_it != chainsInF.end(); ++other_col_it) {
1260 add_to(*other_col_it, toUpdate);
1263 get_column(toUpdate) *= Master_matrix::get_element(chainsInF[0]);
1264 for (
auto other_col_it = chainsInF.begin() + 1; other_col_it != chainsInF.end(); ++other_col_it) {
1265 multiply_source_and_add_to(
1266 Master_matrix::get_element(*other_col_it), Master_matrix::get_row_index(*other_col_it), toUpdate);
1271template <
class Master_matrix>
1274 _container_insert(column, nextIndex_, dimension);
1275 _add_bar(dimension);
1280template <
class Master_matrix>
1285 Pos_index pairPos = pair;
1287 _container_insert(column, nextIndex_, dimension);
1289 get_column(nextIndex_).assign_paired_chain(pair);
1290 auto& pairCol = get_column(pair);
1291 pairCol.assign_paired_chain(nextIndex_);
1293 if constexpr (Master_matrix::Option_list::has_column_pairings && Master_matrix::Option_list::has_vine_update) {
1294 pairPos = Pivot_to_pos_mapper_opt::map_[pairCol.get_pivot()];
1297 _update_barcode(pairPos);
1302template <
class Master_matrix>
1305 [[maybe_unused]]
unsigned int coef)
1307 if constexpr (Master_matrix::Option_list::is_z2) {
1308 std::pair<typename std::set<Index>::iterator,
bool> res_insert;
1309 for (
const Entry& entry : column) {
1310 res_insert = set.insert(entry.get_row_index());
1311 if (!res_insert.second) {
1312 set.erase(res_insert.first);
1316 auto& operators = colSettings_->operators;
1317 for (
const Entry& entry : column) {
1318 auto res = set.emplace(entry.get_row_index(), entry.get_element());
1320 operators.multiply_inplace(res.first->second, coef);
1322 operators.multiply_and_add_inplace_back(entry.get_element(), coef, res.first->second);
1323 if (res.first->second == Field_operators::get_additive_identity()) {
1324 set.erase(res.first);
1331template <
class Master_matrix>
1332template <
typename F>
1335 auto pivot = target.get_pivot();
1336 std::forward<F>(addition)();
1338 if (pivot != target.get_pivot()) {
1339 if constexpr (Master_matrix::Option_list::has_map_column_container) {
1340 std::swap(pivotToColumnIndex_.at(pivot), pivotToColumnIndex_.at(target.get_pivot()));
1342 std::swap(pivotToColumnIndex_[pivot], pivotToColumnIndex_[target.get_pivot()]);
1347template <
class Master_matrix>
1350 static_assert(Master_matrix::Option_list::has_removable_columns,
1351 "'_remove_last' is not implemented for the chosen options.");
1352 static_assert(Master_matrix::Option_list::has_map_column_container || !Master_matrix::Option_list::has_vine_update,
1353 "'_remove_last' is not implemented for the chosen options.");
1357 if constexpr (Master_matrix::Option_list::has_map_column_container) {
1358 auto itToErase = matrix_.find(lastIndex);
1359 Column& colToErase = itToErase->second;
1360 pivot = colToErase.get_pivot();
1362 if constexpr (Master_matrix::Option_list::has_matrix_maximal_dimension_access) {
1363 Dim_opt::_update_down(colToErase.get_dimension());
1366 if (colToErase.is_paired()) matrix_.at(colToErase.get_paired_chain_index()).unassign_paired_chain();
1367 pivotToColumnIndex_.erase(pivot);
1368 matrix_.erase(itToErase);
1370 GUDHI_CHECK(lastIndex == nextIndex_ - 1 && nextIndex_ == matrix_.size(),
1371 std::logic_error(
"Chain_matrix::_remove_last - Indexation problem."));
1373 Column& colToErase = matrix_[lastIndex];
1374 pivot = colToErase.get_pivot();
1376 if constexpr (Master_matrix::Option_list::has_matrix_maximal_dimension_access) {
1377 Dim_opt::_update_down(colToErase.get_dimension());
1380 if (colToErase.is_paired()) matrix_.at(colToErase.get_paired_chain_index()).unassign_paired_chain();
1381 pivotToColumnIndex_[pivot] = Master_matrix::template get_null_value<Index>();
1386 if constexpr (!Master_matrix::Option_list::has_vine_update) {
1391 if constexpr (Master_matrix::Option_list::has_column_pairings) {
1392 Pair_opt::_erase_bar(nextPosition_);
1394 if constexpr (hasPivotToPosMap_) {
1395 Pivot_to_pos_mapper_opt::map_.erase(pivot);
1398 if constexpr (Master_matrix::Option_list::has_row_access) {
1400 RA_opt::get_row(pivot).size() == 0,
1401 std::invalid_argument(
1402 "Chain_matrix::_remove_last - Column asked to be removed does not corresponds to a maximal simplex."));
1403 if constexpr (Master_matrix::Option_list::has_removable_rows) {
1404 RA_opt::erase_empty_row(pivot);
1409template <
class Master_matrix>
1412 if constexpr (Master_matrix::Option_list::has_column_pairings) {
1413 Pair_opt::_update_barcode(birth, nextPosition_);
1418template <
class Master_matrix>
1421 if constexpr (Master_matrix::Option_list::has_column_pairings) {
1422 Pair_opt::_add_bar(dim, nextPosition_);
1427template <
class Master_matrix>
1428template <
class Container>
1431 ID_index pivot = Master_matrix::get_row_index(*(column.rbegin()));
1433 if constexpr (Master_matrix::Option_list::has_map_column_container) {
1434 pivotToColumnIndex_.try_emplace(pivot, pos);
1435 if constexpr (Master_matrix::Option_list::has_row_access) {
1436 matrix_.try_emplace(pos, Column(pos, column, dim, RA_opt::_get_rows_ptr(), colSettings_));
1438 matrix_.try_emplace(pos, Column(column, dim, colSettings_));
1441 if constexpr (Master_matrix::Option_list::has_row_access) {
1442 matrix_.emplace_back(pos, column, dim, RA_opt::_get_rows_ptr(), colSettings_);
1444 matrix_.emplace_back(column, dim, colSettings_);
1446 pivotToColumnIndex_[pivot] = pos;
1450template <
class Master_matrix>
1451template <
class ColumnIterator>
1454 if constexpr (Master_matrix::Option_list::has_map_column_container) {
1455 const auto& col = rep.second;
1456 if constexpr (Master_matrix::Option_list::has_row_access) {
1457 matrix_.try_emplace(rep.first, Column(col, col.get_column_index(), RA_opt::_get_rows_ptr(), colSettings_));
1459 matrix_.try_emplace(rep.first, Column(col, colSettings_));
1462 if constexpr (Master_matrix::Option_list::has_row_access) {
1463 matrix_.emplace_back(rep, rep.get_column_index(), RA_opt::_get_rows_ptr(), colSettings_);
1465 matrix_.emplace_back(rep, colSettings_);
1470template <
class Master_matrix>
1473 if constexpr (Master_matrix::Option_list::is_z2)
1474 column.insert(cellID);
1476 column.emplace(cellID, 1);
Contains the Gudhi::persistence_matrix::Id_to_index_overlay class.
Contains the Gudhi::persistence_matrix::Position_to_index_overlay class.
Matrix structure storing a compatible base of a filtered chain complex. See zigzag....
Definition Chain_matrix.h:58
void remove_maximal_cell(ID_index cellID)
Only available if PersistenceMatrixOptions::has_removable_columns and PersistenceMatrixOptions::has_v...
Definition Chain_matrix.h:887
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:618
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:730
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....
std::vector< Entry_representative > insert_maximal_cell(Index columnIndex, ID_index cellID, const Boundary_range &boundary, Dimension dim=Master_matrix::template get_null_value< Dimension >())
Only available if PersistenceMatrixOptions::has_vine_update is true, as well as, PersistenceMatrixOpt...
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:866
void reset(Column_settings *colSettings)
Resets the matrix to an empty matrix.
Definition Chain_matrix.h:515
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:925
typename Matrix< PersistenceMatrixOptions >::Index Index
Definition Chain_matrix.h:90
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:1007
typename Matrix< PersistenceMatrixOptions >::Pos_index Pos_index
Definition Chain_matrix.h:92
bool is_zero_entry(Index columnIndex, ID_index rowIndex) const
Indicates if the entry at given coordinates has value zero.
Definition Chain_matrix.h:1016
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:707
Chain_matrix(Chain_matrix &&other) noexcept
Move constructor.
Definition Chain_matrix.h:749
typename Matrix< PersistenceMatrixOptions >::Entry_constructor Entry_constructor
Definition Chain_matrix.h:85
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:998
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:1028
Chain_matrix & operator=(Chain_matrix &&other) noexcept
Move assign operator.
Definition Chain_matrix.h:1069
std::vector< Entry_representative > insert_maximal_cell(Index columnIndex, const Boundary_range &boundary, Dimension dim=Master_matrix::template get_null_value< Dimension >())
Only available if PersistenceMatrixOptions::has_vine_update is true, as well as, PersistenceMatrixOpt...
Chain_matrix(Column_settings *colSettings)
Constructs an empty matrix. Only available if PersistenceMatrixOptions::has_column_pairings is true o...
Definition Chain_matrix.h:604
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:643
typename Matrix< PersistenceMatrixOptions >::Row Row
Definition Chain_matrix.h:82
typename Matrix< PersistenceMatrixOptions >::Field_operators Field_operators
Definition Chain_matrix.h:79
typename Matrix< PersistenceMatrixOptions >::Element Field_element
Definition Chain_matrix.h:80
void add_to(Index sourceColumnIndex, Index targetColumnIndex)
Adds column at sourceColumnIndex onto the column at targetColumnIndex in the matrix.
Definition Chain_matrix.h:991
ID_index get_pivot(Index columnIndex)
Returns the row index of the pivot of the given column.
Definition Chain_matrix.h:1039
typename Matrix< PersistenceMatrixOptions >::Entry_representative Entry_representative
Definition Chain_matrix.h:89
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:1022
Chain_matrix(Column_settings *colSettings, const BirthComparatorFunction &birthComparator, const DeathComparatorFunction &deathComparator)
Constructs an empty matrix and stores the given comparators.
Definition Chain_matrix.h:664
Index get_number_of_columns() const
Returns the current number of columns in the matrix.
Definition Chain_matrix.h:974
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:680
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:984
void remove_last()
Only available if PersistenceMatrixOptions::has_removable_columns is true and, if PersistenceMatrixOp...
Definition Chain_matrix.h:945
friend void swap(Chain_matrix &matrix1, Chain_matrix &matrix2) noexcept
Swap operator.
Definition Chain_matrix.h:540
typename Matrix< PersistenceMatrixOptions >::ID_index ID_index
Definition Chain_matrix.h:91
typename Matrix< PersistenceMatrixOptions >::Column Column
Definition Chain_matrix.h:81
typename Matrix< PersistenceMatrixOptions >::Matrix_entry Entry
Definition Chain_matrix.h:84
typename Matrix< PersistenceMatrixOptions >::Dimension Dimension
Definition Chain_matrix.h:93
Chain_matrix & operator=(const Chain_matrix &other)
Assign operator.
Definition Chain_matrix.h:1045
typename Matrix< PersistenceMatrixOptions >::Boundary Boundary
Definition Chain_matrix.h:88
typename Matrix< PersistenceMatrixOptions >::Column_settings Column_settings
Definition Chain_matrix.h:86
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:876
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:41
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)
Insertion_return insert_maximal_cell(Index columnIndex, const Boundary_range &boundary, Dimension dim=Matrix::get_null_value< Dimension >())
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)
Overlay for chain matrices replacing all input and output MatIdx indices of the original methods with...
Definition Position_to_index_overlay.h:43
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