17 #ifndef PM_RU_MATRIX_H
18 #define PM_RU_MATRIX_H
25 namespace persistence_matrix {
38 template <
class Master_matrix>
39 class RU_matrix :
public Master_matrix::RU_pairing_option,
40 public Master_matrix::RU_vine_swap_option,
41 public Master_matrix::RU_representative_cycles_option
50 using Row_type =
typename Master_matrix::Row_type;
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;
87 template <
class Boundary_type = boundary_type>
88 RU_matrix(
const std::vector<Boundary_type>& orderedBoundaries,
134 template <
class Boundary_type = boundary_type>
152 template <
class Boundary_type = boundary_type>
269 index targetColumnIndex);
283 index sourceColumnIndex,
284 index targetColumnIndex);
356 reducedMatrixR_.reset(colSettings);
357 mirrorMatrixU_.reset(colSettings);
358 pivotToColumnIndex_.clear();
361 operators_ = &(colSettings->operators);
373 swap(
static_cast<typename Master_matrix::RU_pairing_option&
>(matrix1),
374 static_cast<typename Master_matrix::RU_pairing_option&
>(matrix2));
375 swap(
static_cast<typename Master_matrix::RU_vine_swap_option&
>(matrix1),
376 static_cast<typename Master_matrix::RU_vine_swap_option&
>(matrix2));
377 swap(
static_cast<typename Master_matrix::RU_representative_cycles_option&
>(matrix1),
378 static_cast<typename Master_matrix::RU_representative_cycles_option&
>(matrix2));
379 swap(matrix1.reducedMatrixR_, matrix2.reducedMatrixR_);
380 swap(matrix1.mirrorMatrixU_, matrix2.mirrorMatrixU_);
381 matrix1.pivotToColumnIndex_.swap(matrix2.pivotToColumnIndex_);
382 std::swap(matrix1.nextEventIndex_, matrix2.nextEventIndex_);
383 std::swap(matrix1.operators_, matrix2.operators_);
389 using swap_opt =
typename Master_matrix::RU_vine_swap_option;
390 using pair_opt =
typename Master_matrix::RU_pairing_option;
391 using rep_opt =
typename Master_matrix::RU_representative_cycles_option;
392 using dictionnary_type =
typename Master_matrix::template dictionnary_type<index>;
393 using barcode_type =
typename Master_matrix::barcode_type;
394 using bar_dictionnary_type =
typename Master_matrix::bar_dictionnary_type;
395 using r_matrix_type =
typename Master_matrix::Boundary_matrix_type;
396 using u_matrix_type =
typename Master_matrix::Base_matrix_type;
401 r_matrix_type reducedMatrixR_;
404 u_matrix_type mirrorMatrixU_;
405 dictionnary_type pivotToColumnIndex_;
410 void _insert_boundary(
index currentIndex);
411 void _initialize_U();
413 void _reduce_last_column(
index lastIndex);
414 void _reduce_column(
index target,
index eventIndex);
415 void _reduce_column_by(
index target,
index source);
419 constexpr barcode_type& _barcode();
420 constexpr bar_dictionnary_type& _indexToBar();
423 template <
class Master_matrix>
428 reducedMatrixR_(colSettings),
429 mirrorMatrixU_(colSettings),
434 operators_ = &(colSettings->operators);
438 template <
class Master_matrix>
439 template <
class Boundary_type>
445 reducedMatrixR_(orderedBoundaries, colSettings),
446 mirrorMatrixU_(orderedBoundaries.size(), colSettings),
447 nextEventIndex_(orderedBoundaries.size()),
451 operators_ = &(colSettings->operators);
455 pivotToColumnIndex_.reserve(orderedBoundaries.size());
457 pivotToColumnIndex_.resize(orderedBoundaries.size(), -1);
464 template <
class Master_matrix>
470 reducedMatrixR_(numberOfColumns, colSettings),
471 mirrorMatrixU_(numberOfColumns, colSettings),
476 operators_ = &(colSettings->operators);
480 pivotToColumnIndex_.reserve(numberOfColumns);
482 pivotToColumnIndex_.resize(numberOfColumns, -1);
485 _indexToBar().reserve(numberOfColumns);
488 swap_opt::positionToRowIdx_.reserve(numberOfColumns);
492 template <
class Master_matrix>
495 : pair_opt(static_cast<const pair_opt&>(matrixToCopy)),
496 swap_opt(static_cast<const swap_opt&>(matrixToCopy)),
497 rep_opt(static_cast<const rep_opt&>(matrixToCopy)),
498 reducedMatrixR_(matrixToCopy.reducedMatrixR_, colSettings),
499 mirrorMatrixU_(matrixToCopy.mirrorMatrixU_, colSettings),
500 pivotToColumnIndex_(matrixToCopy.pivotToColumnIndex_),
501 nextEventIndex_(matrixToCopy.nextEventIndex_),
502 operators_(colSettings == nullptr ? matrixToCopy.operators_ : nullptr)
505 if (colSettings !=
nullptr) operators_ = &(colSettings->operators);
509 template <
class Master_matrix>
511 : pair_opt(std::move(
static_cast<pair_opt&
>(other))),
512 swap_opt(std::move(
static_cast<swap_opt&
>(other))),
513 rep_opt(std::move(
static_cast<rep_opt&
>(other))),
514 reducedMatrixR_(std::move(other.reducedMatrixR_)),
515 mirrorMatrixU_(std::move(other.mirrorMatrixU_)),
516 pivotToColumnIndex_(std::move(other.pivotToColumnIndex_)),
517 nextEventIndex_(std::exchange(other.nextEventIndex_, 0)),
518 operators_(std::exchange(other.operators_,
nullptr))
521 template <
class Master_matrix>
522 template <
class Boundary_type>
525 auto id = reducedMatrixR_.insert_boundary(boundary, dim);
526 if constexpr (Master_matrix::Option_list::has_vine_update) swap_opt::positionToRowIdx_.push_back(
id);
527 _insert_boundary(
id);
530 template <
class Master_matrix>
531 template <
class Boundary_type>
533 const Boundary_type& boundary,
536 if constexpr (Master_matrix::Option_list::has_vine_update) {
537 swap_opt::positionToRowIdx_.push_back(faceIndex);
539 _insert_boundary(reducedMatrixR_.insert_boundary(faceIndex, boundary, dim));
542 template <
class Master_matrix>
547 return reducedMatrixR_.get_column(columnIndex);
549 return mirrorMatrixU_.get_column(columnIndex);
552 template <
class Master_matrix>
555 static_assert(Master_matrix::Option_list::has_row_access,
"'get_row' is not implemented for the chosen options.");
558 return reducedMatrixR_.get_row(rowIndex);
560 return mirrorMatrixU_.get_row(rowIndex);
563 template <
class Master_matrix>
566 reducedMatrixR_.erase_empty_row(rowIndex);
569 template <
class Master_matrix>
572 static_assert(Master_matrix::Option_list::has_removable_columns && Master_matrix::Option_list::has_vine_update,
573 "'remove_maximal_face' is not implemented for the chosen options.");
577 for (
index curr = columnIndex; curr < nextEventIndex_ - 1; ++curr) {
578 swap_opt::vine_swap(curr);
584 template <
class Master_matrix>
587 static_assert(Master_matrix::Option_list::has_removable_columns,
588 "'remove_last' is not implemented for the chosen options.");
590 if (nextEventIndex_ == 0)
return;
594 if constexpr (Master_matrix::Option_list::has_column_pairings) {
595 if constexpr (Master_matrix::hasFixedBarcode) {
596 auto& bar = _barcode()[_indexToBar()[nextEventIndex_]];
597 if (bar.death ==
static_cast<pos_index>(-1)) {
598 _barcode().pop_back();
602 _indexToBar().pop_back();
604 auto it = _indexToBar().find(nextEventIndex_);
605 typename barcode_type::iterator bar = it->second;
607 if (bar->death ==
static_cast<pos_index>(-1))
608 _barcode().erase(bar);
612 _indexToBar().erase(it);
616 mirrorMatrixU_.remove_last();
617 if constexpr (Master_matrix::Option_list::has_map_column_container) {
618 pivotToColumnIndex_.erase(reducedMatrixR_.remove_last());
620 id_index lastPivot = reducedMatrixR_.remove_last();
621 if (lastPivot !=
static_cast<id_index>(-1)) pivotToColumnIndex_[lastPivot] = -1;
624 if constexpr (Master_matrix::Option_list::has_vine_update) {
625 swap_opt::positionToRowIdx_.pop_back();
629 template <
class Master_matrix>
632 return reducedMatrixR_.get_max_dimension();
635 template <
class Master_matrix>
638 return reducedMatrixR_.get_number_of_columns();
641 template <
class Master_matrix>
643 index columnIndex)
const
645 return reducedMatrixR_.get_column_dimension(columnIndex);
648 template <
class Master_matrix>
651 reducedMatrixR_.add_to(sourceColumnIndex, targetColumnIndex);
653 if constexpr (Master_matrix::Option_list::has_vine_update)
654 mirrorMatrixU_.add_to(targetColumnIndex, sourceColumnIndex);
656 mirrorMatrixU_.add_to(sourceColumnIndex, targetColumnIndex);
659 template <
class Master_matrix>
662 index targetColumnIndex)
664 reducedMatrixR_.multiply_target_and_add_to(sourceColumnIndex, coefficient, targetColumnIndex);
665 mirrorMatrixU_.multiply_target_and_add_to(sourceColumnIndex, coefficient, targetColumnIndex);
668 template <
class Master_matrix>
670 index sourceColumnIndex,
671 index targetColumnIndex)
673 reducedMatrixR_.multiply_source_and_add_to(coefficient, sourceColumnIndex, targetColumnIndex);
674 mirrorMatrixU_.multiply_source_and_add_to(coefficient, sourceColumnIndex, targetColumnIndex);
677 template <
class Master_matrix>
681 return reducedMatrixR_.zero_cell(columnIndex, rowIndex);
683 return mirrorMatrixU_.zero_cell(columnIndex, rowIndex);
686 template <
class Master_matrix>
690 return reducedMatrixR_.zero_column(columnIndex);
692 return mirrorMatrixU_.zero_column(columnIndex);
695 template <
class Master_matrix>
699 return reducedMatrixR_.is_zero_cell(columnIndex, rowIndex);
701 return mirrorMatrixU_.is_zero_cell(columnIndex, rowIndex);
704 template <
class Master_matrix>
708 return reducedMatrixR_.is_zero_column(columnIndex);
710 return mirrorMatrixU_.is_zero_column(columnIndex);
713 template <
class Master_matrix>
715 index faceIndex)
const
717 if constexpr (Master_matrix::Option_list::has_map_column_container) {
718 return pivotToColumnIndex_.at(faceIndex);
720 return pivotToColumnIndex_[faceIndex];
724 template <
class Master_matrix>
727 return reducedMatrixR_.get_column(columnIndex).get_pivot();
730 template <
class Master_matrix>
733 swap_opt::operator=(other);
734 pair_opt::operator=(other);
735 rep_opt::operator=(other);
736 reducedMatrixR_ = other.reducedMatrixR_;
737 mirrorMatrixU_ = other.mirrorMatrixU_;
738 pivotToColumnIndex_ = other.pivotToColumnIndex_;
739 nextEventIndex_ = other.nextEventIndex_;
740 operators_ = other.operators_;
744 template <
class Master_matrix>
747 std::cout <<
"R_matrix:\n";
748 reducedMatrixR_.print();
749 std::cout <<
"U_matrix:\n";
750 mirrorMatrixU_.print();
753 template <
class Master_matrix>
756 if constexpr (Master_matrix::Option_list::is_z2) {
759 mirrorMatrixU_.insert_column({{currentIndex, 1}});
762 if constexpr (!Master_matrix::Option_list::has_map_column_container) {
763 while (pivotToColumnIndex_.size() <= currentIndex)
764 pivotToColumnIndex_.resize((pivotToColumnIndex_.size() + 1) * 2, -1);
767 _reduce_last_column(currentIndex);
771 template <
class Master_matrix>
774 typename std::conditional<Master_matrix::Option_list::is_z2, index, std::pair<index, Field_element_type> >::type id;
775 if constexpr (!Master_matrix::Option_list::is_z2)
id.second = 1;
777 for (id_index i = 0; i < reducedMatrixR_.get_number_of_columns(); i++) {
778 if constexpr (Master_matrix::Option_list::is_z2)
786 template <
class Master_matrix>
789 if constexpr (Master_matrix::Option_list::has_column_pairings) {
790 _indexToBar().reserve(reducedMatrixR_.get_number_of_columns());
792 if constexpr (Master_matrix::Option_list::has_vine_update) {
793 swap_opt::positionToRowIdx_.reserve(reducedMatrixR_.get_number_of_columns());
796 for (index i = 0; i < reducedMatrixR_.get_number_of_columns(); i++) {
797 if constexpr (Master_matrix::Option_list::has_vine_update) {
798 swap_opt::positionToRowIdx_.push_back(i);
800 if (!(reducedMatrixR_.is_zero_column(i))) {
801 _reduce_column(i, i);
803 _add_bar(get_column_dimension(i), i);
808 template <
class Master_matrix>
811 if (reducedMatrixR_.get_column(lastIndex).is_empty()) {
812 _add_bar(get_column_dimension(lastIndex), nextEventIndex_);
816 _reduce_column(lastIndex, nextEventIndex_);
819 template <
class Master_matrix>
822 auto get_column_with_pivot_ = [&](id_index pivot) -> index {
823 if (pivot ==
static_cast<id_index
>(-1))
return -1;
824 if constexpr (Master_matrix::Option_list::has_map_column_container) {
825 auto it = pivotToColumnIndex_.find(pivot);
826 if (it == pivotToColumnIndex_.end())
831 return pivotToColumnIndex_[pivot];
835 Column_type& curr = reducedMatrixR_.
get_column(target);
836 id_index pivot = curr.get_pivot();
837 index currIndex = get_column_with_pivot_(pivot);
839 while (pivot !=
static_cast<id_index
>(-1) && currIndex !=
static_cast<index
>(-1)) {
840 _reduce_column_by(target, currIndex);
841 pivot = curr.get_pivot();
842 currIndex = get_column_with_pivot_(pivot);
845 if (pivot !=
static_cast<id_index
>(-1)) {
846 if constexpr (Master_matrix::Option_list::has_map_column_container) {
847 pivotToColumnIndex_.try_emplace(pivot, target);
849 pivotToColumnIndex_[pivot] = target;
851 _update_barcode(pivot, eventIndex);
853 _add_bar(get_column_dimension(target), eventIndex);
857 template <
class Master_matrix>
860 Column_type& curr = reducedMatrixR_.
get_column(target);
861 if constexpr (Master_matrix::Option_list::is_z2) {
862 curr += reducedMatrixR_.get_column(source);
865 if constexpr (Master_matrix::Option_list::has_vine_update)
866 mirrorMatrixU_.get_column(source) += mirrorMatrixU_.get_column(target);
868 mirrorMatrixU_.get_column(target) += mirrorMatrixU_.get_column(source);
870 Column_type& toadd = reducedMatrixR_.get_column(source);
871 Field_element_type coef = toadd.get_pivot_value();
872 coef = operators_->get_inverse(coef);
873 operators_->multiply_inplace(coef, operators_->get_characteristic() - curr.get_pivot_value());
875 curr.multiply_source_and_add(toadd, coef);
876 mirrorMatrixU_.multiply_source_and_add_to(coef, source, target);
881 template <
class Master_matrix>
884 if constexpr (Master_matrix::Option_list::has_column_pairings) {
885 if constexpr (Master_matrix::hasFixedBarcode || !Master_matrix::Option_list::has_removable_columns) {
886 _barcode()[_indexToBar()[birth]].death = death;
887 _indexToBar().push_back(_indexToBar()[birth]);
889 auto& barIt = _indexToBar().at(birth);
890 barIt->death = death;
891 _indexToBar().try_emplace(death, barIt);
896 template <
class Master_matrix>
899 if constexpr (Master_matrix::Option_list::has_column_pairings) {
900 _barcode().emplace_back(dim, birth, -1);
901 if constexpr (Master_matrix::hasFixedBarcode || !Master_matrix::Option_list::has_removable_columns) {
902 _indexToBar().push_back(_barcode().size() - 1);
904 _indexToBar().try_emplace(birth, --_barcode().end());
909 template <
class Master_matrix>
912 if constexpr (Master_matrix::Option_list::has_vine_update)
913 return swap_opt::template RU_pairing<Master_matrix>::barcode_;
915 return pair_opt::barcode_;
918 template <
class Master_matrix>
921 if constexpr (Master_matrix::Option_list::has_vine_update)
922 return swap_opt::template RU_pairing<Master_matrix>::indexToBar_;
924 return pair_opt::indexToBar_;
Data structure for matrices, and in particular thought for matrices representing filtered complexes i...
Definition: matrix.h:143
returned_column_type & 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 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< hasFixedBarcode, std::vector< Bar >, typename std::conditional< PersistenceMatrixOptions::has_removable_columns, std::list< Bar >, std::vector< Bar > >::type >::type barcode_type
Type of the computed barcode. It is either a list of Matrix::Bar or a vector of Matrix::Bar,...
Definition: matrix.h:450
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
void insert_column(const Container_type &column)
Inserts a new ordered column at the end of the matrix by copying the given range of cell_rep_type....
Definition: matrix.h:1538
typename PersistenceMatrixOptions::dimension_type dimension_type
Definition: matrix.h:149
Matrix structure to store the ordered boundary matrix of a filtered complex in order to compute its ...
Definition: ru_matrix.h:42
index get_pivot(index columnIndex)
Returns the row index of the pivot of the given column in .
Definition: ru_matrix.h:725
dimension_type get_max_dimension() const
Returns the maximal dimension of a face stored in the matrix. Only available if PersistenceMatrixOpti...
Definition: ru_matrix.h:630
Column_type & 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:543
typename Master_matrix::dimension_type dimension_type
Definition: ru_matrix.h:59
void add_to(index sourceColumnIndex, index targetColumnIndex)
Adds column at sourceColumnIndex onto the column at targetColumnIndex in the matrix.
Definition: ru_matrix.h:649
typename Master_matrix::pos_index pos_index
Definition: ru_matrix.h:58
void remove_last()
Only available if PersistenceMatrixOptions::has_removable_columns is true. Removes the last face in t...
Definition: ru_matrix.h:585
index get_number_of_columns() const
Returns the current number of columns in the matrix.
Definition: ru_matrix.h:636
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:687
index get_column_with_pivot(index faceIndex) const
Returns the MatIdx index of the column which has the given row index as pivot in ....
Definition: ru_matrix.h:714
RU_matrix(Column_settings *colSettings)
Constructs an empty matrix.
Definition: ru_matrix.h:424
typename Master_matrix::Column_type Column_type
Definition: ru_matrix.h:49
typename Master_matrix::index index
Definition: ru_matrix.h:56
typename Master_matrix::element_type Field_element_type
Definition: ru_matrix.h:48
typename Master_matrix::Cell_constructor Cell_constructor
Definition: ru_matrix.h:52
Row_type & 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:553
void remove_maximal_face(index columnIndex)
Only available if PersistenceMatrixOptions::has_removable_columns and PersistenceMatrixOptions::has_v...
Definition: ru_matrix.h:570
void zero_cell(index columnIndex, index rowIndex, bool inR=true)
Zeroes the cell at the given coordinates in if inR is true or in if inR is false....
Definition: ru_matrix.h:678
friend void swap(RU_matrix &matrix1, RU_matrix &matrix2)
Swap operator.
Definition: ru_matrix.h:372
void 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: ru_matrix.h:523
typename Master_matrix::Field_operators Field_operators
Field operators class. Necessary only if PersistenceMatrixOptions::is_z2 is false.
Definition: ru_matrix.h:47
typename Master_matrix::id_index id_index
Definition: ru_matrix.h:57
dimension_type get_column_dimension(index columnIndex) const
Returns the dimension of the given column.
Definition: ru_matrix.h:642
typename Master_matrix::Row_type Row_type
Definition: ru_matrix.h:51
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: ru_matrix.h:669
void erase_empty_row(index rowIndex)
If PersistenceMatrixOptions::has_row_access and PersistenceMatrixOptions::has_removable_rows are true...
Definition: ru_matrix.h:564
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: ru_matrix.h:660
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:705
void reset(Column_settings *colSettings)
Resets the matrix to an empty matrix.
Definition: ru_matrix.h:355
typename Master_matrix::boundary_type boundary_type
Definition: ru_matrix.h:55
bool is_zero_cell(index columnIndex, index rowIndex, bool inR=true) const
Indicates if the cell at given coordinates has value zero in if inR is true or in if inR is false.
Definition: ru_matrix.h:696
RU_matrix & operator=(const RU_matrix &other)
Assign operator.
Definition: ru_matrix.h:731
typename Master_matrix::Column_settings Column_settings
Definition: ru_matrix.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