17#ifndef PM_BASE_MATRIX_H 
   18#define PM_BASE_MATRIX_H 
   25namespace persistence_matrix {
 
   36template <
class Master_matrix>
 
   37class Base_matrix : 
public Master_matrix::template Base_swap_option<Base_matrix<Master_matrix> >,
 
   38                    protected Master_matrix::Matrix_row_access_option
 
   41  using Index = 
typename Master_matrix::Index;                        
 
   42  using Dimension = 
typename Master_matrix::Dimension;                
 
   48  using Column = 
typename Master_matrix::Column;                        
 
   49  using Boundary = 
typename Master_matrix::Boundary;                    
 
   50  using Row = 
typename Master_matrix::Row;                              
 
   73  template <
class Container = Boundary>
 
  110  template <
class Container = Boundary>
 
  124  template <
class Container = Boundary>
 
  135  template <
class Boundary_range>
 
  137                       Dimension dim = Master_matrix::template get_null_value<Dimension>());
 
  226  template <
class Entry_range_or_column_index>
 
  227  void add_to(
const Entry_range_or_column_index& sourceColumn, 
Index targetColumnIndex);
 
  238  template <
class Entry_range_or_column_index>
 
  241                                  Index targetColumnIndex);
 
  252  template <
class Entry_range_or_column_index>
 
  254                                  const Entry_range_or_column_index& sourceColumn,
 
  255                                  Index targetColumnIndex);
 
  296    nextInsertIndex_ = 0;
 
  297    colSettings_ = colSettings;
 
  308    swap(
static_cast<typename Master_matrix::template Base_swap_option<Base_matrix<Master_matrix> 
>&>(matrix1),
 
  309         static_cast<typename Master_matrix::template Base_swap_option<Base_matrix<Master_matrix> 
>&>(matrix2));
 
  310    matrix1.matrix_.swap(matrix2.matrix_);
 
  311    std::swap(matrix1.nextInsertIndex_, matrix2.nextInsertIndex_);
 
  312    std::swap(matrix1.colSettings_, matrix2.colSettings_);
 
  315      swap(
static_cast<typename Master_matrix::Matrix_row_access_option&
>(matrix1),
 
  316           static_cast<typename Master_matrix::Matrix_row_access_option&
>(matrix2));
 
  323  using Swap_opt = 
typename Master_matrix::template Base_swap_option<Base_matrix<Master_matrix> >;
 
  324  using RA_opt = 
typename Master_matrix::Matrix_row_access_option;
 
  325  using Column_container = 
typename Master_matrix::Column_container;
 
  326  using Entry_representative =
 
  329                                std::pair<Index, Field_element>
 
  334  Column_container matrix_;       
 
  335  Index nextInsertIndex_;         
 
  338  template <
class Container = Boundary>
 
  339  void _insert(
const Container& column, Index columnIndex, Dimension dim);
 
  340  void _orderRowsIfNecessary();
 
  341  const Column& _get_column(Index columnIndex) 
const;
 
  342  Column& _get_column(Index columnIndex);
 
  343  Index _get_real_row_index(Index rowIndex) 
const;
 
  344  template <
class Container>
 
  345  void _container_insert(
const Container& column, Index pos, Dimension dim);
 
  346  void _container_insert(
const Column& column, [[maybe_unused]] Index pos = 0);
 
  349template <
class Master_matrix>
 
  351    : Swap_opt(), RA_opt(), nextInsertIndex_(0), colSettings_(colSettings)
 
  354template <
class Master_matrix>
 
  355template <
class Container>
 
  358    : Swap_opt(columns.size()),
 
  360      RA_opt(columns.size()),
 
  361      matrix_(!Master_matrix::Option_list::has_map_column_container && Master_matrix::Option_list::has_row_access
 
  364      nextInsertIndex_(columns.size()),
 
  365      colSettings_(colSettings)
 
  368    matrix_.reserve(columns.size());
 
  370  for (
Index i = 0; i < columns.size(); i++) {
 
  371    _container_insert(columns[i], i, columns[i].size() == 0 ? 0 : columns[i].size() - 1);
 
  375template <
class Master_matrix>
 
  378    : Swap_opt(numberOfColumns),
 
  379      RA_opt(numberOfColumns),
 
  380      matrix_(!Master_matrix::Option_list::has_map_column_container && Master_matrix::Option_list::has_row_access
 
  384      colSettings_(colSettings)
 
  387    matrix_.reserve(numberOfColumns);
 
  390template <
class Master_matrix>
 
  393    : Swap_opt(static_cast<const Swap_opt&>(matrixToCopy)),
 
  394      RA_opt(static_cast<const RA_opt&>(matrixToCopy)),
 
  395      nextInsertIndex_(matrixToCopy.nextInsertIndex_),
 
  396      colSettings_(colSettings == nullptr ? matrixToCopy.colSettings_ : colSettings)
 
  398  matrix_.reserve(matrixToCopy.matrix_.size());
 
  399  for (
const auto& cont : matrixToCopy.matrix_){
 
  401      _container_insert(cont.second, cont.first);
 
  403      _container_insert(cont);
 
  408template <
class Master_matrix>
 
  410    : Swap_opt(std::move(
static_cast<Swap_opt&
>(other))),
 
  411      RA_opt(std::move(
static_cast<RA_opt&
>(other))),
 
  412      matrix_(std::move(other.matrix_)),
 
  413      nextInsertIndex_(std::exchange(other.nextInsertIndex_, 0)),
 
  414      colSettings_(std::exchange(other.colSettings_, 
nullptr))
 
  417template <
class Master_matrix>
 
  418template <
class Container>
 
  422  _insert(column, nextInsertIndex_, column.size() == 0 ? 0 : column.size() - 1);
 
  426template <
class Master_matrix>
 
  427template <
class Container>
 
  430  static_assert(!Master_matrix::Option_list::has_row_access,
 
  431                "Columns have to be inserted at the end of the matrix when row access is enabled.");
 
  433  if (columnIndex >= nextInsertIndex_) nextInsertIndex_ = columnIndex + 1;
 
  435  _insert(column, columnIndex, column.size() == 0 ? 0 : column.size() - 1);
 
  438template <
class Master_matrix>
 
  439template <
class Boundary_range>
 
  442  if (dim == Master_matrix::template get_null_value<Dimension>()) dim = boundary.size() == 0 ? 0 : boundary.size() - 1;
 
  444  _insert(boundary, nextInsertIndex_++, dim);
 
  447template <
class Master_matrix>
 
  450  _orderRowsIfNecessary();
 
  451  return _get_column(columnIndex);
 
  454template <
class Master_matrix>
 
  457  static_assert(Master_matrix::Option_list::has_row_access, 
"Row access has to be enabled for this method.");
 
  459  _orderRowsIfNecessary();
 
  460  return RA_opt::get_row(rowIndex);
 
  463template <
class Master_matrix>
 
  466  static_assert(Master_matrix::Option_list::has_map_column_container,
 
  467                "'remove_column' is not implemented for the chosen options.");
 
  470  if (columnIndex == nextInsertIndex_ - 1) --nextInsertIndex_;
 
  472  matrix_.erase(columnIndex);
 
  475template <
class Master_matrix>
 
  478  if (nextInsertIndex_ == 0) 
return;  
 
  481  if constexpr (Master_matrix::Option_list::has_map_column_container) {
 
  482    matrix_.erase(nextInsertIndex_);
 
  484    if constexpr (Master_matrix::Option_list::has_row_access) {
 
  485      GUDHI_CHECK(nextInsertIndex_ == matrix_.size() - 1,
 
  486                  std::logic_error(
"Base_matrix::remove_last - Indexation problem."));
 
  489      matrix_[nextInsertIndex_].clear();
 
  494template <
class Master_matrix>
 
  497  if constexpr (Master_matrix::Option_list::has_row_access && Master_matrix::Option_list::has_removable_rows) {
 
  498    RA_opt::erase_empty_row(_get_real_row_index(rowIndex));
 
  500  if constexpr ((Master_matrix::Option_list::has_column_and_row_swaps || Master_matrix::Option_list::has_vine_update) &&
 
  501                Master_matrix::Option_list::has_map_column_container) {
 
  502    auto it = Swap_opt::indexToRow_.find(rowIndex);
 
  503    Swap_opt::rowToIndex_.erase(it->second);
 
  504    Swap_opt::indexToRow_.erase(it);
 
  508template <
class Master_matrix>
 
  511  if constexpr (Master_matrix::Option_list::has_map_column_container) {
 
  512    return matrix_.size();
 
  514    return nextInsertIndex_;  
 
  518template <
class Master_matrix>
 
  519template <
class Entry_range_or_column_index>
 
  521                                               Index targetColumnIndex)
 
  523  if constexpr (std::is_integral_v<Entry_range_or_column_index>) {
 
  524    _get_column(targetColumnIndex) += _get_column(sourceColumn);
 
  526    _get_column(targetColumnIndex) += sourceColumn;
 
  530template <
class Master_matrix>
 
  531template <
class Entry_range_or_column_index>
 
  534                                                                   Index targetColumnIndex)
 
  536  if constexpr (std::is_integral_v<Entry_range_or_column_index>) {
 
  537    _get_column(targetColumnIndex).multiply_target_and_add(coefficient, _get_column(sourceColumn));
 
  539    _get_column(targetColumnIndex).multiply_target_and_add(coefficient, sourceColumn);
 
  543template <
class Master_matrix>
 
  544template <
class Entry_range_or_column_index>
 
  546                                                                   const Entry_range_or_column_index& sourceColumn,
 
  547                                                                   Index targetColumnIndex)
 
  549  if constexpr (std::is_integral_v<Entry_range_or_column_index>) {
 
  550    _get_column(targetColumnIndex).multiply_source_and_add(_get_column(sourceColumn), coefficient);
 
  552    _get_column(targetColumnIndex).multiply_source_and_add(sourceColumn, coefficient);
 
  556template <
class Master_matrix>
 
  559  _get_column(columnIndex).clear(_get_real_row_index(rowIndex));
 
  562template <
class Master_matrix>
 
  564  _get_column(columnIndex).clear();
 
  567template <
class Master_matrix>
 
  570  return !(_get_column(columnIndex).is_non_zero(_get_real_row_index(rowIndex)));
 
  573template <
class Master_matrix>
 
  576  return _get_column(columnIndex).is_empty();
 
  579template <
class Master_matrix>
 
  582  Swap_opt::operator=(other);
 
  583  RA_opt::operator=(other);
 
  585  nextInsertIndex_ = other.nextInsertIndex_;
 
  586  colSettings_ = other.colSettings_;
 
  588  matrix_.reserve(other.matrix_.size());
 
  589  for (
const auto& cont : other.matrix_){
 
  590    if constexpr (Master_matrix::Option_list::has_map_column_container){
 
  591      _container_insert(cont.second, cont.first);
 
  593      _container_insert(cont);
 
  600template <
class Master_matrix>
 
  603  _orderRowsIfNecessary();
 
  604  std::cout << 
"Base_matrix:\n";
 
  605  for (Index i = 0; i < nextInsertIndex_; ++i) {
 
  606    const Column& col = matrix_[i];
 
  607    for (
const auto& e : col.get_content(nextInsertIndex_)) {
 
  611        std::cout << e << 
" ";
 
  616  if constexpr (Master_matrix::Option_list::has_row_access) {
 
  617    std::cout << 
"Row Matrix:\n";
 
  618    for (Index i = 0; i < nextInsertIndex_; ++i) {
 
  619      const auto& row = (*RA_opt::rows_)[i];
 
  620      for (
const auto& entry : row) {
 
  621        std::cout << entry.get_column_index() << 
" ";
 
  623      std::cout << 
"(" << i << 
")\n";
 
  629template <
class Master_matrix>
 
  630template <
class Container>
 
  633  _orderRowsIfNecessary();
 
  637  if (column.begin() != column.end()) {
 
  639    if constexpr (Master_matrix::Option_list::is_z2) {
 
  640      pivot = *std::prev(column.end());
 
  642      pivot = std::prev(column.end())->first;
 
  645    if constexpr (Master_matrix::Option_list::has_row_access && !Master_matrix::Option_list::has_removable_rows)
 
  646      if (RA_opt::rows_->size() <= pivot) RA_opt::rows_->resize(pivot + 1);
 
  650  if constexpr (Master_matrix::Option_list::has_map_column_container) {
 
  651    if constexpr (Master_matrix::Option_list::has_column_and_row_swaps || Master_matrix::Option_list::has_vine_update) {
 
  652      for (
auto id : column) {
 
  654        if constexpr (Master_matrix::Option_list::is_z2) {
 
  659        Swap_opt::indexToRow_[idx] = idx;
 
  660        Swap_opt::rowToIndex_[idx] = idx;
 
  664    if constexpr (Master_matrix::Option_list::has_column_and_row_swaps || Master_matrix::Option_list::has_vine_update) {
 
  665      Index size = Swap_opt::indexToRow_.size();
 
  667        for (Index i = size; i <= pivot; i++) {
 
  668          Swap_opt::indexToRow_.push_back(i);
 
  669          Swap_opt::rowToIndex_.push_back(i);
 
  674    if constexpr (!Master_matrix::Option_list::has_row_access) {
 
  675      if (matrix_.size() <= columnIndex) {
 
  676        matrix_.resize(columnIndex + 1);
 
  681  _container_insert(column, columnIndex, dim);
 
  684template <
class Master_matrix>
 
  687  if constexpr (Master_matrix::Option_list::has_column_and_row_swaps || Master_matrix::Option_list::has_vine_update) {
 
  688    if (Swap_opt::rowSwapped_) Swap_opt::_orderRows();
 
  692template <
class Master_matrix>
 
  694    Index columnIndex)
 const 
  696  if constexpr (Master_matrix::Option_list::has_map_column_container) {
 
  697    return matrix_.at(columnIndex);
 
  699    return matrix_[columnIndex];
 
  703template <
class Master_matrix>
 
  706  if constexpr (Master_matrix::Option_list::has_map_column_container) {
 
  707    return matrix_.at(columnIndex);
 
  709    return matrix_[columnIndex];
 
  713template <
class Master_matrix>
 
  716  if constexpr (Master_matrix::Option_list::has_column_and_row_swaps || Master_matrix::Option_list::has_vine_update) {
 
  717    if constexpr (Master_matrix::Option_list::has_map_column_container) {
 
  718      return Swap_opt::indexToRow_.at(rowIndex);
 
  720      return Swap_opt::indexToRow_[rowIndex];
 
  727template <
class Master_matrix>
 
  728template <
class Container>
 
  730  if constexpr (Master_matrix::Option_list::has_map_column_container) {
 
  731    if constexpr (Master_matrix::Option_list::has_row_access) {
 
  732      matrix_.try_emplace(pos, Column(pos, column, dim, RA_opt::rows_, colSettings_));
 
  734      matrix_.try_emplace(pos, Column(column, dim, colSettings_));
 
  737    if constexpr (Master_matrix::Option_list::has_row_access) {
 
  738      matrix_.emplace_back(pos, column, dim, RA_opt::rows_, colSettings_);
 
  740      matrix_[pos] = Column(column, dim, colSettings_);
 
  745template <
class Master_matrix>
 
  747  if constexpr (Master_matrix::Option_list::has_map_column_container) {
 
  748    if constexpr (Master_matrix::Option_list::has_row_access) {
 
  749      matrix_.try_emplace(pos, Column(column, column.get_column_index(), RA_opt::rows_, colSettings_));
 
  751      matrix_.try_emplace(pos, Column(column, colSettings_));
 
  754    if constexpr (Master_matrix::Option_list::has_row_access) {
 
  755      matrix_.emplace_back(column, column.get_column_index(), RA_opt::rows_, colSettings_);
 
  757      matrix_.emplace_back(column, colSettings_);
 
A basic matrix structure allowing to easily manipulate and access entire columns and rows,...
Definition: Base_matrix.h:39
 
Column & get_column(Index columnIndex)
Returns the column at the given MatIdx index. The type of the column depends on the chosen options,...
Definition: Base_matrix.h:448
 
bool is_zero_entry(Index columnIndex, Index rowIndex) const
Indicates if the entry at given coordinates has value zero.
Definition: Base_matrix.h:568
 
void add_to(const Entry_range_or_column_index &sourceColumn, Index targetColumnIndex)
Adds column represented by sourceColumn onto the column at targetColumnIndex in the matrix.
Definition: Base_matrix.h:520
 
friend void swap(Base_matrix &matrix1, Base_matrix &matrix2)
Swap operator.
Definition: Base_matrix.h:307
 
typename Master_matrix::Row Row
Definition: Base_matrix.h:51
 
Index get_number_of_columns() const
Returns the current number of columns in the matrix.
Definition: Base_matrix.h:509
 
void zero_column(Index columnIndex)
Zeroes the column at the given index.
Definition: Base_matrix.h:563
 
bool is_zero_column(Index columnIndex)
Indicates if the column at given index has value zero.
Definition: Base_matrix.h:574
 
typename Master_matrix::Element Field_element
Definition: Base_matrix.h:47
 
Row & get_row(Index rowIndex)
Only available if PersistenceMatrixOptions::has_row_access is true. Returns the row at the given row ...
Definition: Base_matrix.h:455
 
void insert_boundary(const Boundary_range &boundary, Dimension dim=Master_matrix::template get_null_value< Dimension >())
Same as insert_column, only for interface purposes. The given dimension is ignored and not stored.
Definition: Base_matrix.h:440
 
void reset(Column_settings *colSettings)
Resets the matrix to an empty matrix.
Definition: Base_matrix.h:294
 
Base_matrix & operator=(const Base_matrix &other)
Assign operator.
Definition: Base_matrix.h:580
 
typename Master_matrix::Field_operators Field_operators
Field operators class. Necessary only if PersistenceMatrixOptions::is_z2 is false.
Definition: Base_matrix.h:46
 
typename Master_matrix::Column Column
Definition: Base_matrix.h:48
 
void remove_last()
Removes the last column from the matrix. The last column is at index , where:
Definition: Base_matrix.h:476
 
typename Master_matrix::Column_settings Column_settings
Definition: Base_matrix.h:54
 
typename Master_matrix::Dimension Dimension
Definition: Base_matrix.h:42
 
typename Master_matrix::Index Index
Definition: Base_matrix.h:41
 
Base_matrix(Column_settings *colSettings)
Constructs an empty matrix.
Definition: Base_matrix.h:350
 
typename Master_matrix::Entry_constructor Entry_constructor
Definition: Base_matrix.h:52
 
void remove_column(Index columnIndex)
Only available if PersistenceMatrixOptions::has_map_column_container is true. Otherwise,...
Definition: Base_matrix.h:464
 
typename Master_matrix::Boundary Boundary
Definition: Base_matrix.h:49
 
void multiply_source_and_add_to(const Field_element &coefficient, const Entry_range_or_column_index &sourceColumn, Index targetColumnIndex)
Multiplies the source column with the coefficient before adding it to the target column....
Definition: Base_matrix.h:545
 
void zero_entry(Index columnIndex, Index rowIndex)
Zeroes the entry at the given coordinates.
Definition: Base_matrix.h:557
 
void insert_column(const Container &column)
Inserts a new ordered column at the end of the matrix by copying the given range of Matrix::Entry_rep...
Definition: Base_matrix.h:419
 
void erase_empty_row(Index rowIndex)
If PersistenceMatrixOptions::has_row_access and PersistenceMatrixOptions::has_removable_rows are true...
Definition: Base_matrix.h:495
 
void multiply_target_and_add_to(const Entry_range_or_column_index &sourceColumn, const Field_element &coefficient, Index targetColumnIndex)
Multiplies the target column with the coefficient and then adds the source column to it....
Definition: Base_matrix.h:532
 
Data structure for matrices, and in particular thought for matrices representing filtered complexes i...
Definition: Matrix.h:144
 
typename PersistenceMatrixOptions::Index Index
Definition: Matrix.h:147
 
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
 
typename std::conditional< PersistenceMatrixOptions::has_intrusive_rows, boost::intrusive::list< Matrix_entry, boost::intrusive::constant_time_size< false >, boost::intrusive::base_hook< Base_hook_matrix_row > >, std::set< Matrix_entry, RowEntryComp > >::type Row
Type of the rows stored in the matrix. Is either an intrusive list of Matrix_entry (not ordered) if P...
Definition: Matrix.h:274
 
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