Loading...
Searching...
No Matches
Position_to_index_overlay.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_POS_TO_ID_TRANSLATION_H
18#define PM_POS_TO_ID_TRANSLATION_H
19
20#include <stdexcept>
21#include <vector>
22#include <utility> //std::swap, std::move & std::exchange
23#include <algorithm> //std::transform
24
25#include <gudhi/Debug_utils.h>
26
27namespace Gudhi {
28namespace persistence_matrix {
29
41template <class Underlying_matrix, class Master_matrix>
43{
44 public:
45 using Index = typename Master_matrix::Index;
46 using ID_index = typename Master_matrix::ID_index;
47 using Pos_index = typename Master_matrix::Pos_index;
48 using Dimension = typename Master_matrix::Dimension;
52 using Field_operators = typename Master_matrix::Field_operators;
53 using Field_element = typename Master_matrix::Element;
54 using Boundary = typename Master_matrix::Boundary;
55 using Column = typename Master_matrix::Column;
56 using Row = typename Master_matrix::Row;
58 using Bar = typename Master_matrix::Bar;
59 using Barcode = typename Master_matrix::Barcode;
60 using Cycle = typename Master_matrix::Cycle;
61 using Entry_representative = typename Master_matrix::Entry_representative;
62 using Entry_constructor = typename Master_matrix::Entry_constructor;
63 using Column_settings = typename Master_matrix::Column_settings;
65
94 template <class Boundary_range = Boundary>
95 Position_to_index_overlay(const std::vector<Boundary_range>& orderedBoundaries, Column_settings* colSettings);
103 Position_to_index_overlay(unsigned int numberOfColumns, Column_settings* colSettings);
126 template <typename BirthComparatorFunction, typename DeathComparatorFunction>
128 const BirthComparatorFunction& birthComparator,
129 const DeathComparatorFunction& deathComparator);
166 template <typename BirthComparatorFunction, typename DeathComparatorFunction, class Boundary_range>
167 Position_to_index_overlay(const std::vector<Boundary_range>& orderedBoundaries,
168 Column_settings* colSettings,
169 const BirthComparatorFunction& birthComparator,
170 const DeathComparatorFunction& deathComparator);
194 template <typename BirthComparatorFunction, typename DeathComparatorFunction>
195 Position_to_index_overlay(unsigned int numberOfColumns,
196 Column_settings* colSettings,
197 const BirthComparatorFunction& birthComparator,
198 const DeathComparatorFunction& deathComparator);
208 Position_to_index_overlay(const Position_to_index_overlay& matrixToCopy, Column_settings* colSettings = nullptr);
215
216 ~Position_to_index_overlay() = default;
217
238 template <class Boundary_range = Boundary>
239 void insert_boundary(const Boundary_range& boundary,
240 Dimension dim = Master_matrix::template get_null_value<Dimension>());
258 template <class Boundary_range = Boundary>
259 void insert_boundary(ID_index cellIndex,
260 const Boundary_range& boundary,
261 Dimension dim = Master_matrix::template get_null_value<Dimension>());
275 template <class Boundary_range = Boundary>
276 void insert_maximal_cell(Index columnIndex,
277 const Boundary_range& boundary,
278 Dimension dim = Master_matrix::template get_null_value<Dimension>());
295 template <class Boundary_range = Boundary>
296 void insert_maximal_cell(Index columnIndex,
297 ID_index cellIndex,
298 const Boundary_range& boundary,
299 Dimension dim = Master_matrix::template get_null_value<Dimension>());
300
308 Column& get_column(Pos_index position);
316 const Column& get_column(Pos_index position) const;
325 Row& get_row(ID_index rowIndex);
334 const Row& get_row(ID_index rowIndex) const;
349 void erase_empty_row(ID_index rowIndex);
363 void remove_maximal_cell(Pos_index position);
372 void remove_last();
373
394
405 void add_to(Pos_index sourcePosition, Pos_index targetPosition);
418 void multiply_target_and_add_to(Pos_index sourcePosition, const Field_element& coefficient, Pos_index targetPosition);
431 void multiply_source_and_add_to(const Field_element& coefficient, Pos_index sourcePosition, Pos_index targetPosition);
432
441 bool is_zero_entry(Pos_index position, ID_index rowIndex) const;
452 bool is_zero_column(Pos_index position);
453
461 Pos_index get_column_with_pivot(ID_index cellIndex) const; // assumes that pivot exists
468 ID_index get_pivot(Pos_index position);
469
476 void reset(Column_settings* colSettings)
477 {
478 matrix_.reset(colSettings);
479 positionToIndex_.clear();
480 nextPosition_ = 0;
481 nextIndex_ = 0;
482 }
483
492
496 friend void swap(Position_to_index_overlay& matrix1, Position_to_index_overlay& matrix2) noexcept
497 {
498 swap(matrix1.matrix_, matrix2.matrix_);
499 matrix1.positionToIndex_.swap(matrix2.positionToIndex_);
500 std::swap(matrix1.nextPosition_, matrix2.nextPosition_);
501 std::swap(matrix1.nextIndex_, matrix2.nextIndex_);
502 }
503
504 void print(); // for debug
505
506 // access to optional methods
507
517 const Barcode& get_current_barcode() const;
518
528 void update_all_representative_cycles(Dimension dim = Master_matrix::template get_null_value<Dimension>());
537 void update_representative_cycle(const Bar& bar);
544 const std::vector<Cycle>& get_all_representative_cycles() const;
552 const Cycle& get_representative_cycle(const Bar& bar) const;
553
577 bool vine_swap(Pos_index position);
578
579 private:
580 Underlying_matrix matrix_;
581 std::vector<Index> positionToIndex_;
582 Pos_index nextPosition_;
583 Index nextIndex_;
584
585 template <bool dir>
586 void _move_column(Pos_index start, Pos_index end);
587};
588
589template <class Underlying_matrix, class Master_matrix>
591 Column_settings* colSettings)
592 : matrix_(colSettings), nextPosition_(0), nextIndex_(0)
593{}
594
595template <class Underlying_matrix, class Master_matrix>
596template <class Boundary_range>
598 const std::vector<Boundary_range>& orderedBoundaries,
599 Column_settings* colSettings)
600 : matrix_(orderedBoundaries, colSettings),
601 positionToIndex_(orderedBoundaries.size()),
602 nextPosition_(orderedBoundaries.size()),
603 nextIndex_(orderedBoundaries.size())
604{
605 for (Index i = 0; i < orderedBoundaries.size(); i++) {
606 positionToIndex_[i] = i;
607 }
608}
609
610template <class Underlying_matrix, class Master_matrix>
612 unsigned int numberOfColumns,
613 Column_settings* colSettings)
614 : matrix_(numberOfColumns, colSettings), positionToIndex_(numberOfColumns), nextPosition_(0), nextIndex_(0)
615{}
616
617template <class Underlying_matrix, class Master_matrix>
618template <typename BirthComparatorFunction, typename DeathComparatorFunction>
620 Column_settings* colSettings,
621 const BirthComparatorFunction& birthComparator,
622 const DeathComparatorFunction& deathComparator)
623 : matrix_(colSettings, birthComparator, deathComparator), nextPosition_(0), nextIndex_(0)
624{}
625
626template <class Underlying_matrix, class Master_matrix>
627template <typename BirthComparatorFunction, typename DeathComparatorFunction, class Boundary_range>
629 const std::vector<Boundary_range>& orderedBoundaries,
630 Column_settings* colSettings,
631 const BirthComparatorFunction& birthComparator,
632 const DeathComparatorFunction& deathComparator)
633 : matrix_(orderedBoundaries, colSettings, birthComparator, deathComparator),
634 positionToIndex_(orderedBoundaries.size()),
635 nextPosition_(orderedBoundaries.size()),
636 nextIndex_(orderedBoundaries.size())
637{
638 for (Index i = 0; i < orderedBoundaries.size(); i++) {
639 positionToIndex_[i] = i;
640 }
641}
642
643template <class Underlying_matrix, class Master_matrix>
644template <typename BirthComparatorFunction, typename DeathComparatorFunction>
646 unsigned int numberOfColumns,
647 Column_settings* colSettings,
648 const BirthComparatorFunction& birthComparator,
649 const DeathComparatorFunction& deathComparator)
650 : matrix_(numberOfColumns, colSettings, birthComparator, deathComparator),
651 positionToIndex_(numberOfColumns),
652 nextPosition_(0),
653 nextIndex_(0)
654{}
655
656template <class Underlying_matrix, class Master_matrix>
658 const Position_to_index_overlay& matrixToCopy,
659 Column_settings* colSettings)
660 : matrix_(matrixToCopy.matrix_, colSettings),
661 positionToIndex_(matrixToCopy.positionToIndex_),
662 nextPosition_(matrixToCopy.nextPosition_),
663 nextIndex_(matrixToCopy.nextIndex_)
664{}
665
666template <class Underlying_matrix, class Master_matrix>
668 Position_to_index_overlay&& other) noexcept
669 : matrix_(std::move(other.matrix_)),
670 positionToIndex_(std::move(other.positionToIndex_)),
671 nextPosition_(std::exchange(other.nextPosition_, 0)),
672 nextIndex_(std::exchange(other.nextIndex_, 0))
673{}
674
675template <class Underlying_matrix, class Master_matrix>
676template <class Boundary_range>
678 Dimension dim)
679{
680 if (positionToIndex_.size() <= nextPosition_) {
681 positionToIndex_.resize((nextPosition_ * 2) + 1);
682 }
683
684 positionToIndex_[nextPosition_++] = nextIndex_++;
685
686 matrix_.insert_boundary(boundary, dim);
687}
688
689template <class Underlying_matrix, class Master_matrix>
690template <class Boundary_range>
692 const Boundary_range& boundary,
693 Dimension dim)
694{
695 if (positionToIndex_.size() <= nextPosition_) {
696 positionToIndex_.resize((nextPosition_ * 2) + 1);
697 }
698
699 positionToIndex_[nextPosition_++] = nextIndex_++;
700
701 matrix_.insert_boundary(cellIndex, boundary, dim);
702}
703
704template <class Underlying_matrix, class Master_matrix>
705template <class Boundary_range>
707 Index columnIndex,
708 const Boundary_range& boundary,
709 Dimension dim)
710{
711 GUDHI_CHECK(columnIndex >= 0, std::invalid_argument("Indices have to be positive."));
712
713 insert_boundary(boundary, dim);
714
715 if (nextPosition_ == 1) return;
716
717 // false = backward direction
718 _move_column<false>(nextPosition_ - 1, columnIndex);
719}
720
721template <class Underlying_matrix, class Master_matrix>
722template <class Boundary_range>
724 Index columnIndex,
725 ID_index cellIndex,
726 const Boundary_range& boundary,
727 Dimension dim)
728{
729 GUDHI_CHECK(columnIndex >= 0, std::invalid_argument("Indices have to be positive."));
730
731 insert_boundary(cellIndex, boundary, dim);
732
733 if (nextPosition_ == 1) return;
734
735 // false = backward direction
736 _move_column<false>(nextPosition_ - 1, columnIndex);
737}
738
739template <class Underlying_matrix, class Master_matrix>
742{
743 return matrix_.get_column(positionToIndex_[position]);
744}
745
746template <class Underlying_matrix, class Master_matrix>
749{
750 return matrix_.get_column(positionToIndex_[position]);
751}
752
753template <class Underlying_matrix, class Master_matrix>
756{
757 return matrix_.get_row(rowIndex);
758}
759
760template <class Underlying_matrix, class Master_matrix>
763{
764 return matrix_.get_row(rowIndex);
765}
766
767template <class Underlying_matrix, class Master_matrix>
769{
770 return matrix_.erase_empty_row(rowIndex);
771}
772
773template <class Underlying_matrix, class Master_matrix>
775{
776 --nextPosition_;
777
778 // true = forward direction
779 _move_column<true>(position, nextPosition_);
780
781 matrix_._remove_last(positionToIndex_[nextPosition_]);
782}
783
784template <class Underlying_matrix, class Master_matrix>
786{
787 --nextPosition_;
788 if constexpr (Master_matrix::Option_list::has_vine_update) {
789 std::vector<Index> columnsToSwap;
790 matrix_.remove_maximal_cell(matrix_.get_pivot(positionToIndex_[nextPosition_]), columnsToSwap);
791 } else {
792 matrix_.remove_last(); // linear with vine updates, so it is better to use remove_maximal_cell
793 }
794}
795
796template <class Underlying_matrix, class Master_matrix>
799{
800 return matrix_.get_max_dimension();
801}
802
803template <class Underlying_matrix, class Master_matrix>
806{
807 return matrix_.get_number_of_columns();
808}
809
810template <class Underlying_matrix, class Master_matrix>
813{
814 return matrix_.get_column_dimension(positionToIndex_[position]);
815}
816
817template <class Underlying_matrix, class Master_matrix>
819 Pos_index targetPosition)
820{
821 return matrix_.add_to(positionToIndex_[sourcePosition], positionToIndex_[targetPosition]);
822}
823
824template <class Underlying_matrix, class Master_matrix>
826 Pos_index sourcePosition,
827 const Field_element& coefficient,
828 Pos_index targetPosition)
829{
830 return matrix_.multiply_target_and_add_to(
831 positionToIndex_[sourcePosition], coefficient, positionToIndex_[targetPosition]);
832}
833
834template <class Underlying_matrix, class Master_matrix>
836 const Field_element& coefficient,
837 Pos_index sourcePosition,
838 Pos_index targetPosition)
839{
840 return matrix_.multiply_source_and_add_to(
841 coefficient, positionToIndex_[sourcePosition], positionToIndex_[targetPosition]);
842}
843
844template <class Underlying_matrix, class Master_matrix>
846 ID_index rowIndex) const
847{
848 return matrix_.is_zero_entry(positionToIndex_[position], rowIndex);
849}
850
851template <class Underlying_matrix, class Master_matrix>
853{
854 return matrix_.is_zero_column(positionToIndex_[position]);
855}
856
857template <class Underlying_matrix, class Master_matrix>
860{
861 Index id = matrix_.get_column_with_pivot(cellIndex);
862 Pos_index i = 0;
863 while (positionToIndex_[i] != id) ++i;
864 return i;
865}
866
867template <class Underlying_matrix, class Master_matrix>
870{
871 return matrix_.get_pivot(positionToIndex_[position]);
872}
873
874template <class Underlying_matrix, class Master_matrix>
875inline void Position_to_index_overlay<Underlying_matrix, Master_matrix>::print()
876{
877 return matrix_.print();
878}
879
880template <class Underlying_matrix, class Master_matrix>
883{
884 return matrix_.get_current_barcode();
885}
886
887template <class Underlying_matrix, class Master_matrix>
889{
890 matrix_.update_all_representative_cycles(dim);
891}
892
893template <class Underlying_matrix, class Master_matrix>
895{
896 matrix_.update_representative_cycle(bar);
897}
898
899template <class Underlying_matrix, class Master_matrix>
900inline const std::vector<typename Position_to_index_overlay<Underlying_matrix, Master_matrix>::Cycle>&
902{
903 return matrix_.get_all_representative_cycles();
904}
905
906template <class Underlying_matrix, class Master_matrix>
909{
910 return matrix_.get_representative_cycle(bar);
911}
912
913template <class Underlying_matrix, class Master_matrix>
915{
916 Index next = matrix_.vine_swap_with_z_eq_1_case(positionToIndex_[position], positionToIndex_[position + 1]);
917 if (next == positionToIndex_[position]) {
918 std::swap(positionToIndex_[position], positionToIndex_[position + 1]);
919 return true;
920 }
921
922 return false;
923}
924
925template <class Underlying_matrix, class Master_matrix>
927{
928 Index next = matrix_.vine_swap(positionToIndex_[position], positionToIndex_[position + 1]);
929 if (next == positionToIndex_[position]) {
930 std::swap(positionToIndex_[position], positionToIndex_[position + 1]);
931 return true;
932 }
933
934 return false;
935}
936
937template <class Underlying_matrix, class Master_matrix>
938template <bool dir>
939inline void Position_to_index_overlay<Underlying_matrix, Master_matrix>::_move_column(Pos_index start, Pos_index end)
940{
941 if constexpr (dir) {
942 for (Pos_index p = start; p < end; ++p) {
943 vine_swap(p);
944 }
945 } else {
946 for (Pos_index p = start; p > end; --p) {
947 vine_swap(p - 1);
948 }
949 }
950}
951
952} // namespace persistence_matrix
953} // namespace Gudhi
954
955#endif // PM_POS_TO_ID_TRANSLATION_H
bool is_zero_entry(Pos_index position, ID_index rowIndex) const
Indicates if the entry at given coordinates has value zero.
Definition Position_to_index_overlay.h:845
typename Master_matrix::Index Index
Definition Position_to_index_overlay.h:45
typename Master_matrix::Row Row
Definition Position_to_index_overlay.h:56
Index get_number_of_columns() const
Returns the current number of columns in the matrix.
Definition Position_to_index_overlay.h:805
typename Master_matrix::Entry_representative Entry_representative
Definition Position_to_index_overlay.h:61
Dimension get_column_dimension(Pos_index position) const
Returns the dimension of the given cell.
Definition Position_to_index_overlay.h:812
typename Master_matrix::Cycle Cycle
Definition Position_to_index_overlay.h:60
const Cycle & get_representative_cycle(const Bar &bar) const
Only available if PersistenceMatrixOptions::can_retrieve_representative_cycles is true....
Definition Position_to_index_overlay.h:908
void update_all_representative_cycles(Dimension dim=Master_matrix::template get_null_value< Dimension >())
Only available if PersistenceMatrixOptions::can_retrieve_representative_cycles is true....
Definition Position_to_index_overlay.h:888
Dimension get_max_dimension() const
Returns the maximal dimension of a cell stored in the matrix. Only available if PersistenceMatrixOpti...
Definition Position_to_index_overlay.h:798
typename Master_matrix::Field_operators Field_operators
Field operators class. Necessary only if PersistenceMatrixOptions::is_z2 is false.
Definition Position_to_index_overlay.h:52
typename Master_matrix::Element Field_element
Definition Position_to_index_overlay.h:53
friend void swap(Position_to_index_overlay &matrix1, Position_to_index_overlay &matrix2) noexcept
Swap operator.
Definition Position_to_index_overlay.h:496
void insert_boundary(const Boundary_range &boundary, Dimension dim=Master_matrix::template get_null_value< Dimension >())
Inserts at the end of the matrix a new ordered column corresponding to the given boundary....
Definition Position_to_index_overlay.h:677
void erase_empty_row(ID_index rowIndex)
Only available if PersistenceMatrixOptions::has_row_access and PersistenceMatrixOptions::has_removabl...
Definition Position_to_index_overlay.h:768
const Barcode & get_current_barcode() const
Returns the current barcode of the matrix. Available only if PersistenceMatrixOptions::has_column_pai...
Definition Position_to_index_overlay.h:882
typename Master_matrix::Barcode Barcode
Definition Position_to_index_overlay.h:59
Position_to_index_overlay & operator=(Position_to_index_overlay &&other) noexcept=default
Move assign operator.
bool is_zero_column(Pos_index position)
Indicates if the column at given index has value zero.
Definition Position_to_index_overlay.h:852
void update_representative_cycle(const Bar &bar)
Only available if PersistenceMatrixOptions::can_retrieve_representative_cycles is true....
Definition Position_to_index_overlay.h:894
void multiply_target_and_add_to(Pos_index sourcePosition, const Field_element &coefficient, Pos_index targetPosition)
Multiplies the target column with the coefficient and then adds the source column to it....
Definition Position_to_index_overlay.h:825
typename Master_matrix::Pos_index Pos_index
Definition Position_to_index_overlay.h:47
Position_to_index_overlay(Column_settings *colSettings)
Constructs an empty matrix.
Definition Position_to_index_overlay.h:590
ID_index get_pivot(Pos_index position)
Returns the row index of the pivot of the given column.
Definition Position_to_index_overlay.h:869
typename Master_matrix::ID_index ID_index
Definition Position_to_index_overlay.h:46
void add_to(Pos_index sourcePosition, Pos_index targetPosition)
Adds column corresponding to sourcePosition onto the column corresponding to targetPosition.
Definition Position_to_index_overlay.h:818
void remove_maximal_cell(Pos_index position)
Only available if PersistenceMatrixOptions::has_removable_columns, PersistenceMatrixOptions::has_vine...
Definition Position_to_index_overlay.h:774
Position_to_index_overlay & operator=(const Position_to_index_overlay &other)=default
Assign operator.
void reset(Column_settings *colSettings)
Resets the matrix to an empty matrix.
Definition Position_to_index_overlay.h:476
typename Master_matrix::Column_settings Column_settings
Definition Position_to_index_overlay.h:63
void remove_last()
Only available if PersistenceMatrixOptions::has_removable_columns is true and, if PersistenceMatrixOp...
Definition Position_to_index_overlay.h:785
void insert_maximal_cell(Index columnIndex, const Boundary_range &boundary, Dimension dim=Master_matrix::template get_null_value< Dimension >())
Only available if PersistenceMatrixOptions::has_vine_update is true. Assumes that the cell will be ma...
Definition Position_to_index_overlay.h:706
Row & get_row(ID_index rowIndex)
Only available if PersistenceMatrixOptions::has_row_access is true. Returns the row at the given row ...
Definition Position_to_index_overlay.h:755
typename Master_matrix::Entry_constructor Entry_constructor
Definition Position_to_index_overlay.h:62
typename Master_matrix::Bar Bar
Definition Position_to_index_overlay.h:58
typename Master_matrix::Dimension Dimension
Definition Position_to_index_overlay.h:48
typename Master_matrix::Column Column
Definition Position_to_index_overlay.h:55
typename Master_matrix::Boundary Boundary
Definition Position_to_index_overlay.h:54
void multiply_source_and_add_to(const Field_element &coefficient, Pos_index sourcePosition, Pos_index targetPosition)
Multiplies the source column with the coefficient before adding it to the target column....
Definition Position_to_index_overlay.h:835
Column & get_column(Pos_index position)
Returns the column at the given PosIdx index. The type of the column depends on the chosen options,...
Definition Position_to_index_overlay.h:741
Pos_index get_column_with_pivot(ID_index cellIndex) const
Returns the PosIdx index of the column which has the given row index as pivot. Assumes that the pivot...
Definition Position_to_index_overlay.h:859
bool vine_swap_with_z_eq_1_case(Pos_index position)
Only available if PersistenceMatrixOptions::has_vine_update is true. Does the same than vine_swap,...
Definition Position_to_index_overlay.h:914
bool vine_swap(Pos_index position)
Only available if PersistenceMatrixOptions::has_vine_update is true. Does a vine swap between two cel...
Definition Position_to_index_overlay.h:926
const std::vector< Cycle > & get_all_representative_cycles() const
Only available if PersistenceMatrixOptions::can_retrieve_representative_cycles is true....
Definition Position_to_index_overlay.h:901
Persistence matrix namespace.
Definition FieldOperators.h:18
Gudhi namespace.
Definition SimplicialComplexForAlpha.h:14