18 #ifndef PM_RU_VINE_SWAP_H
19 #define PM_RU_VINE_SWAP_H
22 #include <type_traits>
30 namespace persistence_matrix {
60 template <
class Master_matrix>
61 class RU_vine_swap :
public std::conditional<Master_matrix::Option_list::has_column_pairings,
62 RU_pairing<Master_matrix>,
67 using index =
typename Master_matrix::index;
68 using id_index =
typename Master_matrix::id_index;
69 using pos_index =
typename Master_matrix::pos_index;
119 if constexpr (Master_matrix::Option_list::has_column_pairings) {
122 swap1.positionToRowIdx_.swap(swap2.positionToRowIdx_);
129 std::vector<id_index> positionToRowIdx_;
132 using RUP =
typename std::conditional<Master_matrix::Option_list::has_column_pairings,
136 using ru_matrix =
typename Master_matrix::RU_matrix_type;
138 bool _is_paired(
index columnIndex);
140 void _swap_at_index(
index columnIndex);
141 void _add_to(
index sourceIndex,
index targetIndex);
142 void _positive_transpose(
index columnIndex);
143 void _negative_transpose(
index columnIndex);
144 void _positive_negative_transpose(
index columnIndex);
145 void _negative_positive_transpose(
index columnIndex);
146 bool _positive_vine_swap(
index columnIndex);
147 bool _negative_vine_swap(
index columnIndex);
148 bool _positive_negative_vine_swap(
index columnIndex);
149 bool _negative_positive_vine_swap(
index columnIndex);
156 constexpr ru_matrix* _matrix() {
return static_cast<ru_matrix*
>(
this); }
157 constexpr
const ru_matrix* _matrix()
const {
return static_cast<const ru_matrix*
>(
this); }
160 template <
class Master_matrix>
164 template <
class Master_matrix>
166 : RUP(static_cast<const RUP&>(matrixToCopy)), positionToRowIdx_(matrixToCopy.positionToRowIdx_)
169 template <
class Master_matrix>
171 : RUP(std::move(
static_cast<RUP&
>(other))), positionToRowIdx_(std::move(other.positionToRowIdx_))
174 template <
class Master_matrix>
177 GUDHI_CHECK(
index < _matrix()->reducedMatrixR_.get_number_of_columns() - 1,
178 std::invalid_argument(
"RU_vine_swap::vine_swap_with_z_eq_1_case - Index to swap out of bound."));
180 bool iIsPositive = _matrix()->reducedMatrixR_.is_zero_column(
index);
181 bool iiIsPositive = _matrix()->reducedMatrixR_.is_zero_column(
index + 1);
183 if (iIsPositive && iiIsPositive) {
184 _matrix()->mirrorMatrixU_.zero_cell(
index, positionToRowIdx_[
index + 1]);
185 return _positive_vine_swap(
index);
186 }
else if (!iIsPositive && !iiIsPositive) {
187 return _negative_vine_swap(
index);
188 }
else if (iIsPositive && !iiIsPositive) {
189 return _positive_negative_vine_swap(
index);
191 return _negative_positive_vine_swap(
index);
195 template <
class Master_matrix>
198 GUDHI_CHECK(
index < _matrix()->reducedMatrixR_.get_number_of_columns() - 1,
199 std::invalid_argument(
"RU_vine_swap::vine_swap - Index to swap out of bound."));
201 bool iIsPositive = _matrix()->reducedMatrixR_.is_zero_column(
index);
202 bool iiIsPositive = _matrix()->reducedMatrixR_.is_zero_column(
index + 1);
204 if (iIsPositive && iiIsPositive) {
205 if (_matrix()->reducedMatrixR_.get_column_dimension(
index) !=
206 _matrix()->reducedMatrixR_.get_column_dimension(
index + 1)) {
207 _positive_transpose(
index);
208 _swap_at_index(
index);
211 if (!_matrix()->mirrorMatrixU_.is_zero_cell(
index, positionToRowIdx_[
index + 1])) {
212 _matrix()->mirrorMatrixU_.zero_cell(
index, positionToRowIdx_[
index + 1]);
214 return _positive_vine_swap(
index);
215 }
else if (!iIsPositive && !iiIsPositive) {
216 if (_matrix()->reducedMatrixR_.get_column_dimension(
index) !=
217 _matrix()->reducedMatrixR_.get_column_dimension(
index + 1) ||
218 _matrix()->mirrorMatrixU_.is_zero_cell(
index, positionToRowIdx_[
index + 1])) {
219 _negative_transpose(
index);
220 _swap_at_index(
index);
223 return _negative_vine_swap(
index);
224 }
else if (iIsPositive && !iiIsPositive) {
225 if (_matrix()->reducedMatrixR_.get_column_dimension(
index) !=
226 _matrix()->reducedMatrixR_.get_column_dimension(
index + 1) ||
227 _matrix()->mirrorMatrixU_.is_zero_cell(
index, positionToRowIdx_[
index + 1])) {
228 _positive_negative_transpose(
index);
229 _swap_at_index(
index);
232 return _positive_negative_vine_swap(
index);
234 if (_matrix()->reducedMatrixR_.get_column_dimension(
index) !=
235 _matrix()->reducedMatrixR_.get_column_dimension(
index + 1) ||
236 _matrix()->mirrorMatrixU_.is_zero_cell(
index, positionToRowIdx_[
index + 1])) {
237 _negative_positive_transpose(
index);
238 _swap_at_index(
index);
241 return _negative_positive_vine_swap(
index);
245 template <
class Master_matrix>
248 RUP::operator=(other);
249 positionToRowIdx_.swap(other.positionToRowIdx_);
253 template <
class Master_matrix>
256 if constexpr (Master_matrix::Option_list::has_column_pairings) {
257 return _get_death(columnIndex) !=
static_cast<pos_index
>(-1);
259 if (!_matrix()->reducedMatrixR_.is_zero_column(columnIndex))
return true;
261 if constexpr (Master_matrix::Option_list::has_map_column_container) {
262 if (_matrix()->pivotToColumnIndex_.find(columnIndex) == _matrix()->pivotToColumnIndex_.end())
return false;
264 if (_matrix()->pivotToColumnIndex_.operator[](columnIndex) ==
static_cast<index
>(-1))
return false;
271 template <
class Master_matrix>
272 inline void RU_vine_swap<Master_matrix>::_swap_at_index(index columnIndex)
274 _matrix()->reducedMatrixR_.swap_columns(columnIndex, columnIndex + 1);
275 _matrix()->reducedMatrixR_.swap_rows(positionToRowIdx_[columnIndex], positionToRowIdx_[columnIndex + 1]);
276 _matrix()->mirrorMatrixU_.swap_columns(columnIndex, columnIndex + 1);
277 _matrix()->mirrorMatrixU_.swap_rows(positionToRowIdx_[columnIndex], positionToRowIdx_[columnIndex + 1]);
280 template <
class Master_matrix>
281 inline void RU_vine_swap<Master_matrix>::_add_to(index sourceIndex, index targetIndex)
283 _matrix()->reducedMatrixR_.add_to(sourceIndex, targetIndex);
284 _matrix()->mirrorMatrixU_.add_to(targetIndex, sourceIndex);
287 template <
class Master_matrix>
288 inline void RU_vine_swap<Master_matrix>::_positive_transpose(index columnIndex)
290 if constexpr (Master_matrix::Option_list::has_map_column_container) {
291 if (_is_paired(columnIndex) && _is_paired(columnIndex + 1)) {
292 std::swap(_matrix()->pivotToColumnIndex_.at(columnIndex), _matrix()->pivotToColumnIndex_.at(columnIndex + 1));
293 }
else if (_is_paired(columnIndex)) {
294 _matrix()->pivotToColumnIndex_.emplace(columnIndex + 1, _matrix()->pivotToColumnIndex_.at(columnIndex));
295 _matrix()->pivotToColumnIndex_.erase(columnIndex);
296 }
else if (_is_paired(columnIndex + 1)) {
297 _matrix()->pivotToColumnIndex_.emplace(columnIndex, _matrix()->pivotToColumnIndex_.at(columnIndex + 1));
298 _matrix()->pivotToColumnIndex_.erase(columnIndex + 1);
301 std::swap(_matrix()->pivotToColumnIndex_.operator[](columnIndex),
302 _matrix()->pivotToColumnIndex_.operator[](columnIndex + 1));
305 if constexpr (Master_matrix::Option_list::has_column_pairings) {
306 _birth(columnIndex) = columnIndex + 1;
307 _birth(columnIndex + 1) = columnIndex;
308 std::swap(RUP::indexToBar_.at(columnIndex), RUP::indexToBar_.at(columnIndex + 1));
312 template <
class Master_matrix>
313 inline void RU_vine_swap<Master_matrix>::_negative_transpose(index columnIndex)
315 if constexpr (Master_matrix::Option_list::has_column_pairings) {
316 _death(columnIndex) = columnIndex + 1;
317 _death(columnIndex + 1) = columnIndex;
318 std::swap(RUP::indexToBar_.at(columnIndex), RUP::indexToBar_.at(columnIndex + 1));
320 std::swap(_matrix()->pivotToColumnIndex_.at(_get_birth(columnIndex)),
321 _matrix()->pivotToColumnIndex_.at(_get_birth(columnIndex + 1)));
324 template <
class Master_matrix>
325 inline void RU_vine_swap<Master_matrix>::_positive_negative_transpose(index columnIndex)
327 _matrix()->pivotToColumnIndex_.at(_get_birth(columnIndex + 1)) = columnIndex;
328 if constexpr (Master_matrix::Option_list::has_map_column_container) {
329 if (_is_paired(columnIndex)) {
330 _matrix()->pivotToColumnIndex_.emplace(columnIndex + 1, _matrix()->pivotToColumnIndex_.at(columnIndex));
331 _matrix()->pivotToColumnIndex_.erase(columnIndex);
334 _matrix()->pivotToColumnIndex_.operator[](columnIndex + 1) = _matrix()->pivotToColumnIndex_.operator[](columnIndex);
335 _matrix()->pivotToColumnIndex_.operator[](columnIndex) = -1;
338 if constexpr (Master_matrix::Option_list::has_column_pairings) {
339 _birth(columnIndex) = columnIndex + 1;
340 _death(columnIndex + 1) = columnIndex;
341 std::swap(RUP::indexToBar_.at(columnIndex), RUP::indexToBar_.at(columnIndex + 1));
345 template <
class Master_matrix>
346 inline void RU_vine_swap<Master_matrix>::_negative_positive_transpose(index columnIndex)
348 _matrix()->pivotToColumnIndex_.at(_get_birth(columnIndex)) = columnIndex + 1;
349 if constexpr (Master_matrix::Option_list::has_map_column_container) {
350 if (_is_paired(columnIndex + 1)) {
351 _matrix()->pivotToColumnIndex_.emplace(columnIndex, _matrix()->pivotToColumnIndex_.at(columnIndex + 1));
352 _matrix()->pivotToColumnIndex_.erase(columnIndex + 1);
355 _matrix()->pivotToColumnIndex_.operator[](columnIndex) = _matrix()->pivotToColumnIndex_.operator[](columnIndex + 1);
356 _matrix()->pivotToColumnIndex_.operator[](columnIndex + 1) = -1;
359 if constexpr (Master_matrix::Option_list::has_column_pairings) {
360 _death(columnIndex) = columnIndex + 1;
361 _birth(columnIndex + 1) = columnIndex;
362 std::swap(RUP::indexToBar_.at(columnIndex), RUP::indexToBar_.at(columnIndex + 1));
366 template <
class Master_matrix>
367 inline bool RU_vine_swap<Master_matrix>::_positive_vine_swap(index columnIndex)
369 const pos_index iDeath = _get_death(columnIndex);
370 const pos_index iiDeath = _get_death(columnIndex + 1);
372 if (iDeath !=
static_cast<pos_index
>(-1) && iiDeath !=
static_cast<pos_index
>(-1) &&
373 !(_matrix()->reducedMatrixR_.is_zero_cell(iiDeath, positionToRowIdx_[columnIndex]))) {
374 if (iDeath < iiDeath) {
375 _swap_at_index(columnIndex);
376 _add_to(iDeath, iiDeath);
377 _positive_transpose(columnIndex);
381 _swap_at_index(columnIndex);
382 _add_to(iiDeath, iDeath);
386 _swap_at_index(columnIndex);
388 if (iDeath !=
static_cast<pos_index
>(-1) || iiDeath ==
static_cast<pos_index
>(-1) ||
389 _matrix()->reducedMatrixR_.is_zero_cell(iiDeath, positionToRowIdx_[columnIndex + 1])) {
390 _positive_transpose(columnIndex);
396 template <
class Master_matrix>
397 inline bool RU_vine_swap<Master_matrix>::_negative_vine_swap(index columnIndex)
399 const pos_index iBirth = _get_birth(columnIndex);
400 const pos_index iiBirth = _get_birth(columnIndex + 1);
402 _add_to(columnIndex, columnIndex + 1);
403 _swap_at_index(columnIndex);
405 if (iBirth < iiBirth) {
406 _negative_transpose(columnIndex);
410 _add_to(columnIndex, columnIndex + 1);
415 template <
class Master_matrix>
416 inline bool RU_vine_swap<Master_matrix>::_positive_negative_vine_swap(index columnIndex)
418 _matrix()->mirrorMatrixU_.zero_cell(columnIndex, positionToRowIdx_[columnIndex + 1]);
420 _swap_at_index(columnIndex);
421 _positive_negative_transpose(columnIndex);
426 template <
class Master_matrix>
427 inline bool RU_vine_swap<Master_matrix>::_negative_positive_vine_swap(index columnIndex)
429 _add_to(columnIndex, columnIndex + 1);
430 _swap_at_index(columnIndex);
431 _add_to(columnIndex, columnIndex + 1);
436 template <
class Master_matrix>
439 static_assert(Master_matrix::Option_list::has_column_pairings,
"Pairing necessary to modify death value.");
441 if constexpr (Master_matrix::Option_list::has_removable_columns) {
442 return RUP::indexToBar_.at(simplexIndex)->death;
444 return RUP::barcode_.at(RUP::indexToBar_.at(simplexIndex)).death;
448 template <
class Master_matrix>
451 static_assert(Master_matrix::Option_list::has_column_pairings,
"Pairing necessary to modify birth value.");
453 if constexpr (Master_matrix::Option_list::has_removable_columns) {
454 return RUP::indexToBar_.at(simplexIndex)->birth;
456 return RUP::barcode_.at(RUP::indexToBar_.at(simplexIndex)).birth;
460 template <
class Master_matrix>
463 if constexpr (Master_matrix::Option_list::has_column_pairings) {
464 if constexpr (Master_matrix::Option_list::has_removable_columns) {
465 return RUP::indexToBar_.at(simplexIndex)->death;
467 return RUP::barcode_.at(RUP::indexToBar_.at(simplexIndex)).death;
470 if (!_matrix()->reducedMatrixR_.is_zero_column(simplexIndex))
471 return _matrix()->reducedMatrixR_.get_column(simplexIndex).get_pivot();
473 if constexpr (Master_matrix::Option_list::has_map_column_container) {
474 auto it = _matrix()->pivotToColumnIndex_.find(simplexIndex);
475 if (it == _matrix()->pivotToColumnIndex_.end())
return -1;
478 return _matrix()->pivotToColumnIndex_.operator[](simplexIndex);
483 template <
class Master_matrix>
485 index negativeSimplexIndex)
487 if constexpr (Master_matrix::Option_list::has_column_pairings) {
488 if constexpr (Master_matrix::Option_list::has_removable_columns) {
489 return RUP::indexToBar_.at(negativeSimplexIndex)->birth;
491 return RUP::barcode_.at(RUP::indexToBar_.at(negativeSimplexIndex)).birth;
494 return _matrix()->reducedMatrixR_.get_pivot(negativeSimplexIndex);
Class managing the barcode for RU_matrix if the option was enabled.
Definition: ru_pairing.h:46
Class managing the vine swaps for RU_matrix.
Definition: ru_vine_swap.h:65
typename Master_matrix::index index
Definition: ru_vine_swap.h:67
typename Master_matrix::id_index id_index
Definition: ru_vine_swap.h:68
friend void swap(RU_vine_swap &swap1, RU_vine_swap &swap2)
Swap operator.
Definition: ru_vine_swap.h:118
RU_vine_swap & operator=(RU_vine_swap other)
Assign operator.
Definition: ru_vine_swap.h:246
RU_vine_swap()
Default constructor.
Definition: ru_vine_swap.h:161
bool vine_swap(pos_index index)
Does a vine swap between two faces which are consecutives in the filtration. Roughly,...
Definition: ru_vine_swap.h:196
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:175
typename Master_matrix::pos_index pos_index
Definition: ru_vine_swap.h:69
Gudhi namespace.
Definition: SimplicialComplexForAlpha.h:14
Contains the RU_pairing class and Dummy_ru_pairing structure.
Empty structure. Inheritated instead of RU_pairing, when the barcode is not stored.
Definition: ru_vine_swap.h:48
Empty structure. Inheritated instead of RU_vine_swap, when vine swappes are not enabled.
Definition: ru_vine_swap.h:38