base_swap.h
Go to the documentation of this file.
1 /* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT.
2  * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details.
3  * Author(s): Hannah Schreiber
4  *
5  * Copyright (C) 2022-23 Inria
6  *
7  * Modification(s):
8  * - YYYY/MM Author: Description of the modification
9  */
10 
17 #ifndef PM_BASE_SWAP_H
18 #define PM_BASE_SWAP_H
19 
20 #include <utility> //std::swap, std::move & std::exchange
21 #include <algorithm> //std::max
22 
23 namespace Gudhi {
24 namespace persistence_matrix {
25 
33  friend void swap([[maybe_unused]] Dummy_base_swap& d1, [[maybe_unused]] Dummy_base_swap& d2) {}
34 
35  Dummy_base_swap([[maybe_unused]] unsigned int numberOfColumns = 0) {}
36 };
37 
47 template <class Master_matrix, class Base_matrix>
48 class Base_swap {
49  public:
50  using matrix_type = typename Master_matrix::column_container_type;
51  using index = typename Master_matrix::index;
52  using id_index = typename Master_matrix::id_index;
57  Base_swap();
63  Base_swap(unsigned int numberOfColumns);
69  Base_swap(const Base_swap& matrixToCopy);
75  Base_swap(Base_swap&& other) noexcept;
76 
84  void swap_columns(index columnIndex1, index columnIndex2);
92  void swap_rows(id_index rowIndex1, id_index rowIndex2);
93 
101  friend void swap(Base_swap& base1, Base_swap& base2) {
102  base1.indexToRow_.swap(base2.indexToRow_);
103  base1.rowToIndex_.swap(base2.rowToIndex_);
104  std::swap(base1.rowSwapped_, base2.rowSwapped_);
105  }
106 
107  protected:
108  using index_dictionnary_type = typename Master_matrix::template dictionnary_type<index>;
109  using row_dictionnary_type = typename Master_matrix::template dictionnary_type<id_index>;
110 
111  index_dictionnary_type indexToRow_;
112  row_dictionnary_type rowToIndex_;
113  bool rowSwapped_;
115  void _orderRows();
116 
117  //access to inheritating matrix class
118  constexpr Base_matrix* _matrix() { return static_cast<Base_matrix*>(this); }
119  constexpr const Base_matrix* _matrix() const { return static_cast<const Base_matrix*>(this); }
120 };
121 
122 template <class Master_matrix, class Base_matrix>
123 inline Base_swap<Master_matrix, Base_matrix>::Base_swap() : rowSwapped_(false) {}
124 
125 template <class Master_matrix, class Base_matrix>
126 inline Base_swap<Master_matrix, Base_matrix>::Base_swap(unsigned int numberOfColumns)
127  : indexToRow_(numberOfColumns), rowToIndex_(numberOfColumns), rowSwapped_(false) {
128  for (index i = 0; i < numberOfColumns; i++) {
129  indexToRow_[i] = i;
130  rowToIndex_[i] = i;
131  }
132 }
133 
134 template <class Master_matrix, class Base_matrix>
136  : indexToRow_(matrixToCopy.indexToRow_),
137  rowToIndex_(matrixToCopy.rowToIndex_),
138  rowSwapped_(matrixToCopy.rowSwapped_) {}
139 
140 template <class Master_matrix, class Base_matrix>
141 inline Base_swap<Master_matrix, Base_matrix>::Base_swap(Base_swap<Master_matrix, Base_matrix>&& other) noexcept
142  : indexToRow_(std::move(other.indexToRow_)),
143  rowToIndex_(std::move(other.rowToIndex_)),
144  rowSwapped_(std::exchange(other.rowSwapped_, 0)) {}
145 
146 template <class Master_matrix, class Base_matrix>
147 inline void Base_swap<Master_matrix, Base_matrix>::swap_columns(index columnIndex1, index columnIndex2) {
148  swap(_matrix()->matrix_.at(columnIndex1), _matrix()->matrix_.at(columnIndex2));
149  if constexpr (Master_matrix::Option_list::has_row_access) rowSwapped_ = true; //to update column index in cells.
150 }
151 
152 template <class Master_matrix, class Base_matrix>
154  rowSwapped_ = true;
155 
156  if constexpr (Master_matrix::Option_list::has_map_column_container) {
157  auto it1 = indexToRow_.find(rowIndex1);
158  auto it2 = indexToRow_.find(rowIndex2);
159 
160  if (it1 == indexToRow_.end() && it2 == indexToRow_.end()) return;
161 
162  if (it1 == indexToRow_.end()) {
163  indexToRow_.emplace(rowIndex1, it2->second);
164  rowToIndex_.at(it2->second) = rowIndex1;
165  indexToRow_.erase(it2->second);
166  return;
167  }
168 
169  if (it2 == indexToRow_.end()) {
170  indexToRow_.emplace(rowIndex2, it1->second);
171  rowToIndex_.at(it1->second) = rowIndex2;
172  indexToRow_.erase(it1);
173  return;
174  }
175 
176  std::swap(rowToIndex_.at(it1->second), rowToIndex_.at(it2->second));
177  std::swap(it1->second, it2->second);
178  } else {
179  for (auto i = indexToRow_.size(); i <= std::max(rowIndex1, rowIndex2); ++i) indexToRow_.push_back(i);
180 
181  std::swap(rowToIndex_[indexToRow_[rowIndex1]], rowToIndex_[indexToRow_[rowIndex2]]);
182  std::swap(indexToRow_[rowIndex1], indexToRow_[rowIndex2]);
183  }
184 }
185 
186 template <class Master_matrix, class Base_matrix>
188  indexToRow_.swap(other.indexToRow_);
189  rowToIndex_.swap(other.rowToIndex_);
190  std::swap(rowSwapped_, other.rowSwapped_);
191  return *this;
192 }
193 
194 template <class Master_matrix, class Base_matrix>
196  for (unsigned int i = 0; i < _matrix()->get_number_of_columns(); i++) {
197  _matrix()->matrix_.at(i).reorder(rowToIndex_, i);
198  }
199  for (index i = 0; i < _matrix()->get_number_of_columns(); i++) {
200  indexToRow_[i] = i;
201  rowToIndex_[i] = i;
202  }
203  rowSwapped_ = false;
204 }
205 
206 } // namespace persistence_matrix
207 } // namespace Gudhi
208 
209 #endif // PM_BASE_SWAP_H
A basic matrix structure allowing to easily manipulate and access entire columns and rows,...
Definition: base_matrix.h:39
Class managing the column and row swaps in Base_matrix and Boundary_matrix.
Definition: base_swap.h:48
Base_swap(Base_swap &&other) noexcept
Move constructor.
Base_swap(const Base_swap &matrixToCopy)
Copy constructor.
Base_swap & operator=(Base_swap other)
Assign operator.
Definition: base_swap.h:187
typename Master_matrix::id_index id_index
Definition: base_swap.h:52
friend void swap(Base_swap &base1, Base_swap &base2)
Swap operator.
Definition: base_swap.h:101
Base_swap()
Default constructor.
Definition: base_swap.h:123
typename Master_matrix::index index
Definition: base_swap.h:51
void swap_columns(index columnIndex1, index columnIndex2)
Swaps the two columns at given indices in the column container. Does not updates the column index val...
Definition: base_swap.h:147
void swap_rows(id_index rowIndex1, id_index rowIndex2)
Swaps the two rows at the given indices, but in a lazy manner. That is, the swap is registered but no...
Definition: base_swap.h:153
typename Master_matrix::column_container_type matrix_type
Definition: base_swap.h:50
Data structure for matrices, and in particular thought for matrices representing filtered complexes i...
Definition: matrix.h:143
Gudhi namespace.
Definition: SimplicialComplexForAlpha.h:14
Empty structure. Inheritated instead of Base_swap, when the column and row swaps are not enabled.
Definition: base_swap.h:32