Loading...
Searching...
No Matches
RU_matrix.h
Go to the documentation of this file.
1/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT.
2 * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details.
3 * Author(s): Hannah Schreiber
4 *
5 * Copyright (C) 2022 Inria
6 *
7 * Modification(s):
8 * - 2025/11 Jānis Lazovskis: Added insert_maximal_cell method
9 * - YYYY/MM Author: Description of the modification
10 */
11
17
18#ifndef PM_RU_MATRIX_H
19#define PM_RU_MATRIX_H
20
21#include <utility> //std::swap, std::move & std::exchange
22#include <iostream> //print() only
23#include <vector>
24#include <unordered_map>
25
26namespace Gudhi {
27namespace persistence_matrix {
28
29template <class Master_matrix>
30class RU_pairing;
31
43template <class Master_matrix>
44class RU_matrix : public Master_matrix::RU_pairing_option,
45 public Master_matrix::RU_vine_swap_option,
46 public Master_matrix::RU_representative_cycles_option
47{
48 private:
49 using Pair_opt = typename Master_matrix::RU_pairing_option;
50 using Swap_opt = typename Master_matrix::RU_vine_swap_option;
51 using Rep_opt = typename Master_matrix::RU_representative_cycles_option;
52
53 public:
57 using Field_operators = typename Master_matrix::Field_operators;
58 using Field_element = typename Master_matrix::Element;
59 using Column = typename Master_matrix::Column;
60 using Row = typename Master_matrix::Row;
62 using Entry_constructor = typename Master_matrix::Entry_constructor;
63 using Column_settings = typename Master_matrix::Column_settings;
65 using Boundary = typename Master_matrix::Boundary;
66 using Index = typename Master_matrix::Index;
67 using ID_index = typename Master_matrix::ID_index;
68 using Pos_index = typename Master_matrix::Pos_index;
69 using Dimension = typename Master_matrix::Dimension;
70
98 template <class Boundary_range = Boundary>
99 RU_matrix(const std::vector<Boundary_range>& orderedBoundaries, Column_settings* colSettings);
107 RU_matrix(unsigned int numberOfColumns, Column_settings* colSettings);
117 RU_matrix(const RU_matrix& matrixToCopy, Column_settings* colSettings = nullptr);
123 RU_matrix(RU_matrix&& other) noexcept;
124
125 ~RU_matrix() = default;
126
147 template <class Boundary_range = Boundary>
148 void insert_boundary(const Boundary_range& boundary,
149 Dimension dim = Master_matrix::template get_null_value<Dimension>());
168 template <class Boundary_range = Boundary>
169 void insert_boundary(ID_index cellIndex, const Boundary_range& boundary,
170 Dimension dim = Master_matrix::template get_null_value<Dimension>());
188 template <class Boundary_range = Boundary>
189 void insert_maximal_cell(Index columnIndex,
190 const Boundary_range& boundary,
191 Dimension dim = Master_matrix::template get_null_value<Dimension>());
209 template <class Boundary_range = Boundary>
210 void insert_maximal_cell(Index columnIndex,
211 ID_index cellIndex,
212 const Boundary_range& boundary,
213 Dimension dim = Master_matrix::template get_null_value<Dimension>());
214
229 Column& get_column(Index columnIndex, bool inR = true);
244 Row& get_row(Index rowIndex, bool inR = true);
262 void erase_empty_row(Index rowIndex);
275 void remove_maximal_cell(Index columnIndex);
283
304
315 void add_to(Index sourceColumnIndex, Index targetColumnIndex);
328 void multiply_target_and_add_to(Index sourceColumnIndex, const Field_element& coefficient, Index targetColumnIndex);
341 void multiply_source_and_add_to(const Field_element& coefficient, Index sourceColumnIndex, Index targetColumnIndex);
342
353 void zero_entry(Index columnIndex, Index rowIndex, bool inR = true);
363 void zero_column(Index columnIndex, bool inR = true);
375 bool is_zero_entry(Index columnIndex, Index rowIndex, bool inR = true) const;
388 bool is_zero_column(Index columnIndex, bool inR = true);
389
404 Index get_pivot(Index columnIndex);
405
412 void reset(Column_settings* colSettings)
413 {
414 if constexpr (Master_matrix::Option_list::has_column_pairings) Pair_opt::_reset();
415 if constexpr (Master_matrix::Option_list::can_retrieve_representative_cycles) Rep_opt::_reset();
416 reducedMatrixR_.reset(colSettings);
417 mirrorMatrixU_.reset(colSettings);
418 pivotToColumnIndex_.clear();
419 nextEventIndex_ = 0;
420 positionToID_.clear();
421 operators_ = Master_matrix::get_operator_ptr(colSettings);
422 }
423
431 RU_matrix& operator=(RU_matrix&& other) noexcept;
432
436 friend void swap(RU_matrix& matrix1, RU_matrix& matrix2) noexcept
437 {
438 swap(static_cast<Pair_opt&>(matrix1), static_cast<Pair_opt&>(matrix2));
439 swap(static_cast<Swap_opt&>(matrix1), static_cast<Swap_opt&>(matrix2));
440 swap(static_cast<Rep_opt&>(matrix1), static_cast<Rep_opt&>(matrix2));
441 swap(matrix1.reducedMatrixR_, matrix2.reducedMatrixR_);
442 swap(matrix1.mirrorMatrixU_, matrix2.mirrorMatrixU_);
443 matrix1.pivotToColumnIndex_.swap(matrix2.pivotToColumnIndex_);
444 std::swap(matrix1.nextEventIndex_, matrix2.nextEventIndex_);
445 matrix1.positionToID_.swap(matrix2.positionToID_);
446 std::swap(matrix1.operators_, matrix2.operators_);
447 }
448
449 void print(); // for debug
450
451 private:
452 using Pivot_dictionary = typename Master_matrix::template Dictionary<Index>;
453 using Position_dictionary = std::unordered_map<Pos_index, ID_index>; // TODO: try other type of maps?
454 using Barcode = typename Master_matrix::Barcode;
455 using Bar_dictionary = typename Master_matrix::Bar_dictionary;
456 using R_matrix = typename Master_matrix::Master_boundary_matrix;
457 using U_matrix = typename Master_matrix::Master_base_matrix;
458
459 friend Rep_opt; // direct access to the two matrices
460 friend Swap_opt; // direct access to the two matrices, pivotToColumnIndex_
461 friend RU_pairing<Master_matrix>; // direct access to positionToID_
462
463 R_matrix reducedMatrixR_;
464 // TODO: make U not accessible by default and add option to enable access? Inaccessible, it
465 // needs less options and we could avoid some ifs.
466 U_matrix mirrorMatrixU_;
467 Pivot_dictionary pivotToColumnIndex_;
468 Pos_index nextEventIndex_;
469 Position_dictionary positionToID_;
470 Field_operators const* operators_;
472
473 void _insert_boundary(Index currentIndex);
474 void _initialize_U();
475 void _reduce();
476 void _reduce_last_column(Index lastIndex);
477 void _reduce_column(Index target, Index eventIndex);
478 void _reduce_column_by(Index target, Index source);
479 Index _get_column_with_pivot(ID_index pivot) const;
480 void _update_barcode(ID_index birthPivot, Pos_index death);
481 void _add_bar(Dimension dim, Pos_index birth);
482 void _remove_last_in_barcode(Pos_index eventIndex);
483};
484
485template <class Master_matrix>
487 : Pair_opt(),
488 Swap_opt(),
489 Rep_opt(),
490 reducedMatrixR_(colSettings),
491 mirrorMatrixU_(colSettings),
492 nextEventIndex_(0),
493 operators_(Master_matrix::get_operator_ptr(colSettings))
494{}
495
496template <class Master_matrix>
497template <class Boundary_range>
498inline RU_matrix<Master_matrix>::RU_matrix(const std::vector<Boundary_range>& orderedBoundaries,
499 Column_settings* colSettings)
500 : Pair_opt(),
501 Swap_opt(),
502 Rep_opt(),
503 reducedMatrixR_(orderedBoundaries, colSettings),
504 mirrorMatrixU_(orderedBoundaries.size(), colSettings),
505 nextEventIndex_(orderedBoundaries.size()),
506 operators_(Master_matrix::get_operator_ptr(colSettings))
507{
508 if constexpr (Master_matrix::Option_list::has_map_column_container) {
509 pivotToColumnIndex_.reserve(orderedBoundaries.size());
510 } else {
511 pivotToColumnIndex_.resize(orderedBoundaries.size(), Master_matrix::template get_null_value<Index>());
512 }
513
514 _initialize_U();
515 _reduce();
516}
517
518template <class Master_matrix>
519inline RU_matrix<Master_matrix>::RU_matrix(unsigned int numberOfColumns, Column_settings* colSettings)
520 : Pair_opt(),
521 Swap_opt(),
522 Rep_opt(),
523 reducedMatrixR_(numberOfColumns, colSettings),
524 mirrorMatrixU_(numberOfColumns, colSettings),
525 nextEventIndex_(0),
526 positionToID_(numberOfColumns),
527 operators_(Master_matrix::get_operator_ptr(colSettings))
528{
529 if constexpr (Master_matrix::Option_list::has_map_column_container) {
530 pivotToColumnIndex_.reserve(numberOfColumns);
531 } else {
532 pivotToColumnIndex_.resize(numberOfColumns, Master_matrix::template get_null_value<Index>());
533 }
534 if constexpr (Master_matrix::Option_list::has_column_pairings) {
535 Pair_opt::_reserve(numberOfColumns);
536 }
537}
538
539template <class Master_matrix>
540inline RU_matrix<Master_matrix>::RU_matrix(const RU_matrix& matrixToCopy, Column_settings* colSettings)
541 : Pair_opt(static_cast<const Pair_opt&>(matrixToCopy)),
542 Swap_opt(static_cast<const Swap_opt&>(matrixToCopy)),
543 Rep_opt(static_cast<const Rep_opt&>(matrixToCopy)),
544 reducedMatrixR_(matrixToCopy.reducedMatrixR_, colSettings),
545 mirrorMatrixU_(matrixToCopy.mirrorMatrixU_, colSettings),
546 pivotToColumnIndex_(matrixToCopy.pivotToColumnIndex_),
547 nextEventIndex_(matrixToCopy.nextEventIndex_),
548 positionToID_(matrixToCopy.positionToID_),
549 operators_(colSettings == nullptr ? matrixToCopy.operators_ : Master_matrix::get_operator_ptr(colSettings))
550{}
551
552template <class Master_matrix>
554 : Pair_opt(std::move(static_cast<Pair_opt&>(other))),
555 Swap_opt(std::move(static_cast<Swap_opt&>(other))),
556 Rep_opt(std::move(static_cast<Rep_opt&>(other))),
557 reducedMatrixR_(std::move(other.reducedMatrixR_)),
558 mirrorMatrixU_(std::move(other.mirrorMatrixU_)),
559 pivotToColumnIndex_(std::move(other.pivotToColumnIndex_)),
560 nextEventIndex_(std::exchange(other.nextEventIndex_, 0)),
561 positionToID_(std::move(other.positionToID_)),
562 operators_(std::exchange(other.operators_, nullptr))
563{}
564
565template <class Master_matrix>
566template <class Boundary_range>
567inline void RU_matrix<Master_matrix>::insert_boundary(const Boundary_range& boundary, Dimension dim)
568{
569 _insert_boundary(reducedMatrixR_.insert_boundary(boundary, dim));
570}
571
572template <class Master_matrix>
573template <class Boundary_range>
574inline void RU_matrix<Master_matrix>::insert_boundary(ID_index cellIndex, const Boundary_range& boundary, Dimension dim)
575{
576 // maps for possible shifting between column content and position indices used for birth events
577 if (cellIndex != nextEventIndex_) {
578 positionToID_.emplace(nextEventIndex_, cellIndex);
579 if constexpr (Master_matrix::Option_list::has_column_pairings) {
580 Pair_opt::_insert_id_position(cellIndex, nextEventIndex_);
581 }
582 }
583
584 _insert_boundary(reducedMatrixR_.insert_boundary(cellIndex, boundary, dim));
585}
586
587template <class Master_matrix>
588template <class Boundary_range>
590 const Boundary_range& boundary,
591 Dimension dim)
592{
593 static_assert(Master_matrix::Option_list::has_vine_update,
594 "'insert_maximal_cell' is not implemented for the chosen options.");
595
596 GUDHI_CHECK(columnIndex >= 0, std::invalid_argument("Indices have to be positive."));
597
598 insert_boundary(boundary, dim);
599
600 // If started with 0 columns, no swaps are needed
601 if (get_number_of_columns() == 1) return;
602
603 for (Index curr = get_number_of_columns() - 1; curr > columnIndex; --curr) {
604 Swap_opt::vine_swap(curr - 1);
605 }
606}
607
608template <class Master_matrix>
609template <class Boundary_range>
611 ID_index cellIndex,
612 const Boundary_range& boundary,
613 Dimension dim)
614{
615 static_assert(Master_matrix::Option_list::has_vine_update,
616 "'insert_maximal_cell' is not implemented for the chosen options.");
617
618 GUDHI_CHECK(columnIndex >= 0, std::invalid_argument("Indices have to be positive."));
619
620 insert_boundary(cellIndex, boundary, dim);
621
622 // TODO: factorize following with the other insert_maximal_cell ?
623
624 // If started with 0 columns, no swaps are needed
625 if (get_number_of_columns() == 1) return;
626
627 for (Index curr = get_number_of_columns() - 1; curr > columnIndex; --curr) {
628 Swap_opt::vine_swap(curr - 1);
629 }
630}
631
632template <class Master_matrix>
634{
635 if (inR) {
636 return reducedMatrixR_.get_column(columnIndex);
637 }
638 return mirrorMatrixU_.get_column(columnIndex);
639}
640
641template <class Master_matrix>
643{
644 static_assert(Master_matrix::Option_list::has_row_access, "'get_row' is not implemented for the chosen options.");
645
646 if (inR) {
647 return reducedMatrixR_.get_row(rowIndex);
648 }
649 return mirrorMatrixU_.get_row(rowIndex);
650}
651
652template <class Master_matrix>
654{
655 reducedMatrixR_.erase_empty_row(rowIndex);
656}
657
658template <class Master_matrix>
660{
661 static_assert(Master_matrix::Option_list::has_removable_columns && Master_matrix::Option_list::has_vine_update,
662 "'remove_maximal_cell' is not implemented for the chosen options.");
663
664 // TODO: is there an easy test to verify maximality even without row access?
665
666 for (Index curr = columnIndex; curr < nextEventIndex_ - 1; ++curr) {
667 Swap_opt::vine_swap(curr);
668 }
669
670 remove_last();
671}
672
673template <class Master_matrix>
675{
676 static_assert(Master_matrix::Option_list::has_removable_columns,
677 "'remove_last' is not implemented for the chosen options.");
678
679 if (nextEventIndex_ == 0) return; // empty matrix
680 --nextEventIndex_;
681
682 // assumes PosIdx == MatIdx for boundary matrices.
683 _remove_last_in_barcode(nextEventIndex_);
684
685 mirrorMatrixU_.remove_last();
686 if constexpr (Master_matrix::Option_list::has_map_column_container) {
687 pivotToColumnIndex_.erase(reducedMatrixR_.remove_last());
688 } else {
689 ID_index lastPivot = reducedMatrixR_.remove_last();
690 if (lastPivot != Master_matrix::template get_null_value<ID_index>())
691 pivotToColumnIndex_[lastPivot] = Master_matrix::template get_null_value<Index>();
692 }
693
694 // if has_column_pairings is true, then the element is already removed in _remove_last_in_barcode
695 // to avoid a second "find"
696 if constexpr (!Master_matrix::Option_list::has_column_pairings) {
697 positionToID_.erase(nextEventIndex_);
698 }
699}
700
701template <class Master_matrix>
703{
704 return reducedMatrixR_.get_max_dimension();
705}
706
707template <class Master_matrix>
709{
710 return reducedMatrixR_.get_number_of_columns();
711}
712
713template <class Master_matrix>
715 Index columnIndex) const
716{
717 return reducedMatrixR_.get_column_dimension(columnIndex);
718}
719
720template <class Master_matrix>
721inline void RU_matrix<Master_matrix>::add_to(Index sourceColumnIndex, Index targetColumnIndex)
722{
723 reducedMatrixR_.add_to(sourceColumnIndex, targetColumnIndex);
724 // U transposed to avoid row operations
725 if constexpr (Master_matrix::Option_list::is_z2)
726 mirrorMatrixU_.add_to(targetColumnIndex, sourceColumnIndex);
727 else
728 mirrorMatrixU_.multiply_source_and_add_to(
729 operators_->get_characteristic() - 1, targetColumnIndex, sourceColumnIndex);
730}
731
732template <class Master_matrix>
734 const Field_element& coefficient,
735 Index targetColumnIndex)
736{
737 reducedMatrixR_.multiply_target_and_add_to(sourceColumnIndex, coefficient, targetColumnIndex);
738 // U transposed to avoid row operations
739 mirrorMatrixU_.get_column(targetColumnIndex) *= coefficient;
740 mirrorMatrixU_.multiply_source_and_add_to(operators_->get_characteristic() - 1, targetColumnIndex, sourceColumnIndex);
741}
742
743template <class Master_matrix>
745 Index sourceColumnIndex,
746 Index targetColumnIndex)
747{
748 reducedMatrixR_.multiply_source_and_add_to(coefficient, sourceColumnIndex, targetColumnIndex);
749 // U transposed to avoid row operations
750 if constexpr (Master_matrix::Option_list::is_z2) {
751 if (coefficient) mirrorMatrixU_.add_to(targetColumnIndex, sourceColumnIndex);
752 } else {
753 mirrorMatrixU_.multiply_source_and_add_to(
754 operators_->get_characteristic() - coefficient, targetColumnIndex, sourceColumnIndex);
755 }
756}
757
758template <class Master_matrix>
759inline void RU_matrix<Master_matrix>::zero_entry(Index columnIndex, Index rowIndex, bool inR)
760{
761 if (inR) {
762 return reducedMatrixR_.zero_entry(columnIndex, rowIndex);
763 }
764 return mirrorMatrixU_.zero_entry(columnIndex, rowIndex);
765}
766
767template <class Master_matrix>
768inline void RU_matrix<Master_matrix>::zero_column(Index columnIndex, bool inR)
769{
770 if (inR) {
771 return reducedMatrixR_.zero_column(columnIndex);
772 }
773 return mirrorMatrixU_.zero_column(columnIndex);
774}
775
776template <class Master_matrix>
777inline bool RU_matrix<Master_matrix>::is_zero_entry(Index columnIndex, Index rowIndex, bool inR) const
778{
779 if (inR) {
780 return reducedMatrixR_.is_zero_entry(columnIndex, rowIndex);
781 }
782 return mirrorMatrixU_.is_zero_entry(columnIndex, rowIndex);
783}
784
785template <class Master_matrix>
786inline bool RU_matrix<Master_matrix>::is_zero_column(Index columnIndex, bool inR)
787{
788 if (inR) {
789 return reducedMatrixR_.is_zero_column(columnIndex);
790 }
791 return mirrorMatrixU_.is_zero_column(columnIndex);
792}
793
794template <class Master_matrix>
796{
797 if constexpr (Master_matrix::Option_list::has_map_column_container) {
798 return pivotToColumnIndex_.at(cellIndex);
799 } else {
800 return pivotToColumnIndex_[cellIndex];
801 }
802}
803
804template <class Master_matrix>
806{
807 return reducedMatrixR_.get_column(columnIndex).get_pivot();
808}
809
810template <class Master_matrix>
812{
813 if (this == &other) return *this;
814
815 Swap_opt::operator=(other);
816 Pair_opt::operator=(other);
817 Rep_opt::operator=(other);
818 reducedMatrixR_ = other.reducedMatrixR_;
819 mirrorMatrixU_ = other.mirrorMatrixU_;
820 pivotToColumnIndex_ = other.pivotToColumnIndex_;
821 nextEventIndex_ = other.nextEventIndex_;
822 positionToID_ = other.positionToID_;
823 operators_ = other.operators_;
824
825 return *this;
826}
827
828template <class Master_matrix>
830{
831 if (this == &other) return *this;
832
833 Pair_opt::operator=(std::move(other));
834 Swap_opt::operator=(std::move(other));
835 Rep_opt::operator=(std::move(other));
836
837 reducedMatrixR_ = std::move(other.reducedMatrixR_);
838 mirrorMatrixU_ = std::move(other.mirrorMatrixU_);
839 pivotToColumnIndex_ = std::move(other.pivotToColumnIndex_);
840 nextEventIndex_ = std::exchange(other.nextEventIndex_, 0);
841 positionToID_ = std::move(other.positionToID_);
842 operators_ = std::exchange(other.operators_, nullptr);
843}
844
845template <class Master_matrix>
846inline void RU_matrix<Master_matrix>::print()
847{
848 std::cout << "R_matrix:\n";
849 reducedMatrixR_.print();
850 std::cout << "U_matrix:\n";
851 mirrorMatrixU_.print();
852}
853
854template <class Master_matrix>
855inline void RU_matrix<Master_matrix>::_insert_boundary(Index currentIndex)
856{
857 mirrorMatrixU_.insert_column(currentIndex, 1);
858
859 if constexpr (!Master_matrix::Option_list::has_map_column_container) {
860 ID_index pivot = reducedMatrixR_.get_column(currentIndex).get_pivot();
861 if (pivot != Master_matrix::template get_null_value<ID_index>() && pivotToColumnIndex_.size() <= pivot)
862 pivotToColumnIndex_.resize((pivot + 1) * 2, Master_matrix::template get_null_value<Index>());
863 }
864
865 _reduce_last_column(currentIndex);
866 ++nextEventIndex_;
867}
868
869template <class Master_matrix>
871{
872 for (ID_index i = 0; i < reducedMatrixR_.get_number_of_columns(); i++) {
873 mirrorMatrixU_.insert_column(i, 1);
874 }
875}
876
877template <class Master_matrix>
879{
880 if constexpr (Master_matrix::Option_list::has_column_pairings) {
881 Pair_opt::_reserve(reducedMatrixR_.get_number_of_columns());
882 }
883
884 for (Index i = 0; i < reducedMatrixR_.get_number_of_columns(); i++) {
885 if (!(reducedMatrixR_.is_zero_column(i))) {
886 _reduce_column(i, i);
887 } else {
888 _add_bar(get_column_dimension(i), i);
889 }
890 }
891}
892
893template <class Master_matrix>
894inline void RU_matrix<Master_matrix>::_reduce_last_column(Index lastIndex)
895{
896 if (reducedMatrixR_.get_column(lastIndex).is_empty()) {
897 _add_bar(get_column_dimension(lastIndex), nextEventIndex_);
898 return;
899 }
900
901 _reduce_column(lastIndex, nextEventIndex_);
902}
903
904template <class Master_matrix>
905inline void RU_matrix<Master_matrix>::_reduce_column(Index target, Index eventIndex)
906{
907 Column& curr = reducedMatrixR_.get_column(target);
908 ID_index pivot = curr.get_pivot();
909 Index currIndex = _get_column_with_pivot(pivot);
910
911 while (pivot != Master_matrix::template get_null_value<ID_index>() &&
912 currIndex != Master_matrix::template get_null_value<Index>()) {
913 _reduce_column_by(target, currIndex);
914 pivot = curr.get_pivot();
915 currIndex = _get_column_with_pivot(pivot);
916 }
917
918 if (pivot != Master_matrix::template get_null_value<ID_index>()) {
919 if constexpr (Master_matrix::Option_list::has_map_column_container) {
920 pivotToColumnIndex_.try_emplace(pivot, target);
921 } else {
922 pivotToColumnIndex_[pivot] = target;
923 }
924 _update_barcode(pivot, eventIndex);
925 } else {
926 _add_bar(get_column_dimension(target), eventIndex);
927 }
928}
929
930template <class Master_matrix>
931inline void RU_matrix<Master_matrix>::_reduce_column_by(Index target, Index source)
932{
933 Column& curr = reducedMatrixR_.get_column(target);
934 if constexpr (Master_matrix::Option_list::is_z2) {
935 curr += reducedMatrixR_.get_column(source);
936 // to avoid having to do line operations, U is transposed
937 // TODO: explain this somewhere in the documentation...
938 mirrorMatrixU_.get_column(source).push_back(*mirrorMatrixU_.get_column(target).begin());
939 } else {
940 Column& toadd = reducedMatrixR_.get_column(source);
941 Field_element coef = toadd.get_pivot_value();
942 coef = operators_->get_inverse(coef);
943 operators_->multiply_inplace(coef, operators_->get_characteristic() - curr.get_pivot_value());
944
945 curr.multiply_source_and_add(toadd, coef);
946 auto entry = *mirrorMatrixU_.get_column(target).begin();
947 operators_->multiply_inplace(entry.get_element(), operators_->get_characteristic() - coef);
948 // to avoid having to do line operations, U is transposed
949 // TODO: explain this somewhere in the documentation...
950 mirrorMatrixU_.get_column(source).push_back(entry);
951 }
952}
953
954template <class Master_matrix>
956{
957 if (pivot == Master_matrix::template get_null_value<ID_index>())
958 return Master_matrix::template get_null_value<Index>();
959 if constexpr (Master_matrix::Option_list::has_map_column_container) {
960 auto it = pivotToColumnIndex_.find(pivot);
961 if (it == pivotToColumnIndex_.end()) return Master_matrix::template get_null_value<Index>();
962 return it->second;
963 } else {
964 if (pivot >= pivotToColumnIndex_.size()) return Master_matrix::template get_null_value<Index>();
965 return pivotToColumnIndex_[pivot];
966 }
967}
968
969template <class Master_matrix>
970inline void RU_matrix<Master_matrix>::_update_barcode(ID_index birthPivot, Pos_index death)
971{
972 if constexpr (Master_matrix::Option_list::has_column_pairings) {
973 Pair_opt::_update_barcode(birthPivot, death);
974 }
975}
976
977template <class Master_matrix>
978inline void RU_matrix<Master_matrix>::_add_bar(Dimension dim, Pos_index birth)
979{
980 if constexpr (Master_matrix::Option_list::has_column_pairings) {
981 Pair_opt::_add_bar(dim, birth);
982 }
983}
984
985template <class Master_matrix>
986inline void RU_matrix<Master_matrix>::_remove_last_in_barcode(Pos_index eventIndex)
987{
988 if constexpr (Master_matrix::Option_list::has_column_pairings) {
989 Pair_opt::_remove_last(eventIndex);
990 }
991}
992
993} // namespace persistence_matrix
994} // namespace Gudhi
995
996#endif // PM_RU_MATRIX_H
std::enable_if_t< std::is_integral_v< Integer_index > > multiply_target_and_add_to(Integer_index sourceColumnIndex, int coefficient, Integer_index targetColumnIndex)
Dimension get_column_dimension(Index columnIndex) const
std::conditional_t< RU_rep_cycles_options::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
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)
Insertion_return insert_maximal_cell(Index columnIndex, const Boundary_range &boundary, Dimension dim=Matrix::get_null_value< Dimension >())
Returned_column & get_column(Index columnIndex)
typename RU_rep_cycles_options::Dimension Dimension
Definition Matrix.h:153
bool is_zero_entry(Index columnIndex, ID_index rowIndex)
typename RU_rep_cycles_options::Index Index
Definition Matrix.h:150
void zero_entry(Index columnIndex, ID_index rowIndex)
Insertion_return insert_boundary(const Boundary_range &boundary, Dimension dim=Matrix::get_null_value< Dimension >())
std::conditional_t< RU_rep_cycles_options::column_type==Column_types::HEAP, Matrix_heap_column, std::conditional_t< RU_rep_cycles_options::column_type==Column_types::LIST, Matrix_list_column, std::conditional_t< RU_rep_cycles_options::column_type==Column_types::SET, Matrix_set_column, std::conditional_t< RU_rep_cycles_options::column_type==Column_types::UNORDERED_SET, Matrix_unordered_set_column, std::conditional_t< RU_rep_cycles_options::column_type==Column_types::VECTOR, Matrix_vector_column, std::conditional_t< RU_rep_cycles_options::column_type==Column_types::INTRUSIVE_LIST, Matrix_intrusive_list_column, std::conditional_t< RU_rep_cycles_options::column_type==Column_types::NAIVE_VECTOR, Matrix_naive_vector_column, std::conditional_t< RU_rep_cycles_options::column_type==Column_types::SMALL_VECTOR, Matrix_small_vector_column, Matrix_intrusive_set_column > > > > > > > > Column
Definition Matrix.h:359
std::enable_if_t< std::is_integral_v< Integer_index > > add_to(Integer_index sourceColumnIndex, Integer_index targetColumnIndex)
Matrix structure to store the ordered boundary matrix of a filtered complex in order to compute its ...
Definition RU_matrix.h:47
RU_matrix(const std::vector< Boundary_range > &orderedBoundaries, Column_settings *colSettings)
Constructs a new matrix from the given ranges of Matrix::Entry_representative. Each range corresponds...
Definition RU_matrix.h:498
void remove_maximal_cell(Index columnIndex)
Only available if PersistenceMatrixOptions::has_removable_columns and PersistenceMatrixOptions::has_v...
Definition RU_matrix.h:659
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:786
typename Matrix< PersistenceMatrixOptions >::ID_index ID_index
Definition RU_matrix.h:67
void insert_maximal_cell(Index columnIndex, const Boundary_range &boundary, Dimension dim=Master_matrix::template get_null_value< Dimension >())
Only available if PersistenceMatrixOptions::has_vine_update is true. Assumes that the cell will be ma...
Definition RU_matrix.h:589
void add_to(Index sourceColumnIndex, Index targetColumnIndex)
Adds column at sourceColumnIndex onto the column at targetColumnIndex in the matrix.
Definition RU_matrix.h:721
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:777
void remove_last()
Only available if PersistenceMatrixOptions::has_removable_columns is true. Removes the last cell in t...
Definition RU_matrix.h:674
void insert_boundary(ID_index cellIndex, const Boundary_range &boundary, Dimension dim=Master_matrix::template get_null_value< Dimension >())
It does the same as the other version, but allows the boundary cells to be identified without restric...
Definition RU_matrix.h:574
typename Matrix< PersistenceMatrixOptions >::Element Field_element
Definition RU_matrix.h:58
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:795
RU_matrix(RU_matrix &&other) noexcept
Move constructor.
Definition RU_matrix.h:553
typename Matrix< PersistenceMatrixOptions >::Pos_index Pos_index
Definition RU_matrix.h:68
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:744
typename Matrix< PersistenceMatrixOptions >::Entry_constructor Entry_constructor
Definition RU_matrix.h:62
RU_matrix(Column_settings *colSettings)
Constructs an empty matrix.
Definition RU_matrix.h:486
void erase_empty_row(Index rowIndex)
If PersistenceMatrixOptions::has_row_access and PersistenceMatrixOptions::has_removable_rows are true...
Definition RU_matrix.h:653
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:768
typename Matrix< PersistenceMatrixOptions >::Row Row
Definition RU_matrix.h:60
void insert_maximal_cell(Index columnIndex, ID_index cellIndex, const Boundary_range &boundary, Dimension dim=Master_matrix::template get_null_value< Dimension >())
Only available if PersistenceMatrixOptions::has_vine_update is true. It does the same as the other ve...
Definition RU_matrix.h:610
typename Matrix< PersistenceMatrixOptions >::Field_operators Field_operators
Definition RU_matrix.h:57
Dimension get_max_dimension() const
Returns the maximal dimension of a cell stored in the matrix. Only available if PersistenceMatrixOpti...
Definition RU_matrix.h:702
RU_matrix & operator=(RU_matrix &&other) noexcept
Move assign operator.
Definition RU_matrix.h:829
typename Matrix< PersistenceMatrixOptions >::Column Column
Definition RU_matrix.h:59
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:759
typename Matrix< PersistenceMatrixOptions >::Index Index
Definition RU_matrix.h:66
typename Matrix< PersistenceMatrixOptions >::Boundary Boundary
Definition RU_matrix.h:65
Index get_pivot(Index columnIndex)
Returns the row index of the pivot of the given column in .
Definition RU_matrix.h:805
RU_matrix(unsigned int numberOfColumns, Column_settings *colSettings)
Constructs a new empty matrix and reserves space for the given number of columns.
Definition RU_matrix.h:519
typename Matrix< PersistenceMatrixOptions >::Dimension Dimension
Definition RU_matrix.h:69
RU_matrix(const RU_matrix &matrixToCopy, Column_settings *colSettings=nullptr)
Copy constructor. If colSettings is not a null pointer, its value is kept instead of the one in the c...
Definition RU_matrix.h:540
void reset(Column_settings *colSettings)
Resets the matrix to an empty matrix.
Definition RU_matrix.h:412
Dimension get_column_dimension(Index columnIndex) const
Returns the dimension of the given column.
Definition RU_matrix.h:714
Index get_number_of_columns() const
Returns the current number of columns in the matrix.
Definition RU_matrix.h:708
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:567
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:633
friend void swap(RU_matrix &matrix1, RU_matrix &matrix2) noexcept
Swap operator.
Definition RU_matrix.h:436
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:733
RU_matrix & operator=(const RU_matrix &other)
Assign operator.
Definition RU_matrix.h:811
typename Matrix< PersistenceMatrixOptions >::Column_settings Column_settings
Definition RU_matrix.h:63
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:642
Class managing the barcode for RU_matrix if the option was enabled.
Definition ru_pairing.h:50
Persistence matrix namespace.
Definition FieldOperators.h:18
Gudhi namespace.
Definition SimplicialComplexForAlpha.h:14