20#ifndef PM_CHAIN_VINE_SWAP_H 
   21#define PM_CHAIN_VINE_SWAP_H 
   31namespace persistence_matrix {
 
   44                                      [[maybe_unused]] 
unsigned int columnIndex2)
 
   60  template <
typename BirthComparatorFunction, 
typename DeathComparatorFunction>
 
   62                        [[maybe_unused]] 
const DeathComparatorFunction& deathComparator) {}
 
   83template <
typename Master_matrix>
 
   87  using ID_index = 
typename Master_matrix::ID_index;    
 
   88  using Pos_index = 
typename Master_matrix::Pos_index;  
 
  102      : 
CP(static_cast<const 
CP&>(toCopy)), pivotToPosition_(toCopy.pivotToPosition_){};
 
  109      : 
CP(
std::move(static_cast<
CP&>(other))), pivotToPosition_(
std::move(other.pivotToPosition_)){};
 
  112  using Dictionary = 
typename Master_matrix::template Dictionary<Pos_index>;
 
  114  Dictionary pivotToPosition_;  
 
  117    if constexpr (Master_matrix::Option_list::has_map_column_container) {
 
  118      std::swap(pivotToPosition_.at(pivot1), pivotToPosition_.at(pivot2));
 
  120      std::swap(pivotToPosition_[pivot1], pivotToPosition_[pivot2]);
 
  124  bool is_negative_in_pair(
ID_index pivot)
 const {
 
  125    Pos_index pos = _get_pivot_position(pivot);
 
  126    return death(pivot) == pos;
 
  130    Pos_index pos1 = _get_pivot_position(pivot1);
 
  131    Pos_index pos2 = _get_pivot_position(pivot2);
 
  135    std::swap(CP::indexToBar_.at(pos1), CP::indexToBar_.at(pos2));
 
  139    Pos_index pos1 = _get_pivot_position(pivot1);
 
  140    Pos_index pos2 = _get_pivot_position(pivot2);
 
  144    std::swap(CP::indexToBar_.at(pos1), CP::indexToBar_.at(pos2));
 
  148    Pos_index pos1 = _get_pivot_position(pivot1);
 
  149    Pos_index pos2 = _get_pivot_position(pivot2);
 
  153    std::swap(CP::indexToBar_.at(pos1), CP::indexToBar_.at(pos2));
 
  157    Pos_index pos1 = _get_pivot_position(pivot1);
 
  158    Pos_index pos2 = _get_pivot_position(pivot2);
 
  162    std::swap(CP::indexToBar_.at(pos1), CP::indexToBar_.at(pos2));
 
  166    Pos_index pos1 = _get_pivot_position(pivot1);
 
  167    Pos_index pos2 = _get_pivot_position(pivot2);
 
  168    return pos1 < pos2 ? (pos2 - pos1) == 1 : (pos1 - pos2) == 1;
 
  173    pivotToPosition_.swap(other.pivotToPosition_);
 
  176    swap(
static_cast<Chain_pairing<Master_matrix>&
>(swap1), 
static_cast<Chain_pairing<Master_matrix>&
>(swap2));
 
  177    swap1.pivotToPosition_.swap(swap2.pivotToPosition_);
 
  181    Pos_index simplexIndex = _get_pivot_position(pivot);
 
  183    if constexpr (Master_matrix::Option_list::has_removable_columns) {
 
  184      return CP::indexToBar_.at(simplexIndex)->death;
 
  186      return CP::barcode_.at(CP::indexToBar_.at(simplexIndex)).death;
 
  191    Pos_index simplexIndex = _get_pivot_position(pivot);
 
  193    if constexpr (Master_matrix::Option_list::has_removable_columns) {
 
  194      return CP::indexToBar_.at(simplexIndex)->birth;
 
  196      return CP::barcode_.at(CP::indexToBar_.at(simplexIndex)).birth;
 
  202    if constexpr (Master_matrix::Option_list::has_map_column_container) {
 
  203      return pivotToPosition_.at(
 
  206      return pivotToPosition_[pivot];
 
  211    if constexpr (Master_matrix::Option_list::has_removable_columns) {
 
  212      return CP::indexToBar_.at(simplexIndex)->death;
 
  214      return CP::barcode_.at(CP::indexToBar_.at(simplexIndex)).death;
 
  219    if constexpr (Master_matrix::Option_list::has_removable_columns) {
 
  220      return CP::indexToBar_.at(simplexIndex)->birth;
 
  222      return CP::barcode_.at(CP::indexToBar_.at(simplexIndex)).birth;
 
  235template <
class Master_matrix>
 
  236class Chain_vine_swap : 
public std::conditional<Master_matrix::Option_list::has_column_pairings,
 
  237                                                Chain_barcode_swap<Master_matrix>,
 
  238                                                Dummy_chain_vine_pairing
 
  242  using Index = 
typename Master_matrix::Index;                        
 
  246  using Column = 
typename Master_matrix::Column;                      
 
  316    if constexpr (Master_matrix::Option_list::has_column_pairings) {
 
  320    std::swap(swap1.birthComp_, swap2.birthComp_);
 
  321    std::swap(swap1.deathComp_, swap2.deathComp_);
 
  325  using CP = 
typename std::conditional<Master_matrix::Option_list::has_column_pairings,
 
  331  using Master_chain_matrix = 
typename Master_matrix::Master_chain_matrix;
 
  336  bool _is_negative_in_pair(Index columnIndex);
 
  338  Index _positive_vine_swap(Index columnIndex1, Index columnIndex2);
 
  339  Index _positive_negative_vine_swap(Index columnIndex1, Index columnIndex2);
 
  340  Index _negative_positive_vine_swap(Index columnIndex1, Index columnIndex2);
 
  341  Index _negative_vine_swap(Index columnIndex1, Index columnIndex2);
 
  343  constexpr Master_chain_matrix* _matrix() { 
return static_cast<Master_chain_matrix*
>(
this); }
 
  344  constexpr const Master_chain_matrix* _matrix()
 const { 
return static_cast<const Master_chain_matrix*
>(
this); }
 
  347template <
class Master_matrix>
 
  350  static_assert(Master_matrix::Option_list::has_column_pairings,
 
  351                "If barcode is not stored, at least a birth comparator has to be specified.");
 
  354template <
class Master_matrix>
 
  357    : CP(), birthComp_(
std::move(birthComparator)), deathComp_(
std::move(deathComparator))
 
  360template <
class Master_matrix>
 
  362    : CP(static_cast<const CP&>(matrixToCopy)),
 
  363      birthComp_(matrixToCopy.birthComp_),
 
  364      deathComp_(matrixToCopy.deathComp_)
 
  367template <
class Master_matrix>
 
  369    : CP(std::move(
static_cast<CP&
>(other))),
 
  370      birthComp_(std::move(other.birthComp_)),
 
  371      deathComp_(std::move(other.deathComp_))
 
  374template <
class Master_matrix>
 
  378  const bool col1IsNeg = _is_negative_in_pair(columnIndex1);
 
  379  const bool col2IsNeg = _is_negative_in_pair(columnIndex2);
 
  381  if (col1IsNeg && col2IsNeg) 
return _negative_vine_swap(columnIndex1, columnIndex2);
 
  383  if (col1IsNeg) 
return _negative_positive_vine_swap(columnIndex1, columnIndex2);
 
  385  if (col2IsNeg) 
return _positive_negative_vine_swap(columnIndex1, columnIndex2);
 
  387  return _positive_vine_swap(columnIndex1, columnIndex2);
 
  390template <
class Master_matrix>
 
  394  if constexpr (Master_matrix::Option_list::has_column_pairings) {
 
  395    GUDHI_CHECK(CP::are_adjacent(_matrix()->get_pivot(columnIndex1), _matrix()->get_pivot(columnIndex2)),
 
  396                std::invalid_argument(
 
  397                    "Chain_vine_swap::vine_swap - Columns to be swapped need to be adjacent in the 'real' matrix."));
 
  400  const bool col1IsNeg = _is_negative_in_pair(columnIndex1);
 
  401  const bool col2IsNeg = _is_negative_in_pair(columnIndex2);
 
  403  if (col1IsNeg && col2IsNeg) {
 
  404    if (_matrix()->is_zero_entry(columnIndex2, _matrix()->get_pivot(columnIndex1))) {
 
  405      if constexpr (Master_matrix::Option_list::has_column_pairings) {
 
  406        ID_index pivot1 = _matrix()->get_pivot(columnIndex1);
 
  407        ID_index pivot2 = _matrix()->get_pivot(columnIndex2);
 
  409        CP::negative_transpose(pivot1, pivot2);
 
  410        CP::swap_positions(pivot1, pivot2);
 
  414    return _negative_vine_swap(columnIndex1, columnIndex2);
 
  418    if (_matrix()->is_zero_entry(columnIndex2, _matrix()->get_pivot(columnIndex1))) {
 
  419      if constexpr (Master_matrix::Option_list::has_column_pairings) {
 
  420        ID_index pivot1 = _matrix()->get_pivot(columnIndex1);
 
  421        ID_index pivot2 = _matrix()->get_pivot(columnIndex2);
 
  423        CP::negative_positive_transpose(pivot1, pivot2);
 
  424        CP::swap_positions(pivot1, pivot2);
 
  428    return _negative_positive_vine_swap(columnIndex1, columnIndex2);
 
  432    if (_matrix()->is_zero_entry(columnIndex2, _matrix()->get_pivot(columnIndex1))) {
 
  433      if constexpr (Master_matrix::Option_list::has_column_pairings) {
 
  434        ID_index pivot1 = _matrix()->get_pivot(columnIndex1);
 
  435        ID_index pivot2 = _matrix()->get_pivot(columnIndex2);
 
  437        CP::positive_negative_transpose(pivot1, pivot2);
 
  438        CP::swap_positions(pivot1, pivot2);
 
  442    return _positive_negative_vine_swap(columnIndex1, columnIndex2);
 
  445  if (_matrix()->is_zero_entry(columnIndex2, _matrix()->get_pivot(columnIndex1))) {
 
  446    if constexpr (Master_matrix::Option_list::has_column_pairings) {
 
  447      ID_index pivot1 = _matrix()->get_pivot(columnIndex1);
 
  448      ID_index pivot2 = _matrix()->get_pivot(columnIndex2);
 
  450      CP::positive_transpose(pivot1, pivot2);
 
  451      CP::swap_positions(pivot1, pivot2);
 
  455  return _positive_vine_swap(columnIndex1, columnIndex2);
 
  458template <
class Master_matrix>
 
  461  CP::operator=(other);
 
  462  std::swap(birthComp_, other.birthComp_);
 
  463  std::swap(deathComp_, other.deathComp_);
 
  467template <
class Master_matrix>
 
  470  if constexpr (Master_matrix::Option_list::has_column_pairings) {
 
  471    return CP::is_negative_in_pair(_matrix()->get_pivot(columnIndex));
 
  473    auto& col = _matrix()->get_column(columnIndex);
 
  474    if (!col.is_paired()) 
return false;
 
  475    return col.get_pivot() > _matrix()->get_pivot(col.get_paired_chain_index());
 
  479template <
class Master_matrix>
 
  481    Index columnIndex1, Index columnIndex2)
 
  483  auto& col1 = _matrix()->get_column(columnIndex1);
 
  484  auto& col2 = _matrix()->get_column(columnIndex2);
 
  486  if constexpr (Master_matrix::Option_list::has_column_pairings) {
 
  487    CP::swap_positions(col1.get_pivot(), col2.get_pivot());
 
  491  if (!col1.is_paired()) {  
 
  492    bool hasSmallerBirth;
 
  493    if constexpr (Master_matrix::Option_list::has_column_pairings) {
 
  495      hasSmallerBirth = (CP::birth(col2.get_pivot()) < CP::birth(col1.get_pivot()));
 
  497      hasSmallerBirth = birthComp_(columnIndex1, columnIndex2);
 
  500    if (!col2.is_paired() && hasSmallerBirth) {
 
  501      _matrix()->add_to(columnIndex1, columnIndex2);
 
  502      if constexpr (Master_matrix::Option_list::has_column_pairings) {
 
  503        CP::positive_transpose(col1.get_pivot(), col2.get_pivot());
 
  507    _matrix()->add_to(columnIndex2, columnIndex1);
 
  512  if (!col2.is_paired()) {  
 
  513    static_cast<Master_chain_matrix*
>(
this)->add_to(columnIndex1, columnIndex2);
 
  514    if constexpr (Master_matrix::Option_list::has_column_pairings) {
 
  515      CP::positive_transpose(col1.get_pivot(), col2.get_pivot());
 
  520  bool hasSmallerDeath;
 
  521  if constexpr (Master_matrix::Option_list::has_column_pairings) {
 
  523    hasSmallerDeath = (CP::death(col2.get_pivot()) < CP::death(col1.get_pivot()));
 
  525    hasSmallerDeath = deathComp_(columnIndex1, columnIndex2);
 
  531    _matrix()->add_to(col1.get_paired_chain_index(), col2.get_paired_chain_index());
 
  532    _matrix()->add_to(columnIndex1, columnIndex2);
 
  533    if constexpr (Master_matrix::Option_list::has_column_pairings) {
 
  534      CP::positive_transpose(col1.get_pivot(), col2.get_pivot());
 
  539  _matrix()->add_to(col2.get_paired_chain_index(), col1.get_paired_chain_index());
 
  540  _matrix()->add_to(columnIndex2, columnIndex1);
 
  545template <
class Master_matrix>
 
  547    Index columnIndex1, Index columnIndex2)
 
  549  _matrix()->add_to(columnIndex1, columnIndex2);
 
  551  if constexpr (Master_matrix::Option_list::has_column_pairings) {
 
  552    ID_index pivot1 = _matrix()->get_pivot(columnIndex1);
 
  553    ID_index pivot2 = _matrix()->get_pivot(columnIndex2);
 
  555    CP::positive_negative_transpose(pivot1, pivot2);
 
  556    CP::swap_positions(pivot1, pivot2);
 
  562template <
class Master_matrix>
 
  564    Index columnIndex1, Index columnIndex2)
 
  566  _matrix()->add_to(columnIndex2, columnIndex1);
 
  568  if constexpr (Master_matrix::Option_list::has_column_pairings) {
 
  569    CP::swap_positions(_matrix()->get_pivot(columnIndex1), _matrix()->get_pivot(columnIndex2));
 
  575template <
class Master_matrix>
 
  577    Index columnIndex1, Index columnIndex2)
 
  579  auto& col1 = _matrix()->get_column(columnIndex1);
 
  580  auto& col2 = _matrix()->get_column(columnIndex2);
 
  582  Index pairedIndex1 = col1.get_paired_chain_index();
 
  583  Index pairedIndex2 = col2.get_paired_chain_index();
 
  585  bool hasSmallerBirth;
 
  586  if constexpr (Master_matrix::Option_list::has_column_pairings) {
 
  587    hasSmallerBirth = (CP::birth(col1.get_pivot()) < CP::birth(col2.get_pivot()));
 
  589    hasSmallerBirth = birthComp_(pairedIndex1, pairedIndex2);
 
  592  if constexpr (Master_matrix::Option_list::has_column_pairings) {
 
  593    CP::swap_positions(col1.get_pivot(), col2.get_pivot());
 
  598    _matrix()->add_to(pairedIndex1, pairedIndex2);
 
  599    _matrix()->add_to(columnIndex1, columnIndex2);
 
  601    if constexpr (Master_matrix::Option_list::has_column_pairings) {
 
  602      CP::negative_transpose(col1.get_pivot(), col2.get_pivot());
 
  608  _matrix()->add_to(pairedIndex2, pairedIndex1);
 
  609  _matrix()->add_to(columnIndex2, columnIndex1);
 
Contains the Gudhi::persistence_matrix::Chain_pairing class and Gudhi::persistence_matrix::Dummy_chai...
 
Class managing the barcode for Chain_vine_swap.
Definition: chain_vine_swap.h:85
 
typename Master_matrix::Pos_index Pos_index
Definition: chain_vine_swap.h:88
 
Chain_barcode_swap()
Default constructor.
Definition: chain_vine_swap.h:95
 
Chain_barcode_swap(const Chain_barcode_swap &toCopy)
Copy constructor.
Definition: chain_vine_swap.h:101
 
typename Master_matrix::ID_index ID_index
Definition: chain_vine_swap.h:87
 
Chain_barcode_swap(Chain_barcode_swap &&other)
Move constructor.
Definition: chain_vine_swap.h:108
 
Class managing the barcode for Chain_matrix if the option was enabled.
Definition: chain_pairing.h:48
 
Chain_pairing & operator=(Chain_pairing other)
Assign operator.
Definition: chain_pairing.h:125
 
Class managing the vine swaps for Chain_matrix.
Definition: chain_vine_swap.h:240
 
Chain_vine_swap()
Default constructor. Only available if PersistenceMatrixOptions::has_column_pairings is true.
Definition: chain_vine_swap.h:348
 
typename Master_matrix::Pos_index Pos_index
Definition: chain_vine_swap.h:244
 
Chain_vine_swap & operator=(Chain_vine_swap other)
Assign operator.
Definition: chain_vine_swap.h:459
 
typename Master_matrix::Column_container Column_container
Definition: chain_vine_swap.h:245
 
Index vine_swap(Index columnIndex1, Index columnIndex2)
Does a vine swap between two cells which are consecutive in the filtration. Roughly,...
Definition: chain_vine_swap.h:391
 
typename Master_matrix::Index Index
Definition: chain_vine_swap.h:242
 
typename Master_matrix::ID_index ID_index
Definition: chain_vine_swap.h:243
 
friend void swap(Chain_vine_swap &swap1, Chain_vine_swap &swap2)
Swap operator.
Definition: chain_vine_swap.h:315
 
typename Master_matrix::Column Column
Definition: chain_vine_swap.h:246
 
bool(* EventCompFuncPointer)(Pos_index, Pos_index)
Definition: chain_vine_swap.h:247
 
Index vine_swap_with_z_eq_1_case(Index columnIndex1, Index columnIndex2)
Does the same than vine_swap, but assumes that the swap is non trivial and therefore skips a part of ...
Definition: chain_vine_swap.h:375
 
constexpr bool _no_G_death_comparator(unsigned int columnIndex1, unsigned int columnIndex2)
Default death comparator. Simply assumes that two positive paired columns are never swapped....
Definition: chain_vine_swap.h:43
 
Gudhi namespace.
Definition: SimplicialComplexForAlpha.h:14
 
Empty structure. Inherited instead of Chain_barcode_swap, when the barcode is not stored.
Definition: chain_vine_swap.h:72
 
Empty structure. Inherited instead of Chain_vine_swap, when vine swaps are not enabled.
Definition: chain_vine_swap.h:56