17#ifndef PM_BASE_MATRIX_H
18#define PM_BASE_MATRIX_H
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 Swap_opt =
typename Master_matrix::template Base_swap_option<Base_matrix<Master_matrix> >;
42 using RA_opt =
typename Master_matrix::Matrix_row_access_option;
45 using Index =
typename Master_matrix::Index;
46 using Dimension =
typename Master_matrix::Dimension;
52 using Column =
typename Master_matrix::Column;
53 using Boundary =
typename Master_matrix::Boundary;
54 using Row =
typename Master_matrix::Row;
77 template <
class Container = Boundary>
114 template <
class Container = Boundary,
class = std::enable_if_t<!std::is_arithmetic_v<Container> > >
128 template <
class Container = Boundary,
class = std::enable_if_t<!std::is_arithmetic_v<Container> > >
146 template <
class Boundary_range>
148 Dimension dim = Master_matrix::template get_null_value<Dimension>());
237 template <
class Entry_range_or_column_index>
238 void add_to(
const Entry_range_or_column_index& sourceColumn,
Index targetColumnIndex);
249 template <
class Entry_range_or_column_index>
252 Index targetColumnIndex);
263 template <
class Entry_range_or_column_index>
265 const Entry_range_or_column_index& sourceColumn,
266 Index targetColumnIndex);
307 if constexpr (Master_matrix::Option_list::has_vine_update || Master_matrix::Option_list::has_column_and_row_swaps)
310 nextInsertIndex_ = 0;
311 colSettings_ = colSettings;
328 swap(
static_cast<Swap_opt&
>(matrix1),
static_cast<Swap_opt&
>(matrix2));
329 matrix1.matrix_.swap(matrix2.matrix_);
330 std::swap(matrix1.nextInsertIndex_, matrix2.nextInsertIndex_);
331 std::swap(matrix1.colSettings_, matrix2.colSettings_);
333 if constexpr (Master_matrix::Option_list::has_row_access) {
334 swap(
static_cast<RA_opt&
>(matrix1),
static_cast<RA_opt&
>(matrix2));
341 using Column_container =
typename Master_matrix::Column_container;
342 using Entry_representative =
343 typename std::conditional<Master_matrix::Option_list::is_z2, Index, std::pair<Index, Field_element> >::type;
347 Column_container matrix_;
348 Index nextInsertIndex_;
351 template <
class Container = Boundary,
class = std::enable_if_t<!std::is_arithmetic_v<Container> > >
352 void _insert(
const Container& column, Index columnIndex, Dimension dim);
353 void _insert(Index idx,
Field_element e, Index columnIndex, Dimension dim);
354 void _orderRowsIfNecessary();
355 const Column& _get_column(Index columnIndex)
const;
356 Column& _get_column(Index columnIndex);
357 Index _get_real_row_index(Index rowIndex)
const;
358 template <
class Container>
359 void _container_insert(
const Container& column, Index pos, Dimension dim);
360 void _container_insert(Index idx,
Field_element e, Index pos, Dimension dim);
361 template <
class ColumnIterator>
362 void _container_insert(
const ColumnIterator& rep);
365template <
class Master_matrix>
367 : Swap_opt(), RA_opt(), nextInsertIndex_(0), colSettings_(colSettings)
370template <
class Master_matrix>
371template <
class Container>
373 : Swap_opt(columns.size()),
375 RA_opt(columns.size()),
376 matrix_(!Master_matrix::Option_list::has_map_column_container && Master_matrix::Option_list::has_row_access
379 nextInsertIndex_(columns.size()),
380 colSettings_(colSettings)
382 if constexpr (!Master_matrix::Option_list::has_map_column_container && Master_matrix::Option_list::has_row_access)
383 matrix_.reserve(columns.size());
385 for (
Index i = 0; i < columns.size(); i++) {
386 _container_insert(columns[i], i, columns[i].size() == 0 ? 0 : columns[i].size() - 1);
390template <
class Master_matrix>
392 : Swap_opt(numberOfColumns),
393 RA_opt(numberOfColumns),
394 matrix_(!Master_matrix::Option_list::has_map_column_container && Master_matrix::Option_list::has_row_access
398 colSettings_(colSettings)
400 if constexpr (!Master_matrix::Option_list::has_map_column_container && Master_matrix::Option_list::has_row_access)
401 matrix_.reserve(numberOfColumns);
404template <
class Master_matrix>
406 : Swap_opt(static_cast<const Swap_opt&>(matrixToCopy)),
407 RA_opt(static_cast<const RA_opt&>(matrixToCopy)),
408 nextInsertIndex_(matrixToCopy.nextInsertIndex_),
409 colSettings_(colSettings == nullptr ? matrixToCopy.colSettings_ : colSettings)
411 matrix_.reserve(matrixToCopy.matrix_.size());
412 for (
const auto& cont : matrixToCopy.matrix_) {
413 _container_insert(cont);
417template <
class Master_matrix>
419 : Swap_opt(std::move(
static_cast<Swap_opt&
>(other))),
420 RA_opt(std::move(
static_cast<RA_opt&
>(other))),
421 matrix_(std::move(other.matrix_)),
422 nextInsertIndex_(std::exchange(other.nextInsertIndex_, 0)),
423 colSettings_(std::exchange(other.colSettings_,
nullptr))
427template <
class Master_matrix>
428template <
class Container,
class>
432 _insert(column, nextInsertIndex_, column.size() == 0 ? 0 : column.size() - 1);
436template <
class Master_matrix>
437template <
class Container,
class>
440 static_assert(!Master_matrix::Option_list::has_row_access,
441 "Columns have to be inserted at the end of the matrix when row access is enabled.");
443 if (columnIndex >= nextInsertIndex_) nextInsertIndex_ = columnIndex + 1;
445 _insert(column, columnIndex, column.size() == 0 ? 0 : column.size() - 1);
448template <
class Master_matrix>
452 _insert(idx, e, nextInsertIndex_, 0);
456template <
class Master_matrix>
457template <
class Boundary_range>
460 if (dim == Master_matrix::template get_null_value<Dimension>()) dim = boundary.size() == 0 ? 0 : boundary.size() - 1;
462 _insert(boundary, nextInsertIndex_++, dim);
465template <
class Master_matrix>
468 _orderRowsIfNecessary();
469 return _get_column(columnIndex);
472template <
class Master_matrix>
475 static_assert(Master_matrix::Option_list::has_row_access,
"Row access has to be enabled for this method.");
477 _orderRowsIfNecessary();
478 return RA_opt::get_row(rowIndex);
481template <
class Master_matrix>
484 static_assert(Master_matrix::Option_list::has_map_column_container,
485 "'remove_column' is not implemented for the chosen options.");
488 if (columnIndex == nextInsertIndex_ - 1) --nextInsertIndex_;
490 matrix_.erase(columnIndex);
493template <
class Master_matrix>
496 if (nextInsertIndex_ == 0)
return;
499 if constexpr (Master_matrix::Option_list::has_map_column_container) {
500 matrix_.erase(nextInsertIndex_);
502 if constexpr (Master_matrix::Option_list::has_row_access) {
503 GUDHI_CHECK(nextInsertIndex_ == matrix_.size() - 1,
504 std::logic_error(
"Base_matrix::remove_last - Indexation problem."));
507 matrix_[nextInsertIndex_].clear();
512template <
class Master_matrix>
515 if constexpr (Master_matrix::Option_list::has_row_access && Master_matrix::Option_list::has_removable_rows) {
516 RA_opt::erase_empty_row(_get_real_row_index(rowIndex));
518 if constexpr ((Master_matrix::Option_list::has_column_and_row_swaps || Master_matrix::Option_list::has_vine_update) &&
519 Master_matrix::Option_list::has_map_column_container) {
520 Swap_opt::_erase_row(rowIndex);
524template <
class Master_matrix>
527 if constexpr (Master_matrix::Option_list::has_map_column_container) {
528 return matrix_.size();
530 return nextInsertIndex_;
534template <
class Master_matrix>
535template <
class Entry_range_or_column_index>
538 if constexpr (std::is_integral_v<Entry_range_or_column_index>) {
539 _get_column(targetColumnIndex) += _get_column(sourceColumn);
541 _get_column(targetColumnIndex) += sourceColumn;
545template <
class Master_matrix>
546template <
class Entry_range_or_column_index>
549 Index targetColumnIndex)
551 if constexpr (std::is_integral_v<Entry_range_or_column_index>) {
552 _get_column(targetColumnIndex).multiply_target_and_add(coefficient, _get_column(sourceColumn));
554 _get_column(targetColumnIndex).multiply_target_and_add(coefficient, sourceColumn);
558template <
class Master_matrix>
559template <
class Entry_range_or_column_index>
561 const Entry_range_or_column_index& sourceColumn,
562 Index targetColumnIndex)
564 if constexpr (std::is_integral_v<Entry_range_or_column_index>) {
565 _get_column(targetColumnIndex).multiply_source_and_add(_get_column(sourceColumn), coefficient);
567 _get_column(targetColumnIndex).multiply_source_and_add(sourceColumn, coefficient);
571template <
class Master_matrix>
574 _get_column(columnIndex).clear(_get_real_row_index(rowIndex));
577template <
class Master_matrix>
580 _get_column(columnIndex).clear();
583template <
class Master_matrix>
586 return !(_get_column(columnIndex).is_non_zero(_get_real_row_index(rowIndex)));
589template <
class Master_matrix>
592 return _get_column(columnIndex).is_empty();
595template <
class Master_matrix>
598 if (
this == &other)
return *
this;
600 Swap_opt::operator=(other);
601 RA_opt::operator=(other);
603 nextInsertIndex_ = other.nextInsertIndex_;
604 colSettings_ = other.colSettings_;
606 matrix_.reserve(other.matrix_.size());
607 for (
const auto& cont : other.matrix_) {
608 _container_insert(cont);
614template <
class Master_matrix>
617 if (
this == &other)
return *
this;
619 Swap_opt::operator=(std::move(other));
620 RA_opt::operator=(std::move(other));
622 matrix_ = std::move(other.matrix_);
623 nextInsertIndex_ = std::exchange(other.nextInsertIndex_, 0);
624 colSettings_ = std::exchange(other.colSettings_,
nullptr);
629template <
class Master_matrix>
630inline void Base_matrix<Master_matrix>::print()
632 _orderRowsIfNecessary();
633 std::cout <<
"Base_matrix:\n";
634 for (Index i = 0; i < nextInsertIndex_; ++i) {
635 const Column& col = matrix_[i];
636 for (
const auto& e : col.get_content(nextInsertIndex_)) {
640 std::cout << e <<
" ";
645 if constexpr (Master_matrix::Option_list::has_row_access) {
646 std::cout <<
"Row Matrix:\n";
647 for (Index i = 0; i < nextInsertIndex_; ++i) {
648 const auto& row = RA_opt::get_row(i);
649 for (
const auto& entry : row) {
650 std::cout << entry.get_column_index() <<
" ";
652 std::cout <<
"(" << i <<
")\n";
658template <
class Master_matrix>
659template <
class Container,
class>
662 _orderRowsIfNecessary();
666 if (column.begin() != column.end()) {
668 pivot = Master_matrix::get_row_index(*std::prev(column.end()));
670 if constexpr (Master_matrix::Option_list::has_row_access && !Master_matrix::Option_list::has_removable_rows)
671 RA_opt::_resize(pivot);
675 if constexpr (Master_matrix::Option_list::has_map_column_container) {
676 if constexpr (Master_matrix::Option_list::has_column_and_row_swaps || Master_matrix::Option_list::has_vine_update) {
677 for (
const auto&
id : column) {
678 Swap_opt::_initialize_row_index(Master_matrix::get_row_index(
id));
682 if constexpr (Master_matrix::Option_list::has_column_and_row_swaps || Master_matrix::Option_list::has_vine_update) {
683 Swap_opt::_initialize_row_index(pivot);
686 if constexpr (!Master_matrix::Option_list::has_row_access) {
687 if (matrix_.size() <= columnIndex) {
688 matrix_.resize(columnIndex + 1);
693 _container_insert(column, columnIndex, dim);
696template <
class Master_matrix>
699 _orderRowsIfNecessary();
702 if constexpr (Master_matrix::Option_list::has_row_access && !Master_matrix::Option_list::has_removable_rows)
703 RA_opt::_resize(idx);
706 if constexpr (Master_matrix::Option_list::has_column_and_row_swaps || Master_matrix::Option_list::has_vine_update) {
707 Swap_opt::_initialize_row_index(idx);
711 if constexpr (!Master_matrix::Option_list::has_map_column_container && !Master_matrix::Option_list::has_row_access) {
712 if (matrix_.size() <= columnIndex) {
713 matrix_.resize(columnIndex + 1);
717 _container_insert(idx, e, columnIndex, dim);
720template <
class Master_matrix>
723 if constexpr (Master_matrix::Option_list::has_column_and_row_swaps || Master_matrix::Option_list::has_vine_update) {
724 if (Swap_opt::_row_were_swapped()) Swap_opt::_orderRows();
728template <
class Master_matrix>
730 Index columnIndex)
const
732 if constexpr (Master_matrix::Option_list::has_map_column_container) {
733 return matrix_.at(columnIndex);
735 return matrix_[columnIndex];
739template <
class Master_matrix>
742 if constexpr (Master_matrix::Option_list::has_map_column_container) {
743 return matrix_.at(columnIndex);
745 return matrix_[columnIndex];
749template <
class Master_matrix>
752 if constexpr (Master_matrix::Option_list::has_column_and_row_swaps || Master_matrix::Option_list::has_vine_update) {
753 return Swap_opt::_get_row_index(rowIndex);
759template <
class Master_matrix>
760template <
class Container>
763 if constexpr (Master_matrix::Option_list::has_map_column_container) {
764 if constexpr (Master_matrix::Option_list::has_row_access) {
765 matrix_.try_emplace(pos, Column(pos, column, dim, RA_opt::_get_rows_ptr(), colSettings_));
767 matrix_.try_emplace(pos, Column(column, dim, colSettings_));
770 if constexpr (Master_matrix::Option_list::has_row_access) {
771 matrix_.emplace_back(pos, column, dim, RA_opt::_get_rows_ptr(), colSettings_);
773 matrix_[pos] = Column(column, dim, colSettings_);
778template <
class Master_matrix>
780 if constexpr (Master_matrix::Option_list::has_map_column_container) {
781 if constexpr (Master_matrix::Option_list::has_row_access) {
782 if constexpr (Master_matrix::Option_list::is_z2){
783 matrix_.try_emplace(pos, Column(pos, idx, dim, RA_opt::_get_rows_ptr(), colSettings_));
785 matrix_.try_emplace(pos, Column(pos, idx, e, dim, RA_opt::_get_rows_ptr(), colSettings_));
788 if constexpr (Master_matrix::Option_list::is_z2){
789 matrix_.try_emplace(pos, Column(idx, dim, colSettings_));
791 matrix_.try_emplace(pos, Column(idx, e, dim, colSettings_));
795 if constexpr (Master_matrix::Option_list::has_row_access) {
796 if constexpr (Master_matrix::Option_list::is_z2){
797 matrix_.emplace_back(pos, idx, dim, RA_opt::_get_rows_ptr(), colSettings_);
799 matrix_.emplace_back(pos, idx, e, dim, RA_opt::_get_rows_ptr(), colSettings_);
802 if constexpr (Master_matrix::Option_list::is_z2){
803 matrix_[pos] = Column(idx, dim, colSettings_);
805 matrix_[pos] = Column(idx, e, dim, colSettings_);
811template <
class Master_matrix>
812template <
class ColumnIterator>
815 if constexpr (Master_matrix::Option_list::has_map_column_container) {
816 const auto& col = rep.second;
817 if constexpr (Master_matrix::Option_list::has_row_access) {
818 matrix_.try_emplace(rep.first, Column(col, col.get_column_index(), RA_opt::_get_rows_ptr(), colSettings_));
820 matrix_.try_emplace(rep.first, Column(col, colSettings_));
823 if constexpr (Master_matrix::Option_list::has_row_access) {
824 matrix_.emplace_back(rep, rep.get_column_index(), RA_opt::_get_rows_ptr(), colSettings_);
826 matrix_.emplace_back(rep, 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:466
friend void swap(Base_matrix &matrix1, Base_matrix &matrix2) noexcept
Swap operator.
Definition Base_matrix.h:326
bool is_zero_entry(Index columnIndex, Index rowIndex) const
Indicates if the entry at given coordinates has value zero.
Definition Base_matrix.h:584
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:536
typename Master_matrix::Row Row
Definition Base_matrix.h:54
Index get_number_of_columns() const
Returns the current number of columns in the matrix.
Definition Base_matrix.h:525
void zero_column(Index columnIndex)
Zeroes the column at the given index.
Definition Base_matrix.h:578
bool is_zero_column(Index columnIndex)
Indicates if the column at given index has value zero.
Definition Base_matrix.h:590
typename Master_matrix::Element Field_element
Definition Base_matrix.h:51
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:473
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:458
void reset(Column_settings *colSettings)
Resets the matrix to an empty matrix.
Definition Base_matrix.h:305
Base_matrix & operator=(const Base_matrix &other)
Assign operator.
Definition Base_matrix.h:596
typename Master_matrix::Field_operators Field_operators
Field operators class. Necessary only if PersistenceMatrixOptions::is_z2 is false.
Definition Base_matrix.h:50
typename Master_matrix::Column Column
Definition Base_matrix.h:52
void remove_last()
Removes the last column from the matrix. The last column is at index , where:
Definition Base_matrix.h:494
typename Master_matrix::Column_settings Column_settings
Definition Base_matrix.h:57
typename Master_matrix::Dimension Dimension
Definition Base_matrix.h:46
typename Master_matrix::Index Index
Definition Base_matrix.h:45
Base_matrix(Column_settings *colSettings)
Constructs an empty matrix.
Definition Base_matrix.h:366
typename Master_matrix::Entry_constructor Entry_constructor
Definition Base_matrix.h:56
void remove_column(Index columnIndex)
Only available if PersistenceMatrixOptions::has_map_column_container is true. Otherwise,...
Definition Base_matrix.h:482
typename Master_matrix::Boundary Boundary
Definition Base_matrix.h:53
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:560
void zero_entry(Index columnIndex, Index rowIndex)
Zeroes the entry at the given coordinates.
Definition Base_matrix.h:572
void erase_empty_row(Index rowIndex)
If PersistenceMatrixOptions::has_row_access and PersistenceMatrixOptions::has_removable_rows are true...
Definition Base_matrix.h:513
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:429
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:547
std::enable_if_t< std::is_integral_v< Integer_index > > multiply_target_and_add_to(Integer_index sourceColumnIndex, int coefficient, Integer_index targetColumnIndex)
Multiplies the target column with the coefficient and then adds the source column to it....
Definition Matrix.h:1896
std::conditional_t< 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 > > Row
Type of the rows stored in the matrix. Is either an intrusive list of Matrix_entry (not ordered) if P...
Definition Matrix.h:309
std::enable_if_t< std::is_integral_v< Integer_index > > multiply_source_and_add_to(int coefficient, Integer_index sourceColumnIndex, Integer_index targetColumnIndex)
Multiplies the source column with the coefficient before adding it to the target column....
Definition Matrix.h:1920
void zero_column(Index columnIndex)
Zeroes the column at the given index. Not available for chain matrices and for base matrices with col...
Definition Matrix.h:1964
Returned_column & get_column(Index columnIndex)
Returns the column at the given MatIdx index. For RU matrices, is equivalent to get_column(columnInde...
Definition Matrix.h:1724
bool is_zero_entry(Index columnIndex, ID_index rowIndex)
Indicates if the entry at given coordinates has value zero.
Definition Matrix.h:1986
typename PersistenceMatrixOptions::Index Index
Definition Matrix.h:150
Matrix & operator=(Matrix other) &
Assign operator.
Definition Matrix.h:2045
void zero_entry(Index columnIndex, ID_index rowIndex)
Zeroes the entry at the given coordinates. Not available for chain matrices and for base matrices wit...
Definition Matrix.h:1942
Insertion_return insert_boundary(const Boundary_range &boundary, Dimension dim=Matrix::get_null_value< Dimension >())
Inserts at the end of the matrix a new ordered column corresponding to the given boundary....
Definition Matrix.h:1676
Returned_row & get_row(ID_index rowIndex)
Only available if PersistenceMatrixOptions::has_row_access is true. Returns the row at the given row ...
Definition Matrix.h:1753
void remove_last()
Removes the last inserted column/cell from the matrix. If the matrix is non basic,...
Definition Matrix.h:1835
bool is_zero_column(Index columnIndex)
Indicates if the column at given index has value zero.
Definition Matrix.h:2005
void erase_empty_row(ID_index rowIndex)
The effect varies depending on the matrices and the options:
Definition Matrix.h:1797
void remove_column(Index columnIndex)
Only available for base matrices without column compression and if PersistenceMatrixOptions::has_map_...
Definition Matrix.h:1787
std::conditional_t< PersistenceMatrixOptions::column_type==Column_types::HEAP, Matrix_heap_column, std::conditional_t< PersistenceMatrixOptions::column_type==Column_types::LIST, Matrix_list_column, std::conditional_t< PersistenceMatrixOptions::column_type==Column_types::SET, Matrix_set_column, std::conditional_t< PersistenceMatrixOptions::column_type==Column_types::UNORDERED_SET, Matrix_unordered_set_column, std::conditional_t< PersistenceMatrixOptions::column_type==Column_types::VECTOR, Matrix_vector_column, std::conditional_t< PersistenceMatrixOptions::column_type==Column_types::INTRUSIVE_LIST, Matrix_intrusive_list_column, std::conditional_t< PersistenceMatrixOptions::column_type==Column_types::NAIVE_VECTOR, Matrix_naive_vector_column, std::conditional_t< PersistenceMatrixOptions::column_type==Column_types::SMALL_VECTOR, Matrix_small_vector_column, Matrix_intrusive_set_column > > > > > > > > Column
Type of the columns stored in the matrix. The type depends on the value of PersistenceMatrixOptions::...
Definition Matrix.h:359
Index get_number_of_columns() const
Returns the current number of columns in the matrix.
Definition Matrix.h:1857
std::enable_if_t< std::is_integral_v< Integer_index > > add_to(Integer_index sourceColumnIndex, Integer_index targetColumnIndex)
Adds column at sourceColumnIndex onto the column at targetColumnIndex in the matrix....
Definition Matrix.h:1873
void insert_column(const Container &column)
Inserts a new ordered column at the end of the matrix by copying the given range of Entry_representat...
Definition Matrix.h:1626
Persistence matrix namespace.
Definition FieldOperators.h:18
Gudhi namespace.
Definition SimplicialComplexForAlpha.h:14