Loading...
Searching...
No Matches
Chain_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 * - YYYY/MM Author: Description of the modification
9 */
10
16
17#ifndef PM_CHAIN_MATRIX_H
18#define PM_CHAIN_MATRIX_H
19
20#include <iostream> //print() only
21#include <set>
22#include <map>
23#include <stdexcept>
24#include <vector>
25#include <utility> //std::swap, std::move & std::exchange
26#include <algorithm> //std::sort
27
31
32namespace Gudhi {
33namespace persistence_matrix {
34
46template <class Master_matrix>
47class Chain_matrix : public Master_matrix::Matrix_dimension_option,
48 public Master_matrix::Chain_pairing_option,
49 public Master_matrix::Chain_vine_swap_option,
50 public Master_matrix::Chain_representative_cycles_option,
51 public Master_matrix::Matrix_row_access_option,
52 protected std::conditional_t<
53 Master_matrix::Option_list::has_vine_update &&
54 (Master_matrix::Option_list::has_column_pairings ||
55 Master_matrix::Option_list::can_retrieve_representative_cycles),
56 Index_mapper<typename Master_matrix::template Dictionary<typename Master_matrix::Pos_index>>,
57 Dummy_index_mapper>
58{
59 private:
60 using Dim_opt = typename Master_matrix::Matrix_dimension_option;
61 using Pair_opt = typename Master_matrix::Chain_pairing_option;
62 using Swap_opt = typename Master_matrix::Chain_vine_swap_option;
63 using Rep_opt = typename Master_matrix::Chain_representative_cycles_option;
64 using RA_opt = typename Master_matrix::Matrix_row_access_option;
65
66 static constexpr bool hasPivotToPosMap_ =
67 Master_matrix::Option_list::has_vine_update && (Master_matrix::Option_list::has_column_pairings ||
68 Master_matrix::Option_list::can_retrieve_representative_cycles);
69
70 using Pivot_to_pos_mapper_opt =
71 std::conditional_t<hasPivotToPosMap_,
72 Index_mapper<typename Master_matrix::template Dictionary<typename Master_matrix::Pos_index>>,
73 Dummy_index_mapper>;
74
75 public:
79 using Field_operators = typename Master_matrix::Field_operators;
80 using Field_element = typename Master_matrix::Element;
81 using Column = typename Master_matrix::Column;
82 using Row = typename Master_matrix::Row;
84 using Entry = typename Master_matrix::Matrix_entry;
85 using Entry_constructor = typename Master_matrix::Entry_constructor;
86 using Column_settings = typename Master_matrix::Column_settings;
88 using Boundary = typename Master_matrix::Boundary;
89 using Entry_representative = typename Master_matrix::Entry_representative;
90 using Index = typename Master_matrix::Index;
91 using ID_index = typename Master_matrix::ID_index;
92 using Pos_index = typename Master_matrix::Pos_index;
93 using Dimension = typename Master_matrix::Dimension;
94
128 template <class Boundary_range = Boundary>
129 Chain_matrix(const std::vector<Boundary_range>& orderedBoundaries, Column_settings* colSettings);
139 Chain_matrix(unsigned int numberOfColumns, Column_settings* colSettings);
161 template <typename BirthComparatorFunction, typename DeathComparatorFunction>
163 const BirthComparatorFunction& birthComparator,
164 const DeathComparatorFunction& deathComparator);
201 template <typename BirthComparatorFunction, typename DeathComparatorFunction, class Boundary_range = Boundary>
202 Chain_matrix(const std::vector<Boundary_range>& orderedBoundaries,
203 Column_settings* colSettings,
204 const BirthComparatorFunction& birthComparator,
205 const DeathComparatorFunction& deathComparator);
228 template <typename BirthComparatorFunction, typename DeathComparatorFunction>
229 Chain_matrix(unsigned int numberOfColumns,
230 Column_settings* colSettings,
231 const BirthComparatorFunction& birthComparator,
232 const DeathComparatorFunction& deathComparator);
242 Chain_matrix(const Chain_matrix& matrixToCopy, Column_settings* colSettings = nullptr);
248 Chain_matrix(Chain_matrix&& other) noexcept;
249
250 ~Chain_matrix() = default;
251
273 template <class Boundary_range = Boundary>
274 std::vector<Entry_representative> insert_boundary(
275 const Boundary_range& boundary,
276 Dimension dim = Master_matrix::template get_null_value<Dimension>());
295 template <class Boundary_range = Boundary>
296 std::vector<Entry_representative> insert_boundary(
297 ID_index cellID,
298 const Boundary_range& boundary,
299 Dimension dim = Master_matrix::template get_null_value<Dimension>());
318 template <class Boundary_range = Boundary>
319 std::vector<Entry_representative> insert_maximal_cell(
320 Index columnIndex,
321 const Boundary_range& boundary,
322 Dimension dim = Master_matrix::template get_null_value<Dimension>());
342 template <class Boundary_range = Boundary>
343 std::vector<Entry_representative> insert_maximal_cell(
344 Index columnIndex,
345 ID_index cellID,
346 const Boundary_range& boundary,
347 Dimension dim = Master_matrix::template get_null_value<Dimension>());
355 Column& get_column(Index columnIndex);
363 const Column& get_column(Index columnIndex) const;
405 void remove_maximal_cell(ID_index cellID, const std::vector<ID_index>& columnsToSwap);
421
428
436
447 void add_to(Index sourceColumnIndex, Index targetColumnIndex);
460 void multiply_target_and_add_to(Index sourceColumnIndex, const Field_element& coefficient, Index targetColumnIndex);
473 void multiply_source_and_add_to(const Field_element& coefficient, Index sourceColumnIndex, Index targetColumnIndex);
474
483 bool is_zero_entry(Index columnIndex, ID_index rowIndex) const;
492 bool is_zero_column(Index columnIndex);
493
508
515 void reset(Column_settings* colSettings)
516 {
517 if constexpr (Master_matrix::Option_list::has_matrix_maximal_dimension_access) Dim_opt::_reset();
518 if constexpr (Master_matrix::Option_list::has_column_pairings) Pair_opt::_reset();
519 if constexpr (Master_matrix::Option_list::can_retrieve_representative_cycles) Rep_opt::_reset();
520 if constexpr (hasPivotToPosMap_) Pivot_to_pos_mapper_opt::map_.clear();
521 matrix_.clear();
522 pivotToColumnIndex_.clear();
523 nextIndex_ = 0;
524 nextPosition_ = 0;
525 colSettings_ = colSettings;
526 }
527
536
540 friend void swap(Chain_matrix& matrix1, Chain_matrix& matrix2) noexcept
541 {
542 swap(static_cast<Dim_opt&>(matrix1), static_cast<Dim_opt&>(matrix2));
543 swap(static_cast<Pair_opt&>(matrix1), static_cast<Pair_opt&>(matrix2));
544 swap(static_cast<Swap_opt&>(matrix1), static_cast<Swap_opt&>(matrix2));
545 swap(static_cast<Rep_opt&>(matrix1), static_cast<Rep_opt&>(matrix2));
546 swap(static_cast<Pivot_to_pos_mapper_opt&>(matrix1), static_cast<Pivot_to_pos_mapper_opt&>(matrix2));
547 matrix1.matrix_.swap(matrix2.matrix_);
548 matrix1.pivotToColumnIndex_.swap(matrix2.pivotToColumnIndex_);
549 std::swap(matrix1.nextIndex_, matrix2.nextIndex_);
550 std::swap(matrix1.nextPosition_, matrix2.nextPosition_);
551 std::swap(matrix1.colSettings_, matrix2.colSettings_);
552
553 if constexpr (Master_matrix::Option_list::has_row_access) {
554 swap(static_cast<RA_opt&>(matrix1), static_cast<RA_opt&>(matrix2));
555 }
556 }
557
558 void print() const; // for debug
559
560 friend class Id_to_index_overlay<Chain_matrix<Master_matrix>, Master_matrix>;
561 friend class Position_to_index_overlay<Chain_matrix<Master_matrix>, Master_matrix>;
562
563 private:
564 using Column_container = typename Master_matrix::Column_container;
565 using Dictionary = typename Master_matrix::template Dictionary<Index>;
566 using Barcode = typename Master_matrix::Barcode;
567 using Bar_dictionary = typename Master_matrix::Bar_dictionary;
568 using Tmp_column = typename std::
569 conditional<Master_matrix::Option_list::is_z2, std::set<ID_index>, std::map<ID_index, Field_element>>::type;
570
571 friend Swap_opt; // direct access to index mapper
572 friend Pair_opt; // direct access to index mapper
573 friend Rep_opt; // direct access to index mapper
574
575 Column_container matrix_;
576 Dictionary pivotToColumnIndex_;
577 Index nextIndex_;
578 Pos_index nextPosition_;
579 Column_settings* colSettings_;
580
581 template <class Boundary_range>
582 std::vector<Entry_representative> _reduce_boundary(ID_index cellID, const Boundary_range& boundary, Dimension dim);
583 void _reduce_by_G(Tmp_column& column, std::vector<Entry_representative>& chainsInH, Index currentIndex);
584 void _reduce_by_F(Tmp_column& column, std::vector<Entry_representative>& chainsInF, Index currentIndex);
585 void _build_from_H(ID_index cellID, Tmp_column& column, std::vector<Entry_representative>& chainsInH);
586 void _update_largest_death_in_F(const std::vector<Entry_representative>& chainsInF);
587 void _insert_chain(const Tmp_column& column, Dimension dimension);
588 void _insert_chain(const Tmp_column& column, Dimension dimension, Index pair);
589 void _add_to(const Column& column, Tmp_column& set, unsigned int coef);
590 template <typename F>
591 void _add_to(Column& target, F&& addition);
592 void _remove_last(Index lastIndex);
593 void _update_barcode(Pos_index birth);
594 void _add_bar(Dimension dim);
595 template <class Container>
596 void _container_insert(const Container& column, Index pos, Dimension dim);
597 template <class ColumnIterator>
598 void _container_insert(const ColumnIterator& rep);
599
600 static void _insert_in(ID_index cellID, Tmp_column& column);
601};
602
603template <class Master_matrix>
605 : Dim_opt(Master_matrix::template get_null_value<Dimension>()),
606 Pair_opt(),
607 Swap_opt(),
608 Rep_opt(),
609 RA_opt(),
610 Pivot_to_pos_mapper_opt(),
611 nextIndex_(0),
612 nextPosition_(0),
613 colSettings_(colSettings)
614{}
615
616template <class Master_matrix>
617template <class Boundary_range>
618inline Chain_matrix<Master_matrix>::Chain_matrix(const std::vector<Boundary_range>& orderedBoundaries,
619 Column_settings* colSettings)
620 : Dim_opt(Master_matrix::template get_null_value<Dimension>()),
621 Pair_opt(),
622 Swap_opt(),
623 Rep_opt(),
624 RA_opt(orderedBoundaries.size()),
625 Pivot_to_pos_mapper_opt(),
626 nextIndex_(0),
627 nextPosition_(0),
628 colSettings_(colSettings)
629{
630 matrix_.reserve(orderedBoundaries.size());
631 if constexpr (Master_matrix::Option_list::has_map_column_container) {
632 pivotToColumnIndex_.reserve(orderedBoundaries.size());
633 } else {
634 pivotToColumnIndex_.resize(orderedBoundaries.size(), Master_matrix::template get_null_value<Index>());
635 }
636
637 for (const Boundary_range& b : orderedBoundaries) {
639 }
640}
641
642template <class Master_matrix>
643inline Chain_matrix<Master_matrix>::Chain_matrix(unsigned int numberOfColumns, Column_settings* colSettings)
644 : Dim_opt(Master_matrix::template get_null_value<Dimension>()),
645 Pair_opt(),
646 Swap_opt(),
647 Rep_opt(),
648 RA_opt(numberOfColumns),
649 Pivot_to_pos_mapper_opt(),
650 nextIndex_(0),
651 nextPosition_(0),
652 colSettings_(colSettings)
653{
654 matrix_.reserve(numberOfColumns);
655 if constexpr (Master_matrix::Option_list::has_map_column_container) {
656 pivotToColumnIndex_.reserve(numberOfColumns);
657 } else {
658 pivotToColumnIndex_.resize(numberOfColumns, Master_matrix::template get_null_value<Index>());
659 }
660}
661
662template <class Master_matrix>
663template <typename BirthComparatorFunction, typename DeathComparatorFunction>
665 const BirthComparatorFunction& birthComparator,
666 const DeathComparatorFunction& deathComparator)
667 : Dim_opt(Master_matrix::template get_null_value<Dimension>()),
668 Pair_opt(),
669 Swap_opt(birthComparator, deathComparator),
670 Rep_opt(),
671 RA_opt(),
672 Pivot_to_pos_mapper_opt(),
673 nextIndex_(0),
674 nextPosition_(0),
675 colSettings_(colSettings)
676{}
677
678template <class Master_matrix>
679template <typename BirthComparatorFunction, typename DeathComparatorFunction, class Boundary_range>
680inline Chain_matrix<Master_matrix>::Chain_matrix(const std::vector<Boundary_range>& orderedBoundaries,
681 Column_settings* colSettings,
682 const BirthComparatorFunction& birthComparator,
683 const DeathComparatorFunction& deathComparator)
684 : Dim_opt(Master_matrix::template get_null_value<Dimension>()),
685 Pair_opt(),
686 Swap_opt(birthComparator, deathComparator),
687 Rep_opt(),
688 RA_opt(orderedBoundaries.size()),
689 Pivot_to_pos_mapper_opt(),
690 nextIndex_(0),
691 nextPosition_(0),
692 colSettings_(colSettings)
693{
694 matrix_.reserve(orderedBoundaries.size());
695 if constexpr (Master_matrix::Option_list::has_map_column_container) {
696 pivotToColumnIndex_.reserve(orderedBoundaries.size());
697 } else {
698 pivotToColumnIndex_.resize(orderedBoundaries.size(), Master_matrix::template get_null_value<Index>());
699 }
700 for (const Boundary_range& b : orderedBoundaries) {
702 }
703}
704
705template <class Master_matrix>
706template <typename BirthComparatorFunction, typename DeathComparatorFunction>
707inline Chain_matrix<Master_matrix>::Chain_matrix(unsigned int numberOfColumns,
708 Column_settings* colSettings,
709 const BirthComparatorFunction& birthComparator,
710 const DeathComparatorFunction& deathComparator)
711 : Dim_opt(Master_matrix::template get_null_value<Dimension>()),
712 Pair_opt(),
713 Swap_opt(birthComparator, deathComparator),
714 Rep_opt(),
715 RA_opt(numberOfColumns),
716 Pivot_to_pos_mapper_opt(),
717 nextIndex_(0),
718 nextPosition_(0),
719 colSettings_(colSettings)
720{
721 matrix_.reserve(numberOfColumns);
722 if constexpr (Master_matrix::Option_list::has_map_column_container) {
723 pivotToColumnIndex_.reserve(numberOfColumns);
724 } else {
725 pivotToColumnIndex_.resize(numberOfColumns, Master_matrix::template get_null_value<Index>());
726 }
727}
728
729template <class Master_matrix>
731 : Dim_opt(static_cast<const Dim_opt&>(matrixToCopy)),
732 Pair_opt(static_cast<const Pair_opt&>(matrixToCopy)),
733 Swap_opt(static_cast<const Swap_opt&>(matrixToCopy)),
734 Rep_opt(static_cast<const Rep_opt&>(matrixToCopy)),
735 RA_opt(static_cast<const RA_opt&>(matrixToCopy)),
736 Pivot_to_pos_mapper_opt(static_cast<const Pivot_to_pos_mapper_opt&>(matrixToCopy)),
737 pivotToColumnIndex_(matrixToCopy.pivotToColumnIndex_),
738 nextIndex_(matrixToCopy.nextIndex_),
739 nextPosition_(matrixToCopy.nextPosition_),
740 colSettings_(colSettings == nullptr ? matrixToCopy.colSettings_ : colSettings)
741{
742 matrix_.reserve(matrixToCopy.matrix_.size());
743 for (const auto& cont : matrixToCopy.matrix_) {
744 _container_insert(cont);
745 }
746}
747
748template <class Master_matrix>
750 : Dim_opt(std::move(static_cast<Dim_opt&>(other))),
751 Pair_opt(std::move(static_cast<Pair_opt&>(other))),
752 Swap_opt(std::move(static_cast<Swap_opt&>(other))),
753 Rep_opt(std::move(static_cast<Rep_opt&>(other))),
754 RA_opt(std::move(static_cast<RA_opt&>(other))),
755 Pivot_to_pos_mapper_opt(std::move(static_cast<Pivot_to_pos_mapper_opt&>(other))),
756 matrix_(std::move(other.matrix_)),
757 pivotToColumnIndex_(std::move(other.pivotToColumnIndex_)),
758 nextIndex_(std::exchange(other.nextIndex_, 0)),
759 nextPosition_(std::exchange(other.nextPosition_, 0)),
760 colSettings_(std::exchange(other.colSettings_, nullptr))
761{}
762
763template <class Master_matrix>
764template <class Boundary_range>
765inline std::vector<typename Master_matrix::Entry_representative> Chain_matrix<Master_matrix>::insert_boundary(
766 const Boundary_range& boundary,
767 Dimension dim)
768{
769 return insert_boundary(nextIndex_, boundary, dim);
770}
771
772template <class Master_matrix>
773template <class Boundary_range>
774inline std::vector<typename Master_matrix::Entry_representative>
775Chain_matrix<Master_matrix>::insert_boundary(ID_index cellID, const Boundary_range& boundary, Dimension dim)
776{
777 if constexpr (!Master_matrix::Option_list::has_map_column_container) {
778 if (pivotToColumnIndex_.size() <= cellID) {
779 pivotToColumnIndex_.resize((cellID * 2) + 1, Master_matrix::template get_null_value<Index>());
780 }
781 }
782
783 if constexpr (hasPivotToPosMap_) {
784 if constexpr (Master_matrix::Option_list::has_map_column_container) {
785 Pivot_to_pos_mapper_opt::map_.try_emplace(cellID, nextPosition_);
786 } else {
787 if (Pivot_to_pos_mapper_opt::map_.size() <= cellID)
788 Pivot_to_pos_mapper_opt::map_.resize(pivotToColumnIndex_.size(),
789 Master_matrix::template get_null_value<Pos_index>());
790 Pivot_to_pos_mapper_opt::map_[cellID] = nextPosition_;
791 }
792 }
793
794 if constexpr (Master_matrix::Option_list::has_matrix_maximal_dimension_access) {
795 Dim_opt::_update_up(dim == Master_matrix::template get_null_value<Dimension>()
796 ? (boundary.size() == 0 ? 0 : boundary.size() - 1)
797 : dim);
798 }
799
800 return _reduce_boundary(cellID, boundary, dim);
801}
802
803template <class Master_matrix>
804template <class Boundary_range>
805inline std::vector<typename Master_matrix::Entry_representative>
806Chain_matrix<Master_matrix>::insert_maximal_cell(Index columnIndex, const Boundary_range& boundary, Dimension dim)
807{
808 return insert_maximal_cell(columnIndex, nextIndex_, boundary, dim);
809}
810
811template <class Master_matrix>
812template <class Boundary_range>
813inline std::vector<typename Master_matrix::Entry_representative> Chain_matrix<Master_matrix>::insert_maximal_cell(
814 Index columnIndex,
815 ID_index cellID,
816 const Boundary_range& boundary,
817 Dimension dim)
818{
819 static_assert(
820 Master_matrix::Option_list::has_vine_update && (Master_matrix::Option_list::has_column_pairings ||
821 Master_matrix::Option_list::can_retrieve_representative_cycles),
822 "'insert_maximal_cell' is not implemented for the chosen options.");
823
824 GUDHI_CHECK(columnIndex >= 0, std::invalid_argument("Indices have to be positive."));
825
826 auto chainsInF = insert_boundary(cellID, boundary, dim);
827
828 const auto& pivotToPosition = Pivot_to_pos_mapper_opt::map_;
829 Pos_index startPos = nextPosition_ - 1;
830 Index startIndex = pivotToColumnIndex_[cellID];
831
832 if (startPos > columnIndex) {
833 std::vector<Index> colToSwap;
834 colToSwap.reserve(pivotToPosition.size());
835
836 // first loop stores all column indices whose filtration position should be after the new column
837 // then orders the matrix indices by filtration position as they do not have to correspond
838 // the underlying column container is not the same depending on `has_map_column_container`: one is a map, the
839 // other a vector. To optimize the usage of both containers, the `if constexpr` differentiation is made
840 if constexpr (Master_matrix::Option_list::has_map_column_container) {
841 for (auto& p : pivotToPosition) {
842 if (p.second >= columnIndex && p.second < startPos) colToSwap.push_back(pivotToColumnIndex_.at(p.first));
843 }
844 std::sort(colToSwap.begin(), colToSwap.end(), [&](Index c1, Index c2) {
845 return pivotToPosition.at(get_pivot(c1)) > pivotToPosition.at(get_pivot(c2));
846 });
847 } else {
848 for (Index i = 0; i < pivotToPosition.size(); ++i) {
849 if (pivotToPosition[i] >= columnIndex && pivotToPosition[i] < startPos)
850 colToSwap.push_back(pivotToColumnIndex_[i]);
851 }
852 std::sort(colToSwap.begin(), colToSwap.end(), [&](Index c1, Index c2) {
853 return pivotToPosition[get_pivot(c1)] > pivotToPosition[get_pivot(c2)];
854 });
855 }
856
857 for (Index i : colToSwap) {
858 startIndex = Swap_opt::vine_swap(i, startIndex) == startIndex ? i : startIndex;
859 }
860 }
861
862 return chainsInF;
863}
864
865template <class Master_matrix>
867{
868 if constexpr (Master_matrix::Option_list::has_map_column_container) {
869 return matrix_.at(columnIndex);
870 } else {
871 return matrix_[columnIndex];
872 }
873}
874
875template <class Master_matrix>
877 Index columnIndex) const
878{
879 if constexpr (Master_matrix::Option_list::has_map_column_container) {
880 return matrix_.at(columnIndex);
881 } else {
882 return matrix_[columnIndex];
883 }
884}
885
886template <class Master_matrix>
888{
889 static_assert(
890 Master_matrix::Option_list::has_removable_columns && Master_matrix::Option_list::has_map_column_container,
891 "'remove_maximal_cell' is not implemented for the chosen options.");
892 static_assert(
893 Master_matrix::Option_list::has_vine_update && (Master_matrix::Option_list::has_column_pairings ||
894 Master_matrix::Option_list::can_retrieve_representative_cycles),
895 "'remove_maximal_cell' is not implemented for the chosen options.");
896
897 // TODO: find simple test to verify that col at columnIndex is maximal even without row access.
898
899 const auto& pivotToPosition = Pivot_to_pos_mapper_opt::map_;
900 auto it = pivotToPosition.find(cellID);
901 if (it == pivotToPosition.end()) return; // cell does not exists. TODO: put an assert instead?
902 Pos_index startPos = it->second;
903 Index startIndex = pivotToColumnIndex_.at(cellID);
904
905 if (startPos != nextPosition_ - 1) {
906 std::vector<Index> colToSwap;
907 colToSwap.reserve(matrix_.size());
908
909 for (auto& p : pivotToPosition) {
910 if (p.second > startPos) colToSwap.push_back(pivotToColumnIndex_.at(p.first));
911 }
912 std::sort(colToSwap.begin(), colToSwap.end(), [&](Index c1, Index c2) {
913 return pivotToPosition.at(get_pivot(c1)) < pivotToPosition.at(get_pivot(c2));
914 });
915
916 for (Index i : colToSwap) {
917 startIndex = Swap_opt::vine_swap(startIndex, i);
918 }
919 }
920
921 _remove_last(startIndex);
922}
923
924template <class Master_matrix>
926 const std::vector<ID_index>& columnsToSwap)
927{
928 static_assert(Master_matrix::Option_list::has_removable_columns,
929 "'remove_maximal_cell' is not implemented for the chosen options.");
930 static_assert(Master_matrix::Option_list::has_map_column_container && Master_matrix::Option_list::has_vine_update,
931 "'remove_maximal_cell' is not implemented for the chosen options.");
932
933 // TODO: find simple test to verify that col at columnIndex is maximal even without row access.
934
935 Index startIndex = pivotToColumnIndex_.at(cellID);
936
937 for (ID_index i : columnsToSwap) {
938 startIndex = Swap_opt::vine_swap(startIndex, pivotToColumnIndex_.at(i));
939 }
940
941 _remove_last(startIndex);
942}
943
944template <class Master_matrix>
946{
947 static_assert(Master_matrix::Option_list::has_removable_columns,
948 "'remove_last' is not implemented for the chosen options.");
949 static_assert(Master_matrix::Option_list::has_map_column_container || !Master_matrix::Option_list::has_vine_update,
950 "'remove_last' is not implemented for the chosen options.");
951
952 if (nextIndex_ == 0 || matrix_.empty()) return; // empty matrix
953
954 if constexpr (Master_matrix::Option_list::has_vine_update) {
955 // careful: linear because of the search of the last index. It is better to keep track of the @ref IDIdx index
956 // of the last column while performing swaps (or the @ref MatIdx with the return values of `vine_swap` + get_pivot)
957 // and then call `remove_maximal_cell` with it and an empty `columnsToSwap`.
958
959 ID_index pivot = 0;
960 Index colIndex = 0;
961 for (auto& p : pivotToColumnIndex_) {
962 if (p.first > pivot) { // pivots have to be strictly increasing in order of filtration
963 pivot = p.first;
964 colIndex = p.second;
965 }
966 }
967 _remove_last(colIndex);
968 } else {
969 _remove_last(nextIndex_ - 1);
970 }
971}
972
973template <class Master_matrix>
975{
976 if constexpr (Master_matrix::Option_list::has_map_column_container) {
977 return matrix_.size();
978 } else {
979 return nextIndex_; // matrix could have been resized much bigger while insert
980 }
981}
982
983template <class Master_matrix>
985 Index columnIndex) const
986{
987 return get_column(columnIndex).get_dimension();
988}
989
990template <class Master_matrix>
991inline void Chain_matrix<Master_matrix>::add_to(Index sourceColumnIndex, Index targetColumnIndex)
992{
993 auto& col = get_column(targetColumnIndex);
994 _add_to(col, [&]() { col += get_column(sourceColumnIndex); });
995}
996
997template <class Master_matrix>
999 const Field_element& coefficient,
1000 Index targetColumnIndex)
1001{
1002 auto& col = get_column(targetColumnIndex);
1003 _add_to(col, [&]() { col.multiply_target_and_add(coefficient, get_column(sourceColumnIndex)); });
1004}
1005
1006template <class Master_matrix>
1008 Index sourceColumnIndex,
1009 Index targetColumnIndex)
1010{
1011 auto& col = get_column(targetColumnIndex);
1012 _add_to(col, [&]() { col.multiply_source_and_add(get_column(sourceColumnIndex), coefficient); });
1013}
1014
1015template <class Master_matrix>
1016inline bool Chain_matrix<Master_matrix>::is_zero_entry(Index columnIndex, ID_index rowIndex) const
1017{
1018 return !get_column(columnIndex).is_non_zero(rowIndex);
1019}
1020
1021template <class Master_matrix>
1023{
1024 return get_column(columnIndex).is_empty();
1025}
1026
1027template <class Master_matrix>
1029 ID_index cellID) const
1030{
1031 if constexpr (Master_matrix::Option_list::has_map_column_container) {
1032 return pivotToColumnIndex_.at(cellID);
1033 } else {
1034 return pivotToColumnIndex_[cellID];
1035 }
1036}
1037
1038template <class Master_matrix>
1040{
1041 return get_column(columnIndex).get_pivot();
1042}
1043
1044template <class Master_matrix>
1046{
1047 if (this == &other) return *this;
1048
1049 Dim_opt::operator=(other);
1050 Swap_opt::operator=(other);
1051 Pair_opt::operator=(other);
1052 Rep_opt::operator=(other);
1053 Pivot_to_pos_mapper_opt::operator=(other);
1054 matrix_.clear();
1055 pivotToColumnIndex_ = other.pivotToColumnIndex_;
1056 nextIndex_ = other.nextIndex_;
1057 nextPosition_ = other.nextPosition_;
1058 colSettings_ = other.colSettings_;
1059
1060 matrix_.reserve(other.matrix_.size());
1061 for (const auto& cont : other.matrix_) {
1062 _container_insert(cont);
1063 }
1064
1065 return *this;
1066}
1067
1068template <class Master_matrix>
1070{
1071 if (this == &other) return *this;
1072
1073 Dim_opt::operator=(std::move(other));
1074 Pair_opt::operator=(std::move(other));
1075 Swap_opt::operator=(std::move(other));
1076 Rep_opt::operator=(std::move(other));
1077 RA_opt::operator=(std::move(other));
1078 Pivot_to_pos_mapper_opt::operator=(std::move(other));
1079 matrix_ = std::move(other.matrix_);
1080 pivotToColumnIndex_ = std::move(other.pivotToColumnIndex_);
1081 nextIndex_ = std::exchange(other.nextIndex_, 0);
1082 nextPosition_ = std::exchange(other.nextPosition_, 0);
1083 colSettings_ = std::exchange(other.colSettings_, nullptr);
1084
1085 return *this;
1086}
1087
1088template <class Master_matrix>
1089inline void Chain_matrix<Master_matrix>::print() const
1090{
1091 std::cout << "Column Matrix:\n";
1092 if constexpr (!Master_matrix::Option_list::has_map_column_container) {
1093 for (ID_index i = 0; i < pivotToColumnIndex_.size(); ++i) {
1094 Index pos = pivotToColumnIndex_[i];
1095 if (pos != Master_matrix::template get_null_value<Index>()) {
1096 const Column& col = matrix_[pos];
1097 for (const auto& entry : col) {
1098 std::cout << entry.get_row_index() << " ";
1099 }
1100 std::cout << "(" << i << ", " << pos << ")\n";
1101 }
1102 }
1103 if constexpr (Master_matrix::Option_list::has_row_access) {
1104 std::cout << "\n";
1105 std::cout << "Row Matrix:\n";
1106 for (ID_index i = 0; i < pivotToColumnIndex_.size(); ++i) {
1107 Index pos = pivotToColumnIndex_[i];
1108 if (pos != Master_matrix::template get_null_value<Index>()) {
1109 const Row& row = RA_opt::get_row(pos);
1110 for (const auto& entry : row) {
1111 std::cout << entry.get_column_index() << " ";
1112 }
1113 std::cout << "(" << i << ", " << pos << ")\n";
1114 }
1115 }
1116 }
1117 } else {
1118 for (const auto& p : pivotToColumnIndex_) {
1119 const Column& col = matrix_.at(p.second);
1120 for (const auto& entry : col) {
1121 std::cout << entry.get_row_index() << " ";
1122 }
1123 std::cout << "(" << p.first << ", " << p.second << ")\n";
1124 }
1125 if constexpr (Master_matrix::Option_list::has_row_access) {
1126 std::cout << "\n";
1127 std::cout << "Row Matrix:\n";
1128 for (const auto& p : pivotToColumnIndex_) {
1129 const Row& row = RA_opt::get_row(p.first);
1130 for (const auto& entry : row) {
1131 std::cout << entry.get_column_index() << " ";
1132 }
1133 std::cout << "(" << p.first << ", " << p.second << ")\n";
1134 }
1135 }
1136 }
1137 std::cout << "\n";
1138}
1139
1140template <class Master_matrix>
1141template <class Boundary_range>
1142inline std::vector<typename Master_matrix::Entry_representative>
1143Chain_matrix<Master_matrix>::_reduce_boundary(ID_index cellID, const Boundary_range& boundary, Dimension dim)
1144{
1145 Tmp_column column(boundary.begin(), boundary.end());
1146 if (dim == Master_matrix::template get_null_value<Dimension>())
1147 dim = boundary.begin() == boundary.end() ? 0 : boundary.size() - 1;
1148 std::vector<Entry_representative> chainsInH; // for corresponding indices in H (paired columns)
1149 std::vector<Entry_representative> chainsInF; // for corresponding indices in F (unpaired, essential columns)
1150
1151 auto get_last = [&column]() {
1152 if constexpr (Master_matrix::Option_list::is_z2)
1153 return *(column.rbegin());
1154 else
1155 return column.rbegin()->first;
1156 };
1157
1158 if (boundary.begin() == boundary.end()) {
1159 _insert_in(cellID, column);
1160 _insert_chain(column, dim);
1161 return chainsInF;
1162 }
1163
1164 Index currentIndex = get_column_with_pivot(get_last());
1165
1166 while (get_column(currentIndex).is_paired()) {
1167 _reduce_by_G(column, chainsInH, currentIndex);
1168
1169 if (column.empty()) {
1170 // produce the sum of all col_h in chains_in_H
1171 _build_from_H(cellID, column, chainsInH);
1172 // create a new cycle (in F) sigma - \sum col_h
1173 _insert_chain(column, dim);
1174 return chainsInF;
1175 }
1176
1177 currentIndex = get_column_with_pivot(get_last());
1178 }
1179
1180 while (!column.empty()) {
1181 currentIndex = get_column_with_pivot(get_last());
1182
1183 if (!get_column(currentIndex).is_paired()) {
1184 // only fills currentEssentialCycleIndices if Z2 coefficients, so chainsInF remains empty
1185 _reduce_by_F(column, chainsInF, currentIndex);
1186 } else {
1187 _reduce_by_G(column, chainsInH, currentIndex);
1188 }
1189 }
1190
1191 _update_largest_death_in_F(chainsInF);
1192
1193 // Compute the new column cellID + \sum col_h, for col_h in chains_in_H
1194 _build_from_H(cellID, column, chainsInH);
1195
1196 // Create and insert (\sum col_h) + sigma (in H, paired with chain_fp) in matrix_
1197 _insert_chain(column, dim, Master_matrix::get_row_index(chainsInF[0]));
1198
1199 return chainsInF;
1200}
1201
1202template <class Master_matrix>
1203inline void Chain_matrix<Master_matrix>::_reduce_by_G(Tmp_column& column,
1204 std::vector<Entry_representative>& chainsInH,
1205 Index currentIndex)
1206{
1207 Column& col = get_column(currentIndex);
1208 if constexpr (Master_matrix::Option_list::is_z2) {
1209 _add_to(col, column, 1U); // Reduce with the column col_g
1210 chainsInH.push_back(col.get_paired_chain_index()); // keep the col_h with which col_g is paired
1211 } else {
1212 Field_element coef = col.get_pivot_value();
1213 auto& operators = colSettings_->operators;
1214 coef = operators.get_inverse(coef);
1215 operators.multiply_inplace(coef, operators.get_characteristic() - column.rbegin()->second);
1216
1217 _add_to(col, column, coef); // Reduce with the column col_g
1218 chainsInH.emplace_back(col.get_paired_chain_index(), coef); // keep the col_h with which col_g is paired
1219 }
1220}
1221
1222template <class Master_matrix>
1223inline void Chain_matrix<Master_matrix>::_reduce_by_F(Tmp_column& column,
1224 std::vector<Entry_representative>& chainsInF,
1225 Index currentIndex)
1226{
1227 Column& col = get_column(currentIndex);
1228 if constexpr (Master_matrix::Option_list::is_z2) {
1229 _add_to(col, column, 1U); // Reduce with the column col_g
1230 chainsInF.push_back(currentIndex);
1231 } else {
1232 Field_element coef = col.get_pivot_value();
1233 auto& operators = colSettings_->operators;
1234 coef = operators.get_inverse(coef);
1235 operators.multiply_inplace(coef, operators.get_characteristic() - column.rbegin()->second);
1236
1237 _add_to(col, column, coef); // Reduce with the column col_g
1238 chainsInF.emplace_back(currentIndex, operators.get_characteristic() - coef);
1239 }
1240}
1241
1242template <class Master_matrix>
1243inline void Chain_matrix<Master_matrix>::_build_from_H(ID_index cellID,
1244 Tmp_column& column,
1245 std::vector<Entry_representative>& chainsInH)
1246{
1247 _insert_in(cellID, column);
1248
1249 for (const auto& idx_h : chainsInH) {
1250 _add_to(get_column(Master_matrix::get_row_index(idx_h)), column, Master_matrix::get_element(idx_h));
1251 }
1252}
1253
1254template <class Master_matrix>
1255inline void Chain_matrix<Master_matrix>::_update_largest_death_in_F(const std::vector<Entry_representative>& chainsInF)
1256{
1257 Index toUpdate = Master_matrix::get_row_index(chainsInF[0]);
1258 if constexpr (Master_matrix::Option_list::is_z2) {
1259 for (auto other_col_it = chainsInF.begin() + 1; other_col_it != chainsInF.end(); ++other_col_it) {
1260 add_to(*other_col_it, toUpdate);
1261 }
1262 } else {
1263 get_column(toUpdate) *= Master_matrix::get_element(chainsInF[0]);
1264 for (auto other_col_it = chainsInF.begin() + 1; other_col_it != chainsInF.end(); ++other_col_it) {
1265 multiply_source_and_add_to(
1266 Master_matrix::get_element(*other_col_it), Master_matrix::get_row_index(*other_col_it), toUpdate);
1267 }
1268 }
1269}
1270
1271template <class Master_matrix>
1272inline void Chain_matrix<Master_matrix>::_insert_chain(const Tmp_column& column, Dimension dimension)
1273{
1274 _container_insert(column, nextIndex_, dimension);
1275 _add_bar(dimension);
1276
1277 ++nextIndex_;
1278}
1279
1280template <class Master_matrix>
1281inline void Chain_matrix<Master_matrix>::_insert_chain(const Tmp_column& column, Dimension dimension, Index pair)
1282{
1283 // true when no vine updates and if nextIndex_ is updated in remove_last for special case of no vines
1284 // because then @ref PosIdx == @ref MatIdx
1285 Pos_index pairPos = pair;
1286
1287 _container_insert(column, nextIndex_, dimension);
1288
1289 get_column(nextIndex_).assign_paired_chain(pair);
1290 auto& pairCol = get_column(pair);
1291 pairCol.assign_paired_chain(nextIndex_);
1292
1293 if constexpr (Master_matrix::Option_list::has_column_pairings && Master_matrix::Option_list::has_vine_update) {
1294 pairPos = Pivot_to_pos_mapper_opt::map_[pairCol.get_pivot()];
1295 }
1296
1297 _update_barcode(pairPos);
1298
1299 ++nextIndex_;
1300}
1301
1302template <class Master_matrix>
1303inline void Chain_matrix<Master_matrix>::_add_to(const Column& column,
1304 Tmp_column& set,
1305 [[maybe_unused]] unsigned int coef)
1306{
1307 if constexpr (Master_matrix::Option_list::is_z2) {
1308 std::pair<typename std::set<Index>::iterator, bool> res_insert;
1309 for (const Entry& entry : column) {
1310 res_insert = set.insert(entry.get_row_index());
1311 if (!res_insert.second) {
1312 set.erase(res_insert.first);
1313 }
1314 }
1315 } else {
1316 auto& operators = colSettings_->operators;
1317 for (const Entry& entry : column) {
1318 auto res = set.emplace(entry.get_row_index(), entry.get_element());
1319 if (res.second) {
1320 operators.multiply_inplace(res.first->second, coef);
1321 } else {
1322 operators.multiply_and_add_inplace_back(entry.get_element(), coef, res.first->second);
1323 if (res.first->second == Field_operators::get_additive_identity()) {
1324 set.erase(res.first);
1325 }
1326 }
1327 }
1328 }
1329}
1330
1331template <class Master_matrix>
1332template <typename F>
1333inline void Chain_matrix<Master_matrix>::_add_to(Column& target, F&& addition)
1334{
1335 auto pivot = target.get_pivot();
1336 std::forward<F>(addition)();
1337
1338 if (pivot != target.get_pivot()) {
1339 if constexpr (Master_matrix::Option_list::has_map_column_container) {
1340 std::swap(pivotToColumnIndex_.at(pivot), pivotToColumnIndex_.at(target.get_pivot()));
1341 } else {
1342 std::swap(pivotToColumnIndex_[pivot], pivotToColumnIndex_[target.get_pivot()]);
1343 }
1344 }
1345}
1346
1347template <class Master_matrix>
1348inline void Chain_matrix<Master_matrix>::_remove_last(Index lastIndex)
1349{
1350 static_assert(Master_matrix::Option_list::has_removable_columns,
1351 "'_remove_last' is not implemented for the chosen options.");
1352 static_assert(Master_matrix::Option_list::has_map_column_container || !Master_matrix::Option_list::has_vine_update,
1353 "'_remove_last' is not implemented for the chosen options.");
1354
1355 ID_index pivot;
1356
1357 if constexpr (Master_matrix::Option_list::has_map_column_container) {
1358 auto itToErase = matrix_.find(lastIndex);
1359 Column& colToErase = itToErase->second;
1360 pivot = colToErase.get_pivot();
1361
1362 if constexpr (Master_matrix::Option_list::has_matrix_maximal_dimension_access) {
1363 Dim_opt::_update_down(colToErase.get_dimension());
1364 }
1365
1366 if (colToErase.is_paired()) matrix_.at(colToErase.get_paired_chain_index()).unassign_paired_chain();
1367 pivotToColumnIndex_.erase(pivot);
1368 matrix_.erase(itToErase);
1369 } else {
1370 GUDHI_CHECK(lastIndex == nextIndex_ - 1 && nextIndex_ == matrix_.size(),
1371 std::logic_error("Chain_matrix::_remove_last - Indexation problem."));
1372
1373 Column& colToErase = matrix_[lastIndex];
1374 pivot = colToErase.get_pivot();
1375
1376 if constexpr (Master_matrix::Option_list::has_matrix_maximal_dimension_access) {
1377 Dim_opt::_update_down(colToErase.get_dimension());
1378 }
1379
1380 if (colToErase.is_paired()) matrix_.at(colToErase.get_paired_chain_index()).unassign_paired_chain();
1381 pivotToColumnIndex_[pivot] = Master_matrix::template get_null_value<Index>();
1382 matrix_.pop_back();
1383 // TODO: resize matrix_ when a lot is removed? Could be not the best strategy if user inserts a lot back afterwards.
1384 }
1385
1386 if constexpr (!Master_matrix::Option_list::has_vine_update) {
1387 --nextIndex_; // should not be updated when there are vine updates, as possibly lastIndex != nextIndex - 1
1388 }
1389
1390 --nextPosition_;
1391 if constexpr (Master_matrix::Option_list::has_column_pairings) {
1392 Pair_opt::_erase_bar(nextPosition_);
1393 }
1394 if constexpr (hasPivotToPosMap_) {
1395 Pivot_to_pos_mapper_opt::map_.erase(pivot);
1396 }
1397
1398 if constexpr (Master_matrix::Option_list::has_row_access) {
1399 GUDHI_CHECK(
1400 RA_opt::get_row(pivot).size() == 0,
1401 std::invalid_argument(
1402 "Chain_matrix::_remove_last - Column asked to be removed does not corresponds to a maximal simplex."));
1403 if constexpr (Master_matrix::Option_list::has_removable_rows) {
1404 RA_opt::erase_empty_row(pivot);
1405 }
1406 }
1407}
1408
1409template <class Master_matrix>
1410inline void Chain_matrix<Master_matrix>::_update_barcode(Pos_index birth)
1411{
1412 if constexpr (Master_matrix::Option_list::has_column_pairings) {
1413 Pair_opt::_update_barcode(birth, nextPosition_);
1414 }
1415 ++nextPosition_;
1416}
1417
1418template <class Master_matrix>
1419inline void Chain_matrix<Master_matrix>::_add_bar(Dimension dim)
1420{
1421 if constexpr (Master_matrix::Option_list::has_column_pairings) {
1422 Pair_opt::_add_bar(dim, nextPosition_);
1423 }
1424 ++nextPosition_;
1425}
1426
1427template <class Master_matrix>
1428template <class Container>
1429inline void Chain_matrix<Master_matrix>::_container_insert(const Container& column, Index pos, Dimension dim)
1430{
1431 ID_index pivot = Master_matrix::get_row_index(*(column.rbegin()));
1432
1433 if constexpr (Master_matrix::Option_list::has_map_column_container) {
1434 pivotToColumnIndex_.try_emplace(pivot, pos);
1435 if constexpr (Master_matrix::Option_list::has_row_access) {
1436 matrix_.try_emplace(pos, Column(pos, column, dim, RA_opt::_get_rows_ptr(), colSettings_));
1437 } else {
1438 matrix_.try_emplace(pos, Column(column, dim, colSettings_));
1439 }
1440 } else {
1441 if constexpr (Master_matrix::Option_list::has_row_access) {
1442 matrix_.emplace_back(pos, column, dim, RA_opt::_get_rows_ptr(), colSettings_);
1443 } else {
1444 matrix_.emplace_back(column, dim, colSettings_);
1445 }
1446 pivotToColumnIndex_[pivot] = pos;
1447 }
1448}
1449
1450template <class Master_matrix>
1451template <class ColumnIterator> // Pair (pos,Column) if has_map_column_container, Column otherwise
1452inline void Chain_matrix<Master_matrix>::_container_insert(const ColumnIterator& rep)
1453{
1454 if constexpr (Master_matrix::Option_list::has_map_column_container) {
1455 const auto& col = rep.second;
1456 if constexpr (Master_matrix::Option_list::has_row_access) {
1457 matrix_.try_emplace(rep.first, Column(col, col.get_column_index(), RA_opt::_get_rows_ptr(), colSettings_));
1458 } else {
1459 matrix_.try_emplace(rep.first, Column(col, colSettings_));
1460 }
1461 } else {
1462 if constexpr (Master_matrix::Option_list::has_row_access) {
1463 matrix_.emplace_back(rep, rep.get_column_index(), RA_opt::_get_rows_ptr(), colSettings_);
1464 } else {
1465 matrix_.emplace_back(rep, colSettings_);
1466 }
1467 }
1468}
1469
1470template <class Master_matrix>
1471inline void Chain_matrix<Master_matrix>::_insert_in(ID_index cellID, Tmp_column& column)
1472{
1473 if constexpr (Master_matrix::Option_list::is_z2)
1474 column.insert(cellID);
1475 else
1476 column.emplace(cellID, 1);
1477}
1478
1479} // namespace persistence_matrix
1480} // namespace Gudhi
1481
1482#endif // PM_CHAIN_MATRIX_H
Contains the Gudhi::persistence_matrix::Id_to_index_overlay class.
Contains the Gudhi::persistence_matrix::Position_to_index_overlay class.
Matrix structure storing a compatible base of a filtered chain complex. See zigzag....
Definition Chain_matrix.h:58
void remove_maximal_cell(ID_index cellID)
Only available if PersistenceMatrixOptions::has_removable_columns and PersistenceMatrixOptions::has_v...
Definition Chain_matrix.h:887
Chain_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 Chain_matrix.h:618
Chain_matrix(const Chain_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 Chain_matrix.h:730
std::vector< Entry_representative > 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....
std::vector< Entry_representative > insert_maximal_cell(Index columnIndex, ID_index cellID, const Boundary_range &boundary, Dimension dim=Master_matrix::template get_null_value< Dimension >())
Only available if PersistenceMatrixOptions::has_vine_update is true, as well as, PersistenceMatrixOpt...
Column & get_column(Index columnIndex)
Returns the column at the given MatIdx index. The type of the column depends on the chosen options,...
Definition Chain_matrix.h:866
void reset(Column_settings *colSettings)
Resets the matrix to an empty matrix.
Definition Chain_matrix.h:515
void remove_maximal_cell(ID_index cellID, const std::vector< ID_index > &columnsToSwap)
Only available if PersistenceMatrixOptions::has_removable_columns, PersistenceMatrixOptions::has_vine...
Definition Chain_matrix.h:925
typename Matrix< PersistenceMatrixOptions >::Index Index
Definition Chain_matrix.h:90
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 Chain_matrix.h:1007
typename Matrix< PersistenceMatrixOptions >::Pos_index Pos_index
Definition Chain_matrix.h:92
bool is_zero_entry(Index columnIndex, ID_index rowIndex) const
Indicates if the entry at given coordinates has value zero.
Definition Chain_matrix.h:1016
Chain_matrix(unsigned int numberOfColumns, Column_settings *colSettings, const BirthComparatorFunction &birthComparator, const DeathComparatorFunction &deathComparator)
Constructs a new empty matrix and reserves space for the given number of columns.
Definition Chain_matrix.h:707
Chain_matrix(Chain_matrix &&other) noexcept
Move constructor.
Definition Chain_matrix.h:749
typename Matrix< PersistenceMatrixOptions >::Entry_constructor Entry_constructor
Definition Chain_matrix.h:85
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 Chain_matrix.h:998
Index get_column_with_pivot(ID_index cellID) const
Returns the column with given row index as pivot. Assumes that the pivot exists.
Definition Chain_matrix.h:1028
Chain_matrix & operator=(Chain_matrix &&other) noexcept
Move assign operator.
Definition Chain_matrix.h:1069
std::vector< Entry_representative > 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, as well as, PersistenceMatrixOpt...
Chain_matrix(Column_settings *colSettings)
Constructs an empty matrix. Only available if PersistenceMatrixOptions::has_column_pairings is true o...
Definition Chain_matrix.h:604
Chain_matrix(unsigned int numberOfColumns, Column_settings *colSettings)
Constructs a new empty matrix and reserves space for the given number of columns. Only available if P...
Definition Chain_matrix.h:643
typename Matrix< PersistenceMatrixOptions >::Row Row
Definition Chain_matrix.h:82
typename Matrix< PersistenceMatrixOptions >::Field_operators Field_operators
Definition Chain_matrix.h:79
typename Matrix< PersistenceMatrixOptions >::Element Field_element
Definition Chain_matrix.h:80
void add_to(Index sourceColumnIndex, Index targetColumnIndex)
Adds column at sourceColumnIndex onto the column at targetColumnIndex in the matrix.
Definition Chain_matrix.h:991
ID_index get_pivot(Index columnIndex)
Returns the row index of the pivot of the given column.
Definition Chain_matrix.h:1039
typename Matrix< PersistenceMatrixOptions >::Entry_representative Entry_representative
Definition Chain_matrix.h:89
bool is_zero_column(Index columnIndex)
Indicates if the column at given index has value zero. Note that if the matrix is valid,...
Definition Chain_matrix.h:1022
Chain_matrix(Column_settings *colSettings, const BirthComparatorFunction &birthComparator, const DeathComparatorFunction &deathComparator)
Constructs an empty matrix and stores the given comparators.
Definition Chain_matrix.h:664
Index get_number_of_columns() const
Returns the current number of columns in the matrix.
Definition Chain_matrix.h:974
Chain_matrix(const std::vector< Boundary_range > &orderedBoundaries, Column_settings *colSettings, const BirthComparatorFunction &birthComparator, const DeathComparatorFunction &deathComparator)
Constructs a new matrix from the given ranges of Matrix::Entry_representative. Each range corresponds...
Definition Chain_matrix.h:680
std::vector< Entry_representative > insert_boundary(ID_index cellID, 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...
Dimension get_column_dimension(Index columnIndex) const
Returns the dimension of the given column.
Definition Chain_matrix.h:984
void remove_last()
Only available if PersistenceMatrixOptions::has_removable_columns is true and, if PersistenceMatrixOp...
Definition Chain_matrix.h:945
friend void swap(Chain_matrix &matrix1, Chain_matrix &matrix2) noexcept
Swap operator.
Definition Chain_matrix.h:540
typename Matrix< PersistenceMatrixOptions >::ID_index ID_index
Definition Chain_matrix.h:91
typename Matrix< PersistenceMatrixOptions >::Column Column
Definition Chain_matrix.h:81
typename Matrix< PersistenceMatrixOptions >::Matrix_entry Entry
Definition Chain_matrix.h:84
typename Matrix< PersistenceMatrixOptions >::Dimension Dimension
Definition Chain_matrix.h:93
Chain_matrix & operator=(const Chain_matrix &other)
Assign operator.
Definition Chain_matrix.h:1045
typename Matrix< PersistenceMatrixOptions >::Boundary Boundary
Definition Chain_matrix.h:88
typename Matrix< PersistenceMatrixOptions >::Column_settings Column_settings
Definition Chain_matrix.h:86
const Column & get_column(Index columnIndex) const
Returns the column at the given MatIdx index. The type of the column depends on the chosen options,...
Definition Chain_matrix.h:876
Matrix entry class. Stores by default only the row index it belongs to, but can also store its column...
Definition entry_types.h:163
Overlay for non-basic matrices replacing all input and output MatIdx indices of the original methods ...
Definition Id_to_index_overlay.h:41
std::enable_if_t< std::is_integral_v< Integer_index > > multiply_target_and_add_to(Integer_index sourceColumnIndex, int coefficient, Integer_index targetColumnIndex)
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 >())
typename Chain_rep_cycles_options::Dimension Dimension
Definition Matrix.h:153
bool is_zero_entry(Index columnIndex, ID_index rowIndex)
typename Chain_rep_cycles_options::Index Index
Definition Matrix.h:150
Insertion_return insert_boundary(const Boundary_range &boundary, Dimension dim=Matrix::get_null_value< Dimension >())
std::conditional_t< Chain_rep_cycles_options::column_type==Column_types::HEAP, Matrix_heap_column, std::conditional_t< Chain_rep_cycles_options::column_type==Column_types::LIST, Matrix_list_column, std::conditional_t< Chain_rep_cycles_options::column_type==Column_types::SET, Matrix_set_column, std::conditional_t< Chain_rep_cycles_options::column_type==Column_types::UNORDERED_SET, Matrix_unordered_set_column, std::conditional_t< Chain_rep_cycles_options::column_type==Column_types::VECTOR, Matrix_vector_column, std::conditional_t< Chain_rep_cycles_options::column_type==Column_types::INTRUSIVE_LIST, Matrix_intrusive_list_column, std::conditional_t< Chain_rep_cycles_options::column_type==Column_types::NAIVE_VECTOR, Matrix_naive_vector_column, std::conditional_t< Chain_rep_cycles_options::column_type==Column_types::SMALL_VECTOR, Matrix_small_vector_column, Matrix_intrusive_set_column > > > > > > > > Column
Definition Matrix.h:359
typename Chain_rep_cycles_options::Index ID_index
Definition Matrix.h:151
std::enable_if_t< std::is_integral_v< Integer_index > > add_to(Integer_index sourceColumnIndex, Integer_index targetColumnIndex)
Overlay for chain matrices replacing all input and output MatIdx indices of the original methods with...
Definition Position_to_index_overlay.h:43
Contains the Gudhi::persistence_matrix::Index_mapper class and Gudhi::persistence_matrix::Dummy_index...
Persistence matrix namespace.
Definition FieldOperators.h:18
Gudhi namespace.
Definition SimplicialComplexForAlpha.h:14