17 #ifndef PM_BOUNDARY_MATRIX_H
18 #define PM_BOUNDARY_MATRIX_H
26 namespace persistence_matrix {
39 template <
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;
56 using Row_type =
typename Master_matrix::Row_type;
90 template <
class Boundary_type = boundary_type>
141 template <
class Boundary_type = boundary_type>
160 template <
class Boundary_type = boundary_type>
251 index targetColumnIndex);
265 index sourceColumnIndex,
266 index targetColumnIndex);
321 nextInsertIndex_ = 0;
322 colSettings_ = colSettings;
333 swap(
static_cast<typename Master_matrix::Matrix_dimension_option&
>(matrix1),
334 static_cast<typename Master_matrix::Matrix_dimension_option&
>(matrix2));
335 swap(
static_cast<typename Master_matrix::template Base_swap_option<Boundary_matrix<Master_matrix>
>&>(matrix1),
336 static_cast<typename Master_matrix::template Base_swap_option<Boundary_matrix<Master_matrix>
>&>(matrix2));
337 swap(
static_cast<typename Master_matrix::Base_pairing_option&
>(matrix1),
338 static_cast<typename Master_matrix::Base_pairing_option&
>(matrix2));
339 matrix1.matrix_.swap(matrix2.matrix_);
340 std::swap(matrix1.nextInsertIndex_, matrix2.nextInsertIndex_);
341 std::swap(matrix1.colSettings_, matrix2.colSettings_);
343 if constexpr (Master_matrix::Option_list::has_row_access) {
344 swap(
static_cast<typename Master_matrix::Matrix_row_access_option&
>(matrix1),
345 static_cast<typename Master_matrix::Matrix_row_access_option&
>(matrix2));
352 using dim_opt =
typename Master_matrix::Matrix_dimension_option;
353 using swap_opt =
typename Master_matrix::template Base_swap_option<Boundary_matrix<Master_matrix> >;
354 using pair_opt =
typename Master_matrix::Base_pairing_option;
355 using ra_opt =
typename Master_matrix::Matrix_row_access_option;
356 using matrix_type =
typename Master_matrix::column_container_type;
362 index nextInsertIndex_;
365 static constexpr
bool activeDimOption =
366 Master_matrix::Option_list::has_matrix_maximal_dimension_access || Master_matrix::maxDimensionIsNeeded;
367 static constexpr
bool activeSwapOption =
368 Master_matrix::Option_list::has_column_and_row_swaps || Master_matrix::Option_list::has_vine_update;
369 static constexpr
bool activePairingOption = Master_matrix::Option_list::has_column_pairings &&
370 !Master_matrix::Option_list::has_vine_update &&
371 !Master_matrix::Option_list::can_retrieve_representative_cycles;
373 void _orderRowsIfNecessary();
376 index _get_real_row_index(
index rowIndex)
const;
377 template <
class Container_type>
379 void _container_insert(
const Column_type& column, [[maybe_unused]]
index pos = 0);
382 template <
class Master_matrix>
389 colSettings_(colSettings)
392 template <
class Master_matrix>
393 template <
class Boundary_type>
397 swap_opt(orderedBoundaries.size()),
399 ra_opt(orderedBoundaries.size()),
400 nextInsertIndex_(orderedBoundaries.size()),
401 colSettings_(colSettings)
403 matrix_.reserve(orderedBoundaries.size());
405 for (
index i = 0; i < orderedBoundaries.size(); i++) {
406 _container_insert(orderedBoundaries[i], i, orderedBoundaries[i].size() == 0 ? 0 : orderedBoundaries[i].size() - 1);
410 template <
class Master_matrix>
414 swap_opt(numberOfColumns),
416 ra_opt(numberOfColumns),
417 matrix_(!Master_matrix::Option_list::has_map_column_container && Master_matrix::Option_list::has_row_access
421 colSettings_(colSettings)
423 if constexpr (!Master_matrix::Option_list::has_map_column_container && Master_matrix::Option_list::has_row_access)
424 matrix_.reserve(numberOfColumns);
427 template <
class Master_matrix>
430 : dim_opt(static_cast<const dim_opt&>(matrixToCopy)),
431 swap_opt(static_cast<const swap_opt&>(matrixToCopy)),
432 pair_opt(static_cast<const pair_opt&>(matrixToCopy)),
433 ra_opt(static_cast<const ra_opt&>(matrixToCopy)),
434 nextInsertIndex_(matrixToCopy.nextInsertIndex_),
435 colSettings_(colSettings == nullptr ? matrixToCopy.colSettings_ : colSettings)
437 matrix_.reserve(matrixToCopy.matrix_.size());
438 for (
const auto& cont : matrixToCopy.matrix_){
439 if constexpr (Master_matrix::Option_list::has_map_column_container){
440 _container_insert(cont.second, cont.first);
442 _container_insert(cont);
447 template <
class Master_matrix>
449 : dim_opt(std::move(
static_cast<dim_opt&
>(other))),
450 swap_opt(std::move(
static_cast<swap_opt&
>(other))),
451 pair_opt(std::move(
static_cast<pair_opt&
>(other))),
452 ra_opt(std::move(
static_cast<ra_opt&
>(other))),
453 matrix_(std::move(other.matrix_)),
454 nextInsertIndex_(std::exchange(other.nextInsertIndex_, 0)),
455 colSettings_(std::exchange(other.colSettings_,
nullptr))
458 template <
class Master_matrix>
459 template <
class Boundary_type>
463 return insert_boundary(nextInsertIndex_, boundary, dim);
466 template <
class Master_matrix>
467 template <
class Boundary_type>
471 if (dim == -1) dim = boundary.size() == 0 ? 0 : boundary.size() - 1;
473 _orderRowsIfNecessary();
476 if constexpr (Master_matrix::Option_list::has_row_access && !Master_matrix::Option_list::has_removable_rows) {
478 if constexpr (Master_matrix::Option_list::is_z2) {
479 pivot = *std::prev(boundary.end());
481 pivot = std::prev(boundary.end())->first;
484 if (ra_opt::rows_->size() <= pivot) ra_opt::rows_->resize(pivot + 1);
488 if constexpr (Master_matrix::Option_list::has_map_column_container) {
489 if constexpr (activeSwapOption) {
490 swap_opt::indexToRow_.emplace(faceIndex, faceIndex);
491 swap_opt::rowToIndex_.emplace(faceIndex, faceIndex);
494 if constexpr (activeSwapOption) {
495 for (
index i = swap_opt::indexToRow_.size(); i <= faceIndex; ++i) {
496 swap_opt::indexToRow_.push_back(i);
497 swap_opt::rowToIndex_.push_back(i);
502 _container_insert(boundary, nextInsertIndex_, dim);
504 return nextInsertIndex_++;
507 template <
class Master_matrix>
511 _orderRowsIfNecessary();
513 return _get_column(columnIndex);
516 template <
class Master_matrix>
519 static_assert(Master_matrix::Option_list::has_row_access,
"'get_row' is not implemented for the chosen options.");
521 _orderRowsIfNecessary();
523 return ra_opt::get_row(rowIndex);
526 template <
class Master_matrix>
529 static_assert(Master_matrix::Option_list::has_removable_columns,
530 "'remove_last' is not implemented for the chosen options.");
532 if (nextInsertIndex_ == 0)
return -1;
536 if constexpr (activeDimOption) {
537 dim_opt::update_down(matrix_.at(nextInsertIndex_).get_dimension());
542 if constexpr (Master_matrix::Option_list::has_map_column_container) {
543 auto it = matrix_.find(nextInsertIndex_);
544 pivot = it->second.get_pivot();
545 if constexpr (activeSwapOption) {
547 if (swap_opt::rowSwapped_ && pivot !=
static_cast<id_index>(-1)) {
548 swap_opt::_orderRows();
549 pivot = it->second.get_pivot();
554 pivot = matrix_[nextInsertIndex_].get_pivot();
555 if constexpr (activeSwapOption) {
557 if (swap_opt::rowSwapped_ && pivot !=
static_cast<id_index>(-1)) {
558 swap_opt::_orderRows();
559 pivot = matrix_[nextInsertIndex_].get_pivot();
562 if constexpr (Master_matrix::Option_list::has_row_access) {
563 GUDHI_CHECK(nextInsertIndex_ == matrix_.size() - 1,
564 std::logic_error(
"Boundary_matrix::remove_last - Indexation problem."));
567 matrix_[nextInsertIndex_].clear();
571 erase_empty_row(nextInsertIndex_);
574 if constexpr (activePairingOption) {
575 pair_opt::_remove_last(nextInsertIndex_);
581 template <
class Master_matrix>
586 if constexpr (activeSwapOption) {
587 if constexpr (Master_matrix::Option_list::has_map_column_container) {
588 auto it = swap_opt::indexToRow_.find(rowIndex);
590 swap_opt::rowToIndex_.erase(rowID);
591 swap_opt::indexToRow_.erase(it);
593 rowID = swap_opt::indexToRow_[rowIndex];
597 if constexpr (Master_matrix::Option_list::has_row_access && Master_matrix::Option_list::has_removable_rows) {
598 ra_opt::erase_empty_row(rowID);
602 template <
class Master_matrix>
605 if constexpr (Master_matrix::Option_list::has_map_column_container) {
606 return matrix_.size();
608 return nextInsertIndex_;
612 template <
class Master_matrix>
614 index columnIndex)
const
616 return _get_column(columnIndex).get_dimension();
619 template <
class Master_matrix>
622 _get_column(targetColumnIndex) += _get_column(sourceColumnIndex);
625 template <
class Master_matrix>
628 index targetColumnIndex)
630 _get_column(targetColumnIndex).multiply_target_and_add(coefficient, _get_column(sourceColumnIndex));
633 template <
class Master_matrix>
635 index sourceColumnIndex,
636 index targetColumnIndex)
638 _get_column(targetColumnIndex).multiply_source_and_add(_get_column(sourceColumnIndex), coefficient);
641 template <
class Master_matrix>
644 _get_column(columnIndex).clear(_get_real_row_index(rowIndex));
647 template <
class Master_matrix>
650 _get_column(columnIndex).clear();
653 template <
class Master_matrix>
656 return !(_get_column(columnIndex).is_non_zero(_get_real_row_index(rowIndex)));
659 template <
class Master_matrix>
662 return _get_column(columnIndex).is_empty();
665 template <
class Master_matrix>
668 _orderRowsIfNecessary();
670 return _get_column(columnIndex).get_pivot();
673 template <
class Master_matrix>
676 dim_opt::operator=(other);
677 swap_opt::operator=(other);
678 pair_opt::operator=(other);
679 ra_opt::operator=(other);
682 nextInsertIndex_ = other.nextInsertIndex_;
683 colSettings_ = other.colSettings_;
685 matrix_.reserve(other.matrix_.size());
686 for (
const auto& cont : other.matrix_){
687 if constexpr (Master_matrix::Option_list::has_map_column_container){
688 _container_insert(cont.second, cont.first);
690 _container_insert(cont);
697 template <
class Master_matrix>
700 if constexpr (activeSwapOption) {
701 if (swap_opt::rowSwapped_) swap_opt::_orderRows();
703 std::cout <<
"Boundary_matrix:\n";
704 for (index i = 0; i < nextInsertIndex_; ++i) {
705 Column_type& col = matrix_[i];
706 for (
auto e : col.get_content(nextInsertIndex_)) {
710 std::cout << e <<
" ";
715 if constexpr (Master_matrix::Option_list::has_row_access) {
716 std::cout <<
"Row Matrix:\n";
717 for (id_index i = 0; i < nextInsertIndex_; ++i) {
718 const auto& row = ra_opt::rows_[i];
719 for (
const auto& cell : row) {
720 std::cout << cell.get_column_index() <<
" ";
722 std::cout <<
"(" << i <<
")\n";
728 template <
class Master_matrix>
729 inline void Boundary_matrix<Master_matrix>::_orderRowsIfNecessary()
731 if constexpr (activeSwapOption) {
732 if (swap_opt::rowSwapped_) swap_opt::_orderRows();
736 template <
class Master_matrix>
738 index columnIndex)
const
740 if constexpr (Master_matrix::Option_list::has_map_column_container) {
741 return matrix_.at(columnIndex);
743 return matrix_[columnIndex];
747 template <
class Master_matrix>
751 if constexpr (Master_matrix::Option_list::has_map_column_container) {
752 return matrix_.at(columnIndex);
754 return matrix_[columnIndex];
758 template <
class Master_matrix>
760 index rowIndex)
const
762 if constexpr (Master_matrix::Option_list::has_column_and_row_swaps || Master_matrix::Option_list::has_vine_update) {
763 if constexpr (Master_matrix::Option_list::has_map_column_container) {
764 return swap_opt::indexToRow_.at(rowIndex);
766 return swap_opt::indexToRow_[rowIndex];
773 template <
class Master_matrix>
774 template <
class Container_type>
775 inline void Boundary_matrix<Master_matrix>::_container_insert(
const Container_type& column,
779 if constexpr (Master_matrix::Option_list::has_map_column_container) {
780 if constexpr (Master_matrix::Option_list::has_row_access) {
781 matrix_.try_emplace(pos, Column_type(pos, column, dim, ra_opt::rows_, colSettings_));
783 matrix_.try_emplace(pos, Column_type(column, dim, colSettings_));
786 if constexpr (Master_matrix::Option_list::has_row_access) {
787 matrix_.emplace_back(pos, column, dim, ra_opt::rows_, colSettings_);
789 if (matrix_.size() <= pos) {
790 matrix_.emplace_back(column, dim, colSettings_);
792 matrix_[pos] = Column_type(column, dim, colSettings_);
796 if constexpr (activeDimOption) {
797 dim_opt::update_up(dim);
801 template <
class Master_matrix>
802 inline void Boundary_matrix<Master_matrix>::_container_insert(
const Column_type& column, [[maybe_unused]] index pos)
804 if constexpr (Master_matrix::Option_list::has_map_column_container) {
805 if constexpr (Master_matrix::Option_list::has_row_access) {
806 matrix_.try_emplace(pos, Column_type(column, column.get_column_index(), ra_opt::rows_, colSettings_));
808 matrix_.try_emplace(pos, Column_type(column, colSettings_));
811 if constexpr (Master_matrix::Option_list::has_row_access) {
812 matrix_.emplace_back(column, column.get_column_index(), ra_opt::rows_, colSettings_);
814 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::Cell_constructor Cell_constructor
Definition: boundary_matrix.h:58
dimension_type get_column_dimension(index columnIndex) const
Returns the dimension of the given column.
Definition: boundary_matrix.h:613
void multiply_source_and_add_to(const Field_element_type &coefficient, index sourceColumnIndex, index targetColumnIndex)
Multiplies the source column with the coefficiant before adding it to the target column....
Definition: boundary_matrix.h:634
typename Master_matrix::Column_settings Column_settings
Definition: boundary_matrix.h:60
bool is_zero_cell(index columnIndex, index rowIndex) const
Indicates if the cell at given coordinates has value zero.
Definition: boundary_matrix.h:654
void zero_column(index columnIndex)
Zeroes the column at the given index.
Definition: boundary_matrix.h:648
void multiply_target_and_add_to(index sourceColumnIndex, const Field_element_type &coefficient, index targetColumnIndex)
Multiplies the target column with the coefficiant and then adds the source column to it....
Definition: boundary_matrix.h:626
void erase_empty_row(index rowIndex)
If PersistenceMatrixOptions::has_row_access and PersistenceMatrixOptions::has_removable_rows are true...
Definition: boundary_matrix.h:582
bool is_zero_column(index columnIndex)
Indicates if the column at given index has value zero.
Definition: boundary_matrix.h:660
friend void swap(Boundary_matrix &matrix1, Boundary_matrix &matrix2)
Swap operator.
Definition: boundary_matrix.h:332
typename Master_matrix::Column_type Column_type
Definition: boundary_matrix.h:54
Row_type & get_row(index rowIndex)
Only available if PersistenceMatrixOptions::has_row_access is true. Returns the row at the given row ...
Definition: boundary_matrix.h:517
void add_to(index sourceColumnIndex, index targetColumnIndex)
Adds column at sourceColumnIndex onto the column at targetColumnIndex in the matrix.
Definition: boundary_matrix.h:620
typename Master_matrix::element_type Field_element_type
Definition: boundary_matrix.h:53
index get_pivot(index columnIndex)
Returns the pivot of the given column.
Definition: boundary_matrix.h:666
typename Master_matrix::dimension_type dimension_type
Definition: boundary_matrix.h:48
void reset(Column_settings *colSettings)
Resets the matrix to an empty matrix.
Definition: boundary_matrix.h:319
typename Master_matrix::boundary_type boundary_type
Definition: boundary_matrix.h:55
typename Master_matrix::index index
Definition: boundary_matrix.h:46
void zero_cell(index columnIndex, index rowIndex)
Zeroes the cell at the given coordinates.
Definition: boundary_matrix.h:642
typename Master_matrix::id_index id_index
Definition: boundary_matrix.h:47
index insert_boundary(const Boundary_type &boundary, dimension_type dim=-1)
Inserts at the end of the matrix a new ordered column corresponding to the given boundary....
Definition: boundary_matrix.h:460
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: boundary_matrix.h:508
Boundary_matrix(Column_settings *colSettings)
Constructs an empty matrix.
Definition: boundary_matrix.h:383
typename Master_matrix::Row_type Row_type
Definition: boundary_matrix.h:57
index get_number_of_columns() const
Returns the current number of columns in the matrix.
Definition: boundary_matrix.h:603
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:674
index remove_last()
Only available if PersistenceMatrixOptions::has_removable_columns is true. Removes the last face in t...
Definition: boundary_matrix.h:527
Gudhi namespace.
Definition: SimplicialComplexForAlpha.h:14