19#ifndef PM_RU_VINE_SWAP_H
20#define PM_RU_VINE_SWAP_H
60template <
typename Master_matrix>
64 using Index =
typename Master_matrix::Index;
65 using ID_index =
typename Master_matrix::ID_index;
66 using Pos_index =
typename Master_matrix::Pos_index;
91 RUP::operator=(other);
97 RUP::operator=(std::move(other));
103 swap(
static_cast<RUP&
>(swap1),
static_cast<RUP&
>(swap2));
107 void _positive_transpose_barcode(
Index columnIndex)
109 _birth(columnIndex) = columnIndex + 1;
110 _birth(columnIndex + 1) = columnIndex;
111 std::swap(RUP::indexToBar_.at(columnIndex), RUP::indexToBar_.at(columnIndex + 1));
114 void _negative_transpose_barcode(
Index columnIndex)
116 _death(columnIndex) = columnIndex + 1;
117 _death(columnIndex + 1) = columnIndex;
118 std::swap(RUP::indexToBar_.at(columnIndex), RUP::indexToBar_.at(columnIndex + 1));
121 void _positive_negative_transpose_barcode(
Index columnIndex)
123 _birth(columnIndex) = columnIndex + 1;
124 _death(columnIndex + 1) = columnIndex;
125 std::swap(RUP::indexToBar_.at(columnIndex), RUP::indexToBar_.at(columnIndex + 1));
128 void _negative_positive_transpose_barcode(
Index columnIndex)
130 _death(columnIndex) = columnIndex + 1;
131 _birth(columnIndex + 1) = columnIndex;
132 std::swap(RUP::indexToBar_.at(columnIndex), RUP::indexToBar_.at(columnIndex + 1));
137 if constexpr (Master_matrix::Option_list::has_removable_columns) {
138 return RUP::indexToBar_.at(index)->death;
140 return RUP::barcode_.at(RUP::indexToBar_.at(index)).death;
146 if constexpr (Master_matrix::Option_list::has_removable_columns) {
147 return RUP::indexToBar_.at(index)->birth;
149 return RUP::barcode_.at(RUP::indexToBar_.at(index)).birth;
153 void _reset() { RUP::_reset(); }
158 if constexpr (Master_matrix::Option_list::has_removable_columns) {
159 return RUP::indexToBar_.at(index)->death;
161 return RUP::barcode_.at(RUP::indexToBar_.at(index)).death;
167 if constexpr (Master_matrix::Option_list::has_removable_columns) {
168 return RUP::indexToBar_.at(index)->birth;
170 return RUP::barcode_.at(RUP::indexToBar_.at(index)).birth;
183template <
class Master_matrix>
187 using Index =
typename Master_matrix::Index;
225 using Master_RU_matrix =
typename Master_matrix::Master_RU_matrix;
227 bool _is_paired(Index columnIndex);
228 void _swap_at_index(Index columnIndex);
229 void _add_to(Index sourceIndex, Index targetIndex);
230 void _positive_transpose(Index columnIndex);
231 void _negative_transpose(Index columnIndex);
232 void _positive_negative_transpose(Index columnIndex);
233 void _negative_positive_transpose(Index columnIndex);
234 bool _positive_vine_swap(Index columnIndex);
235 bool _negative_vine_swap(Index columnIndex);
236 bool _positive_negative_vine_swap(Index columnIndex);
237 bool _negative_positive_vine_swap(Index columnIndex);
238 Pos_index _get_death(Index simplexIndex);
239 Pos_index _get_birth(Index simplexIndex);
242 constexpr Master_RU_matrix* _matrix() {
return static_cast<Master_RU_matrix*
>(
this); }
244 constexpr const Master_RU_matrix* _matrix()
const {
return static_cast<const Master_RU_matrix*
>(
this); }
247template <
class Master_matrix>
250 GUDHI_CHECK(index < _matrix()->reducedMatrixR_.get_number_of_columns() - 1,
251 std::invalid_argument(
"RU_vine_swap::vine_swap_with_z_eq_1_case - Index to swap out of bound."));
253 bool iIsPositive = _matrix()->reducedMatrixR_.is_zero_column(index);
254 bool iiIsPositive = _matrix()->reducedMatrixR_.is_zero_column(index + 1);
256 if (iIsPositive && iiIsPositive) {
257 _matrix()->mirrorMatrixU_.zero_entry(index, _get_row_id_from_position(index + 1));
258 return _positive_vine_swap(index);
260 if (!iIsPositive && !iiIsPositive) {
261 return _negative_vine_swap(index);
263 if (iIsPositive && !iiIsPositive) {
264 return _positive_negative_vine_swap(index);
266 return _negative_positive_vine_swap(index);
269template <
class Master_matrix>
272 GUDHI_CHECK(index < _matrix()->reducedMatrixR_.get_number_of_columns() - 1,
273 std::invalid_argument(
"RU_vine_swap::vine_swap - Index to swap out of bound."));
275 bool iIsPositive = _matrix()->reducedMatrixR_.is_zero_column(index);
276 bool iiIsPositive = _matrix()->reducedMatrixR_.is_zero_column(index + 1);
278 if (iIsPositive && iiIsPositive) {
279 if (_matrix()->reducedMatrixR_.get_column_dimension(index) !=
280 _matrix()->reducedMatrixR_.get_column_dimension(index + 1)) {
281 _positive_transpose(index);
282 _swap_at_index(index);
285 if (!_matrix()->mirrorMatrixU_.is_zero_entry(index, _get_row_id_from_position(index + 1))) {
286 _matrix()->mirrorMatrixU_.zero_entry(index, _get_row_id_from_position(index + 1));
288 return _positive_vine_swap(index);
290 if (!iIsPositive && !iiIsPositive) {
291 if (_matrix()->reducedMatrixR_.get_column_dimension(index) !=
292 _matrix()->reducedMatrixR_.get_column_dimension(index + 1) ||
293 _matrix()->mirrorMatrixU_.is_zero_entry(index, _get_row_id_from_position(index + 1))) {
294 _negative_transpose(index);
295 _swap_at_index(index);
298 return _negative_vine_swap(index);
300 if (iIsPositive && !iiIsPositive) {
301 if (_matrix()->reducedMatrixR_.get_column_dimension(index) !=
302 _matrix()->reducedMatrixR_.get_column_dimension(index + 1) ||
303 _matrix()->mirrorMatrixU_.is_zero_entry(index, _get_row_id_from_position(index + 1))) {
304 _positive_negative_transpose(index);
305 _swap_at_index(index);
308 return _positive_negative_vine_swap(index);
310 if (_matrix()->reducedMatrixR_.get_column_dimension(index) !=
311 _matrix()->reducedMatrixR_.get_column_dimension(index + 1) ||
312 _matrix()->mirrorMatrixU_.is_zero_entry(index, _get_row_id_from_position(index + 1))) {
313 _negative_positive_transpose(index);
314 _swap_at_index(index);
317 return _negative_positive_vine_swap(index);
320template <
class Master_matrix>
321inline bool RU_vine_swap<Master_matrix>::_is_paired(Index columnIndex)
323 if constexpr (Master_matrix::Option_list::has_column_pairings) {
324 return _get_death(columnIndex) != Master_matrix::template get_null_value<Pos_index>();
326 if (!_matrix()->reducedMatrixR_.is_zero_column(columnIndex))
return true;
328 if constexpr (Master_matrix::Option_list::has_map_column_container) {
329 return _matrix()->pivotToColumnIndex_.find(columnIndex) != _matrix()->pivotToColumnIndex_.end();
331 if (_matrix()->pivotToColumnIndex_.size() <= columnIndex)
return false;
332 return _matrix()->pivotToColumnIndex_[columnIndex] != Master_matrix::template get_null_value<Index>();
337template <
class Master_matrix>
338inline void RU_vine_swap<Master_matrix>::_swap_at_index(Index columnIndex)
340 _matrix()->reducedMatrixR_.swap_columns(columnIndex, columnIndex + 1);
341 _matrix()->reducedMatrixR_.swap_rows(_get_row_id_from_position(columnIndex),
342 _get_row_id_from_position(columnIndex + 1));
343 _matrix()->mirrorMatrixU_.swap_columns(columnIndex, columnIndex + 1);
344 _matrix()->mirrorMatrixU_.swap_rows(_get_row_id_from_position(columnIndex),
345 _get_row_id_from_position(columnIndex + 1));
348template <
class Master_matrix>
349inline void RU_vine_swap<Master_matrix>::_add_to(Index sourceIndex, Index targetIndex)
351 _matrix()->reducedMatrixR_.add_to(sourceIndex, targetIndex);
352 _matrix()->mirrorMatrixU_.add_to(targetIndex, sourceIndex);
355template <
class Master_matrix>
356inline void RU_vine_swap<Master_matrix>::_positive_transpose(Index columnIndex)
358 if constexpr (Master_matrix::Option_list::has_map_column_container) {
359 if (_is_paired(columnIndex) && _is_paired(columnIndex + 1)) {
360 std::swap(_matrix()->pivotToColumnIndex_.at(columnIndex), _matrix()->pivotToColumnIndex_.at(columnIndex + 1));
361 }
else if (_is_paired(columnIndex)) {
362 _matrix()->pivotToColumnIndex_.emplace(columnIndex + 1, _matrix()->pivotToColumnIndex_.at(columnIndex));
363 _matrix()->pivotToColumnIndex_.erase(columnIndex);
364 }
else if (_is_paired(columnIndex + 1)) {
365 _matrix()->pivotToColumnIndex_.emplace(columnIndex, _matrix()->pivotToColumnIndex_.at(columnIndex + 1));
366 _matrix()->pivotToColumnIndex_.erase(columnIndex + 1);
369 if (_is_paired(columnIndex) || _is_paired(columnIndex + 1)) {
370 if (columnIndex + 1 >= _matrix()->pivotToColumnIndex_.size()) {
372 _matrix()->pivotToColumnIndex_.push_back(Master_matrix::template get_null_value<Index>());
374 std::swap(_matrix()->pivotToColumnIndex_[columnIndex], _matrix()->pivotToColumnIndex_[columnIndex + 1]);
378 if constexpr (Master_matrix::Option_list::has_column_pairings) {
379 _matrix()->_positive_transpose_barcode(columnIndex);
383template <
class Master_matrix>
384inline void RU_vine_swap<Master_matrix>::_negative_transpose(Index columnIndex)
386 if constexpr (Master_matrix::Option_list::has_column_pairings) {
387 _matrix()->_negative_transpose_barcode(columnIndex);
389 if constexpr (Master_matrix::Option_list::has_map_column_container) {
390 std::swap(_matrix()->pivotToColumnIndex_.at(_get_birth(columnIndex)),
391 _matrix()->pivotToColumnIndex_.at(_get_birth(columnIndex + 1)));
393 std::swap(_matrix()->pivotToColumnIndex_[_get_birth(columnIndex)],
394 _matrix()->pivotToColumnIndex_[_get_birth(columnIndex + 1)]);
398template <
class Master_matrix>
399inline void RU_vine_swap<Master_matrix>::_positive_negative_transpose(Index columnIndex)
401 if constexpr (Master_matrix::Option_list::has_map_column_container) {
402 _matrix()->pivotToColumnIndex_.at(_get_birth(columnIndex + 1)) = columnIndex;
403 if (_is_paired(columnIndex)) {
404 _matrix()->pivotToColumnIndex_.emplace(columnIndex + 1, _matrix()->pivotToColumnIndex_.at(columnIndex));
405 _matrix()->pivotToColumnIndex_.erase(columnIndex);
408 _matrix()->pivotToColumnIndex_[_get_birth(columnIndex + 1)] = columnIndex;
409 if (_is_paired(columnIndex)){
410 if (columnIndex + 1 >= _matrix()->pivotToColumnIndex_.size()) {
412 _matrix()->pivotToColumnIndex_.push_back(Master_matrix::template get_null_value<Index>());
414 _matrix()->pivotToColumnIndex_[columnIndex + 1] = _matrix()->pivotToColumnIndex_[columnIndex];
415 _matrix()->pivotToColumnIndex_[columnIndex] = Master_matrix::template get_null_value<Index>();
419 if constexpr (Master_matrix::Option_list::has_column_pairings) {
420 _matrix()->_positive_negative_transpose_barcode(columnIndex);
424template <
class Master_matrix>
425inline void RU_vine_swap<Master_matrix>::_negative_positive_transpose(Index columnIndex)
427 if constexpr (Master_matrix::Option_list::has_map_column_container) {
428 _matrix()->pivotToColumnIndex_.at(_get_birth(columnIndex)) = columnIndex + 1;
429 if (_is_paired(columnIndex + 1)) {
430 _matrix()->pivotToColumnIndex_.emplace(columnIndex, _matrix()->pivotToColumnIndex_.at(columnIndex + 1));
431 _matrix()->pivotToColumnIndex_.erase(columnIndex + 1);
434 _matrix()->pivotToColumnIndex_[_get_birth(columnIndex)] = columnIndex + 1;
435 if (_is_paired(columnIndex + 1)){
436 _matrix()->pivotToColumnIndex_[columnIndex] = _matrix()->pivotToColumnIndex_[columnIndex + 1];
437 _matrix()->pivotToColumnIndex_[columnIndex + 1] = Master_matrix::template get_null_value<Index>();
441 if constexpr (Master_matrix::Option_list::has_column_pairings) {
442 _matrix()->_negative_positive_transpose_barcode(columnIndex);
446template <
class Master_matrix>
447inline bool RU_vine_swap<Master_matrix>::_positive_vine_swap(Index columnIndex)
449 const Pos_index iDeath = _get_death(columnIndex);
450 const Pos_index iiDeath = _get_death(columnIndex + 1);
452 if (iDeath != Master_matrix::template get_null_value<Pos_index>() &&
453 iiDeath != Master_matrix::template get_null_value<Pos_index>() &&
454 !(_matrix()->reducedMatrixR_.is_zero_entry(iiDeath, _get_row_id_from_position(columnIndex)))) {
455 if (iDeath < iiDeath) {
456 _swap_at_index(columnIndex);
457 _add_to(iDeath, iiDeath);
458 _positive_transpose(columnIndex);
462 _swap_at_index(columnIndex);
463 _add_to(iiDeath, iDeath);
467 _swap_at_index(columnIndex);
469 if (iDeath != Master_matrix::template get_null_value<Pos_index>() ||
470 iiDeath == Master_matrix::template get_null_value<Pos_index>() ||
471 _matrix()->reducedMatrixR_.is_zero_entry(iiDeath, _get_row_id_from_position(columnIndex + 1))) {
472 _positive_transpose(columnIndex);
478template <
class Master_matrix>
479inline bool RU_vine_swap<Master_matrix>::_negative_vine_swap(Index columnIndex)
481 const Pos_index iBirth = _get_birth(columnIndex);
482 const Pos_index iiBirth = _get_birth(columnIndex + 1);
484 _add_to(columnIndex, columnIndex + 1);
485 _swap_at_index(columnIndex);
487 if (iBirth < iiBirth) {
488 _negative_transpose(columnIndex);
492 _add_to(columnIndex, columnIndex + 1);
497template <
class Master_matrix>
498inline bool RU_vine_swap<Master_matrix>::_positive_negative_vine_swap(Index columnIndex)
500 _matrix()->mirrorMatrixU_.zero_entry(columnIndex, _get_row_id_from_position(columnIndex + 1));
502 _positive_negative_transpose(columnIndex);
503 _swap_at_index(columnIndex);
508template <
class Master_matrix>
509inline bool RU_vine_swap<Master_matrix>::_negative_positive_vine_swap(Index columnIndex)
511 _add_to(columnIndex, columnIndex + 1);
512 _swap_at_index(columnIndex);
513 _add_to(columnIndex, columnIndex + 1);
518template <
class Master_matrix>
521 if constexpr (Master_matrix::Option_list::has_column_pairings) {
522 return _matrix()->_death_val(simplexIndex);
524 if (!_matrix()->reducedMatrixR_.is_zero_column(simplexIndex))
525 return _matrix()->reducedMatrixR_.get_column(simplexIndex).get_pivot();
527 if constexpr (Master_matrix::Option_list::has_map_column_container) {
528 auto it = _matrix()->pivotToColumnIndex_.find(simplexIndex);
529 if (it == _matrix()->pivotToColumnIndex_.end())
return Master_matrix::template get_null_value<Pos_index>();
532 if (simplexIndex >= _matrix()->pivotToColumnIndex_.size())
533 return Master_matrix::template get_null_value<Pos_index>();
534 return _matrix()->pivotToColumnIndex_[simplexIndex];
539template <
class Master_matrix>
541 Index negativeSimplexIndex)
543 if constexpr (Master_matrix::Option_list::has_column_pairings) {
544 return _matrix()->_birth_val(negativeSimplexIndex);
546 return _matrix()->reducedMatrixR_.get_pivot(negativeSimplexIndex);
550template <
class Master_matrix>
552 Pos_index position)
const
554 const auto& map = _matrix()->positionToID_;
555 auto it = map.find(position);
556 return it == map.end() ? position : it->second;
Class managing the barcode for RU_vine_swap.
Definition ru_vine_swap.h:62
RU_barcode_swap()=default
Default constructor.
typename Master_matrix::Index Index
Definition ru_vine_swap.h:64
RU_barcode_swap(const RU_barcode_swap &toCopy)
Copy constructor.
Definition ru_vine_swap.h:79
typename Master_matrix::Pos_index Pos_index
Definition ru_vine_swap.h:66
typename Master_matrix::ID_index ID_index
Definition ru_vine_swap.h:65
RU_barcode_swap(RU_barcode_swap &&other) noexcept
Move constructor.
Definition ru_vine_swap.h:85
RU_pairing()=default
Default constructor.
RU_vine_swap()=default
Default constructor.
typename Master_matrix::ID_index ID_index
Definition ru_vine_swap.h:188
friend void swap(RU_vine_swap &swap1, RU_vine_swap &swap2) noexcept
Swap operator.
Definition ru_vine_swap.h:222
typename Master_matrix::Index Index
Definition ru_vine_swap.h:187
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:248
typename Master_matrix::Pos_index Pos_index
Definition ru_vine_swap.h:189
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:270
Persistence matrix namespace.
Definition FieldOperators.h:18
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:49
Empty structure. Inherited instead of RU_vine_swap, when vine swaps are not enabled.
Definition ru_vine_swap.h:37