19#ifndef PM_RU_VINE_SWAP_H 
   20#define PM_RU_VINE_SWAP_H 
   31namespace persistence_matrix {
 
   63template <
class Master_matrix>
 
   64class RU_vine_swap : 
public std::conditional<Master_matrix::Option_list::has_column_pairings, 
 
   65                                             RU_pairing<Master_matrix>,
 
   68                     public std::conditional<Master_matrix::Option_list::has_column_pairings &&
 
   69                                                Master_matrix::Option_list::has_removable_columns, 
 
   71                                             Cell_position_to_ID_mapper<typename Master_matrix::ID_index,
 
   72                                                                        typename Master_matrix::Pos_index>
 
   76  using Index = 
typename Master_matrix::Index;          
 
   77  using ID_index = 
typename Master_matrix::ID_index;    
 
   78  using Pos_index = 
typename Master_matrix::Pos_index;  
 
  128    if constexpr (Master_matrix::Option_list::has_column_pairings) {
 
  131    if (!Master_matrix::Option_list::has_column_pairings || !Master_matrix::Option_list::has_removable_columns) {
 
  132      swap(
static_cast<Cell_position_to_ID_mapper<ID_index, Pos_index>&
>(swap1),
 
  133           static_cast<Cell_position_to_ID_mapper<ID_index, Pos_index>&
>(swap2));
 
  139  using RUP = 
typename std::conditional<Master_matrix::Option_list::has_column_pairings, 
 
  144  using RUM = 
typename std::conditional<Master_matrix::Option_list::has_column_pairings &&
 
  145                                            Master_matrix::Option_list::has_removable_columns,
 
  147                                        Cell_position_to_ID_mapper<ID_index, Pos_index>
 
  149  constexpr auto& _positionToRowIdx();
 
  152  using Master_RU_matrix = 
typename Master_matrix::Master_RU_matrix;
 
  154  bool _is_paired(Index columnIndex);
 
  156  void _swap_at_index(Index columnIndex);
 
  157  void _add_to(Index sourceIndex, Index targetIndex);
 
  158  void _positive_transpose(Index columnIndex);
 
  159  void _negative_transpose(Index columnIndex);
 
  160  void _positive_negative_transpose(Index columnIndex);
 
  161  void _negative_positive_transpose(Index columnIndex);
 
  162  bool _positive_vine_swap(Index columnIndex);
 
  163  bool _negative_vine_swap(Index columnIndex);
 
  164  bool _positive_negative_vine_swap(Index columnIndex);
 
  165  bool _negative_positive_vine_swap(Index columnIndex);
 
  169  Pos_index _get_death(Index simplexIndex);
 
  170  Pos_index _get_birth(Index simplexIndex);
 
  174  constexpr Master_RU_matrix* _matrix() { 
return static_cast<Master_RU_matrix*
>(
this); }
 
  175  constexpr const Master_RU_matrix* _matrix()
 const { 
return static_cast<const Master_RU_matrix*
>(
this); }
 
  178template <
class Master_matrix>
 
  182template <
class Master_matrix>
 
  184    : RUP(static_cast<const RUP&>(matrixToCopy)),
 
  185      RUM(static_cast<const RUM&>(matrixToCopy))
 
  188template <
class Master_matrix>
 
  190    : RUP(std::move(
static_cast<RUP&
>(other))),
 
  191      RUM(std::move(
static_cast<RUM&
>(other)))
 
  194template <
class Master_matrix>
 
  197  GUDHI_CHECK(index < _matrix()->reducedMatrixR_.get_number_of_columns() - 1,
 
  198              std::invalid_argument(
"RU_vine_swap::vine_swap_with_z_eq_1_case - Index to swap out of bound."));
 
  200  bool iIsPositive = _matrix()->reducedMatrixR_.is_zero_column(index);
 
  201  bool iiIsPositive = _matrix()->reducedMatrixR_.is_zero_column(index + 1);
 
  203  if (iIsPositive && iiIsPositive) {
 
  204    _matrix()->mirrorMatrixU_.zero_entry(index, _get_row_id_from_position(index + 1));
 
  205    return _positive_vine_swap(index);
 
  206  } 
else if (!iIsPositive && !iiIsPositive) {
 
  207    return _negative_vine_swap(index);
 
  208  } 
else if (iIsPositive && !iiIsPositive) {
 
  209    return _positive_negative_vine_swap(index);
 
  211    return _negative_positive_vine_swap(index);
 
  215template <
class Master_matrix>
 
  218  GUDHI_CHECK(index < _matrix()->reducedMatrixR_.get_number_of_columns() - 1,
 
  219              std::invalid_argument(
"RU_vine_swap::vine_swap - Index to swap out of bound."));
 
  221  bool iIsPositive = _matrix()->reducedMatrixR_.is_zero_column(index);
 
  222  bool iiIsPositive = _matrix()->reducedMatrixR_.is_zero_column(index + 1);
 
  224  if (iIsPositive && iiIsPositive) {
 
  225    if (_matrix()->reducedMatrixR_.get_column_dimension(index) !=
 
  226        _matrix()->reducedMatrixR_.get_column_dimension(index + 1)) {
 
  227      _positive_transpose(index);
 
  228      _swap_at_index(index);
 
  231    if (!_matrix()->mirrorMatrixU_.is_zero_entry(index, _get_row_id_from_position(index + 1))) {
 
  232      _matrix()->mirrorMatrixU_.zero_entry(index, _get_row_id_from_position(index + 1));
 
  234    return _positive_vine_swap(index);
 
  235  } 
else if (!iIsPositive && !iiIsPositive) {
 
  236    if (_matrix()->reducedMatrixR_.get_column_dimension(index) !=
 
  237            _matrix()->reducedMatrixR_.get_column_dimension(index + 1) ||
 
  238        _matrix()->mirrorMatrixU_.is_zero_entry(index, _get_row_id_from_position(index + 1))) {
 
  239      _negative_transpose(index);
 
  240      _swap_at_index(index);
 
  243    return _negative_vine_swap(index);
 
  244  } 
else if (iIsPositive && !iiIsPositive) {
 
  245    if (_matrix()->reducedMatrixR_.get_column_dimension(index) !=
 
  246            _matrix()->reducedMatrixR_.get_column_dimension(index + 1) ||
 
  247        _matrix()->mirrorMatrixU_.is_zero_entry(index, _get_row_id_from_position(index + 1))) {
 
  248      _positive_negative_transpose(index);
 
  249      _swap_at_index(index);
 
  252    return _positive_negative_vine_swap(index);
 
  254    if (_matrix()->reducedMatrixR_.get_column_dimension(index) !=
 
  255            _matrix()->reducedMatrixR_.get_column_dimension(index + 1) ||
 
  256        _matrix()->mirrorMatrixU_.is_zero_entry(index, _get_row_id_from_position(index + 1))) {
 
  257      _negative_positive_transpose(index);
 
  258      _swap_at_index(index);
 
  261    return _negative_positive_vine_swap(index);
 
  265template <
class Master_matrix>
 
  268  RUP::operator=(other);
 
  269  RUM::operator=(other);
 
  273template <
class Master_matrix>
 
  276  if constexpr (Master_matrix::Option_list::has_column_pairings) {
 
  277    return _get_death(columnIndex) != Master_matrix::template get_null_value<Pos_index>();
 
  279    if (!_matrix()->reducedMatrixR_.is_zero_column(columnIndex)) 
return true;
 
  281    if constexpr (Master_matrix::Option_list::has_map_column_container) {
 
  282      if (_matrix()->pivotToColumnIndex_.find(columnIndex) == _matrix()->pivotToColumnIndex_.end()) 
return false;
 
  284      if (_matrix()->pivotToColumnIndex_[columnIndex] == Master_matrix::template get_null_value<Index>())
 
  292template <
class Master_matrix>
 
  293inline void RU_vine_swap<Master_matrix>::_swap_at_index(Index columnIndex)
 
  295  _matrix()->reducedMatrixR_.swap_columns(columnIndex, columnIndex + 1);
 
  296  _matrix()->reducedMatrixR_.swap_rows(_get_row_id_from_position(columnIndex),
 
  297                                       _get_row_id_from_position(columnIndex + 1));
 
  298  _matrix()->mirrorMatrixU_.swap_columns(columnIndex, columnIndex + 1);
 
  299  _matrix()->mirrorMatrixU_.swap_rows(_get_row_id_from_position(columnIndex),
 
  300                                      _get_row_id_from_position(columnIndex + 1));
 
  303template <
class Master_matrix>
 
  304inline void RU_vine_swap<Master_matrix>::_add_to(Index sourceIndex, Index targetIndex) 
 
  306  _matrix()->reducedMatrixR_.add_to(sourceIndex, targetIndex);
 
  307  _matrix()->mirrorMatrixU_.add_to(targetIndex, sourceIndex);
 
  310template <
class Master_matrix>
 
  311inline void RU_vine_swap<Master_matrix>::_positive_transpose(Index columnIndex) 
 
  313  if constexpr (Master_matrix::Option_list::has_map_column_container) {
 
  314    if (_is_paired(columnIndex) && _is_paired(columnIndex + 1)) {
 
  315      std::swap(_matrix()->pivotToColumnIndex_.at(columnIndex), _matrix()->pivotToColumnIndex_.at(columnIndex + 1));
 
  316    } 
else if (_is_paired(columnIndex)) {
 
  317      _matrix()->pivotToColumnIndex_.emplace(columnIndex + 1, _matrix()->pivotToColumnIndex_.at(columnIndex));
 
  318      _matrix()->pivotToColumnIndex_.erase(columnIndex);
 
  319    } 
else if (_is_paired(columnIndex + 1)) {
 
  320      _matrix()->pivotToColumnIndex_.emplace(columnIndex, _matrix()->pivotToColumnIndex_.at(columnIndex + 1));
 
  321      _matrix()->pivotToColumnIndex_.erase(columnIndex + 1);
 
  324    std::swap(_matrix()->pivotToColumnIndex_[columnIndex],
 
  325              _matrix()->pivotToColumnIndex_[columnIndex + 1]);
 
  328  if constexpr (Master_matrix::Option_list::has_column_pairings) {
 
  329    _birth(columnIndex) = columnIndex + 1;
 
  330    _birth(columnIndex + 1) = columnIndex;
 
  331    std::swap(RUP::indexToBar_.at(columnIndex), RUP::indexToBar_.at(columnIndex + 1));
 
  335template <
class Master_matrix>
 
  336inline void RU_vine_swap<Master_matrix>::_negative_transpose(Index columnIndex) 
 
  338  if constexpr (Master_matrix::Option_list::has_column_pairings) {
 
  339    _death(columnIndex) = columnIndex + 1;
 
  340    _death(columnIndex + 1) = columnIndex;
 
  341    std::swap(RUP::indexToBar_.at(columnIndex), RUP::indexToBar_.at(columnIndex + 1));
 
  343  std::swap(_matrix()->pivotToColumnIndex_.at(_get_birth(columnIndex)),
 
  344            _matrix()->pivotToColumnIndex_.at(_get_birth(columnIndex + 1)));
 
  347template <
class Master_matrix>
 
  348inline void RU_vine_swap<Master_matrix>::_positive_negative_transpose(Index columnIndex) 
 
  350  _matrix()->pivotToColumnIndex_.at(_get_birth(columnIndex + 1)) = columnIndex;
 
  351  if constexpr (Master_matrix::Option_list::has_map_column_container) {
 
  352    if (_is_paired(columnIndex)) {
 
  353      _matrix()->pivotToColumnIndex_.emplace(columnIndex + 1, _matrix()->pivotToColumnIndex_.at(columnIndex));
 
  354      _matrix()->pivotToColumnIndex_.erase(columnIndex);
 
  357    _matrix()->pivotToColumnIndex_[columnIndex + 1] = _matrix()->pivotToColumnIndex_[columnIndex];
 
  358    _matrix()->pivotToColumnIndex_[columnIndex] = Master_matrix::template get_null_value<Index>();
 
  361  if constexpr (Master_matrix::Option_list::has_column_pairings) {
 
  362    _birth(columnIndex) = columnIndex + 1;
 
  363    _death(columnIndex + 1) = columnIndex;
 
  364    std::swap(RUP::indexToBar_.at(columnIndex), RUP::indexToBar_.at(columnIndex + 1));
 
  368template <
class Master_matrix>
 
  369inline void RU_vine_swap<Master_matrix>::_negative_positive_transpose(Index columnIndex) 
 
  371  _matrix()->pivotToColumnIndex_.at(_get_birth(columnIndex)) = columnIndex + 1;
 
  372  if constexpr (Master_matrix::Option_list::has_map_column_container) {
 
  373    if (_is_paired(columnIndex + 1)) {
 
  374      _matrix()->pivotToColumnIndex_.emplace(columnIndex, _matrix()->pivotToColumnIndex_.at(columnIndex + 1));
 
  375      _matrix()->pivotToColumnIndex_.erase(columnIndex + 1);
 
  378    _matrix()->pivotToColumnIndex_[columnIndex] = _matrix()->pivotToColumnIndex_[columnIndex + 1];
 
  379    _matrix()->pivotToColumnIndex_[columnIndex + 1] = Master_matrix::template get_null_value<Index>();
 
  382  if constexpr (Master_matrix::Option_list::has_column_pairings) {
 
  383    _death(columnIndex) = columnIndex + 1;
 
  384    _birth(columnIndex + 1) = columnIndex;
 
  385    std::swap(RUP::indexToBar_.at(columnIndex), RUP::indexToBar_.at(columnIndex + 1));
 
  389template <
class Master_matrix>
 
  390inline bool RU_vine_swap<Master_matrix>::_positive_vine_swap(Index columnIndex) 
 
  392  const Pos_index iDeath = _get_death(columnIndex);
 
  393  const Pos_index iiDeath = _get_death(columnIndex + 1);
 
  395  if (iDeath != Master_matrix::template get_null_value<Pos_index>() &&
 
  396      iiDeath != Master_matrix::template get_null_value<Pos_index>() &&
 
  397      !(_matrix()->reducedMatrixR_.is_zero_entry(iiDeath, _get_row_id_from_position(columnIndex)))) {
 
  398    if (iDeath < iiDeath) {
 
  399      _swap_at_index(columnIndex);
 
  400      _add_to(iDeath, iiDeath);
 
  401      _positive_transpose(columnIndex);
 
  405    _swap_at_index(columnIndex);
 
  406    _add_to(iiDeath, iDeath);
 
  410  _swap_at_index(columnIndex);
 
  412  if (iDeath != Master_matrix::template get_null_value<Pos_index>() ||
 
  413      iiDeath == Master_matrix::template get_null_value<Pos_index>() ||
 
  414      _matrix()->reducedMatrixR_.is_zero_entry(iiDeath, _get_row_id_from_position(columnIndex + 1))) {
 
  415    _positive_transpose(columnIndex);
 
  421template <
class Master_matrix>
 
  422inline bool RU_vine_swap<Master_matrix>::_negative_vine_swap(Index columnIndex) 
 
  424  const Pos_index iBirth = _get_birth(columnIndex);
 
  425  const Pos_index iiBirth = _get_birth(columnIndex + 1);
 
  427  _add_to(columnIndex, columnIndex + 1);
 
  428  _swap_at_index(columnIndex);
 
  430  if (iBirth < iiBirth) {
 
  431    _negative_transpose(columnIndex);
 
  435  _add_to(columnIndex, columnIndex + 1);
 
  440template <
class Master_matrix>
 
  441inline bool RU_vine_swap<Master_matrix>::_positive_negative_vine_swap(Index columnIndex) 
 
  443  _matrix()->mirrorMatrixU_.zero_entry(columnIndex, _get_row_id_from_position(columnIndex + 1));
 
  445  _swap_at_index(columnIndex);
 
  446  _positive_negative_transpose(columnIndex);
 
  451template <
class Master_matrix>
 
  452inline bool RU_vine_swap<Master_matrix>::_negative_positive_vine_swap(Index columnIndex) 
 
  454  _add_to(columnIndex, columnIndex + 1);  
 
  455  _swap_at_index(columnIndex);      
 
  456  _add_to(columnIndex, columnIndex + 1);  
 
  461template <
class Master_matrix>
 
  464  static_assert(Master_matrix::Option_list::has_column_pairings, 
"Pairing necessary to modify death value.");
 
  466  if constexpr (Master_matrix::Option_list::has_removable_columns) {
 
  467    return RUP::indexToBar_.at(simplexIndex)->death;
 
  469    return RUP::barcode_.at(RUP::indexToBar_.at(simplexIndex)).death;
 
  473template <
class Master_matrix>
 
  476  static_assert(Master_matrix::Option_list::has_column_pairings, 
"Pairing necessary to modify birth value.");
 
  478  if constexpr (Master_matrix::Option_list::has_removable_columns) {
 
  479    return RUP::indexToBar_.at(simplexIndex)->birth;
 
  481    return RUP::barcode_.at(RUP::indexToBar_.at(simplexIndex)).birth;
 
  485template <
class Master_matrix>
 
  488  if constexpr (Master_matrix::Option_list::has_column_pairings) {
 
  489    if constexpr (Master_matrix::Option_list::has_removable_columns) {
 
  490      return RUP::indexToBar_.at(simplexIndex)->death;
 
  492      return RUP::barcode_.at(RUP::indexToBar_.at(simplexIndex)).death;
 
  495    if (!_matrix()->reducedMatrixR_.is_zero_column(simplexIndex))
 
  496      return _matrix()->reducedMatrixR_.get_column(simplexIndex).get_pivot();
 
  498    if constexpr (Master_matrix::Option_list::has_map_column_container) {
 
  499      auto it = _matrix()->pivotToColumnIndex_.find(simplexIndex);
 
  500      if (it == _matrix()->pivotToColumnIndex_.end()) 
return Master_matrix::template get_null_value<Pos_index>();
 
  503      return _matrix()->pivotToColumnIndex_[simplexIndex];
 
  508template <
class Master_matrix>
 
  510    Index negativeSimplexIndex) 
 
  512  if constexpr (Master_matrix::Option_list::has_column_pairings) {
 
  513    if constexpr (Master_matrix::Option_list::has_removable_columns) {
 
  514      return RUP::indexToBar_.at(negativeSimplexIndex)->birth;
 
  516      return RUP::barcode_.at(RUP::indexToBar_.at(negativeSimplexIndex)).birth;
 
  519    return _matrix()->reducedMatrixR_.get_pivot(negativeSimplexIndex);
 
  523template <
class Master_matrix>
 
  527  auto it = _positionToRowIdx().find(position);
 
  528  return it == _positionToRowIdx().end() ? position : it->second;
 
  531template <
class Master_matrix>
 
  532inline constexpr auto& RU_vine_swap<Master_matrix>::_positionToRowIdx()
 
  534  if constexpr (Master_matrix::Option_list::has_column_pairings && Master_matrix::Option_list::has_removable_columns)
 
  535    return RUP::PIDM::map_;
 
Contains the Gudhi::persistence_matrix::Cell_position_to_ID_mapper class and Gudhi::persistence_matri...
 
Class managing the barcode for RU_matrix if the option was enabled.
Definition: ru_pairing.h:54
 
Class managing the vine swaps for RU_matrix.
Definition: ru_vine_swap.h:74
 
friend void swap(RU_vine_swap &swap1, RU_vine_swap &swap2)
Swap operator.
Definition: ru_vine_swap.h:127
 
RU_vine_swap & operator=(RU_vine_swap other)
Assign operator.
Definition: ru_vine_swap.h:266
 
typename Master_matrix::ID_index ID_index
Definition: ru_vine_swap.h:77
 
RU_vine_swap()
Default constructor.
Definition: ru_vine_swap.h:179
 
typename Master_matrix::Index Index
Definition: ru_vine_swap.h:76
 
bool vine_swap_with_z_eq_1_case(Pos_index index)
Does the same than vine_swap, but assumes that the swap is non trivial and therefore skips a part of ...
Definition: ru_vine_swap.h:195
 
typename Master_matrix::Pos_index Pos_index
Definition: ru_vine_swap.h:78
 
bool vine_swap(Pos_index index)
Does a vine swap between two cells which are consecutive in the filtration. Roughly,...
Definition: ru_vine_swap.h:216
 
Gudhi namespace.
Definition: SimplicialComplexForAlpha.h:14
 
Contains the Gudhi::persistence_matrix::RU_pairing class and Gudhi::persistence_matrix::Dummy_ru_pair...
 
Empty structure. Inherited instead of RU_pairing, when the barcode is not stored.
Definition: ru_vine_swap.h:51
 
Empty structure. Inherited instead of RU_vine_swap, when vine swaps are not enabled.
Definition: ru_vine_swap.h:40