17#ifndef PM_BOUNDARY_MATRIX_H 
   18#define PM_BOUNDARY_MATRIX_H 
   26namespace persistence_matrix {
 
   39template <
class Master_matrix>
 
   41                        public Master_matrix::template Base_swap_option<Boundary_matrix<Master_matrix> >,
 
   42                        public Master_matrix::Base_pairing_option,
 
   43                        public Master_matrix::Matrix_row_access_option
 
   46  using Index = 
typename Master_matrix::Index;                        
 
   47  using ID_index = 
typename Master_matrix::ID_index;                  
 
   48  using Dimension = 
typename Master_matrix::Dimension;                
 
   54  using Column = 
typename Master_matrix::Column;                        
 
   55  using Boundary = 
typename Master_matrix::Boundary;                    
 
   56  using Row = 
typename Master_matrix::Row;                              
 
   91  template <
class Boundary_range = Boundary>
 
  143  template <
class Boundary_range = Boundary>
 
  145                        Dimension dim = Master_matrix::template get_null_value<Dimension>());
 
  164  template <
class Boundary_range = Boundary>
 
  166                        Dimension dim = Master_matrix::template get_null_value<Dimension>());
 
  256                                  Index targetColumnIndex);
 
  270                                  Index sourceColumnIndex,
 
  271                                  Index targetColumnIndex);
 
  326    nextInsertIndex_ = 0;
 
  327    colSettings_ = colSettings;
 
  338    swap(
static_cast<typename Master_matrix::Matrix_dimension_option&
>(matrix1),
 
  339         static_cast<typename Master_matrix::Matrix_dimension_option&
>(matrix2));
 
  340    swap(
static_cast<typename Master_matrix::template Base_swap_option<Boundary_matrix<Master_matrix> 
>&>(matrix1),
 
  341         static_cast<typename Master_matrix::template Base_swap_option<Boundary_matrix<Master_matrix> 
>&>(matrix2));
 
  342    swap(
static_cast<typename Master_matrix::Base_pairing_option&
>(matrix1),
 
  343         static_cast<typename Master_matrix::Base_pairing_option&
>(matrix2));
 
  344    matrix1.matrix_.swap(matrix2.matrix_);
 
  345    std::swap(matrix1.nextInsertIndex_, matrix2.nextInsertIndex_);
 
  346    std::swap(matrix1.colSettings_, matrix2.colSettings_);
 
  348    if constexpr (Master_matrix::Option_list::has_row_access) {
 
  349      swap(
static_cast<typename Master_matrix::Matrix_row_access_option&
>(matrix1),
 
  350           static_cast<typename Master_matrix::Matrix_row_access_option&
>(matrix2));
 
  357  using Dim_opt = 
typename Master_matrix::Matrix_dimension_option;
 
  358  using Swap_opt = 
typename Master_matrix::template Base_swap_option<Boundary_matrix<Master_matrix> >;
 
  359  using Pair_opt = 
typename Master_matrix::Base_pairing_option;
 
  360  using RA_opt = 
typename Master_matrix::Matrix_row_access_option;
 
  361  using Column_container = 
typename Master_matrix::Column_container;
 
  366  Column_container matrix_;       
 
  367  Index nextInsertIndex_;         
 
  370  static constexpr bool activeDimOption =
 
  371      Master_matrix::Option_list::has_matrix_maximal_dimension_access || Master_matrix::maxDimensionIsNeeded;
 
  372  static constexpr bool activeSwapOption =
 
  373      Master_matrix::Option_list::has_column_and_row_swaps || Master_matrix::Option_list::has_vine_update;
 
  374  static constexpr bool activePairingOption = Master_matrix::Option_list::has_column_pairings &&
 
  375                                              !Master_matrix::Option_list::has_vine_update &&
 
  376                                              !Master_matrix::Option_list::can_retrieve_representative_cycles;
 
  378  void _orderRowsIfNecessary();
 
  379  const Column& _get_column(Index columnIndex) 
const;
 
  380  Column& _get_column(Index columnIndex);
 
  381  Index _get_real_row_index(Index rowIndex) 
const;
 
  382  template <
class Container>
 
  383  void _container_insert(
const Container& column, Index pos, Dimension dim);
 
  384  void _container_insert(
const Column& column, [[maybe_unused]] Index pos = 0);
 
  387template <
class Master_matrix>
 
  389    : Dim_opt(Master_matrix::template get_null_value<
Dimension>()),
 
  394      colSettings_(colSettings)
 
  397template <
class Master_matrix>
 
  398template <
class Boundary_range>
 
  401    : Dim_opt(Master_matrix::template get_null_value<
Dimension>()),
 
  402      Swap_opt(orderedBoundaries.size()),
 
  404      RA_opt(orderedBoundaries.size()),
 
  405      nextInsertIndex_(orderedBoundaries.size()),
 
  406      colSettings_(colSettings)
 
  408  matrix_.reserve(orderedBoundaries.size());
 
  410  for (
Index i = 0; i < orderedBoundaries.size(); i++) {
 
  411    _container_insert(orderedBoundaries[i], i, orderedBoundaries[i].size() == 0 ? 0 : orderedBoundaries[i].size() - 1);
 
  415template <
class Master_matrix>
 
  418    : Dim_opt(Master_matrix::template get_null_value<
Dimension>()),
 
  419      Swap_opt(numberOfColumns),
 
  421      RA_opt(numberOfColumns),
 
  422      matrix_(!Master_matrix::Option_list::has_map_column_container && Master_matrix::Option_list::has_row_access
 
  426      colSettings_(colSettings)
 
  428  if constexpr (!Master_matrix::Option_list::has_map_column_container && Master_matrix::Option_list::has_row_access)
 
  429    matrix_.reserve(numberOfColumns);
 
  432template <
class Master_matrix>
 
  435    : Dim_opt(static_cast<const Dim_opt&>(matrixToCopy)),
 
  436      Swap_opt(static_cast<const Swap_opt&>(matrixToCopy)),
 
  437      Pair_opt(static_cast<const Pair_opt&>(matrixToCopy)),
 
  438      RA_opt(static_cast<const RA_opt&>(matrixToCopy)),
 
  439      nextInsertIndex_(matrixToCopy.nextInsertIndex_),
 
  440      colSettings_(colSettings == nullptr ? matrixToCopy.colSettings_ : colSettings)
 
  442  matrix_.reserve(matrixToCopy.matrix_.size());
 
  443  for (
const auto& cont : matrixToCopy.matrix_){
 
  444    if constexpr (Master_matrix::Option_list::has_map_column_container){
 
  445      _container_insert(cont.second, cont.first);
 
  447      _container_insert(cont);
 
  452template <
class Master_matrix>
 
  454    : Dim_opt(std::move(
static_cast<Dim_opt&
>(other))),
 
  455      Swap_opt(std::move(
static_cast<Swap_opt&
>(other))),
 
  456      Pair_opt(std::move(
static_cast<Pair_opt&
>(other))),
 
  457      RA_opt(std::move(
static_cast<RA_opt&
>(other))),
 
  458      matrix_(std::move(other.matrix_)),
 
  459      nextInsertIndex_(std::exchange(other.nextInsertIndex_, 0)),
 
  460      colSettings_(std::exchange(other.colSettings_, 
nullptr))
 
  463template <
class Master_matrix>
 
  464template <
class Boundary_range>
 
  466    const Boundary_range& boundary, 
Dimension dim)
 
  468  return insert_boundary(nextInsertIndex_, boundary, dim);
 
  471template <
class Master_matrix>
 
  472template <
class Boundary_range>
 
  476  if (dim == Master_matrix::template get_null_value<Dimension>()) dim = boundary.size() == 0 ? 0 : boundary.size() - 1;
 
  478  _orderRowsIfNecessary();
 
  481  if constexpr (Master_matrix::Option_list::has_row_access && !Master_matrix::Option_list::has_removable_rows) {
 
  482    if (boundary.size() != 0){
 
  484      if constexpr (Master_matrix::Option_list::is_z2) {
 
  485        pivot = *std::prev(boundary.end());
 
  487        pivot = std::prev(boundary.end())->first;
 
  490      if (RA_opt::rows_->size() <= pivot) RA_opt::rows_->resize(pivot + 1);
 
  495  if constexpr (Master_matrix::Option_list::has_map_column_container) {
 
  496    if constexpr (activeSwapOption) {
 
  497      Swap_opt::indexToRow_.emplace(cellIndex, cellIndex);
 
  498      Swap_opt::rowToIndex_.emplace(cellIndex, cellIndex);
 
  501    if constexpr (activeSwapOption) {
 
  502      for (
Index i = Swap_opt::indexToRow_.size(); i <= cellIndex; ++i) {
 
  503        Swap_opt::indexToRow_.push_back(i);
 
  504        Swap_opt::rowToIndex_.push_back(i);
 
  510  if constexpr (activePairingOption){
 
  511    if (cellIndex != nextInsertIndex_){
 
  512      Pair_opt::idToPosition_.emplace(cellIndex, nextInsertIndex_);
 
  513      if constexpr (Master_matrix::Option_list::has_removable_columns){
 
  514        Pair_opt::PIDM::map_.emplace(nextInsertIndex_, cellIndex);
 
  519  _container_insert(boundary, nextInsertIndex_, dim);
 
  521  return nextInsertIndex_++;
 
  524template <
class Master_matrix>
 
  527  _orderRowsIfNecessary();
 
  529  return _get_column(columnIndex);
 
  532template <
class Master_matrix>
 
  535  static_assert(Master_matrix::Option_list::has_row_access, 
"'get_row' is not implemented for the chosen options.");
 
  537  _orderRowsIfNecessary();
 
  539  return RA_opt::get_row(rowIndex);
 
  542template <
class Master_matrix>
 
  545  static_assert(Master_matrix::Option_list::has_removable_columns,
 
  546                "'remove_last' is not implemented for the chosen options.");
 
  548  if (nextInsertIndex_ == 0) 
return Master_matrix::template get_null_value<Index>();  
 
  552  if constexpr (activeDimOption) {
 
  553    Dim_opt::update_down(matrix_.at(nextInsertIndex_).get_dimension());
 
  558  if constexpr (Master_matrix::Option_list::has_map_column_container) {
 
  559    auto it = matrix_.find(nextInsertIndex_);
 
  560    pivot = it->second.get_pivot();
 
  561    if constexpr (activeSwapOption) {
 
  563      if (Swap_opt::rowSwapped_ && pivot != Master_matrix::template get_null_value<ID_index>()) {
 
  564        Swap_opt::_orderRows();
 
  565        pivot = it->second.get_pivot();
 
  570    pivot = matrix_[nextInsertIndex_].get_pivot();
 
  571    if constexpr (activeSwapOption) {
 
  573      if (Swap_opt::rowSwapped_ && pivot != Master_matrix::template get_null_value<ID_index>()) {
 
  574        Swap_opt::_orderRows();
 
  575        pivot = matrix_[nextInsertIndex_].get_pivot();
 
  578    if constexpr (Master_matrix::Option_list::has_row_access) {
 
  579      GUDHI_CHECK(nextInsertIndex_ == matrix_.size() - 1,
 
  580                  std::logic_error(
"Boundary_matrix::remove_last - Indexation problem."));
 
  583      matrix_[nextInsertIndex_].clear();
 
  587  erase_empty_row(nextInsertIndex_);  
 
  590  if constexpr (activePairingOption) {
 
  591    Pair_opt::_remove_last(nextInsertIndex_);
 
  597template <
class Master_matrix>
 
  602  if constexpr (activeSwapOption) {
 
  603    if constexpr (Master_matrix::Option_list::has_map_column_container) {
 
  604      auto it = Swap_opt::indexToRow_.find(rowIndex);
 
  606      Swap_opt::rowToIndex_.erase(rowID);
 
  607      Swap_opt::indexToRow_.erase(it);
 
  609      rowID = Swap_opt::indexToRow_[rowIndex];
 
  613  if constexpr (Master_matrix::Option_list::has_row_access && Master_matrix::Option_list::has_removable_rows) {
 
  614    RA_opt::erase_empty_row(rowID);
 
  618template <
class Master_matrix>
 
  621  if constexpr (Master_matrix::Option_list::has_map_column_container) {
 
  622    return matrix_.size();
 
  624    return nextInsertIndex_;  
 
  628template <
class Master_matrix>
 
  630    Index columnIndex)
 const 
  632  return _get_column(columnIndex).get_dimension();
 
  635template <
class Master_matrix>
 
  638  _get_column(targetColumnIndex) += _get_column(sourceColumnIndex);
 
  641template <
class Master_matrix>
 
  644                                                                       Index targetColumnIndex)
 
  646  _get_column(targetColumnIndex).multiply_target_and_add(coefficient, _get_column(sourceColumnIndex));
 
  649template <
class Master_matrix>
 
  651                                                                       Index sourceColumnIndex,
 
  652                                                                       Index targetColumnIndex)
 
  654  _get_column(targetColumnIndex).multiply_source_and_add(_get_column(sourceColumnIndex), coefficient);
 
  657template <
class Master_matrix>
 
  660  _get_column(columnIndex).clear(_get_real_row_index(rowIndex));
 
  663template <
class Master_matrix>
 
  666  _get_column(columnIndex).clear();
 
  669template <
class Master_matrix>
 
  672  return !(_get_column(columnIndex).is_non_zero(_get_real_row_index(rowIndex)));
 
  675template <
class Master_matrix>
 
  678  return _get_column(columnIndex).is_empty();
 
  681template <
class Master_matrix>
 
  684  _orderRowsIfNecessary();
 
  686  return _get_column(columnIndex).get_pivot();
 
  689template <
class Master_matrix>
 
  692  Dim_opt::operator=(other);
 
  693  Swap_opt::operator=(other);
 
  694  Pair_opt::operator=(other);
 
  695  RA_opt::operator=(other);
 
  698  nextInsertIndex_ = other.nextInsertIndex_;
 
  699  colSettings_ = other.colSettings_;
 
  701  matrix_.reserve(other.matrix_.size());
 
  702  for (
const auto& cont : other.matrix_){
 
  703    if constexpr (Master_matrix::Option_list::has_map_column_container){
 
  704      _container_insert(cont.second, cont.first);
 
  706      _container_insert(cont);
 
  713template <
class Master_matrix>
 
  716  if constexpr (activeSwapOption) {
 
  717    if (Swap_opt::rowSwapped_) Swap_opt::_orderRows();
 
  719  std::cout << 
"Boundary_matrix:\n";
 
  720  for (Index i = 0; i < nextInsertIndex_; ++i) {
 
  721    Column& col = matrix_[i];
 
  722    for (
auto e : col.get_content(nextInsertIndex_)) {
 
  726        std::cout << e << 
" ";
 
  731  if constexpr (Master_matrix::Option_list::has_row_access) {
 
  732    std::cout << 
"Row Matrix:\n";
 
  733    for (ID_index i = 0; i < nextInsertIndex_; ++i) {
 
  734      const auto& row = (*RA_opt::rows_)[i];
 
  735      for (
const typename Column::Entry& entry : row) {
 
  736        std::cout << entry.get_column_index() << 
" ";
 
  738      std::cout << 
"(" << i << 
")\n";
 
  744template <
class Master_matrix>
 
  745inline void Boundary_matrix<Master_matrix>::_orderRowsIfNecessary()
 
  747  if constexpr (activeSwapOption) {
 
  748    if (Swap_opt::rowSwapped_) Swap_opt::_orderRows();
 
  752template <
class Master_matrix>
 
  754    Index columnIndex)
 const 
  756  if constexpr (Master_matrix::Option_list::has_map_column_container) {
 
  757    return matrix_.at(columnIndex);
 
  759    return matrix_[columnIndex];
 
  763template <
class Master_matrix>
 
  767  if constexpr (Master_matrix::Option_list::has_map_column_container) {
 
  768    return matrix_.at(columnIndex);
 
  770    return matrix_[columnIndex];
 
  774template <
class Master_matrix>
 
  776    Index rowIndex)
 const 
  778  if constexpr (Master_matrix::Option_list::has_column_and_row_swaps || Master_matrix::Option_list::has_vine_update) {
 
  779    if constexpr (Master_matrix::Option_list::has_map_column_container) {
 
  780      return Swap_opt::indexToRow_.at(rowIndex);
 
  782      return Swap_opt::indexToRow_[rowIndex];
 
  789template <
class Master_matrix>
 
  790template <
class Container>
 
  791inline void Boundary_matrix<Master_matrix>::_container_insert(
const Container& column,
 
  795  if constexpr (Master_matrix::Option_list::has_map_column_container) {
 
  796    if constexpr (Master_matrix::Option_list::has_row_access) {
 
  797      matrix_.try_emplace(pos, Column(pos, column, dim, RA_opt::rows_, colSettings_));
 
  799      matrix_.try_emplace(pos, Column(column, dim, colSettings_));
 
  802    if constexpr (Master_matrix::Option_list::has_row_access) {
 
  803      matrix_.emplace_back(pos, column, dim, RA_opt::rows_, colSettings_);
 
  805      if (matrix_.size() <= pos) {
 
  806        matrix_.emplace_back(column, dim, colSettings_);
 
  808        matrix_[pos] = Column(column, dim, colSettings_);
 
  812  if constexpr (activeDimOption) {
 
  813    Dim_opt::update_up(dim);
 
  817template <
class Master_matrix>
 
  818inline void Boundary_matrix<Master_matrix>::_container_insert(
const Column& column, [[maybe_unused]] Index pos)
 
  820  if constexpr (Master_matrix::Option_list::has_map_column_container) {
 
  821    if constexpr (Master_matrix::Option_list::has_row_access) {
 
  822      matrix_.try_emplace(pos, Column(column, column.get_column_index(), RA_opt::rows_, colSettings_));
 
  824      matrix_.try_emplace(pos, Column(column, colSettings_));
 
  827    if constexpr (Master_matrix::Option_list::has_row_access) {
 
  828      matrix_.emplace_back(column, column.get_column_index(), RA_opt::rows_, colSettings_);
 
  830      matrix_.emplace_back(column, colSettings_);
 
Matrix structure to store the ordered boundary matrix  of a filtered complex in order to compute its ...
Definition: Boundary_matrix.h:44
 
typename Master_matrix::Dimension Dimension
Definition: Boundary_matrix.h:48
 
typename Master_matrix::Entry_constructor Entry_constructor
Definition: Boundary_matrix.h:58
 
typename Master_matrix::Element Field_element
Definition: Boundary_matrix.h:53
 
void erase_empty_row(Index rowIndex)
If PersistenceMatrixOptions::has_row_access and PersistenceMatrixOptions::has_removable_rows are true...
Definition: Boundary_matrix.h:598
 
typename Master_matrix::Column_settings Column_settings
Definition: Boundary_matrix.h:60
 
typename Master_matrix::Index Index
Definition: Boundary_matrix.h:46
 
Dimension get_column_dimension(Index columnIndex) const
Returns the dimension of the given column.
Definition: Boundary_matrix.h:629
 
void zero_entry(Index columnIndex, Index rowIndex)
Zeroes the entry at the given coordinates.
Definition: Boundary_matrix.h:658
 
Index remove_last()
Only available if PersistenceMatrixOptions::has_removable_columns is true. Removes the last cell in t...
Definition: Boundary_matrix.h:543
 
bool is_zero_column(Index columnIndex)
Indicates if the column at given index has value zero.
Definition: Boundary_matrix.h:676
 
friend void swap(Boundary_matrix &matrix1, Boundary_matrix &matrix2)
Swap operator.
Definition: Boundary_matrix.h:337
 
void zero_column(Index columnIndex)
Zeroes the column at the given index.
Definition: Boundary_matrix.h:664
 
Index get_number_of_columns() const
Returns the current number of columns in the matrix.
Definition: Boundary_matrix.h:619
 
bool is_zero_entry(Index columnIndex, Index rowIndex) const
Indicates if the entry at given coordinates has value zero.
Definition: Boundary_matrix.h:670
 
typename Master_matrix::Boundary Boundary
Definition: Boundary_matrix.h:55
 
void reset(Column_settings *colSettings)
Resets the matrix to an empty matrix.
Definition: Boundary_matrix.h:324
 
typename Master_matrix::Row Row
Definition: Boundary_matrix.h:57
 
Index get_pivot(Index columnIndex)
Returns the pivot of the given column.
Definition: Boundary_matrix.h:682
 
Column & get_column(Index columnIndex)
Returns the column at the given MatIdx index. The type of the column depends on the chosen options,...
Definition: Boundary_matrix.h:525
 
Index 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....
Definition: Boundary_matrix.h:465
 
typename Master_matrix::Column Column
Definition: Boundary_matrix.h:54
 
void add_to(Index sourceColumnIndex, Index targetColumnIndex)
Adds column at sourceColumnIndex onto the column at targetColumnIndex in the matrix.
Definition: Boundary_matrix.h:636
 
typename Master_matrix::ID_index ID_index
Definition: Boundary_matrix.h:47
 
Boundary_matrix(Column_settings *colSettings)
Constructs an empty matrix.
Definition: Boundary_matrix.h:388
 
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: Boundary_matrix.h:650
 
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: Boundary_matrix.h:642
 
Row & get_row(Index rowIndex)
Only available if PersistenceMatrixOptions::has_row_access is true. Returns the row at the given row ...
Definition: Boundary_matrix.h:533
 
typename Master_matrix::Field_operators Field_operators
Field operators class. Necessary only if PersistenceMatrixOptions::is_z2 is false.
Definition: Boundary_matrix.h:52
 
Boundary_matrix & operator=(const Boundary_matrix &other)
Assign operator.
Definition: Boundary_matrix.h:690
 
Gudhi namespace.
Definition: SimplicialComplexForAlpha.h:14