18 #ifndef PM_CHAIN_VINE_SWAP_H
19 #define PM_CHAIN_VINE_SWAP_H
29 namespace persistence_matrix {
42 [[maybe_unused]]
unsigned int columnIndex2)
57 template <
typename BirthComparatorFunction,
typename DeathComparatorFunction>
59 [[maybe_unused]]
const DeathComparatorFunction& deathComparator) {}
79 template <
typename Master_matrix>
83 using id_index =
typename Master_matrix::id_index;
84 using pos_index =
typename Master_matrix::pos_index;
97 :
CP(static_cast<const
CP&>(toCopy)), pivotToPosition_(toCopy.pivotToPosition_){};
104 :
CP(std::move(static_cast<
CP&>(other))), pivotToPosition_(std::move(other.pivotToPosition_)){};
107 using dictionnary_type =
typename Master_matrix::template dictionnary_type<pos_index>;
109 dictionnary_type pivotToPosition_;
112 if constexpr (Master_matrix::Option_list::has_map_column_container) {
113 std::swap(pivotToPosition_.at(pivot1), pivotToPosition_.at(pivot2));
115 std::swap(pivotToPosition_[pivot1], pivotToPosition_[pivot2]);
119 bool is_negative_in_pair(
id_index pivot)
const {
120 pos_index pos = _get_pivot_position(pivot);
121 return death(pivot) == pos;
125 pos_index pos1 = _get_pivot_position(pivot1);
126 pos_index pos2 = _get_pivot_position(pivot2);
130 std::swap(CP::indexToBar_.at(pos1), CP::indexToBar_.at(pos2));
134 pos_index pos1 = _get_pivot_position(pivot1);
135 pos_index pos2 = _get_pivot_position(pivot2);
139 std::swap(CP::indexToBar_.at(pos1), CP::indexToBar_.at(pos2));
143 pos_index pos1 = _get_pivot_position(pivot1);
144 pos_index pos2 = _get_pivot_position(pivot2);
148 std::swap(CP::indexToBar_.at(pos1), CP::indexToBar_.at(pos2));
152 pos_index pos1 = _get_pivot_position(pivot1);
153 pos_index pos2 = _get_pivot_position(pivot2);
157 std::swap(CP::indexToBar_.at(pos1), CP::indexToBar_.at(pos2));
161 pos_index pos1 = _get_pivot_position(pivot1);
162 pos_index pos2 = _get_pivot_position(pivot2);
163 return pos1 < pos2 ? (pos2 - pos1) == 1 : (pos1 - pos2) == 1;
168 pivotToPosition_.swap(other.pivotToPosition_);
171 swap(
static_cast<Chain_pairing<Master_matrix>&
>(swap1),
static_cast<Chain_pairing<Master_matrix>&
>(swap2));
172 swap1.pivotToPosition_.swap(swap2.pivotToPosition_);
176 pos_index simplexIndex = _get_pivot_position(pivot);
178 if constexpr (Master_matrix::Option_list::has_removable_columns) {
179 return CP::indexToBar_.at(simplexIndex)->death;
181 return CP::barcode_.at(CP::indexToBar_.at(simplexIndex)).death;
186 pos_index simplexIndex = _get_pivot_position(pivot);
188 if constexpr (Master_matrix::Option_list::has_removable_columns) {
189 return CP::indexToBar_.at(simplexIndex)->birth;
191 return CP::barcode_.at(CP::indexToBar_.at(simplexIndex)).birth;
197 if constexpr (Master_matrix::Option_list::has_map_column_container) {
198 return pivotToPosition_.at(
201 return pivotToPosition_[pivot];
206 if constexpr (Master_matrix::Option_list::has_removable_columns) {
207 return CP::indexToBar_.at(simplexIndex)->death;
209 return CP::barcode_.at(CP::indexToBar_.at(simplexIndex)).death;
214 if constexpr (Master_matrix::Option_list::has_removable_columns) {
215 return CP::indexToBar_.at(simplexIndex)->birth;
217 return CP::barcode_.at(CP::indexToBar_.at(simplexIndex)).birth;
230 template <
class Master_matrix>
231 class Chain_vine_swap :
public std::conditional<Master_matrix::Option_list::has_column_pairings,
232 Chain_barcode_swap<Master_matrix>,
233 Dummy_chain_vine_pairing
237 using index =
typename Master_matrix::index;
240 using matrix_type =
typename Master_matrix::column_container_type;
311 if constexpr (Master_matrix::Option_list::has_column_pairings) {
315 std::swap(swap1.birthComp_, swap2.birthComp_);
316 std::swap(swap1.deathComp_, swap2.deathComp_);
320 using CP =
typename std::conditional<Master_matrix::Option_list::has_column_pairings,
326 using chain_matrix =
typename Master_matrix::Chain_matrix_type;
331 bool _is_negative_in_pair(
index columnIndex);
334 index _positive_negative_vine_swap(
index columnIndex1,
index columnIndex2);
335 index _negative_positive_vine_swap(
index columnIndex1,
index columnIndex2);
338 constexpr chain_matrix* _matrix() {
return static_cast<chain_matrix*
>(
this); }
339 constexpr
const chain_matrix* _matrix()
const {
return static_cast<const chain_matrix*
>(
this); }
342 template <
class Master_matrix>
345 static_assert(Master_matrix::Option_list::has_column_pairings,
346 "If barcode is not stored, at least a birth comparator has to be specified.");
349 template <
class Master_matrix>
352 : CP(), birthComp_(std::move(birthComparator)), deathComp_(std::move(deathComparator))
355 template <
class Master_matrix>
357 : CP(static_cast<const CP&>(matrixToCopy)),
358 birthComp_(matrixToCopy.birthComp_),
359 deathComp_(matrixToCopy.deathComp_)
362 template <
class Master_matrix>
364 : CP(std::move(
static_cast<CP&
>(other))),
365 birthComp_(std::move(other.birthComp_)),
366 deathComp_(std::move(other.deathComp_))
369 template <
class Master_matrix>
373 const bool col1IsNeg = _is_negative_in_pair(columnIndex1);
374 const bool col2IsNeg = _is_negative_in_pair(columnIndex2);
376 if (col1IsNeg && col2IsNeg)
return _negative_vine_swap(columnIndex1, columnIndex2);
378 if (col1IsNeg)
return _negative_positive_vine_swap(columnIndex1, columnIndex2);
380 if (col2IsNeg)
return _positive_negative_vine_swap(columnIndex1, columnIndex2);
382 return _positive_vine_swap(columnIndex1, columnIndex2);
385 template <
class Master_matrix>
389 if constexpr (Master_matrix::Option_list::has_column_pairings) {
390 GUDHI_CHECK(CP::are_adjacent(_matrix()->get_pivot(columnIndex1), _matrix()->get_pivot(columnIndex2)),
391 std::invalid_argument(
392 "Chain_vine_swap::vine_swap - Columns to be swaped need to be adjacent in the 'real' matrix."));
395 const bool col1IsNeg = _is_negative_in_pair(columnIndex1);
396 const bool col2IsNeg = _is_negative_in_pair(columnIndex2);
398 if (col1IsNeg && col2IsNeg) {
399 if (_matrix()->is_zero_cell(columnIndex2, _matrix()->get_pivot(columnIndex1))) {
400 if constexpr (Master_matrix::Option_list::has_column_pairings) {
401 id_index pivot1 = _matrix()->get_pivot(columnIndex1);
402 id_index pivot2 = _matrix()->get_pivot(columnIndex2);
404 CP::negative_transpose(pivot1, pivot2);
405 CP::swap_positions(pivot1, pivot2);
409 return _negative_vine_swap(columnIndex1, columnIndex2);
413 if (_matrix()->is_zero_cell(columnIndex2, _matrix()->get_pivot(columnIndex1))) {
414 if constexpr (Master_matrix::Option_list::has_column_pairings) {
415 id_index pivot1 = _matrix()->get_pivot(columnIndex1);
416 id_index pivot2 = _matrix()->get_pivot(columnIndex2);
418 CP::negative_positive_transpose(pivot1, pivot2);
419 CP::swap_positions(pivot1, pivot2);
423 return _negative_positive_vine_swap(columnIndex1, columnIndex2);
427 if (_matrix()->is_zero_cell(columnIndex2, _matrix()->get_pivot(columnIndex1))) {
428 if constexpr (Master_matrix::Option_list::has_column_pairings) {
429 id_index pivot1 = _matrix()->get_pivot(columnIndex1);
430 id_index pivot2 = _matrix()->get_pivot(columnIndex2);
432 CP::positive_negative_transpose(pivot1, pivot2);
433 CP::swap_positions(pivot1, pivot2);
437 return _positive_negative_vine_swap(columnIndex1, columnIndex2);
440 if (_matrix()->is_zero_cell(columnIndex2, _matrix()->get_pivot(columnIndex1))) {
441 if constexpr (Master_matrix::Option_list::has_column_pairings) {
442 id_index pivot1 = _matrix()->get_pivot(columnIndex1);
443 id_index pivot2 = _matrix()->get_pivot(columnIndex2);
445 CP::positive_transpose(pivot1, pivot2);
446 CP::swap_positions(pivot1, pivot2);
450 return _positive_vine_swap(columnIndex1, columnIndex2);
453 template <
class Master_matrix>
456 CP::operator=(other);
457 std::swap(birthComp_, other.birthComp_);
458 std::swap(deathComp_, other.deathComp_);
462 template <
class Master_matrix>
465 if constexpr (Master_matrix::Option_list::has_column_pairings) {
466 return CP::is_negative_in_pair(_matrix()->get_pivot(columnIndex));
468 auto& col = _matrix()->get_column(columnIndex);
469 if (!col.is_paired())
return false;
470 return col.get_pivot() > _matrix()->get_pivot(col.get_paired_chain_index());
474 template <
class Master_matrix>
476 index columnIndex1, index columnIndex2)
478 auto& col1 = _matrix()->get_column(columnIndex1);
479 auto& col2 = _matrix()->get_column(columnIndex2);
481 if constexpr (Master_matrix::Option_list::has_column_pairings) {
482 CP::swap_positions(col1.get_pivot(), col2.get_pivot());
485 if (!col1.is_paired()) {
486 bool hasSmallerBirth;
487 if constexpr (Master_matrix::Option_list::has_column_pairings) {
489 hasSmallerBirth = (CP::birth(col2.get_pivot()) < CP::birth(col1.get_pivot()));
491 hasSmallerBirth = birthComp_(columnIndex1, columnIndex2);
494 if (!col2.is_paired() && hasSmallerBirth) {
495 _matrix()->add_to(columnIndex1, columnIndex2);
496 if constexpr (Master_matrix::Option_list::has_column_pairings) {
497 CP::positive_transpose(col1.get_pivot(), col2.get_pivot());
501 _matrix()->add_to(columnIndex2, columnIndex1);
506 if (!col2.is_paired()) {
507 static_cast<chain_matrix*
>(
this)->add_to(columnIndex1, columnIndex2);
508 if constexpr (Master_matrix::Option_list::has_column_pairings) {
509 CP::positive_transpose(col1.get_pivot(), col2.get_pivot());
514 bool hasSmallerDeath;
515 if constexpr (Master_matrix::Option_list::has_column_pairings) {
517 hasSmallerDeath = (CP::death(col2.get_pivot()) < CP::death(col1.get_pivot()));
519 hasSmallerDeath = deathComp_(columnIndex1, columnIndex2);
525 _matrix()->add_to(col1.get_paired_chain_index(), col2.get_paired_chain_index());
526 _matrix()->add_to(columnIndex1, columnIndex2);
527 if constexpr (Master_matrix::Option_list::has_column_pairings) {
528 CP::positive_transpose(col1.get_pivot(), col2.get_pivot());
533 _matrix()->add_to(col2.get_paired_chain_index(), col1.get_paired_chain_index());
534 _matrix()->add_to(columnIndex2, columnIndex1);
539 template <
class Master_matrix>
541 index columnIndex1, index columnIndex2)
543 _matrix()->add_to(columnIndex1, columnIndex2);
545 if constexpr (Master_matrix::Option_list::has_column_pairings) {
546 id_index pivot1 = _matrix()->get_pivot(columnIndex1);
547 id_index pivot2 = _matrix()->get_pivot(columnIndex2);
549 CP::positive_negative_transpose(pivot1, pivot2);
550 CP::swap_positions(pivot1, pivot2);
556 template <
class Master_matrix>
558 index columnIndex1, index columnIndex2)
560 _matrix()->add_to(columnIndex2, columnIndex1);
562 if constexpr (Master_matrix::Option_list::has_column_pairings) {
563 CP::swap_positions(_matrix()->get_pivot(columnIndex1), _matrix()->get_pivot(columnIndex2));
569 template <
class Master_matrix>
571 index columnIndex1, index columnIndex2)
573 auto& col1 = _matrix()->get_column(columnIndex1);
574 auto& col2 = _matrix()->get_column(columnIndex2);
576 index pairedIndex1 = col1.get_paired_chain_index();
577 index pairedIndex2 = col2.get_paired_chain_index();
579 bool hasSmallerBirth;
580 if constexpr (Master_matrix::Option_list::has_column_pairings) {
581 hasSmallerBirth = (CP::birth(col1.get_pivot()) < CP::birth(col2.get_pivot()));
583 hasSmallerBirth = birthComp_(pairedIndex1, pairedIndex2);
586 if constexpr (Master_matrix::Option_list::has_column_pairings) {
587 CP::swap_positions(col1.get_pivot(), col2.get_pivot());
592 _matrix()->add_to(pairedIndex1, pairedIndex2);
593 _matrix()->add_to(columnIndex1, columnIndex2);
595 if constexpr (Master_matrix::Option_list::has_column_pairings) {
596 CP::negative_transpose(col1.get_pivot(), col2.get_pivot());
602 _matrix()->add_to(pairedIndex2, pairedIndex1);
603 _matrix()->add_to(columnIndex2, columnIndex1);
Contains the Chain_pairing class and Dummy_chain_pairing structure.
Class managing the barcode for Chain_vine_swap.
Definition: chain_vine_swap.h:81
typename Master_matrix::pos_index pos_index
Definition: chain_vine_swap.h:84
Chain_barcode_swap()
Default constructor.
Definition: chain_vine_swap.h:90
typename Master_matrix::id_index id_index
Definition: chain_vine_swap.h:83
Chain_barcode_swap(const Chain_barcode_swap &toCopy)
Copy constructor.
Definition: chain_vine_swap.h:96
Chain_barcode_swap(Chain_barcode_swap &&other)
Move constructor.
Definition: chain_vine_swap.h:103
Class managing the barcode for Chain_matrix if the option was enabled.
Definition: chain_pairing.h:46
Chain_pairing & operator=(Chain_pairing other)
Assign operator.
Definition: chain_pairing.h:123
Class managing the vine swaps for Chain_matrix.
Definition: chain_vine_swap.h:235
Chain_vine_swap()
Default constructor. Only available if PersistenceMatrixOptions::has_column_pairings is true.
Definition: chain_vine_swap.h:343
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:370
Chain_vine_swap & operator=(Chain_vine_swap other)
Assign operator.
Definition: chain_vine_swap.h:454
index vine_swap(index columnIndex1, index columnIndex2)
Does a vine swap between two faces which are consecutives in the filtration. Roughly,...
Definition: chain_vine_swap.h:386
friend void swap(Chain_vine_swap &swap1, Chain_vine_swap &swap2)
Swap operator.
Definition: chain_vine_swap.h:310
typename Master_matrix::column_container_type matrix_type
Definition: chain_vine_swap.h:240
typename Master_matrix::Column_type Column_type
Definition: chain_vine_swap.h:241
typename Master_matrix::id_index id_index
Definition: chain_vine_swap.h:238
typename Master_matrix::pos_index pos_index
Definition: chain_vine_swap.h:239
typename Master_matrix::index index
Definition: chain_vine_swap.h:237
bool(* EventCompFuncPointer)(pos_index, pos_index)
Definition: chain_vine_swap.h:242
constexpr bool _no_G_death_comparator([[maybe_unused]] unsigned int columnIndex1, [[maybe_unused]] unsigned int columnIndex2)
Default death comparator. Simply assumes that two positive paired columns are never swapped....
Definition: chain_vine_swap.h:41
Gudhi namespace.
Definition: SimplicialComplexForAlpha.h:14
Empty structure. Inheritated instead of Chain_barcode_swap, when the barcode is not stored.
Definition: chain_vine_swap.h:68
Empty structure. Inheritated instead of Chain_vine_swap, when vine swappes are not enabled.
Definition: chain_vine_swap.h:53