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