17 #ifndef PM_BASE_MATRIX_H
18 #define PM_BASE_MATRIX_H
25 namespace persistence_matrix {
36 template <
class Master_matrix>
37 class 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;
50 using Row_type =
typename Master_matrix::Row_type;
73 template <
class Container_type = container_type>
74 Base_matrix(
const std::vector<Container_type>& columns,
110 template <
class Container_type = container_type>
123 template <
class Container_type = container_type>
133 template <
class Boundary_type>
223 template <
class Cell_range_or_column_index>
224 void add_to(
const Cell_range_or_column_index& sourceColumn,
index targetColumnIndex);
235 template <
class Cell_range_or_column_index>
238 index targetColumnIndex);
249 template <
class Cell_range_or_column_index>
251 const Cell_range_or_column_index& sourceColumn,
252 index targetColumnIndex);
293 nextInsertIndex_ = 0;
294 colSettings_ = colSettings;
305 swap(
static_cast<typename Master_matrix::template Base_swap_option<Base_matrix<Master_matrix>
>&>(matrix1),
306 static_cast<typename Master_matrix::template Base_swap_option<Base_matrix<Master_matrix>
>&>(matrix2));
307 matrix1.matrix_.swap(matrix2.matrix_);
308 std::swap(matrix1.nextInsertIndex_, matrix2.nextInsertIndex_);
309 std::swap(matrix1.colSettings_, matrix2.colSettings_);
312 swap(
static_cast<typename Master_matrix::Matrix_row_access_option&
>(matrix1),
313 static_cast<typename Master_matrix::Matrix_row_access_option&
>(matrix2));
320 using swap_opt =
typename Master_matrix::template Base_swap_option<Base_matrix<Master_matrix> >;
321 using ra_opt =
typename Master_matrix::Matrix_row_access_option;
322 using matrix_type =
typename Master_matrix::column_container_type;
323 using cell_rep_type =
326 std::pair<index, Field_element_type>
332 index nextInsertIndex_;
335 template <
class Container_type = container_type>
337 void _orderRowsIfNecessary();
340 index _get_real_row_index(
index rowIndex)
const;
341 template <
class Container_type>
343 void _container_insert(
const Column_type& column, [[maybe_unused]]
index pos = 0);
346 template <
class Master_matrix>
348 : swap_opt(), ra_opt(), nextInsertIndex_(0), colSettings_(colSettings)
351 template <
class Master_matrix>
352 template <
class Container_type>
355 : swap_opt(columns.size()),
357 ra_opt(columns.size()),
358 matrix_(!Master_matrix::Option_list::has_map_column_container && Master_matrix::Option_list::has_row_access
361 nextInsertIndex_(columns.size()),
362 colSettings_(colSettings)
365 matrix_.reserve(columns.size());
367 for (
index i = 0; i < columns.size(); i++) {
368 _container_insert(columns[i], i, columns[i].size() == 0 ? 0 : columns[i].size() - 1);
372 template <
class Master_matrix>
375 : swap_opt(numberOfColumns),
376 ra_opt(numberOfColumns),
377 matrix_(!Master_matrix::Option_list::has_map_column_container && Master_matrix::Option_list::has_row_access
381 colSettings_(colSettings)
384 matrix_.reserve(numberOfColumns);
387 template <
class Master_matrix>
390 : swap_opt(static_cast<const swap_opt&>(matrixToCopy)),
391 ra_opt(static_cast<const ra_opt&>(matrixToCopy)),
392 nextInsertIndex_(matrixToCopy.nextInsertIndex_),
393 colSettings_(colSettings == nullptr ? matrixToCopy.colSettings_ : colSettings)
395 matrix_.reserve(matrixToCopy.matrix_.size());
396 for (
const auto& cont : matrixToCopy.matrix_){
398 _container_insert(cont.second, cont.first);
400 _container_insert(cont);
405 template <
class Master_matrix>
407 : swap_opt(std::move(
static_cast<swap_opt&
>(other))),
408 ra_opt(std::move(
static_cast<ra_opt&
>(other))),
409 matrix_(std::move(other.matrix_)),
410 nextInsertIndex_(std::exchange(other.nextInsertIndex_, 0)),
411 colSettings_(std::exchange(other.colSettings_,
nullptr))
414 template <
class Master_matrix>
415 template <
class Container_type>
419 _insert(column, nextInsertIndex_, column.size() == 0 ? 0 : column.size() - 1);
423 template <
class Master_matrix>
424 template <
class Container_type>
427 static_assert(!Master_matrix::Option_list::has_row_access,
428 "Columns have to be inserted at the end of the matrix when row access is enabled.");
430 if (columnIndex >= nextInsertIndex_) nextInsertIndex_ = columnIndex + 1;
432 _insert(column, columnIndex, column.size() == 0 ? 0 : column.size() - 1);
435 template <
class Master_matrix>
436 template <
class Boundary_type>
439 if (dim == -1) dim = boundary.size() == 0 ? 0 : boundary.size() - 1;
441 _insert(boundary, nextInsertIndex_++, dim);
444 template <
class Master_matrix>
447 _orderRowsIfNecessary();
448 return _get_column(columnIndex);
451 template <
class Master_matrix>
454 static_assert(Master_matrix::Option_list::has_row_access,
"Row access has to be enabled for this method.");
456 _orderRowsIfNecessary();
457 return ra_opt::get_row(rowIndex);
460 template <
class Master_matrix>
463 static_assert(Master_matrix::Option_list::has_map_column_container,
464 "'remove_column' is not implemented for the chosen options.");
467 if (columnIndex == nextInsertIndex_ - 1) --nextInsertIndex_;
469 matrix_.erase(columnIndex);
472 template <
class Master_matrix>
475 if (nextInsertIndex_ == 0)
return;
478 if constexpr (Master_matrix::Option_list::has_map_column_container) {
479 matrix_.erase(nextInsertIndex_);
481 if constexpr (Master_matrix::Option_list::has_row_access) {
482 GUDHI_CHECK(nextInsertIndex_ == matrix_.size() - 1,
483 std::logic_error(
"Base_matrix::remove_last - Indexation problem."));
486 matrix_[nextInsertIndex_].clear();
491 template <
class Master_matrix>
494 if constexpr (Master_matrix::Option_list::has_row_access && Master_matrix::Option_list::has_removable_rows) {
495 ra_opt::erase_empty_row(_get_real_row_index(rowIndex));
497 if constexpr ((Master_matrix::Option_list::has_column_and_row_swaps || Master_matrix::Option_list::has_vine_update) &&
498 Master_matrix::Option_list::has_map_column_container) {
499 auto it = swap_opt::indexToRow_.find(rowIndex);
500 swap_opt::rowToIndex_.erase(it->second);
501 swap_opt::indexToRow_.erase(it);
505 template <
class Master_matrix>
508 if constexpr (Master_matrix::Option_list::has_map_column_container) {
509 return matrix_.size();
511 return nextInsertIndex_;
515 template <
class Master_matrix>
516 template <
class Cell_range_or_column_index>
518 index targetColumnIndex)
520 if constexpr (std::is_integral_v<Cell_range_or_column_index>) {
521 _get_column(targetColumnIndex) += _get_column(sourceColumn);
523 _get_column(targetColumnIndex) += sourceColumn;
527 template <
class Master_matrix>
528 template <
class Cell_range_or_column_index>
531 index targetColumnIndex)
533 if constexpr (std::is_integral_v<Cell_range_or_column_index>) {
534 _get_column(targetColumnIndex).multiply_target_and_add(coefficient, _get_column(sourceColumn));
536 _get_column(targetColumnIndex).multiply_target_and_add(coefficient, sourceColumn);
540 template <
class Master_matrix>
541 template <
class Cell_range_or_column_index>
543 const Cell_range_or_column_index& sourceColumn,
544 index targetColumnIndex)
546 if constexpr (std::is_integral_v<Cell_range_or_column_index>) {
547 _get_column(targetColumnIndex).multiply_source_and_add(_get_column(sourceColumn), coefficient);
549 _get_column(targetColumnIndex).multiply_source_and_add(sourceColumn, coefficient);
553 template <
class Master_matrix>
556 _get_column(columnIndex).clear(_get_real_row_index(rowIndex));
559 template <
class Master_matrix>
561 _get_column(columnIndex).clear();
564 template <
class Master_matrix>
567 return !(_get_column(columnIndex).is_non_zero(_get_real_row_index(rowIndex)));
570 template <
class Master_matrix>
573 return _get_column(columnIndex).is_empty();
576 template <
class Master_matrix>
579 swap_opt::operator=(other);
580 ra_opt::operator=(other);
582 nextInsertIndex_ = other.nextInsertIndex_;
583 colSettings_ = other.colSettings_;
585 matrix_.reserve(other.matrix_.size());
586 for (
const auto& cont : other.matrix_){
587 if constexpr (Master_matrix::Option_list::has_map_column_container){
588 _container_insert(cont.second, cont.first);
590 _container_insert(cont);
597 template <
class Master_matrix>
600 _orderRowsIfNecessary();
601 std::cout <<
"Base_matrix:\n";
602 for (index i = 0; i < nextInsertIndex_; ++i) {
603 const Column_type& col = matrix_[i];
604 for (
const auto& e : col.get_content(nextInsertIndex_)) {
608 std::cout << e <<
" ";
613 if constexpr (Master_matrix::Option_list::has_row_access) {
614 std::cout <<
"Row Matrix:\n";
615 for (index i = 0; i < nextInsertIndex_; ++i) {
616 const auto& row = ra_opt::rows_[i];
617 for (
const auto& cell : row) {
618 std::cout << cell.get_column_index() <<
" ";
620 std::cout <<
"(" << i <<
")\n";
626 template <
class Master_matrix>
627 template <
class Container_type>
630 _orderRowsIfNecessary();
634 if (column.begin() != column.end()) {
636 if constexpr (Master_matrix::Option_list::is_z2) {
637 pivot = *std::prev(column.end());
639 pivot = std::prev(column.end())->first;
642 if constexpr (Master_matrix::Option_list::has_row_access && !Master_matrix::Option_list::has_removable_rows)
643 if (ra_opt::rows_->size() <= pivot) ra_opt::rows_->resize(pivot + 1);
647 if constexpr (Master_matrix::Option_list::has_map_column_container) {
648 if constexpr (Master_matrix::Option_list::has_column_and_row_swaps || Master_matrix::Option_list::has_vine_update) {
649 for (
auto id : column) {
651 if constexpr (Master_matrix::Option_list::is_z2) {
656 swap_opt::indexToRow_[idx] = idx;
657 swap_opt::rowToIndex_[idx] = idx;
661 if constexpr (Master_matrix::Option_list::has_column_and_row_swaps || Master_matrix::Option_list::has_vine_update) {
662 index size = swap_opt::indexToRow_.size();
664 for (index i = size; i <= pivot; i++) {
665 swap_opt::indexToRow_.push_back(i);
666 swap_opt::rowToIndex_.push_back(i);
671 if constexpr (!Master_matrix::Option_list::has_row_access) {
672 if (matrix_.size() <= columnIndex) {
673 matrix_.resize(columnIndex + 1);
678 _container_insert(column, columnIndex, dim);
681 template <
class Master_matrix>
684 if constexpr (Master_matrix::Option_list::has_column_and_row_swaps || Master_matrix::Option_list::has_vine_update) {
685 if (swap_opt::rowSwapped_) swap_opt::_orderRows();
689 template <
class Master_matrix>
691 index columnIndex)
const
693 if constexpr (Master_matrix::Option_list::has_map_column_container) {
694 return matrix_.at(columnIndex);
696 return matrix_[columnIndex];
700 template <
class Master_matrix>
703 if constexpr (Master_matrix::Option_list::has_map_column_container) {
704 return matrix_.at(columnIndex);
706 return matrix_[columnIndex];
710 template <
class Master_matrix>
713 if constexpr (Master_matrix::Option_list::has_column_and_row_swaps || Master_matrix::Option_list::has_vine_update) {
714 if constexpr (Master_matrix::Option_list::has_map_column_container) {
715 return swap_opt::indexToRow_.at(rowIndex);
717 return swap_opt::indexToRow_[rowIndex];
724 template <
class Master_matrix>
725 template <
class Container_type>
727 if constexpr (Master_matrix::Option_list::has_map_column_container) {
728 if constexpr (Master_matrix::Option_list::has_row_access) {
729 matrix_.try_emplace(pos, Column_type(pos, column, dim, ra_opt::rows_, colSettings_));
731 matrix_.try_emplace(pos, Column_type(column, dim, colSettings_));
734 if constexpr (Master_matrix::Option_list::has_row_access) {
735 matrix_.emplace_back(pos, column, dim, ra_opt::rows_, colSettings_);
737 matrix_[pos] = Column_type(column, dim, colSettings_);
742 template <
class Master_matrix>
744 if constexpr (Master_matrix::Option_list::has_map_column_container) {
745 if constexpr (Master_matrix::Option_list::has_row_access) {
746 matrix_.try_emplace(pos, Column_type(column, column.get_column_index(), ra_opt::rows_, colSettings_));
748 matrix_.try_emplace(pos, Column_type(column, colSettings_));
751 if constexpr (Master_matrix::Option_list::has_row_access) {
752 matrix_.emplace_back(column, column.get_column_index(), ra_opt::rows_, colSettings_);
754 matrix_.emplace_back(column, colSettings_);
A basic matrix structure allowing to easily manipulate and access entire columns and rows,...
Definition: base_matrix.h:39
void insert_column(const Container_type &column)
Inserts a new ordered column at the end of the matrix by copying the given range of Matrix::cell_rep_...
Definition: base_matrix.h:416
void add_to(const Cell_range_or_column_index &sourceColumn, index targetColumnIndex)
Adds column represented by sourceColumn onto the column at targetColumnIndex in the matrix.
Definition: base_matrix.h:517
friend void swap(Base_matrix &matrix1, Base_matrix &matrix2)
Swap operator.
Definition: base_matrix.h:304
typename Master_matrix::dimension_type dimension_type
Definition: base_matrix.h:42
Row_type & get_row(index rowIndex)
Only available if PersistenceMatrixOptions::has_row_access is true. Returns the row at the given row ...
Definition: base_matrix.h:452
bool is_zero_column(index columnIndex)
Indicates if the column at given index has value zero.
Definition: base_matrix.h:571
void remove_column(index columnIndex)
Only available if PersistenceMatrixOptions::has_map_column_container is true. Otherwise,...
Definition: base_matrix.h:461
void reset(Column_settings *colSettings)
Resets the matrix to an empty matrix.
Definition: base_matrix.h:291
index get_number_of_columns() const
Returns the current number of columns in the matrix.
Definition: base_matrix.h:506
Base_matrix & operator=(const Base_matrix &other)
Assign operator.
Definition: base_matrix.h:577
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::index index
Definition: base_matrix.h:41
void remove_last()
Removes the last column from the matrix. The last column is at index , where:
Definition: base_matrix.h:473
typename Master_matrix::Column_settings Column_settings
Definition: base_matrix.h:54
typename Master_matrix::boundary_type container_type
Definition: base_matrix.h:49
void multiply_target_and_add_to(const Cell_range_or_column_index &sourceColumn, const Field_element_type &coefficient, index targetColumnIndex)
Multiplies the target column with the coefficiant and then adds the source column to it....
Definition: base_matrix.h:529
void insert_boundary(const Boundary_type &boundary, dimension_type dim=-1)
Same as insert_column, only for interface purposes. The given dimension is ignored and not stored.
Definition: base_matrix.h:437
void erase_empty_row(index rowIndex)
If PersistenceMatrixOptions::has_row_access and PersistenceMatrixOptions::has_removable_rows are true...
Definition: base_matrix.h:492
typename Master_matrix::Row_type Row_type
Definition: base_matrix.h:51
Base_matrix(Column_settings *colSettings)
Constructs an empty matrix.
Definition: base_matrix.h:347
void zero_cell(index columnIndex, index rowIndex)
Zeroes the cell at the given coordinates.
Definition: base_matrix.h:554
void zero_column(index columnIndex)
Zeroes the column at the given index.
Definition: base_matrix.h:560
Column_type & get_column(index columnIndex)
Returns the column at the given MatIdx index. The type of the column depends on the choosen options,...
Definition: base_matrix.h:445
void multiply_source_and_add_to(const Field_element_type &coefficient, const Cell_range_or_column_index &sourceColumn, index targetColumnIndex)
Multiplies the source column with the coefficiant before adding it to the target column....
Definition: base_matrix.h:542
typename Master_matrix::Column_type Column_type
Definition: base_matrix.h:48
bool is_zero_cell(index columnIndex, index rowIndex) const
Indicates if the cell at given coordinates has value zero.
Definition: base_matrix.h:565
typename Master_matrix::Cell_constructor Cell_constructor
Definition: base_matrix.h:52
typename Master_matrix::element_type Field_element_type
Definition: base_matrix.h:47
Data structure for matrices, and in particular thought for matrices representing filtered complexes i...
Definition: matrix.h:143
typename std::conditional< PersistenceMatrixOptions::has_intrusive_rows, boost::intrusive::list< Cell_type, boost::intrusive::constant_time_size< false >, boost::intrusive::base_hook< base_hook_matrix_row > >, std::set< Cell_type, RowCellComp > >::type Row_type
Type of the rows stored in the matrix. Is either an intrusive list of Cell_type (not ordered) if Pers...
Definition: matrix.h:281
typename std::conditional< PersistenceMatrixOptions::column_type==Column_types::HEAP, Heap_column_type, typename std::conditional< PersistenceMatrixOptions::column_type==Column_types::LIST, List_column_type, typename std::conditional< PersistenceMatrixOptions::column_type==Column_types::SET, Set_column_type, typename std::conditional< PersistenceMatrixOptions::column_type==Column_types::UNORDERED_SET, Unordered_set_column_type, typename std::conditional< PersistenceMatrixOptions::column_type==Column_types::VECTOR, Vector_column_type, typename std::conditional< PersistenceMatrixOptions::column_type==Column_types::INTRUSIVE_LIST, Intrusive_list_column_type, typename std::conditional< PersistenceMatrixOptions::column_type==Column_types::NAIVE_VECTOR, Naive_vector_column_type, Intrusive_set_column_type >::type >::type >::type >::type >::type >::type >::type Column_type
Type of the columns stored in the matrix. The type depends on the value of PersistenceMatrixOptions::...
Definition: matrix.h:370
typename PersistenceMatrixOptions::index_type index
Definition: matrix.h:146
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