17#ifndef PM_CHAIN_MATRIX_H 
   18#define PM_CHAIN_MATRIX_H 
   31namespace persistence_matrix {
 
   44template <
class Master_matrix>
 
   46                     public Master_matrix::Chain_pairing_option,
 
   47                     public Master_matrix::Chain_vine_swap_option,
 
   48                     public Master_matrix::Chain_representative_cycles_option,
 
   49                     public Master_matrix::Matrix_row_access_option
 
   57  using Column = 
typename Master_matrix::Column;                            
 
   58  using Row = 
typename Master_matrix::Row;                                  
 
   60  using Entry = 
typename Master_matrix::Matrix_entry;                       
 
   64  using Boundary = 
typename Master_matrix::Boundary;                        
 
   66  using Index = 
typename Master_matrix::Index;                              
 
   67  using ID_index = 
typename Master_matrix::ID_index;                        
 
   68  using Pos_index = 
typename Master_matrix::Pos_index;                      
 
   69  using Dimension = 
typename Master_matrix::Dimension;                      
 
  104  template <
class Boundary_range = Boundary>
 
  105  Chain_matrix(
const std::vector<Boundary_range>& orderedBoundaries,
 
  138  template <
typename BirthComparatorFunction, 
typename DeathComparatorFunction>
 
  140               const BirthComparatorFunction& birthComparator,
 
  141               const DeathComparatorFunction& deathComparator);
 
  178  template <
typename BirthComparatorFunction, 
typename DeathComparatorFunction, 
class Boundary_range = Boundary>
 
  179  Chain_matrix(
const std::vector<Boundary_range>& orderedBoundaries,
 
  181               const BirthComparatorFunction& birthComparator,
 
  182               const DeathComparatorFunction& deathComparator);
 
  205  template <
typename BirthComparatorFunction, 
typename DeathComparatorFunction>
 
  208               const BirthComparatorFunction& birthComparator,
 
  209               const DeathComparatorFunction& deathComparator);
 
  249  template <
class Boundary_range = Boundary>
 
  251      const Boundary_range& boundary, 
Dimension dim = Master_matrix::template get_null_value<Dimension>());
 
  270  template <
class Boundary_range = Boundary>
 
  273      const Boundary_range& boundary,
 
  274      Dimension dim = Master_matrix::template get_null_value<Dimension>());
 
  388                                  Index targetColumnIndex);
 
  402                                  Index sourceColumnIndex,
 
  403                                  Index targetColumnIndex);
 
  447    pivotToColumnIndex_.clear();
 
  449    colSettings_ = colSettings;
 
  460    swap(
static_cast<typename Master_matrix::Matrix_dimension_option&
>(matrix1),
 
  461         static_cast<typename Master_matrix::Matrix_dimension_option&
>(matrix2));
 
  462    swap(
static_cast<typename Master_matrix::Chain_pairing_option&
>(matrix1),
 
  463         static_cast<typename Master_matrix::Chain_pairing_option&
>(matrix2));
 
  464    swap(
static_cast<typename Master_matrix::Chain_vine_swap_option&
>(matrix1),
 
  465         static_cast<typename Master_matrix::Chain_vine_swap_option&
>(matrix2));
 
  466    swap(
static_cast<typename Master_matrix::Chain_representative_cycles_option&
>(matrix1),
 
  467         static_cast<typename Master_matrix::Chain_representative_cycles_option&
>(matrix2));
 
  468    matrix1.matrix_.swap(matrix2.matrix_);
 
  469    matrix1.pivotToColumnIndex_.swap(matrix2.pivotToColumnIndex_);
 
  470    std::swap(matrix1.nextIndex_, matrix2.nextIndex_);
 
  471    std::swap(matrix1.colSettings_, matrix2.colSettings_);
 
  474      swap(
static_cast<typename Master_matrix::Matrix_row_access_option&
>(matrix1),
 
  475           static_cast<typename Master_matrix::Matrix_row_access_option&
>(matrix2));
 
  484  using Dim_opt = 
typename Master_matrix::Matrix_dimension_option;
 
  485  using Swap_opt = 
typename Master_matrix::Chain_vine_swap_option;
 
  486  using Pair_opt = 
typename Master_matrix::Chain_pairing_option;
 
  487  using Rep_opt = 
typename Master_matrix::Chain_representative_cycles_option;
 
  488  using RA_opt = 
typename Master_matrix::Matrix_row_access_option;
 
  489  using Column_container = 
typename Master_matrix::Column_container;
 
  490  using Dictionary = 
typename Master_matrix::template Dictionary<Index>;
 
  491  using Barcode = 
typename Master_matrix::Barcode;
 
  492  using Bar_dictionary = 
typename Master_matrix::Bar_dictionary;
 
  495                                               std::map<ID_index, Field_element>
 
  498  Column_container matrix_;       
 
  499  Dictionary pivotToColumnIndex_; 
 
  503  template <
class Boundary_range>
 
  504  std::vector<Entry_representative> _reduce_boundary(
ID_index cellID, 
const Boundary_range& boundary, Dimension dim);
 
  505  void _reduce_by_G(Tmp_column& column, std::vector<Entry_representative>& chainsInH, Index currentPivot);
 
  506  void _reduce_by_F(Tmp_column& column, std::vector<Entry_representative>& chainsInF, Index currentPivot);
 
  507  void _build_from_H(
ID_index cellID, Tmp_column& column, std::vector<Entry_representative>& chainsInH);
 
  508  void _update_largest_death_in_F(
const std::vector<Entry_representative>& chainsInF);
 
  509  void _insert_chain(
const Tmp_column& column, Dimension dimension);
 
  510  void _insert_chain(
const Tmp_column& column, Dimension dimension, Index pair);
 
  511  void _add_to(
const Column& column, Tmp_column& set, 
unsigned int coef);
 
  512  template <
typename F>
 
  513  void _add_to(
Column& target, F&& addition);
 
  514  void _remove_last(Index lastIndex);
 
  516  void _add_bar(Dimension dim);
 
  517  template <
class Container>
 
  518  void _container_insert(
const Container& column, Index pos, Dimension dim);
 
  519  void _container_insert(
const Column& column, [[maybe_unused]] Index pos = 0);
 
  521  constexpr Barcode& _barcode();
 
  522  constexpr Bar_dictionary& _indexToBar();
 
  526template <
class Master_matrix>
 
  528    : Dim_opt(Master_matrix::template get_null_value<
Dimension>()),
 
  534      colSettings_(colSettings)
 
  537template <
class Master_matrix>
 
  538template <
class Boundary_range>
 
  541    : Dim_opt(Master_matrix::template get_null_value<
Dimension>()),
 
  545      RA_opt(orderedBoundaries.size()),
 
  547      colSettings_(colSettings)
 
  549  matrix_.reserve(orderedBoundaries.size());
 
  551    pivotToColumnIndex_.reserve(orderedBoundaries.size());
 
  553    pivotToColumnIndex_.resize(orderedBoundaries.size(), Master_matrix::template get_null_value<Index>());
 
  556  for (
const Boundary_range& b : orderedBoundaries) {
 
  561template <
class Master_matrix>
 
  564    : Dim_opt(Master_matrix::template get_null_value<
Dimension>()),
 
  568      RA_opt(numberOfColumns),
 
  570      colSettings_(colSettings)
 
  572  matrix_.reserve(numberOfColumns);
 
  574    pivotToColumnIndex_.reserve(numberOfColumns);
 
  576    pivotToColumnIndex_.resize(numberOfColumns, Master_matrix::template get_null_value<Index>());
 
  580template <
class Master_matrix>
 
  581template <
typename BirthComparatorFunction, 
typename DeathComparatorFunction>
 
  583                                                 const BirthComparatorFunction& birthComparator,
 
  584                                                 const DeathComparatorFunction& deathComparator)
 
  585    : Dim_opt(Master_matrix::template get_null_value<
Dimension>()),
 
  587      Swap_opt(birthComparator, deathComparator),
 
  591      colSettings_(colSettings)
 
  594template <
class Master_matrix>
 
  595template <
typename BirthComparatorFunction, 
typename DeathComparatorFunction, 
class Boundary_range>
 
  598                                                 const BirthComparatorFunction& birthComparator,
 
  599                                                 const DeathComparatorFunction& deathComparator)
 
  600    : Dim_opt(Master_matrix::template get_null_value<
Dimension>()),
 
  602      Swap_opt(birthComparator, deathComparator),
 
  604      RA_opt(orderedBoundaries.size()),
 
  606      colSettings_(colSettings)
 
  608  matrix_.reserve(orderedBoundaries.size());
 
  610    pivotToColumnIndex_.reserve(orderedBoundaries.size());
 
  612    pivotToColumnIndex_.resize(orderedBoundaries.size(), Master_matrix::template get_null_value<Index>());
 
  614  for (
const Boundary_range& b : orderedBoundaries) {
 
  619template <
class Master_matrix>
 
  620template <
typename BirthComparatorFunction, 
typename DeathComparatorFunction>
 
  623                                                 const BirthComparatorFunction& birthComparator,
 
  624                                                 const DeathComparatorFunction& deathComparator)
 
  625    : Dim_opt(Master_matrix::template get_null_value<
Dimension>()),
 
  627      Swap_opt(birthComparator, deathComparator),
 
  629      RA_opt(numberOfColumns),
 
  631      colSettings_(colSettings)
 
  633  matrix_.reserve(numberOfColumns);
 
  635    pivotToColumnIndex_.reserve(numberOfColumns);
 
  637    pivotToColumnIndex_.resize(numberOfColumns, Master_matrix::template get_null_value<Index>());
 
  641template <
class Master_matrix>
 
  643    : Dim_opt(static_cast<const Dim_opt&>(matrixToCopy)),
 
  644      Pair_opt(static_cast<const Pair_opt&>(matrixToCopy)),
 
  645      Swap_opt(static_cast<const Swap_opt&>(matrixToCopy)),
 
  646      Rep_opt(static_cast<const Rep_opt&>(matrixToCopy)),
 
  647      RA_opt(static_cast<const RA_opt&>(matrixToCopy)),
 
  648      pivotToColumnIndex_(matrixToCopy.pivotToColumnIndex_),
 
  649      nextIndex_(matrixToCopy.nextIndex_),
 
  650      colSettings_(colSettings == nullptr ? matrixToCopy.colSettings_ : colSettings)
 
  652  matrix_.reserve(matrixToCopy.matrix_.size());
 
  653  for (
const auto& cont : matrixToCopy.matrix_){
 
  655      _container_insert(cont.second, cont.first);
 
  657      _container_insert(cont);
 
  662template <
class Master_matrix>
 
  664    : Dim_opt(std::move(
static_cast<Dim_opt&
>(other))),
 
  665      Pair_opt(std::move(
static_cast<Pair_opt&
>(other))),
 
  666      Swap_opt(std::move(
static_cast<Swap_opt&
>(other))),
 
  667      Rep_opt(std::move(
static_cast<Rep_opt&
>(other))),
 
  668      RA_opt(std::move(
static_cast<RA_opt&
>(other))),
 
  669      matrix_(std::move(other.matrix_)),
 
  670      pivotToColumnIndex_(std::move(other.pivotToColumnIndex_)),
 
  671      nextIndex_(std::exchange(other.nextIndex_, 0)),
 
  672      colSettings_(std::exchange(other.colSettings_, 
nullptr))
 
  675template <
class Master_matrix>
 
  676template <
class Boundary_range>
 
  678    const Boundary_range& boundary, Dimension dim)
 
  680  return insert_boundary(nextIndex_, boundary, dim);
 
  683template <
class Master_matrix>
 
  684template <
class Boundary_range>
 
  686    ID_index cellID, 
const Boundary_range& boundary, Dimension dim)
 
  688  if constexpr (!Master_matrix::Option_list::has_map_column_container) {
 
  689    if (pivotToColumnIndex_.size() <= cellID) {
 
  690      pivotToColumnIndex_.resize(cellID * 2 + 1, Master_matrix::template get_null_value<Index>());
 
  694  if constexpr (Master_matrix::Option_list::has_vine_update && Master_matrix::Option_list::has_column_pairings) {
 
  695    if constexpr (Master_matrix::Option_list::has_map_column_container) {
 
  696      Swap_opt::CP::pivotToPosition_.try_emplace(cellID, _nextPosition());
 
  698      if (Swap_opt::CP::pivotToPosition_.size() <= cellID)
 
  699        Swap_opt::CP::pivotToPosition_.resize(pivotToColumnIndex_.size(),
 
  700                                              Master_matrix::template get_null_value<Pos_index>());
 
  701      Swap_opt::CP::pivotToPosition_[cellID] = _nextPosition();
 
  705  if constexpr (Master_matrix::Option_list::has_matrix_maximal_dimension_access) {
 
  706    Dim_opt::update_up(dim == Master_matrix::template get_null_value<Dimension>()
 
  707                           ? (boundary.size() == 0 ? 0 : boundary.size() - 1)
 
  711  return _reduce_boundary(cellID, boundary, dim);
 
  714template <
class Master_matrix>
 
  717  if constexpr (Master_matrix::Option_list::has_map_column_container) {
 
  718    return matrix_.at(columnIndex);
 
  720    return matrix_[columnIndex];
 
  724template <
class Master_matrix>
 
  726    Index columnIndex)
 const 
  728  if constexpr (Master_matrix::Option_list::has_map_column_container) {
 
  729    return matrix_.at(columnIndex);
 
  731    return matrix_[columnIndex];
 
  735template <
class Master_matrix>
 
  738  static_assert(Master_matrix::Option_list::has_removable_columns,
 
  739                "'remove_maximal_cell' is not implemented for the chosen options.");
 
  740  static_assert(Master_matrix::Option_list::has_map_column_container &&
 
  741                    Master_matrix::Option_list::has_vine_update &&
 
  742                    Master_matrix::Option_list::has_column_pairings,
 
  743                "'remove_maximal_cell' is not implemented for the chosen options.");
 
  747  const auto& pivotToPosition = Swap_opt::CP::pivotToPosition_;
 
  748  auto it = pivotToPosition.find(cellID);
 
  749  if (it == pivotToPosition.end()) 
return;  
 
  751  Index startIndex = pivotToColumnIndex_.at(cellID);
 
  753  if (startPos != _nextPosition() - 1) {
 
  754    std::vector<Index> colToSwap;
 
  755    colToSwap.reserve(matrix_.size());
 
  757    for (
auto& p : pivotToPosition) {
 
  758      if (p.second > startPos) colToSwap.push_back(pivotToColumnIndex_.at(p.first));
 
  760    std::sort(colToSwap.begin(), colToSwap.end(), [&](
Index c1, 
Index c2) {
 
  761      return pivotToPosition.at(get_pivot(c1)) < pivotToPosition.at(get_pivot(c2));
 
  764    for (
Index i : colToSwap) {
 
  765      startIndex = Swap_opt::vine_swap(startIndex, i);
 
  769  _remove_last(startIndex);
 
  772template <
class Master_matrix>
 
  774                                                             const std::vector<ID_index>& columnsToSwap)
 
  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                "'remove_maximal_cell' is not implemented for the chosen options.");
 
  783  Index startIndex = pivotToColumnIndex_.at(cellID);
 
  786    startIndex = Swap_opt::vine_swap(startIndex, pivotToColumnIndex_.at(i));
 
  789  _remove_last(startIndex);
 
  792template <
class Master_matrix>
 
  795  static_assert(Master_matrix::Option_list::has_removable_columns,
 
  796                "'remove_last' is not implemented for the chosen options.");
 
  797  static_assert(Master_matrix::Option_list::has_map_column_container || !Master_matrix::Option_list::has_vine_update,
 
  798                "'remove_last' is not implemented for the chosen options.");
 
  800  if (nextIndex_ == 0 || matrix_.empty()) 
return;  
 
  802  if constexpr (Master_matrix::Option_list::has_vine_update) {
 
  809    for (
auto& p : pivotToColumnIndex_) {
 
  810      if (p.first > pivot) {  
 
  815    _remove_last(colIndex);
 
  817    _remove_last(nextIndex_ - 1);
 
  821template <
class Master_matrix>
 
  824  if constexpr (Master_matrix::Option_list::has_map_column_container) {
 
  825    return matrix_.size();
 
  831template <
class Master_matrix>
 
  833    Index columnIndex)
 const 
  835  return get_column(columnIndex).get_dimension();
 
  838template <
class Master_matrix>
 
  841  auto& col = get_column(targetColumnIndex);
 
  842  _add_to(col, [&]() { col += get_column(sourceColumnIndex); });
 
  845template <
class Master_matrix>
 
  848                                                                    Index targetColumnIndex)
 
  850  auto& col = get_column(targetColumnIndex);
 
  851  _add_to(col, [&]() { col.multiply_target_and_add(coefficient, get_column(sourceColumnIndex)); });
 
  854template <
class Master_matrix>
 
  856                                                                    Index sourceColumnIndex,
 
  857                                                                    Index targetColumnIndex)
 
  859  auto& col = get_column(targetColumnIndex);
 
  860  _add_to(col, [&]() { col.multiply_source_and_add(get_column(sourceColumnIndex), coefficient); });
 
  863template <
class Master_matrix>
 
  866  return !get_column(columnIndex).is_non_zero(rowIndex);
 
  869template <
class Master_matrix>
 
  872  return get_column(columnIndex).is_empty();
 
  875template <
class Master_matrix>
 
  879  if constexpr (Master_matrix::Option_list::has_map_column_container) {
 
  880    return pivotToColumnIndex_.at(cellID);
 
  882    return pivotToColumnIndex_[cellID];
 
  886template <
class Master_matrix>
 
  889  return get_column(columnIndex).get_pivot();
 
  892template <
class Master_matrix>
 
  895  Dim_opt::operator=(other);
 
  896  Swap_opt::operator=(other);
 
  897  Pair_opt::operator=(other);
 
  898  Rep_opt::operator=(other);
 
  900  pivotToColumnIndex_ = other.pivotToColumnIndex_;
 
  901  nextIndex_ = other.nextIndex_;
 
  902  colSettings_ = other.colSettings_;
 
  904  matrix_.reserve(other.matrix_.size());
 
  905  for (
const auto& cont : other.matrix_){
 
  906    if constexpr (Master_matrix::Option_list::has_map_column_container){
 
  907      _container_insert(cont.second, cont.first);
 
  909      _container_insert(cont);
 
  916template <
class Master_matrix>
 
  919  std::cout << 
"Column Matrix:\n";
 
  920  if constexpr (!Master_matrix::Option_list::has_map_column_container) {
 
  921    for (ID_index i = 0; i < pivotToColumnIndex_.size(); ++i) {
 
  922      Index pos = pivotToColumnIndex_[i];
 
  923      if (pos != Master_matrix::template get_null_value<Index>()){
 
  924        const Column& col = matrix_[pos];
 
  925        for (
const auto& entry : col) {
 
  926          std::cout << entry.get_row_index() << 
" ";
 
  928        std::cout << 
"(" << i << 
", " << pos << 
")\n";
 
  931    if constexpr (Master_matrix::Option_list::has_row_access) {
 
  933      std::cout << 
"Row Matrix:\n";
 
  934      for (ID_index i = 0; i < pivotToColumnIndex_.size(); ++i) {
 
  935        Index pos = pivotToColumnIndex_[i];
 
  936        if (pos != Master_matrix::template get_null_value<Index>()){
 
  937          const Row& row = RA_opt::get_row(pos);
 
  938          for (
const auto& entry : row) {
 
  939            std::cout << entry.get_column_index() << 
" ";
 
  941          std::cout << 
"(" << i << 
", " << pos << 
")\n";
 
  946    for (
const auto& p : pivotToColumnIndex_) {
 
  947      const Column& col = matrix_.at(p.second);
 
  948      for (
const auto& entry : col) {
 
  949        std::cout << entry.get_row_index() << 
" ";
 
  951      std::cout << 
"(" << p.first << 
", " << p.second << 
")\n";
 
  953    if constexpr (Master_matrix::Option_list::has_row_access) {
 
  955      std::cout << 
"Row Matrix:\n";
 
  956      for (
const auto& p : pivotToColumnIndex_) {
 
  957        const Row& row = RA_opt::get_row(p.first);
 
  958        for (
const auto& entry : row) {
 
  959          std::cout << entry.get_column_index() << 
" ";
 
  961        std::cout << 
"(" << p.first << 
", " << p.second << 
")\n";
 
  968template <
class Master_matrix>
 
  969template <
class Boundary_range>
 
  971    ID_index cellID, 
const Boundary_range& boundary, Dimension dim)
 
  973  Tmp_column column(boundary.begin(), boundary.end());
 
  974  if (dim == Master_matrix::template get_null_value<Dimension>())
 
  975    dim = boundary.begin() == boundary.end() ? 0 : boundary.size() - 1;
 
  976  std::vector<Entry_representative> chainsInH;  
 
  977  std::vector<Entry_representative> chainsInF;  
 
  979  auto get_last = [&column]() {
 
  980    if constexpr (Master_matrix::Option_list::is_z2)
 
  981      return *(column.rbegin());
 
  983      return column.rbegin()->first;
 
  986  if (boundary.begin() == boundary.end()) {
 
  987    if constexpr (Master_matrix::Option_list::is_z2)
 
  988      column.insert(cellID);
 
  990      column.emplace(cellID, 1);
 
  991    _insert_chain(column, dim);
 
  995  Index currentIndex = get_column_with_pivot(get_last());
 
  997  while (get_column(currentIndex).is_paired()) {
 
  998    _reduce_by_G(column, chainsInH, currentIndex);
 
 1000    if (column.empty()) {
 
 1002      _build_from_H(cellID, column, chainsInH);
 
 1004      _insert_chain(column, dim);
 
 1008    currentIndex = get_column_with_pivot(get_last());
 
 1011  while (!column.empty()) {
 
 1012    currentIndex = get_column_with_pivot(get_last());
 
 1014    if (!get_column(currentIndex).is_paired()) {
 
 1016      _reduce_by_F(column, chainsInF, currentIndex);
 
 1018      _reduce_by_G(column, chainsInH, currentIndex);
 
 1022  _update_largest_death_in_F(chainsInF);
 
 1025  _build_from_H(cellID, column, chainsInH);
 
 1028  if constexpr (Master_matrix::Option_list::is_z2)
 
 1029    _insert_chain(column, dim, chainsInF[0]);
 
 1031    _insert_chain(column, dim, chainsInF[0].first);
 
 1036template <
class Master_matrix>
 
 1038                                                      std::vector<Entry_representative>& chainsInH,
 
 1041  Column& col = get_column(currentIndex);
 
 1042  if constexpr (Master_matrix::Option_list::is_z2) {
 
 1043    _add_to(col, column, 1u);                           
 
 1044    chainsInH.push_back(col.get_paired_chain_index());  
 
 1046    Field_element coef = col.get_pivot_value();
 
 1047    auto& operators = colSettings_->operators;
 
 1048    coef = operators.get_inverse(coef);
 
 1049    operators.multiply_inplace(coef, operators.get_characteristic() - column.rbegin()->second);
 
 1051    _add_to(col, column, coef);                                       
 
 1052    chainsInH.emplace_back(col.get_paired_chain_index(), coef); 
 
 1056template <
class Master_matrix>
 
 1058                                                      std::vector<Entry_representative>& chainsInF,
 
 1061  Column& col = get_column(currentIndex);
 
 1062  if constexpr (Master_matrix::Option_list::is_z2) {
 
 1063    _add_to(col, column, 1u);  
 
 1064    chainsInF.push_back(currentIndex);
 
 1066    Field_element coef = col.get_pivot_value();
 
 1067    auto& operators = colSettings_->operators;
 
 1068    coef = operators.get_inverse(coef);
 
 1069    operators.multiply_inplace(coef, operators.get_characteristic() - column.rbegin()->second);
 
 1071    _add_to(col, column, coef);  
 
 1072    chainsInF.emplace_back(currentIndex, operators.get_characteristic() - coef);
 
 1076template <
class Master_matrix>
 
 1079                                                       std::vector<Entry_representative>& chainsInH)
 
 1081  if constexpr (Master_matrix::Option_list::is_z2) {
 
 1082    column.insert(cellID);
 
 1083    for (Index idx_h : chainsInH) {
 
 1084      _add_to(get_column(idx_h), column, 1u);
 
 1087    column.emplace(cellID, 1);
 
 1088    for (std::pair<Index, Field_element>& idx_h : chainsInH) {
 
 1089      _add_to(get_column(idx_h.first), column, idx_h.second);
 
 1094template <
class Master_matrix>
 
 1097  if constexpr (Master_matrix::Option_list::is_z2) {
 
 1098    Index toUpdate = chainsInF[0];
 
 1099    for (
auto other_col_it = chainsInF.begin() + 1; other_col_it != chainsInF.end(); ++other_col_it) {
 
 1100      add_to(*other_col_it, toUpdate);
 
 1103    Index toUpdate = chainsInF[0].first;
 
 1104    get_column(toUpdate) *= chainsInF[0].second;
 
 1105    for (
auto other_col_it = chainsInF.begin() + 1; other_col_it != chainsInF.end(); ++other_col_it) {
 
 1106      multiply_source_and_add_to(other_col_it->second, other_col_it->first, toUpdate);
 
 1111template <
class Master_matrix>
 
 1114  _container_insert(column, nextIndex_, dimension);
 
 1115  _add_bar(dimension);
 
 1120template <
class Master_matrix>
 
 1125  Pos_index pairPos = pair;
 
 1127  _container_insert(column, nextIndex_, dimension);
 
 1129  get_column(nextIndex_).assign_paired_chain(pair);
 
 1130  auto& pairCol = get_column(pair);
 
 1131  pairCol.assign_paired_chain(nextIndex_);
 
 1133  if constexpr (Master_matrix::Option_list::has_column_pairings && Master_matrix::Option_list::has_vine_update) {
 
 1134    pairPos = Swap_opt::CP::pivotToPosition_[pairCol.get_pivot()];
 
 1137  _update_barcode(pairPos);
 
 1142template <
class Master_matrix>
 
 1145                                                 [[maybe_unused]] 
unsigned int coef)
 
 1147  if constexpr (Master_matrix::Option_list::is_z2) {
 
 1148    std::pair<typename std::set<Index>::iterator, 
bool> res_insert;
 
 1149    for (
const Entry& entry : column) {
 
 1150      res_insert = set.insert(entry.get_row_index());
 
 1151      if (!res_insert.second) {
 
 1152        set.erase(res_insert.first);
 
 1156    auto& operators = colSettings_->operators;
 
 1157    for (
const Entry& entry : column) {
 
 1158      auto res = set.emplace(entry.get_row_index(), entry.get_element());
 
 1160        operators.multiply_inplace(res.first->second, coef);
 
 1162        operators.multiply_and_add_inplace_back(entry.get_element(), coef, res.first->second);
 
 1163        if (res.first->second == Field_operators::get_additive_identity()) {
 
 1164          set.erase(res.first);
 
 1171template <
class Master_matrix>
 
 1172template <
typename F>
 
 1175  auto pivot = target.get_pivot();
 
 1178  if (pivot != target.get_pivot()) {
 
 1179    if constexpr (Master_matrix::Option_list::has_map_column_container) {
 
 1180      std::swap(pivotToColumnIndex_.at(pivot), pivotToColumnIndex_.at(target.get_pivot()));
 
 1182      std::swap(pivotToColumnIndex_[pivot], pivotToColumnIndex_[target.get_pivot()]);
 
 1187template <
class Master_matrix>
 
 1190  static_assert(Master_matrix::Option_list::has_removable_columns,
 
 1191                "'_remove_last' is not implemented for the chosen options.");
 
 1192  static_assert(Master_matrix::Option_list::has_map_column_container || !Master_matrix::Option_list::has_vine_update,
 
 1193                "'_remove_last' is not implemented for the chosen options.");
 
 1197  if constexpr (Master_matrix::Option_list::has_map_column_container) {
 
 1198    auto itToErase = matrix_.find(lastIndex);
 
 1199    Column& colToErase = itToErase->second;
 
 1202    if constexpr (Master_matrix::Option_list::has_matrix_maximal_dimension_access) {
 
 1203      Dim_opt::update_down(colToErase.get_dimension());
 
 1206    if (colToErase.is_paired()) matrix_.at(colToErase.get_paired_chain_index()).unassign_paired_chain();
 
 1207    pivotToColumnIndex_.erase(pivot);
 
 1208    matrix_.erase(itToErase);
 
 1210    GUDHI_CHECK(lastIndex == nextIndex_ - 1 && nextIndex_ == matrix_.size(),
 
 1211                std::logic_error(
"Chain_matrix::_remove_last - Indexation problem."));
 
 1213    Column& colToErase = matrix_[lastIndex];
 
 1214    pivot = colToErase.get_pivot();
 
 1216    if constexpr (Master_matrix::Option_list::has_matrix_maximal_dimension_access) {
 
 1217      Dim_opt::update_down(colToErase.get_dimension());
 
 1220    if (colToErase.is_paired()) matrix_.at(colToErase.get_paired_chain_index()).unassign_paired_chain();
 
 1221    pivotToColumnIndex_[pivot] = Master_matrix::template get_null_value<Index>();
 
 1226  if constexpr (!Master_matrix::Option_list::has_vine_update) {
 
 1230  if constexpr (Master_matrix::Option_list::has_column_pairings) {
 
 1231    auto it = _indexToBar().find(--_nextPosition());
 
 1232    typename Barcode::iterator bar = it->second;
 
 1234    if (bar->death == Master_matrix::template get_null_value<Pos_index>())
 
 1235      _barcode().erase(bar);
 
 1237      bar->death = Master_matrix::template get_null_value<Pos_index>();
 
 1239    _indexToBar().erase(it);
 
 1240    if constexpr (Master_matrix::Option_list::has_vine_update) Swap_opt::CP::pivotToPosition_.erase(pivot);
 
 1243  if constexpr (Master_matrix::Option_list::has_row_access) {
 
 1245        RA_opt::get_row(pivot).size() == 0,
 
 1246        std::invalid_argument(
 
 1247            "Chain_matrix::_remove_last - Column asked to be removed does not corresponds to a maximal simplex."));
 
 1248    if constexpr (Master_matrix::Option_list::has_removable_rows) {
 
 1249      RA_opt::erase_empty_row(pivot);
 
 1254template <
class Master_matrix>
 
 1257  if constexpr (Master_matrix::Option_list::has_column_pairings) {
 
 1258    if constexpr (Master_matrix::Option_list::has_removable_columns) {
 
 1259      auto& barIt = _indexToBar().at(birth);
 
 1260      barIt->death = _nextPosition();
 
 1261      _indexToBar().try_emplace(_nextPosition(), barIt);  
 
 1263      _barcode()[_indexToBar()[birth]].death = _nextPosition();
 
 1264      _indexToBar().push_back(_indexToBar()[birth]);
 
 1270template <
class Master_matrix>
 
 1273  if constexpr (Master_matrix::Option_list::has_column_pairings) {
 
 1274    _barcode().emplace_back(_nextPosition(), Master_matrix::template get_null_value<Pos_index>(), dim);
 
 1275    if constexpr (Master_matrix::Option_list::has_removable_columns) {
 
 1276      _indexToBar().try_emplace(_nextPosition(), --_barcode().end());
 
 1278      _indexToBar().push_back(_barcode().size() - 1);
 
 1284template <
class Master_matrix>
 
 1285template <
class Container>
 
 1289  if constexpr (Master_matrix::Option_list::is_z2) {
 
 1290    pivot = *(column.rbegin());
 
 1292    pivot = column.rbegin()->first;
 
 1294  if constexpr (Master_matrix::Option_list::has_map_column_container) {
 
 1295    pivotToColumnIndex_.try_emplace(pivot, pos);
 
 1296    if constexpr (Master_matrix::Option_list::has_row_access) {
 
 1297      matrix_.try_emplace(pos, Column(pos, column, dim, RA_opt::rows_, colSettings_));
 
 1299      matrix_.try_emplace(pos, Column(column, dim, colSettings_));
 
 1302    if constexpr (Master_matrix::Option_list::has_row_access) {
 
 1303      matrix_.emplace_back(pos, column, dim, RA_opt::rows_, colSettings_);
 
 1305      matrix_.emplace_back(column, dim, colSettings_);
 
 1307    pivotToColumnIndex_[pivot] = pos;
 
 1311template <
class Master_matrix>
 
 1314  if constexpr (Master_matrix::Option_list::has_map_column_container) {
 
 1315    if constexpr (Master_matrix::Option_list::has_row_access) {
 
 1316      matrix_.try_emplace(pos, Column(column, column.get_column_index(), RA_opt::rows_, colSettings_));
 
 1318      matrix_.try_emplace(pos, Column(column, colSettings_));
 
 1321    if constexpr (Master_matrix::Option_list::has_row_access) {
 
 1322      matrix_.emplace_back(column, column.get_column_index(), RA_opt::rows_, colSettings_);
 
 1324      matrix_.emplace_back(column, colSettings_);
 
 1329template <
class Master_matrix>
 
 1332  if constexpr (Master_matrix::Option_list::has_vine_update)
 
 1333    return Swap_opt::template Chain_pairing<Master_matrix>::barcode_;
 
 1335    return Pair_opt::barcode_;
 
 1338template <
class Master_matrix>
 
 1339inline constexpr typename Chain_matrix<Master_matrix>::Bar_dictionary&
 
 1342  if constexpr (Master_matrix::Option_list::has_vine_update)
 
 1343    return Swap_opt::template Chain_pairing<Master_matrix>::indexToBar_;
 
 1345    return Pair_opt::indexToBar_;
 
 1348template <
class Master_matrix>
 
 1351  if constexpr (Master_matrix::Option_list::has_vine_update)
 
 1352    return Swap_opt::template Chain_pairing<Master_matrix>::nextPosition_;
 
 1354    return Pair_opt::nextPosition_;
 
Contains the Gudhi::persistence_matrix::Id_to_index_overlay class.
 
Matrix structure storing a compatible base of a filtered chain complex. See . The base is constructed...
Definition: Chain_matrix.h:50
 
void remove_maximal_cell(ID_index cellID)
Only available if PersistenceMatrixOptions::has_removable_columns and PersistenceMatrixOptions::has_v...
Definition: Chain_matrix.h:736
 
friend void swap(Chain_matrix &matrix1, Chain_matrix &matrix2)
Swap operator.
Definition: Chain_matrix.h:459
 
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:715
 
void reset(Column_settings *colSettings)
Resets the matrix to an empty matrix.
Definition: Chain_matrix.h:445
 
typename Master_matrix::Index Index
Definition: Chain_matrix.h:66
 
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:855
 
typename Master_matrix::Pos_index Pos_index
Definition: Chain_matrix.h:68
 
bool is_zero_entry(Index columnIndex, ID_index rowIndex) const
Indicates if the entry at given coordinates has value zero.
Definition: Chain_matrix.h:864
 
typename Master_matrix::Entry_constructor Entry_constructor
Definition: Chain_matrix.h:61
 
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:846
 
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:876
 
Chain_matrix(Column_settings *colSettings)
Constructs an empty matrix. Only available if PersistenceMatrixOptions::has_column_pairings is true o...
Definition: Chain_matrix.h:527
 
typename Master_matrix::Row Row
Definition: Chain_matrix.h:59
 
typename Master_matrix::Field_operators Field_operators
Field operators class. Necessary only if PersistenceMatrixOptions::is_z2 is false.
Definition: Chain_matrix.h:55
 
typename Master_matrix::Element Field_element
Definition: Chain_matrix.h:56
 
void add_to(Index sourceColumnIndex, Index targetColumnIndex)
Adds column at sourceColumnIndex onto the column at targetColumnIndex in the matrix.
Definition: Chain_matrix.h:839
 
ID_index get_pivot(Index columnIndex)
Returns the row index of the pivot of the given column.
Definition: Chain_matrix.h:887
 
typename Master_matrix::Entry_representative Entry_representative
Definition: Chain_matrix.h:65
 
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:870
 
Index get_number_of_columns() const
Returns the current number of columns in the matrix.
Definition: Chain_matrix.h:822
 
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:832
 
void remove_last()
Only available if PersistenceMatrixOptions::has_removable_columns is true and, if PersistenceMatrixOp...
Definition: Chain_matrix.h:793
 
typename Master_matrix::ID_index ID_index
Definition: Chain_matrix.h:67
 
typename Master_matrix::Column Column
Definition: Chain_matrix.h:57
 
typename Master_matrix::Matrix_entry Entry
Definition: Chain_matrix.h:60
 
typename Master_matrix::Dimension Dimension
Definition: Chain_matrix.h:69
 
Chain_matrix & operator=(const Chain_matrix &other)
Assign operator.
Definition: Chain_matrix.h:893
 
typename Master_matrix::Boundary Boundary
Definition: Chain_matrix.h:64
 
typename Master_matrix::Column_settings Column_settings
Definition: Chain_matrix.h:63
 
Overlay for non-basic matrices replacing all input and output MatIdx indices of the original methods ...
Definition: Id_to_index_overlay.h:42
 
Data structure for matrices, and in particular thought for matrices representing filtered complexes i...
Definition: Matrix.h:144
 
typename std::conditional< hasFixedBarcode, std::vector< Bar >, typename std::conditional< PersistenceMatrixOptions::has_removable_columns, std::list< Bar >, std::vector< Bar > >::type >::type Barcode
Type of the computed barcode. It is either a list of Matrix::Bar or a vector of Matrix::Bar,...
Definition: Matrix.h:447
 
ID_index get_pivot(Index columnIndex)
Returns the row index of the pivot of the given column. Only available for non-basic matrices.
Definition: Matrix.h:1930
 
typename PersistenceMatrixOptions::Dimension Dimension
Definition: Matrix.h:150
 
typename PersistenceMatrixOptions::Index Index
Definition: Matrix.h:147
 
typename PersistenceMatrixOptions::Index ID_index
Definition: Matrix.h:148
 
typename PersistenceMatrixOptions::Index Pos_index
Definition: Matrix.h:149
 
typename std::conditional< PersistenceMatrixOptions::column_type==Column_types::HEAP, Matrix_heap_column, typename std::conditional< PersistenceMatrixOptions::column_type==Column_types::LIST, Matrix_list_column, typename std::conditional< PersistenceMatrixOptions::column_type==Column_types::SET, Matrix_set_column, typename std::conditional< PersistenceMatrixOptions::column_type==Column_types::UNORDERED_SET, Matrix_unordered_set_column, typename std::conditional< PersistenceMatrixOptions::column_type==Column_types::VECTOR, Matrix_vector_column, typename std::conditional< PersistenceMatrixOptions::column_type==Column_types::INTRUSIVE_LIST, Matrix_intrusive_list_column, typename std::conditional< PersistenceMatrixOptions::column_type==Column_types::NAIVE_VECTOR, Matrix_naive_vector_column, typename std::conditional< PersistenceMatrixOptions::column_type==Column_types::SMALL_VECTOR, Matrix_small_vector_column, Matrix_intrusive_set_column >::type >::type >::type >::type >::type >::type >::type >::type Column
Type of the columns stored in the matrix. The type depends on the value of PersistenceMatrixOptions::...
Definition: Matrix.h:368
 
Gudhi namespace.
Definition: SimplicialComplexForAlpha.h:14
 
static const bool has_map_column_container
If set to true, the underlying container containing the matrix columns is an std::unordered_map....
Definition: PersistenceMatrixOptions.h:101
 
static const bool has_row_access
If set to true, enables the method Matrix::get_row.
Definition: PersistenceMatrixOptions.h:111
 
static const bool is_z2
If true, indicates that the values contained in the matrix are in  and can therefore be treated like ...
Definition: PersistenceMatrixOptions.h:56