25namespace persistence_matrix {
38template <
class Master_matrix>
39class RU_matrix :
public Master_matrix::RU_pairing_option,
40 public Master_matrix::RU_vine_swap_option,
41 public Master_matrix::RU_representative_cycles_option
49 using Column =
typename Master_matrix::Column;
50 using Row =
typename Master_matrix::Row;
55 using Boundary =
typename Master_matrix::Boundary;
56 using Index =
typename Master_matrix::Index;
57 using ID_index =
typename Master_matrix::ID_index;
58 using Pos_index =
typename Master_matrix::Pos_index;
59 using Dimension =
typename Master_matrix::Dimension;
88 template <
class Boundary_range = Boundary>
134 template <
class Boundary_range = Boundary>
136 Dimension dim = Master_matrix::template get_null_value<Dimension>());
154 template <
class Boundary_range = Boundary>
156 Dimension dim = Master_matrix::template get_null_value<Dimension>());
355 reducedMatrixR_.reset(colSettings);
356 mirrorMatrixU_.reset(colSettings);
357 pivotToColumnIndex_.clear();
360 operators_ = &(colSettings->operators);
372 swap(
static_cast<typename Master_matrix::RU_pairing_option&
>(matrix1),
373 static_cast<typename Master_matrix::RU_pairing_option&
>(matrix2));
374 swap(
static_cast<typename Master_matrix::RU_vine_swap_option&
>(matrix1),
375 static_cast<typename Master_matrix::RU_vine_swap_option&
>(matrix2));
376 swap(
static_cast<typename Master_matrix::RU_representative_cycles_option&
>(matrix1),
377 static_cast<typename Master_matrix::RU_representative_cycles_option&
>(matrix2));
378 swap(matrix1.reducedMatrixR_, matrix2.reducedMatrixR_);
379 swap(matrix1.mirrorMatrixU_, matrix2.mirrorMatrixU_);
380 matrix1.pivotToColumnIndex_.swap(matrix2.pivotToColumnIndex_);
381 std::swap(matrix1.nextEventIndex_, matrix2.nextEventIndex_);
382 std::swap(matrix1.operators_, matrix2.operators_);
388 using Swap_opt =
typename Master_matrix::RU_vine_swap_option;
389 using Pair_opt =
typename Master_matrix::RU_pairing_option;
390 using Rep_opt =
typename Master_matrix::RU_representative_cycles_option;
391 using Dictionary =
typename Master_matrix::template Dictionary<Index>;
392 using Barcode =
typename Master_matrix::Barcode;
393 using Bar_dictionary =
typename Master_matrix::Bar_dictionary;
394 using R_matrix =
typename Master_matrix::Master_boundary_matrix;
395 using U_matrix =
typename Master_matrix::Master_base_matrix;
400 R_matrix reducedMatrixR_;
403 U_matrix mirrorMatrixU_;
404 Dictionary pivotToColumnIndex_;
409 void _insert_boundary(Index currentIndex);
410 void _initialize_U();
412 void _reduce_last_column(Index lastIndex);
413 void _reduce_column(Index target, Index eventIndex);
414 void _reduce_column_by(Index target, Index source);
416 void _add_bar(Dimension dim,
Pos_index birth);
417 void _remove_last_in_barcode(
Pos_index eventIndex);
419 constexpr Bar_dictionary& _indexToBar();
422template <
class Master_matrix>
427 reducedMatrixR_(colSettings),
428 mirrorMatrixU_(colSettings),
433 operators_ = &(colSettings->operators);
437template <
class Master_matrix>
438template <
class Boundary_range>
444 reducedMatrixR_(orderedBoundaries, colSettings),
445 mirrorMatrixU_(orderedBoundaries.size(), colSettings),
446 nextEventIndex_(orderedBoundaries.size()),
450 operators_ = &(colSettings->operators);
454 pivotToColumnIndex_.reserve(orderedBoundaries.size());
456 pivotToColumnIndex_.resize(orderedBoundaries.size(), Master_matrix::template get_null_value<Index>());
463template <
class Master_matrix>
468 reducedMatrixR_(numberOfColumns, colSettings),
469 mirrorMatrixU_(numberOfColumns, colSettings),
474 operators_ = &(colSettings->operators);
478 pivotToColumnIndex_.reserve(numberOfColumns);
480 pivotToColumnIndex_.resize(numberOfColumns, Master_matrix::template get_null_value<Index>());
483 _indexToBar().reserve(numberOfColumns);
486 Swap_opt::_positionToRowIdx().reserve(numberOfColumns);
490template <
class Master_matrix>
492 : Pair_opt(static_cast<const Pair_opt&>(matrixToCopy)),
493 Swap_opt(static_cast<const Swap_opt&>(matrixToCopy)),
494 Rep_opt(static_cast<const Rep_opt&>(matrixToCopy)),
495 reducedMatrixR_(matrixToCopy.reducedMatrixR_, colSettings),
496 mirrorMatrixU_(matrixToCopy.mirrorMatrixU_, colSettings),
497 pivotToColumnIndex_(matrixToCopy.pivotToColumnIndex_),
498 nextEventIndex_(matrixToCopy.nextEventIndex_),
499 operators_(colSettings == nullptr ? matrixToCopy.operators_ : nullptr)
502 if (colSettings !=
nullptr) operators_ = &(colSettings->operators);
506template <
class Master_matrix>
508 : Pair_opt(std::move(
static_cast<Pair_opt&
>(other))),
509 Swap_opt(std::move(
static_cast<Swap_opt&
>(other))),
510 Rep_opt(std::move(
static_cast<Rep_opt&
>(other))),
511 reducedMatrixR_(std::move(other.reducedMatrixR_)),
512 mirrorMatrixU_(std::move(other.mirrorMatrixU_)),
513 pivotToColumnIndex_(std::move(other.pivotToColumnIndex_)),
514 nextEventIndex_(std::exchange(other.nextEventIndex_, 0)),
515 operators_(std::exchange(other.operators_,
nullptr))
518template <
class Master_matrix>
519template <
class Boundary_range>
522 _insert_boundary(reducedMatrixR_.insert_boundary(boundary, dim));
525template <
class Master_matrix>
526template <
class Boundary_range>
528 const Boundary_range& boundary,
532 if constexpr (Master_matrix::Option_list::has_column_pairings && !Master_matrix::Option_list::has_vine_update) {
533 if (cellIndex != nextEventIndex_) {
534 Pair_opt::idToPosition_.emplace(cellIndex, nextEventIndex_);
535 if constexpr (Master_matrix::Option_list::has_removable_columns) {
536 Pair_opt::PIDM::map_.emplace(nextEventIndex_, cellIndex);
540 if constexpr (Master_matrix::Option_list::has_vine_update) {
541 if (cellIndex != nextEventIndex_) {
542 Swap_opt::_positionToRowIdx().emplace(nextEventIndex_, cellIndex);
543 if constexpr (Master_matrix::Option_list::has_column_pairings) {
548 _insert_boundary(reducedMatrixR_.insert_boundary(cellIndex, boundary, dim));
551template <
class Master_matrix>
555 return reducedMatrixR_.get_column(columnIndex);
557 return mirrorMatrixU_.get_column(columnIndex);
560template <
class Master_matrix>
563 static_assert(Master_matrix::Option_list::has_row_access,
"'get_row' is not implemented for the chosen options.");
566 return reducedMatrixR_.get_row(rowIndex);
568 return mirrorMatrixU_.get_row(rowIndex);
571template <
class Master_matrix>
574 reducedMatrixR_.erase_empty_row(rowIndex);
577template <
class Master_matrix>
580 static_assert(Master_matrix::Option_list::has_removable_columns && Master_matrix::Option_list::has_vine_update,
581 "'remove_maximal_cell' is not implemented for the chosen options.");
585 for (
Index curr = columnIndex; curr < nextEventIndex_ - 1; ++curr) {
586 Swap_opt::vine_swap(curr);
592template <
class Master_matrix>
595 static_assert(Master_matrix::Option_list::has_removable_columns,
596 "'remove_last' is not implemented for the chosen options.");
598 if (nextEventIndex_ == 0)
return;
602 _remove_last_in_barcode(nextEventIndex_);
604 mirrorMatrixU_.remove_last();
605 if constexpr (Master_matrix::Option_list::has_map_column_container) {
606 pivotToColumnIndex_.erase(reducedMatrixR_.remove_last());
608 ID_index lastPivot = reducedMatrixR_.remove_last();
609 if (lastPivot != Master_matrix::template get_null_value<ID_index>())
610 pivotToColumnIndex_[lastPivot] = Master_matrix::template get_null_value<Index>();
615 if constexpr (Master_matrix::Option_list::has_vine_update && !Master_matrix::Option_list::has_column_pairings) {
616 Swap_opt::_positionToRowIdx().erase(nextEventIndex_);
620template <
class Master_matrix>
623 return reducedMatrixR_.get_max_dimension();
626template <
class Master_matrix>
629 return reducedMatrixR_.get_number_of_columns();
632template <
class Master_matrix>
634 Index columnIndex)
const
636 return reducedMatrixR_.get_column_dimension(columnIndex);
639template <
class Master_matrix>
642 reducedMatrixR_.add_to(sourceColumnIndex, targetColumnIndex);
644 if constexpr (Master_matrix::Option_list::is_z2)
645 mirrorMatrixU_.add_to(targetColumnIndex, sourceColumnIndex);
647 mirrorMatrixU_.add_to(sourceColumnIndex, targetColumnIndex);
650template <
class Master_matrix>
653 Index targetColumnIndex)
655 static_assert(!Master_matrix::Option_list::is_z2,
656 "Multiplication with something else than the identity is not allowed with Z2 coefficients.");
657 reducedMatrixR_.multiply_target_and_add_to(sourceColumnIndex, coefficient, targetColumnIndex);
658 mirrorMatrixU_.multiply_target_and_add_to(sourceColumnIndex, coefficient, targetColumnIndex);
661template <
class Master_matrix>
663 Index sourceColumnIndex,
664 Index targetColumnIndex)
666 static_assert(!Master_matrix::Option_list::is_z2,
667 "Multiplication with something else than the identity is not allowed with Z2 coefficients.");
668 reducedMatrixR_.multiply_source_and_add_to(coefficient, sourceColumnIndex, targetColumnIndex);
669 mirrorMatrixU_.multiply_source_and_add_to(coefficient, sourceColumnIndex, targetColumnIndex);
672template <
class Master_matrix>
676 return reducedMatrixR_.zero_entry(columnIndex, rowIndex);
678 return mirrorMatrixU_.zero_entry(columnIndex, rowIndex);
681template <
class Master_matrix>
685 return reducedMatrixR_.zero_column(columnIndex);
687 return mirrorMatrixU_.zero_column(columnIndex);
690template <
class Master_matrix>
694 return reducedMatrixR_.is_zero_entry(columnIndex, rowIndex);
696 return mirrorMatrixU_.is_zero_entry(columnIndex, rowIndex);
699template <
class Master_matrix>
703 return reducedMatrixR_.is_zero_column(columnIndex);
705 return mirrorMatrixU_.is_zero_column(columnIndex);
708template <
class Master_matrix>
711 if constexpr (Master_matrix::Option_list::has_map_column_container) {
712 return pivotToColumnIndex_.at(cellIndex);
714 return pivotToColumnIndex_[cellIndex];
718template <
class Master_matrix>
721 return reducedMatrixR_.get_column(columnIndex).get_pivot();
724template <
class Master_matrix>
727 Swap_opt::operator=(other);
728 Pair_opt::operator=(other);
729 Rep_opt::operator=(other);
730 reducedMatrixR_ = other.reducedMatrixR_;
731 mirrorMatrixU_ = other.mirrorMatrixU_;
732 pivotToColumnIndex_ = other.pivotToColumnIndex_;
733 nextEventIndex_ = other.nextEventIndex_;
734 operators_ = other.operators_;
738template <
class Master_matrix>
741 std::cout <<
"R_matrix:\n";
742 reducedMatrixR_.print();
743 std::cout <<
"U_matrix:\n";
744 mirrorMatrixU_.print();
747template <
class Master_matrix>
750 if constexpr (Master_matrix::Option_list::is_z2) {
753 mirrorMatrixU_.insert_column({{currentIndex, 1}});
756 if constexpr (!Master_matrix::Option_list::has_map_column_container) {
757 ID_index pivot = reducedMatrixR_.get_column(currentIndex).get_pivot();
758 if (pivot != Master_matrix::template get_null_value<ID_index>() && pivotToColumnIndex_.size() <= pivot)
759 pivotToColumnIndex_.resize((pivot + 1) * 2, Master_matrix::template get_null_value<Index>());
762 _reduce_last_column(currentIndex);
766template <
class Master_matrix>
769 typename std::conditional<Master_matrix::Option_list::is_z2, Index, std::pair<Index, Field_element> >::type id;
770 if constexpr (!Master_matrix::Option_list::is_z2)
id.second = 1;
772 for (ID_index i = 0; i < reducedMatrixR_.get_number_of_columns(); i++) {
773 if constexpr (Master_matrix::Option_list::is_z2)
781template <
class Master_matrix>
784 if constexpr (Master_matrix::Option_list::has_column_pairings) {
785 _indexToBar().reserve(reducedMatrixR_.get_number_of_columns());
788 for (Index i = 0; i < reducedMatrixR_.get_number_of_columns(); i++) {
789 if (!(reducedMatrixR_.is_zero_column(i))) {
790 _reduce_column(i, i);
792 _add_bar(get_column_dimension(i), i);
797template <
class Master_matrix>
800 if (reducedMatrixR_.get_column(lastIndex).is_empty()) {
801 _add_bar(get_column_dimension(lastIndex), nextEventIndex_);
805 _reduce_column(lastIndex, nextEventIndex_);
808template <
class Master_matrix>
811 auto get_column_with_pivot_ = [&](ID_index pivot) -> Index {
812 if (pivot == Master_matrix::template get_null_value<ID_index>())
813 return Master_matrix::template get_null_value<Index>();
814 if constexpr (Master_matrix::Option_list::has_map_column_container) {
815 auto it = pivotToColumnIndex_.find(pivot);
816 if (it == pivotToColumnIndex_.end())
817 return Master_matrix::template get_null_value<Index>();
821 return pivotToColumnIndex_[pivot];
825 Column& curr = reducedMatrixR_.
get_column(target);
826 ID_index pivot = curr.get_pivot();
827 Index currIndex = get_column_with_pivot_(pivot);
829 while (pivot != Master_matrix::template get_null_value<ID_index>() &&
830 currIndex != Master_matrix::template get_null_value<Index>()) {
831 _reduce_column_by(target, currIndex);
832 pivot = curr.get_pivot();
833 currIndex = get_column_with_pivot_(pivot);
836 if (pivot != Master_matrix::template get_null_value<ID_index>()) {
837 if constexpr (Master_matrix::Option_list::has_map_column_container) {
838 pivotToColumnIndex_.try_emplace(pivot, target);
840 pivotToColumnIndex_[pivot] = target;
842 _update_barcode(pivot, eventIndex);
844 _add_bar(get_column_dimension(target), eventIndex);
848template <
class Master_matrix>
851 Column& curr = reducedMatrixR_.
get_column(target);
852 if constexpr (Master_matrix::Option_list::is_z2) {
853 curr += reducedMatrixR_.get_column(source);
856 mirrorMatrixU_.get_column(source).push_back(*mirrorMatrixU_.get_column(target).begin());
858 Column& toadd = reducedMatrixR_.get_column(source);
859 Field_element coef = toadd.get_pivot_value();
860 coef = operators_->get_inverse(coef);
861 operators_->multiply_inplace(coef, operators_->get_characteristic() - curr.get_pivot_value());
863 curr.multiply_source_and_add(toadd, coef);
866 mirrorMatrixU_.multiply_source_and_add_to(coef, source, target);
870template <
class Master_matrix>
873 if constexpr (Master_matrix::Option_list::has_column_pairings) {
874 if constexpr (Master_matrix::Option_list::has_vine_update)
875 Swap_opt::template RU_pairing<Master_matrix>::_update_barcode(birthPivot, death);
877 Pair_opt::_update_barcode(birthPivot, death);
881template <
class Master_matrix>
884 if constexpr (Master_matrix::Option_list::has_column_pairings) {
885 if constexpr (Master_matrix::Option_list::has_vine_update)
886 Swap_opt::template RU_pairing<Master_matrix>::_add_bar(dim, birth);
888 Pair_opt::_add_bar(dim, birth);
892template <
class Master_matrix>
895 if constexpr (Master_matrix::Option_list::has_column_pairings) {
896 if constexpr (Master_matrix::Option_list::has_vine_update)
897 Swap_opt::template RU_pairing<Master_matrix>::_remove_last(eventIndex);
899 Pair_opt::_remove_last(eventIndex);
903template <
class Master_matrix>
906 if constexpr (Master_matrix::Option_list::has_vine_update)
907 return Swap_opt::template RU_pairing<Master_matrix>::indexToBar_;
909 return Pair_opt::indexToBar_;
Data structure for matrices, and in particular thought for matrices representing filtered complexes i...
Definition: Matrix.h:144
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:1609
typename PersistenceMatrixOptions::Dimension Dimension
Definition: Matrix.h:150
typename PersistenceMatrixOptions::Index Index
Definition: Matrix.h:147
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:1538
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
Matrix structure to store the ordered boundary matrix of a filtered complex in order to compute its ...
Definition: RU_matrix.h:42
void remove_maximal_cell(Index columnIndex)
Only available if PersistenceMatrixOptions::has_removable_columns and PersistenceMatrixOptions::has_v...
Definition: RU_matrix.h:578
bool is_zero_column(Index columnIndex, bool inR=true)
Indicates if the column at given index has value zero in if inR is true or in if inR is false.
Definition: RU_matrix.h:700
typename Master_matrix::ID_index ID_index
Definition: RU_matrix.h:57
void add_to(Index sourceColumnIndex, Index targetColumnIndex)
Adds column at sourceColumnIndex onto the column at targetColumnIndex in the matrix.
Definition: RU_matrix.h:640
bool is_zero_entry(Index columnIndex, Index rowIndex, bool inR=true) const
Indicates if the entry at given coordinates has value zero in if inR is true or in if inR is false.
Definition: RU_matrix.h:691
void remove_last()
Only available if PersistenceMatrixOptions::has_removable_columns is true. Removes the last cell in t...
Definition: RU_matrix.h:593
typename Master_matrix::Element Field_element
Definition: RU_matrix.h:48
Index get_column_with_pivot(Index cellIndex) const
Returns the MatIdx index of the column which has the given row index as pivot in ....
Definition: RU_matrix.h:709
typename Master_matrix::Pos_index Pos_index
Definition: RU_matrix.h:58
void multiply_source_and_add_to(const Field_element &coefficient, Index sourceColumnIndex, Index targetColumnIndex)
Multiplies the source column with the coefficient before adding it to the target column....
Definition: RU_matrix.h:662
typename Master_matrix::Entry_constructor Entry_constructor
Definition: RU_matrix.h:52
RU_matrix(Column_settings *colSettings)
Constructs an empty matrix.
Definition: RU_matrix.h:423
void erase_empty_row(Index rowIndex)
If PersistenceMatrixOptions::has_row_access and PersistenceMatrixOptions::has_removable_rows are true...
Definition: RU_matrix.h:572
void zero_column(Index columnIndex, bool inR=true)
Zeroes the column at the given index in if inR is true or in if inR is false. Should be used with c...
Definition: RU_matrix.h:682
typename Master_matrix::Row Row
Definition: RU_matrix.h:51
friend void swap(RU_matrix &matrix1, RU_matrix &matrix2)
Swap operator.
Definition: RU_matrix.h:371
typename Master_matrix::Field_operators Field_operators
Field operators class. Necessary only if PersistenceMatrixOptions::is_z2 is false.
Definition: RU_matrix.h:47
Dimension get_max_dimension() const
Returns the maximal dimension of a cell stored in the matrix. Only available if PersistenceMatrixOpti...
Definition: RU_matrix.h:621
typename Master_matrix::Column Column
Definition: RU_matrix.h:49
void zero_entry(Index columnIndex, Index rowIndex, bool inR=true)
Zeroes the entry at the given coordinates in if inR is true or in if inR is false....
Definition: RU_matrix.h:673
typename Master_matrix::Index Index
Definition: RU_matrix.h:56
typename Master_matrix::Boundary Boundary
Definition: RU_matrix.h:55
Index get_pivot(Index columnIndex)
Returns the row index of the pivot of the given column in .
Definition: RU_matrix.h:719
typename Master_matrix::Dimension Dimension
Definition: RU_matrix.h:59
void reset(Column_settings *colSettings)
Resets the matrix to an empty matrix.
Definition: RU_matrix.h:354
Dimension get_column_dimension(Index columnIndex) const
Returns the dimension of the given column.
Definition: RU_matrix.h:633
Index get_number_of_columns() const
Returns the current number of columns in the matrix.
Definition: RU_matrix.h:627
void insert_boundary(const Boundary_range &boundary, Dimension dim=Master_matrix::template get_null_value< Dimension >())
Inserts at the end of the matrix a new ordered column corresponding to the given boundary....
Definition: RU_matrix.h:520
Column & get_column(Index columnIndex, bool inR=true)
Returns the column at the given MatIdx index in if inR is true and in if inR is false....
Definition: RU_matrix.h:552
void multiply_target_and_add_to(Index sourceColumnIndex, const Field_element &coefficient, Index targetColumnIndex)
Multiplies the target column with the coefficient and then adds the source column to it....
Definition: RU_matrix.h:651
RU_matrix & operator=(const RU_matrix &other)
Assign operator.
Definition: RU_matrix.h:725
typename Master_matrix::Column_settings Column_settings
Definition: RU_matrix.h:54
Row & get_row(Index rowIndex, bool inR=true)
Returns the row at the given row index in if inR is true and in if inR is false....
Definition: RU_matrix.h:561
Class managing the barcode for RU_matrix if the option was enabled.
Definition: ru_pairing.h:54
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 is_z2
If true, indicates that the values contained in the matrix are in and can therefore be treated like ...
Definition: PersistenceMatrixOptions.h:56
static const bool has_column_pairings
If set to true, enables the method Matrix::get_current_barcode. The matrix will then either be a boun...
Definition: PersistenceMatrixOptions.h:148
static const bool has_vine_update
If set to true, enables the methods Matrix::vine_swap and Matrix::vine_swap_with_z_eq_1_case....
Definition: PersistenceMatrixOptions.h:154