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
30
31namespace Gudhi {
32namespace persistence_matrix {
33
45template <class Master_matrix>
46class Chain_matrix : public Master_matrix::Matrix_dimension_option,
47 public Master_matrix::Chain_pairing_option,
48 public Master_matrix::Chain_vine_swap_option,
49 public Master_matrix::Chain_representative_cycles_option,
50 public Master_matrix::Matrix_row_access_option,
51 protected std::conditional_t<
52 Master_matrix::Option_list::has_vine_update &&
53 (Master_matrix::Option_list::has_column_pairings ||
54 Master_matrix::Option_list::can_retrieve_representative_cycles),
55 Index_mapper<typename Master_matrix::template Dictionary<typename Master_matrix::Pos_index>>,
56 Dummy_index_mapper>
57{
58 private:
59 using Dim_opt = typename Master_matrix::Matrix_dimension_option;
60 using Pair_opt = typename Master_matrix::Chain_pairing_option;
61 using Swap_opt = typename Master_matrix::Chain_vine_swap_option;
62 using Rep_opt = typename Master_matrix::Chain_representative_cycles_option;
63 using RA_opt = typename Master_matrix::Matrix_row_access_option;
64
65 static constexpr bool hasPivotToPosMap_ =
66 Master_matrix::Option_list::has_vine_update && (Master_matrix::Option_list::has_column_pairings ||
67 Master_matrix::Option_list::can_retrieve_representative_cycles);
68
69 using Pivot_to_pos_mapper_opt =
70 std::conditional_t<hasPivotToPosMap_,
71 Index_mapper<typename Master_matrix::template Dictionary<typename Master_matrix::Pos_index>>,
72 Dummy_index_mapper>;
73
74 public:
78 using Field_operators = typename Master_matrix::Field_operators;
79 using Field_element = typename Master_matrix::Element;
80 using Column = typename Master_matrix::Column;
81 using Row = typename Master_matrix::Row;
83 using Entry = typename Master_matrix::Matrix_entry;
84 using Entry_constructor = typename Master_matrix::Entry_constructor;
85 using Column_settings = typename Master_matrix::Column_settings;
87 using Boundary = typename Master_matrix::Boundary;
88 using Entry_representative = typename Master_matrix::Entry_representative;
89 using Index = typename Master_matrix::Index;
90 using ID_index = typename Master_matrix::ID_index;
91 using Pos_index = typename Master_matrix::Pos_index;
92 using Dimension = typename Master_matrix::Dimension;
93
127 template <class Boundary_range = Boundary>
128 Chain_matrix(const std::vector<Boundary_range>& orderedBoundaries, Column_settings* colSettings);
138 Chain_matrix(unsigned int numberOfColumns, Column_settings* colSettings);
160 template <typename BirthComparatorFunction, typename DeathComparatorFunction>
162 const BirthComparatorFunction& birthComparator,
163 const DeathComparatorFunction& deathComparator);
200 template <typename BirthComparatorFunction, typename DeathComparatorFunction, class Boundary_range = Boundary>
201 Chain_matrix(const std::vector<Boundary_range>& orderedBoundaries,
202 Column_settings* colSettings,
203 const BirthComparatorFunction& birthComparator,
204 const DeathComparatorFunction& deathComparator);
227 template <typename BirthComparatorFunction, typename DeathComparatorFunction>
228 Chain_matrix(unsigned int numberOfColumns,
229 Column_settings* colSettings,
230 const BirthComparatorFunction& birthComparator,
231 const DeathComparatorFunction& deathComparator);
241 Chain_matrix(const Chain_matrix& matrixToCopy, Column_settings* colSettings = nullptr);
247 Chain_matrix(Chain_matrix&& other) noexcept;
248
249 ~Chain_matrix() = default;
250
272 template <class Boundary_range = Boundary>
273 std::vector<Entry_representative> insert_boundary(
274 const Boundary_range& boundary,
275 Dimension dim = Master_matrix::template get_null_value<Dimension>());
294 template <class Boundary_range = Boundary>
295 std::vector<Entry_representative> insert_boundary(
296 ID_index cellID,
297 const Boundary_range& boundary,
298 Dimension dim = Master_matrix::template get_null_value<Dimension>());
306 Column& get_column(Index columnIndex);
314 const Column& get_column(Index columnIndex) const;
355 void remove_maximal_cell(ID_index cellID, const std::vector<ID_index>& columnsToSwap);
371
378
386
397 void add_to(Index sourceColumnIndex, Index targetColumnIndex);
410 void multiply_target_and_add_to(Index sourceColumnIndex, const Field_element& coefficient, Index targetColumnIndex);
423 void multiply_source_and_add_to(const Field_element& coefficient, Index sourceColumnIndex, Index targetColumnIndex);
424
433 bool is_zero_entry(Index columnIndex, ID_index rowIndex) const;
442 bool is_zero_column(Index columnIndex);
443
458
465 void reset(Column_settings* colSettings)
466 {
467 if constexpr (Master_matrix::Option_list::has_matrix_maximal_dimension_access) Dim_opt::_reset();
468 if constexpr (Master_matrix::Option_list::has_column_pairings) Pair_opt::_reset();
469 if constexpr (Master_matrix::Option_list::can_retrieve_representative_cycles) Rep_opt::_reset();
470 if constexpr (hasPivotToPosMap_) Pivot_to_pos_mapper_opt::map_.clear();
471 matrix_.clear();
472 pivotToColumnIndex_.clear();
473 nextIndex_ = 0;
474 nextPosition_ = 0;
475 colSettings_ = colSettings;
476 }
477
486
490 friend void swap(Chain_matrix& matrix1, Chain_matrix& matrix2) noexcept
491 {
492 swap(static_cast<Dim_opt&>(matrix1), static_cast<Dim_opt&>(matrix2));
493 swap(static_cast<Pair_opt&>(matrix1), static_cast<Pair_opt&>(matrix2));
494 swap(static_cast<Swap_opt&>(matrix1), static_cast<Swap_opt&>(matrix2));
495 swap(static_cast<Rep_opt&>(matrix1), static_cast<Rep_opt&>(matrix2));
496 swap(static_cast<Pivot_to_pos_mapper_opt&>(matrix1), static_cast<Pivot_to_pos_mapper_opt&>(matrix2));
497 matrix1.matrix_.swap(matrix2.matrix_);
498 matrix1.pivotToColumnIndex_.swap(matrix2.pivotToColumnIndex_);
499 std::swap(matrix1.nextIndex_, matrix2.nextIndex_);
500 std::swap(matrix1.nextPosition_, matrix2.nextPosition_);
501 std::swap(matrix1.colSettings_, matrix2.colSettings_);
502
503 if constexpr (Master_matrix::Option_list::has_row_access) {
504 swap(static_cast<RA_opt&>(matrix1), static_cast<RA_opt&>(matrix2));
505 }
506 }
507
508 void print() const; // for debug
509
510 friend class Id_to_index_overlay<Chain_matrix<Master_matrix>, Master_matrix>;
511
512 private:
513 using Column_container = typename Master_matrix::Column_container;
514 using Dictionary = typename Master_matrix::template Dictionary<Index>;
515 using Barcode = typename Master_matrix::Barcode;
516 using Bar_dictionary = typename Master_matrix::Bar_dictionary;
517 using Tmp_column = typename std::
518 conditional<Master_matrix::Option_list::is_z2, std::set<ID_index>, std::map<ID_index, Field_element>>::type;
519
520 friend Swap_opt; // direct access to index mapper
521 friend Pair_opt; // direct access to index mapper
522 friend Rep_opt; // direct access to index mapper
523
524 Column_container matrix_;
525 Dictionary pivotToColumnIndex_;
526 Index nextIndex_;
527 Pos_index nextPosition_;
528 Column_settings* colSettings_;
529
530 template <class Boundary_range>
531 std::vector<Entry_representative> _reduce_boundary(ID_index cellID, const Boundary_range& boundary, Dimension dim);
532 void _reduce_by_G(Tmp_column& column, std::vector<Entry_representative>& chainsInH, Index currentIndex);
533 void _reduce_by_F(Tmp_column& column, std::vector<Entry_representative>& chainsInF, Index currentIndex);
534 void _build_from_H(ID_index cellID, Tmp_column& column, std::vector<Entry_representative>& chainsInH);
535 void _update_largest_death_in_F(const std::vector<Entry_representative>& chainsInF);
536 void _insert_chain(const Tmp_column& column, Dimension dimension);
537 void _insert_chain(const Tmp_column& column, Dimension dimension, Index pair);
538 void _add_to(const Column& column, Tmp_column& set, unsigned int coef);
539 template <typename F>
540 void _add_to(Column& target, F&& addition);
541 void _remove_last(Index lastIndex);
542 void _update_barcode(Pos_index birth);
543 void _add_bar(Dimension dim);
544 template <class Container>
545 void _container_insert(const Container& column, Index pos, Dimension dim);
546 template <class ColumnIterator>
547 void _container_insert(const ColumnIterator& rep);
548
549 static void _insert_in(ID_index cellID, Tmp_column& column);
550};
551
552template <class Master_matrix>
554 : Dim_opt(Master_matrix::template get_null_value<Dimension>()),
555 Pair_opt(),
556 Swap_opt(),
557 Rep_opt(),
558 RA_opt(),
559 Pivot_to_pos_mapper_opt(),
560 nextIndex_(0),
561 nextPosition_(0),
562 colSettings_(colSettings)
563{}
564
565template <class Master_matrix>
566template <class Boundary_range>
567inline Chain_matrix<Master_matrix>::Chain_matrix(const std::vector<Boundary_range>& orderedBoundaries,
568 Column_settings* colSettings)
569 : Dim_opt(Master_matrix::template get_null_value<Dimension>()),
570 Pair_opt(),
571 Swap_opt(),
572 Rep_opt(),
573 RA_opt(orderedBoundaries.size()),
574 Pivot_to_pos_mapper_opt(),
575 nextIndex_(0),
576 nextPosition_(0),
577 colSettings_(colSettings)
578{
579 matrix_.reserve(orderedBoundaries.size());
580 if constexpr (Master_matrix::Option_list::has_map_column_container) {
581 pivotToColumnIndex_.reserve(orderedBoundaries.size());
582 } else {
583 pivotToColumnIndex_.resize(orderedBoundaries.size(), Master_matrix::template get_null_value<Index>());
584 }
585
586 for (const Boundary_range& b : orderedBoundaries) {
588 }
589}
590
591template <class Master_matrix>
592inline Chain_matrix<Master_matrix>::Chain_matrix(unsigned int numberOfColumns, Column_settings* colSettings)
593 : Dim_opt(Master_matrix::template get_null_value<Dimension>()),
594 Pair_opt(),
595 Swap_opt(),
596 Rep_opt(),
597 RA_opt(numberOfColumns),
598 Pivot_to_pos_mapper_opt(),
599 nextIndex_(0),
600 nextPosition_(0),
601 colSettings_(colSettings)
602{
603 matrix_.reserve(numberOfColumns);
604 if constexpr (Master_matrix::Option_list::has_map_column_container) {
605 pivotToColumnIndex_.reserve(numberOfColumns);
606 } else {
607 pivotToColumnIndex_.resize(numberOfColumns, Master_matrix::template get_null_value<Index>());
608 }
609}
610
611template <class Master_matrix>
612template <typename BirthComparatorFunction, typename DeathComparatorFunction>
614 const BirthComparatorFunction& birthComparator,
615 const DeathComparatorFunction& deathComparator)
616 : Dim_opt(Master_matrix::template get_null_value<Dimension>()),
617 Pair_opt(),
618 Swap_opt(birthComparator, deathComparator),
619 Rep_opt(),
620 RA_opt(),
621 Pivot_to_pos_mapper_opt(),
622 nextIndex_(0),
623 nextPosition_(0),
624 colSettings_(colSettings)
625{}
626
627template <class Master_matrix>
628template <typename BirthComparatorFunction, typename DeathComparatorFunction, class Boundary_range>
629inline Chain_matrix<Master_matrix>::Chain_matrix(const std::vector<Boundary_range>& orderedBoundaries,
630 Column_settings* colSettings,
631 const BirthComparatorFunction& birthComparator,
632 const DeathComparatorFunction& deathComparator)
633 : Dim_opt(Master_matrix::template get_null_value<Dimension>()),
634 Pair_opt(),
635 Swap_opt(birthComparator, deathComparator),
636 Rep_opt(),
637 RA_opt(orderedBoundaries.size()),
638 Pivot_to_pos_mapper_opt(),
639 nextIndex_(0),
640 nextPosition_(0),
641 colSettings_(colSettings)
642{
643 matrix_.reserve(orderedBoundaries.size());
644 if constexpr (Master_matrix::Option_list::has_map_column_container) {
645 pivotToColumnIndex_.reserve(orderedBoundaries.size());
646 } else {
647 pivotToColumnIndex_.resize(orderedBoundaries.size(), Master_matrix::template get_null_value<Index>());
648 }
649 for (const Boundary_range& b : orderedBoundaries) {
651 }
652}
653
654template <class Master_matrix>
655template <typename BirthComparatorFunction, typename DeathComparatorFunction>
656inline Chain_matrix<Master_matrix>::Chain_matrix(unsigned int numberOfColumns,
657 Column_settings* colSettings,
658 const BirthComparatorFunction& birthComparator,
659 const DeathComparatorFunction& deathComparator)
660 : Dim_opt(Master_matrix::template get_null_value<Dimension>()),
661 Pair_opt(),
662 Swap_opt(birthComparator, deathComparator),
663 Rep_opt(),
664 RA_opt(numberOfColumns),
665 Pivot_to_pos_mapper_opt(),
666 nextIndex_(0),
667 nextPosition_(0),
668 colSettings_(colSettings)
669{
670 matrix_.reserve(numberOfColumns);
671 if constexpr (Master_matrix::Option_list::has_map_column_container) {
672 pivotToColumnIndex_.reserve(numberOfColumns);
673 } else {
674 pivotToColumnIndex_.resize(numberOfColumns, Master_matrix::template get_null_value<Index>());
675 }
676}
677
678template <class Master_matrix>
680 : Dim_opt(static_cast<const Dim_opt&>(matrixToCopy)),
681 Pair_opt(static_cast<const Pair_opt&>(matrixToCopy)),
682 Swap_opt(static_cast<const Swap_opt&>(matrixToCopy)),
683 Rep_opt(static_cast<const Rep_opt&>(matrixToCopy)),
684 RA_opt(static_cast<const RA_opt&>(matrixToCopy)),
685 Pivot_to_pos_mapper_opt(static_cast<const Pivot_to_pos_mapper_opt&>(matrixToCopy)),
686 pivotToColumnIndex_(matrixToCopy.pivotToColumnIndex_),
687 nextIndex_(matrixToCopy.nextIndex_),
688 nextPosition_(matrixToCopy.nextPosition_),
689 colSettings_(colSettings == nullptr ? matrixToCopy.colSettings_ : colSettings)
690{
691 matrix_.reserve(matrixToCopy.matrix_.size());
692 for (const auto& cont : matrixToCopy.matrix_) {
693 _container_insert(cont);
694 }
695}
696
697template <class Master_matrix>
699 : Dim_opt(std::move(static_cast<Dim_opt&>(other))),
700 Pair_opt(std::move(static_cast<Pair_opt&>(other))),
701 Swap_opt(std::move(static_cast<Swap_opt&>(other))),
702 Rep_opt(std::move(static_cast<Rep_opt&>(other))),
703 RA_opt(std::move(static_cast<RA_opt&>(other))),
704 Pivot_to_pos_mapper_opt(std::move(static_cast<Pivot_to_pos_mapper_opt&>(other))),
705 matrix_(std::move(other.matrix_)),
706 pivotToColumnIndex_(std::move(other.pivotToColumnIndex_)),
707 nextIndex_(std::exchange(other.nextIndex_, 0)),
708 nextPosition_(std::exchange(other.nextPosition_, 0)),
709 colSettings_(std::exchange(other.colSettings_, nullptr))
710{}
711
712template <class Master_matrix>
713template <class Boundary_range>
714inline std::vector<typename Master_matrix::Entry_representative> Chain_matrix<Master_matrix>::insert_boundary(
715 const Boundary_range& boundary,
716 Dimension dim)
717{
718 return insert_boundary(nextIndex_, boundary, dim);
719}
720
721template <class Master_matrix>
722template <class Boundary_range>
723inline std::vector<typename Master_matrix::Entry_representative>
724Chain_matrix<Master_matrix>::insert_boundary(ID_index cellID, const Boundary_range& boundary, Dimension dim)
725{
726 if constexpr (!Master_matrix::Option_list::has_map_column_container) {
727 if (pivotToColumnIndex_.size() <= cellID) {
728 pivotToColumnIndex_.resize((cellID * 2) + 1, Master_matrix::template get_null_value<Index>());
729 }
730 }
731
732 if constexpr (hasPivotToPosMap_) {
733 if constexpr (Master_matrix::Option_list::has_map_column_container) {
734 Pivot_to_pos_mapper_opt::map_.try_emplace(cellID, nextPosition_);
735 } else {
736 if (Pivot_to_pos_mapper_opt::map_.size() <= cellID)
737 Pivot_to_pos_mapper_opt::map_.resize(pivotToColumnIndex_.size(),
738 Master_matrix::template get_null_value<Pos_index>());
739 Pivot_to_pos_mapper_opt::map_[cellID] = nextPosition_;
740 }
741 }
742
743 if constexpr (Master_matrix::Option_list::has_matrix_maximal_dimension_access) {
744 Dim_opt::_update_up(dim == Master_matrix::template get_null_value<Dimension>()
745 ? (boundary.size() == 0 ? 0 : boundary.size() - 1)
746 : dim);
747 }
748
749 return _reduce_boundary(cellID, boundary, dim);
750}
751
752template <class Master_matrix>
754{
755 if constexpr (Master_matrix::Option_list::has_map_column_container) {
756 return matrix_.at(columnIndex);
757 } else {
758 return matrix_[columnIndex];
759 }
760}
761
762template <class Master_matrix>
764 Index columnIndex) const
765{
766 if constexpr (Master_matrix::Option_list::has_map_column_container) {
767 return matrix_.at(columnIndex);
768 } else {
769 return matrix_[columnIndex];
770 }
771}
772
773template <class Master_matrix>
775{
776 static_assert(Master_matrix::Option_list::has_removable_columns,
777 "'remove_maximal_cell' is not implemented for the chosen options.");
778 static_assert(Master_matrix::Option_list::has_map_column_container && Master_matrix::Option_list::has_vine_update &&
779 Master_matrix::Option_list::has_column_pairings,
780 "'remove_maximal_cell' is not implemented for the chosen options.");
781
782 // TODO: find simple test to verify that col at columnIndex is maximal even without row access.
783
784 const auto& pivotToPosition = Pivot_to_pos_mapper_opt::map_;
785 auto it = pivotToPosition.find(cellID);
786 if (it == pivotToPosition.end()) return; // cell does not exists. TODO: put an assert instead?
787 Pos_index startPos = it->second;
788 Index startIndex = pivotToColumnIndex_.at(cellID);
789
790 if (startPos != nextPosition_ - 1) {
791 std::vector<Index> colToSwap;
792 colToSwap.reserve(matrix_.size());
793
794 for (auto& p : pivotToPosition) {
795 if (p.second > startPos) colToSwap.push_back(pivotToColumnIndex_.at(p.first));
796 }
797 std::sort(colToSwap.begin(), colToSwap.end(), [&](Index c1, Index c2) {
798 return pivotToPosition.at(get_pivot(c1)) < pivotToPosition.at(get_pivot(c2));
799 });
800
801 for (Index i : colToSwap) {
802 startIndex = Swap_opt::vine_swap(startIndex, i);
803 }
804 }
805
806 _remove_last(startIndex);
807}
808
809template <class Master_matrix>
811 const std::vector<ID_index>& columnsToSwap)
812{
813 static_assert(Master_matrix::Option_list::has_removable_columns,
814 "'remove_maximal_cell' is not implemented for the chosen options.");
815 static_assert(Master_matrix::Option_list::has_map_column_container && Master_matrix::Option_list::has_vine_update,
816 "'remove_maximal_cell' is not implemented for the chosen options.");
817
818 // TODO: find simple test to verify that col at columnIndex is maximal even without row access.
819
820 Index startIndex = pivotToColumnIndex_.at(cellID);
821
822 for (ID_index i : columnsToSwap) {
823 startIndex = Swap_opt::vine_swap(startIndex, pivotToColumnIndex_.at(i));
824 }
825
826 _remove_last(startIndex);
827}
828
829template <class Master_matrix>
831{
832 static_assert(Master_matrix::Option_list::has_removable_columns,
833 "'remove_last' is not implemented for the chosen options.");
834 static_assert(Master_matrix::Option_list::has_map_column_container || !Master_matrix::Option_list::has_vine_update,
835 "'remove_last' is not implemented for the chosen options.");
836
837 if (nextIndex_ == 0 || matrix_.empty()) return; // empty matrix
838
839 if constexpr (Master_matrix::Option_list::has_vine_update) {
840 // careful: linear because of the search of the last index. It is better to keep track of the @ref IDIdx index
841 // of the last column while performing swaps (or the @ref MatIdx with the return values of `vine_swap` + get_pivot)
842 // and then call `remove_maximal_cell` with it and an empty `columnsToSwap`.
843
844 ID_index pivot = 0;
845 Index colIndex = 0;
846 for (auto& p : pivotToColumnIndex_) {
847 if (p.first > pivot) { // pivots have to be strictly increasing in order of filtration
848 pivot = p.first;
849 colIndex = p.second;
850 }
851 }
852 _remove_last(colIndex);
853 } else {
854 _remove_last(nextIndex_ - 1);
855 }
856}
857
858template <class Master_matrix>
860{
861 if constexpr (Master_matrix::Option_list::has_map_column_container) {
862 return matrix_.size();
863 } else {
864 return nextIndex_; // matrix could have been resized much bigger while insert
865 }
866}
867
868template <class Master_matrix>
870 Index columnIndex) const
871{
872 return get_column(columnIndex).get_dimension();
873}
874
875template <class Master_matrix>
876inline void Chain_matrix<Master_matrix>::add_to(Index sourceColumnIndex, Index targetColumnIndex)
877{
878 auto& col = get_column(targetColumnIndex);
879 _add_to(col, [&]() { col += get_column(sourceColumnIndex); });
880}
881
882template <class Master_matrix>
884 const Field_element& coefficient,
885 Index targetColumnIndex)
886{
887 auto& col = get_column(targetColumnIndex);
888 _add_to(col, [&]() { col.multiply_target_and_add(coefficient, get_column(sourceColumnIndex)); });
889}
890
891template <class Master_matrix>
893 Index sourceColumnIndex,
894 Index targetColumnIndex)
895{
896 auto& col = get_column(targetColumnIndex);
897 _add_to(col, [&]() { col.multiply_source_and_add(get_column(sourceColumnIndex), coefficient); });
898}
899
900template <class Master_matrix>
901inline bool Chain_matrix<Master_matrix>::is_zero_entry(Index columnIndex, ID_index rowIndex) const
902{
903 return !get_column(columnIndex).is_non_zero(rowIndex);
904}
905
906template <class Master_matrix>
908{
909 return get_column(columnIndex).is_empty();
910}
911
912template <class Master_matrix>
914 ID_index cellID) const
915{
916 if constexpr (Master_matrix::Option_list::has_map_column_container) {
917 return pivotToColumnIndex_.at(cellID);
918 } else {
919 return pivotToColumnIndex_[cellID];
920 }
921}
922
923template <class Master_matrix>
925{
926 return get_column(columnIndex).get_pivot();
927}
928
929template <class Master_matrix>
931{
932 if (this == &other) return *this;
933
934 Dim_opt::operator=(other);
935 Swap_opt::operator=(other);
936 Pair_opt::operator=(other);
937 Rep_opt::operator=(other);
938 Pivot_to_pos_mapper_opt::operator=(other);
939 matrix_.clear();
940 pivotToColumnIndex_ = other.pivotToColumnIndex_;
941 nextIndex_ = other.nextIndex_;
942 nextPosition_ = other.nextPosition_;
943 colSettings_ = other.colSettings_;
944
945 matrix_.reserve(other.matrix_.size());
946 for (const auto& cont : other.matrix_) {
947 _container_insert(cont);
948 }
949
950 return *this;
951}
952
953template <class Master_matrix>
955{
956 if (this == &other) return *this;
957
958 Dim_opt::operator=(std::move(other));
959 Pair_opt::operator=(std::move(other));
960 Swap_opt::operator=(std::move(other));
961 Rep_opt::operator=(std::move(other));
962 RA_opt::operator=(std::move(other));
963 Pivot_to_pos_mapper_opt::operator=(std::move(other));
964 matrix_ = std::move(other.matrix_);
965 pivotToColumnIndex_ = std::move(other.pivotToColumnIndex_);
966 nextIndex_ = std::exchange(other.nextIndex_, 0);
967 nextPosition_ = std::exchange(other.nextPosition_, 0);
968 colSettings_ = std::exchange(other.colSettings_, nullptr);
969
970 return *this;
971}
972
973template <class Master_matrix>
974inline void Chain_matrix<Master_matrix>::print() const
975{
976 std::cout << "Column Matrix:\n";
977 if constexpr (!Master_matrix::Option_list::has_map_column_container) {
978 for (ID_index i = 0; i < pivotToColumnIndex_.size(); ++i) {
979 Index pos = pivotToColumnIndex_[i];
980 if (pos != Master_matrix::template get_null_value<Index>()) {
981 const Column& col = matrix_[pos];
982 for (const auto& entry : col) {
983 std::cout << entry.get_row_index() << " ";
984 }
985 std::cout << "(" << i << ", " << pos << ")\n";
986 }
987 }
988 if constexpr (Master_matrix::Option_list::has_row_access) {
989 std::cout << "\n";
990 std::cout << "Row Matrix:\n";
991 for (ID_index i = 0; i < pivotToColumnIndex_.size(); ++i) {
992 Index pos = pivotToColumnIndex_[i];
993 if (pos != Master_matrix::template get_null_value<Index>()) {
994 const Row& row = RA_opt::get_row(pos);
995 for (const auto& entry : row) {
996 std::cout << entry.get_column_index() << " ";
997 }
998 std::cout << "(" << i << ", " << pos << ")\n";
999 }
1000 }
1001 }
1002 } else {
1003 for (const auto& p : pivotToColumnIndex_) {
1004 const Column& col = matrix_.at(p.second);
1005 for (const auto& entry : col) {
1006 std::cout << entry.get_row_index() << " ";
1007 }
1008 std::cout << "(" << p.first << ", " << p.second << ")\n";
1009 }
1010 if constexpr (Master_matrix::Option_list::has_row_access) {
1011 std::cout << "\n";
1012 std::cout << "Row Matrix:\n";
1013 for (const auto& p : pivotToColumnIndex_) {
1014 const Row& row = RA_opt::get_row(p.first);
1015 for (const auto& entry : row) {
1016 std::cout << entry.get_column_index() << " ";
1017 }
1018 std::cout << "(" << p.first << ", " << p.second << ")\n";
1019 }
1020 }
1021 }
1022 std::cout << "\n";
1023}
1024
1025template <class Master_matrix>
1026template <class Boundary_range>
1027inline std::vector<typename Master_matrix::Entry_representative>
1028Chain_matrix<Master_matrix>::_reduce_boundary(ID_index cellID, const Boundary_range& boundary, Dimension dim)
1029{
1030 Tmp_column column(boundary.begin(), boundary.end());
1031 if (dim == Master_matrix::template get_null_value<Dimension>())
1032 dim = boundary.begin() == boundary.end() ? 0 : boundary.size() - 1;
1033 std::vector<Entry_representative> chainsInH; // for corresponding indices in H (paired columns)
1034 std::vector<Entry_representative> chainsInF; // for corresponding indices in F (unpaired, essential columns)
1035
1036 auto get_last = [&column]() {
1037 if constexpr (Master_matrix::Option_list::is_z2)
1038 return *(column.rbegin());
1039 else
1040 return column.rbegin()->first;
1041 };
1042
1043 if (boundary.begin() == boundary.end()) {
1044 _insert_in(cellID, column);
1045 _insert_chain(column, dim);
1046 return chainsInF;
1047 }
1048
1049 Index currentIndex = get_column_with_pivot(get_last());
1050
1051 while (get_column(currentIndex).is_paired()) {
1052 _reduce_by_G(column, chainsInH, currentIndex);
1053
1054 if (column.empty()) {
1055 // produce the sum of all col_h in chains_in_H
1056 _build_from_H(cellID, column, chainsInH);
1057 // create a new cycle (in F) sigma - \sum col_h
1058 _insert_chain(column, dim);
1059 return chainsInF;
1060 }
1061
1062 currentIndex = get_column_with_pivot(get_last());
1063 }
1064
1065 while (!column.empty()) {
1066 currentIndex = get_column_with_pivot(get_last());
1067
1068 if (!get_column(currentIndex).is_paired()) {
1069 // only fills currentEssentialCycleIndices if Z2 coefficients, so chainsInF remains empty
1070 _reduce_by_F(column, chainsInF, currentIndex);
1071 } else {
1072 _reduce_by_G(column, chainsInH, currentIndex);
1073 }
1074 }
1075
1076 _update_largest_death_in_F(chainsInF);
1077
1078 // Compute the new column cellID + \sum col_h, for col_h in chains_in_H
1079 _build_from_H(cellID, column, chainsInH);
1080
1081 // Create and insert (\sum col_h) + sigma (in H, paired with chain_fp) in matrix_
1082 _insert_chain(column, dim, Master_matrix::get_row_index(chainsInF[0]));
1083
1084 return chainsInF;
1085}
1086
1087template <class Master_matrix>
1088inline void Chain_matrix<Master_matrix>::_reduce_by_G(Tmp_column& column,
1089 std::vector<Entry_representative>& chainsInH,
1090 Index currentIndex)
1091{
1092 Column& col = get_column(currentIndex);
1093 if constexpr (Master_matrix::Option_list::is_z2) {
1094 _add_to(col, column, 1U); // Reduce with the column col_g
1095 chainsInH.push_back(col.get_paired_chain_index()); // keep the col_h with which col_g is paired
1096 } else {
1097 Field_element coef = col.get_pivot_value();
1098 auto& operators = colSettings_->operators;
1099 coef = operators.get_inverse(coef);
1100 operators.multiply_inplace(coef, operators.get_characteristic() - column.rbegin()->second);
1101
1102 _add_to(col, column, coef); // Reduce with the column col_g
1103 chainsInH.emplace_back(col.get_paired_chain_index(), coef); // keep the col_h with which col_g is paired
1104 }
1105}
1106
1107template <class Master_matrix>
1108inline void Chain_matrix<Master_matrix>::_reduce_by_F(Tmp_column& column,
1109 std::vector<Entry_representative>& chainsInF,
1110 Index currentIndex)
1111{
1112 Column& col = get_column(currentIndex);
1113 if constexpr (Master_matrix::Option_list::is_z2) {
1114 _add_to(col, column, 1U); // Reduce with the column col_g
1115 chainsInF.push_back(currentIndex);
1116 } else {
1117 Field_element coef = col.get_pivot_value();
1118 auto& operators = colSettings_->operators;
1119 coef = operators.get_inverse(coef);
1120 operators.multiply_inplace(coef, operators.get_characteristic() - column.rbegin()->second);
1121
1122 _add_to(col, column, coef); // Reduce with the column col_g
1123 chainsInF.emplace_back(currentIndex, operators.get_characteristic() - coef);
1124 }
1125}
1126
1127template <class Master_matrix>
1128inline void Chain_matrix<Master_matrix>::_build_from_H(ID_index cellID,
1129 Tmp_column& column,
1130 std::vector<Entry_representative>& chainsInH)
1131{
1132 _insert_in(cellID, column);
1133
1134 for (const auto& idx_h : chainsInH) {
1135 _add_to(get_column(Master_matrix::get_row_index(idx_h)), column, Master_matrix::get_element(idx_h));
1136 }
1137}
1138
1139template <class Master_matrix>
1140inline void Chain_matrix<Master_matrix>::_update_largest_death_in_F(const std::vector<Entry_representative>& chainsInF)
1141{
1142 Index toUpdate = Master_matrix::get_row_index(chainsInF[0]);
1143 if constexpr (Master_matrix::Option_list::is_z2) {
1144 for (auto other_col_it = chainsInF.begin() + 1; other_col_it != chainsInF.end(); ++other_col_it) {
1145 add_to(*other_col_it, toUpdate);
1146 }
1147 } else {
1148 get_column(toUpdate) *= Master_matrix::get_element(chainsInF[0]);
1149 for (auto other_col_it = chainsInF.begin() + 1; other_col_it != chainsInF.end(); ++other_col_it) {
1150 multiply_source_and_add_to(
1151 Master_matrix::get_element(*other_col_it), Master_matrix::get_row_index(*other_col_it), toUpdate);
1152 }
1153 }
1154}
1155
1156template <class Master_matrix>
1157inline void Chain_matrix<Master_matrix>::_insert_chain(const Tmp_column& column, Dimension dimension)
1158{
1159 _container_insert(column, nextIndex_, dimension);
1160 _add_bar(dimension);
1161
1162 ++nextIndex_;
1163}
1164
1165template <class Master_matrix>
1166inline void Chain_matrix<Master_matrix>::_insert_chain(const Tmp_column& column, Dimension dimension, Index pair)
1167{
1168 // true when no vine updates and if nextIndex_ is updated in remove_last for special case of no vines
1169 // because then @ref PosIdx == @ref MatIdx
1170 Pos_index pairPos = pair;
1171
1172 _container_insert(column, nextIndex_, dimension);
1173
1174 get_column(nextIndex_).assign_paired_chain(pair);
1175 auto& pairCol = get_column(pair);
1176 pairCol.assign_paired_chain(nextIndex_);
1177
1178 if constexpr (Master_matrix::Option_list::has_column_pairings && Master_matrix::Option_list::has_vine_update) {
1179 pairPos = Pivot_to_pos_mapper_opt::map_[pairCol.get_pivot()];
1180 }
1181
1182 _update_barcode(pairPos);
1183
1184 ++nextIndex_;
1185}
1186
1187template <class Master_matrix>
1188inline void Chain_matrix<Master_matrix>::_add_to(const Column& column,
1189 Tmp_column& set,
1190 [[maybe_unused]] unsigned int coef)
1191{
1192 if constexpr (Master_matrix::Option_list::is_z2) {
1193 std::pair<typename std::set<Index>::iterator, bool> res_insert;
1194 for (const Entry& entry : column) {
1195 res_insert = set.insert(entry.get_row_index());
1196 if (!res_insert.second) {
1197 set.erase(res_insert.first);
1198 }
1199 }
1200 } else {
1201 auto& operators = colSettings_->operators;
1202 for (const Entry& entry : column) {
1203 auto res = set.emplace(entry.get_row_index(), entry.get_element());
1204 if (res.second) {
1205 operators.multiply_inplace(res.first->second, coef);
1206 } else {
1207 operators.multiply_and_add_inplace_back(entry.get_element(), coef, res.first->second);
1208 if (res.first->second == Field_operators::get_additive_identity()) {
1209 set.erase(res.first);
1210 }
1211 }
1212 }
1213 }
1214}
1215
1216template <class Master_matrix>
1217template <typename F>
1218inline void Chain_matrix<Master_matrix>::_add_to(Column& target, F&& addition)
1219{
1220 auto pivot = target.get_pivot();
1221 std::forward<F>(addition)();
1222
1223 if (pivot != target.get_pivot()) {
1224 if constexpr (Master_matrix::Option_list::has_map_column_container) {
1225 std::swap(pivotToColumnIndex_.at(pivot), pivotToColumnIndex_.at(target.get_pivot()));
1226 } else {
1227 std::swap(pivotToColumnIndex_[pivot], pivotToColumnIndex_[target.get_pivot()]);
1228 }
1229 }
1230}
1231
1232template <class Master_matrix>
1233inline void Chain_matrix<Master_matrix>::_remove_last(Index lastIndex)
1234{
1235 static_assert(Master_matrix::Option_list::has_removable_columns,
1236 "'_remove_last' is not implemented for the chosen options.");
1237 static_assert(Master_matrix::Option_list::has_map_column_container || !Master_matrix::Option_list::has_vine_update,
1238 "'_remove_last' is not implemented for the chosen options.");
1239
1240 ID_index pivot;
1241
1242 if constexpr (Master_matrix::Option_list::has_map_column_container) {
1243 auto itToErase = matrix_.find(lastIndex);
1244 Column& colToErase = itToErase->second;
1245 pivot = colToErase.get_pivot();
1246
1247 if constexpr (Master_matrix::Option_list::has_matrix_maximal_dimension_access) {
1248 Dim_opt::_update_down(colToErase.get_dimension());
1249 }
1250
1251 if (colToErase.is_paired()) matrix_.at(colToErase.get_paired_chain_index()).unassign_paired_chain();
1252 pivotToColumnIndex_.erase(pivot);
1253 matrix_.erase(itToErase);
1254 } else {
1255 GUDHI_CHECK(lastIndex == nextIndex_ - 1 && nextIndex_ == matrix_.size(),
1256 std::logic_error("Chain_matrix::_remove_last - Indexation problem."));
1257
1258 Column& colToErase = matrix_[lastIndex];
1259 pivot = colToErase.get_pivot();
1260
1261 if constexpr (Master_matrix::Option_list::has_matrix_maximal_dimension_access) {
1262 Dim_opt::_update_down(colToErase.get_dimension());
1263 }
1264
1265 if (colToErase.is_paired()) matrix_.at(colToErase.get_paired_chain_index()).unassign_paired_chain();
1266 pivotToColumnIndex_[pivot] = Master_matrix::template get_null_value<Index>();
1267 matrix_.pop_back();
1268 // TODO: resize matrix_ when a lot is removed? Could be not the best strategy if user inserts a lot back afterwards.
1269 }
1270
1271 if constexpr (!Master_matrix::Option_list::has_vine_update) {
1272 --nextIndex_; // should not be updated when there are vine updates, as possibly lastIndex != nextIndex - 1
1273 }
1274
1275 --nextPosition_;
1276 if constexpr (Master_matrix::Option_list::has_column_pairings) {
1277 Pair_opt::_erase_bar(nextPosition_);
1278 }
1279 if constexpr (hasPivotToPosMap_) {
1280 Pivot_to_pos_mapper_opt::map_.erase(pivot);
1281 }
1282
1283 if constexpr (Master_matrix::Option_list::has_row_access) {
1284 GUDHI_CHECK(
1285 RA_opt::get_row(pivot).size() == 0,
1286 std::invalid_argument(
1287 "Chain_matrix::_remove_last - Column asked to be removed does not corresponds to a maximal simplex."));
1288 if constexpr (Master_matrix::Option_list::has_removable_rows) {
1289 RA_opt::erase_empty_row(pivot);
1290 }
1291 }
1292}
1293
1294template <class Master_matrix>
1295inline void Chain_matrix<Master_matrix>::_update_barcode(Pos_index birth)
1296{
1297 if constexpr (Master_matrix::Option_list::has_column_pairings) {
1298 Pair_opt::_update_barcode(birth, nextPosition_);
1299 }
1300 ++nextPosition_;
1301}
1302
1303template <class Master_matrix>
1304inline void Chain_matrix<Master_matrix>::_add_bar(Dimension dim)
1305{
1306 if constexpr (Master_matrix::Option_list::has_column_pairings) {
1307 Pair_opt::_add_bar(dim, nextPosition_);
1308 }
1309 ++nextPosition_;
1310}
1311
1312template <class Master_matrix>
1313template <class Container>
1314inline void Chain_matrix<Master_matrix>::_container_insert(const Container& column, Index pos, Dimension dim)
1315{
1316 ID_index pivot = Master_matrix::get_row_index(*(column.rbegin()));
1317
1318 if constexpr (Master_matrix::Option_list::has_map_column_container) {
1319 pivotToColumnIndex_.try_emplace(pivot, pos);
1320 if constexpr (Master_matrix::Option_list::has_row_access) {
1321 matrix_.try_emplace(pos, Column(pos, column, dim, RA_opt::_get_rows_ptr(), colSettings_));
1322 } else {
1323 matrix_.try_emplace(pos, Column(column, dim, colSettings_));
1324 }
1325 } else {
1326 if constexpr (Master_matrix::Option_list::has_row_access) {
1327 matrix_.emplace_back(pos, column, dim, RA_opt::_get_rows_ptr(), colSettings_);
1328 } else {
1329 matrix_.emplace_back(column, dim, colSettings_);
1330 }
1331 pivotToColumnIndex_[pivot] = pos;
1332 }
1333}
1334
1335template <class Master_matrix>
1336template <class ColumnIterator> // Pair (pos,Column) if has_map_column_container, Column otherwise
1337inline void Chain_matrix<Master_matrix>::_container_insert(const ColumnIterator& rep)
1338{
1339 if constexpr (Master_matrix::Option_list::has_map_column_container) {
1340 const auto& col = rep.second;
1341 if constexpr (Master_matrix::Option_list::has_row_access) {
1342 matrix_.try_emplace(rep.first, Column(col, col.get_column_index(), RA_opt::_get_rows_ptr(), colSettings_));
1343 } else {
1344 matrix_.try_emplace(rep.first, Column(col, colSettings_));
1345 }
1346 } else {
1347 if constexpr (Master_matrix::Option_list::has_row_access) {
1348 matrix_.emplace_back(rep, rep.get_column_index(), RA_opt::_get_rows_ptr(), colSettings_);
1349 } else {
1350 matrix_.emplace_back(rep, colSettings_);
1351 }
1352 }
1353}
1354
1355template <class Master_matrix>
1356inline void Chain_matrix<Master_matrix>::_insert_in(ID_index cellID, Tmp_column& column)
1357{
1358 if constexpr (Master_matrix::Option_list::is_z2)
1359 column.insert(cellID);
1360 else
1361 column.emplace(cellID, 1);
1362}
1363
1364} // namespace persistence_matrix
1365} // namespace Gudhi
1366
1367#endif // PM_CHAIN_MATRIX_H
Contains the Gudhi::persistence_matrix::Id_to_index_overlay class.
Matrix structure storing a compatible base of a filtered chain complex. See zigzag....
Definition Chain_matrix.h:57
void remove_maximal_cell(ID_index cellID)
Only available if PersistenceMatrixOptions::has_removable_columns and PersistenceMatrixOptions::has_v...
Definition Chain_matrix.h:774
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:567
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:679
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....
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:753
void reset(Column_settings *colSettings)
Resets the matrix to an empty matrix.
Definition Chain_matrix.h:465
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:810
typename Matrix< PersistenceMatrixOptions >::Index Index
Definition Chain_matrix.h:89
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:892
typename Matrix< PersistenceMatrixOptions >::Pos_index Pos_index
Definition Chain_matrix.h:91
bool is_zero_entry(Index columnIndex, ID_index rowIndex) const
Indicates if the entry at given coordinates has value zero.
Definition Chain_matrix.h:901
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:656
Chain_matrix(Chain_matrix &&other) noexcept
Move constructor.
Definition Chain_matrix.h:698
typename Matrix< PersistenceMatrixOptions >::Entry_constructor Entry_constructor
Definition Chain_matrix.h:84
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:883
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:913
Chain_matrix & operator=(Chain_matrix &&other) noexcept
Move assign operator.
Definition Chain_matrix.h:954
Chain_matrix(Column_settings *colSettings)
Constructs an empty matrix. Only available if PersistenceMatrixOptions::has_column_pairings is true o...
Definition Chain_matrix.h:553
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:592
typename Matrix< PersistenceMatrixOptions >::Row Row
Definition Chain_matrix.h:81
typename Matrix< PersistenceMatrixOptions >::Field_operators Field_operators
Definition Chain_matrix.h:78
typename Matrix< PersistenceMatrixOptions >::Element Field_element
Definition Chain_matrix.h:79
void add_to(Index sourceColumnIndex, Index targetColumnIndex)
Adds column at sourceColumnIndex onto the column at targetColumnIndex in the matrix.
Definition Chain_matrix.h:876
ID_index get_pivot(Index columnIndex)
Returns the row index of the pivot of the given column.
Definition Chain_matrix.h:924
typename Matrix< PersistenceMatrixOptions >::Entry_representative Entry_representative
Definition Chain_matrix.h:88
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:907
Chain_matrix(Column_settings *colSettings, const BirthComparatorFunction &birthComparator, const DeathComparatorFunction &deathComparator)
Constructs an empty matrix and stores the given comparators.
Definition Chain_matrix.h:613
Index get_number_of_columns() const
Returns the current number of columns in the matrix.
Definition Chain_matrix.h:859
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:629
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:869
void remove_last()
Only available if PersistenceMatrixOptions::has_removable_columns is true and, if PersistenceMatrixOp...
Definition Chain_matrix.h:830
friend void swap(Chain_matrix &matrix1, Chain_matrix &matrix2) noexcept
Swap operator.
Definition Chain_matrix.h:490
typename Matrix< PersistenceMatrixOptions >::ID_index ID_index
Definition Chain_matrix.h:90
typename Matrix< PersistenceMatrixOptions >::Column Column
Definition Chain_matrix.h:80
typename Matrix< PersistenceMatrixOptions >::Matrix_entry Entry
Definition Chain_matrix.h:83
typename Matrix< PersistenceMatrixOptions >::Dimension Dimension
Definition Chain_matrix.h:92
Chain_matrix & operator=(const Chain_matrix &other)
Assign operator.
Definition Chain_matrix.h:930
typename Matrix< PersistenceMatrixOptions >::Boundary Boundary
Definition Chain_matrix.h:87
typename Matrix< PersistenceMatrixOptions >::Column_settings Column_settings
Definition Chain_matrix.h:85
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:763
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:42
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)
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)
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