base_pairing.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-24 Inria
6  *
7  * Modification(s):
8  * - YYYY/MM Author: Description of the modification
9  */
10 
17 #ifndef PM_BASE_PAIRING_H
18 #define PM_BASE_PAIRING_H
19 
20 #include <utility> //std::swap & std::move
21 #include <unordered_map>
22 #include <algorithm>
23 #include <vector>
24 
25 namespace Gudhi {
26 namespace persistence_matrix {
27 
36  friend void swap([[maybe_unused]] Dummy_base_pairing& d1, [[maybe_unused]] Dummy_base_pairing& d2) {}
37 };
38 
47 template <class Master_matrix>
49 {
50  public:
51  using Bar = typename Master_matrix::Bar;
52  using barcode_type = typename Master_matrix::barcode_type;
53  using matrix_type = typename Master_matrix::column_container_type;
54  using index = typename Master_matrix::index;
55  using dimension_type = typename Master_matrix::dimension_type;
60  Base_pairing();
66  Base_pairing(const Base_pairing& matrixToCopy);
72  Base_pairing(Base_pairing&& other) noexcept;
73 
84 
92  friend void swap(Base_pairing& pairing1, Base_pairing& pairing2) {
93  pairing1.barcode_.swap(pairing2.barcode_);
94  pairing1.deathToBar_.swap(pairing2.deathToBar_);
95  std::swap(pairing1.isReduced_, pairing2.isReduced_);
96  }
97 
98  protected:
99  using pos_index = typename Master_matrix::pos_index;
100  using dictionnary_type = typename Master_matrix::bar_dictionnary_type;
101  using base_matrix = typename Master_matrix::Boundary_matrix_type;
102 
103  barcode_type barcode_;
104  dictionnary_type deathToBar_;
105  bool isReduced_;
107  void _reduce();
108  void _remove_last(pos_index columnIndex);
109 
110  //access to inheritating Boundary_matrix class
111  constexpr base_matrix* _matrix() { return static_cast<base_matrix*>(this); }
112  constexpr const base_matrix* _matrix() const { return static_cast<const base_matrix*>(this); }
113 };
114 
115 template <class Master_matrix>
116 inline Base_pairing<Master_matrix>::Base_pairing() : isReduced_(false)
117 {}
118 
119 template <class Master_matrix>
121  : barcode_(matrixToCopy.barcode_), deathToBar_(matrixToCopy.deathToBar_), isReduced_(matrixToCopy.isReduced_)
122 {}
123 
124 template <class Master_matrix>
126  : barcode_(std::move(other.barcode_)),
127  deathToBar_(std::move(other.deathToBar_)),
128  isReduced_(std::move(other.isReduced_))
129 {}
130 
131 template <class Master_matrix>
133 {
134  if (!isReduced_) _reduce();
135  return barcode_;
136 }
137 
138 template <class Master_matrix>
140 {
141  using id_index = typename Master_matrix::index;
142  std::unordered_map<id_index, index> pivotsToColumn(_matrix()->get_number_of_columns());
143 
144  auto dim = _matrix()->get_max_dimension();
145  std::vector<std::vector<index> > columnsByDim(dim + 1);
146  for (unsigned int i = 0; i < _matrix()->get_number_of_columns(); i++) {
147  columnsByDim[dim - _matrix()->get_column_dimension(i)].push_back(i);
148  }
149 
150  for (const auto& cols : columnsByDim) {
151  for (index i : cols) {
152  auto& curr = _matrix()->get_column(i);
153  if (curr.is_empty()) {
154  if (pivotsToColumn.find(i) == pivotsToColumn.end()) {
155  barcode_.emplace_back(dim, i, -1);
156  }
157  } else {
158  id_index pivot = curr.get_pivot();
159 
160  while (pivot != static_cast<id_index>(-1) && pivotsToColumn.find(pivot) != pivotsToColumn.end()) {
161  if constexpr (Master_matrix::Option_list::is_z2) {
162  curr += _matrix()->get_column(pivotsToColumn.at(pivot));
163  } else {
164  auto& toadd = _matrix()->get_column(pivotsToColumn.at(pivot));
165  typename Master_matrix::element_type coef = toadd.get_pivot_value();
166  auto& operators = _matrix()->colSettings_->operators;
167  coef = operators.get_inverse(coef);
168  operators.multiply_inplace(coef, operators.get_characteristic() - curr.get_pivot_value());
169  curr.multiply_source_and_add(toadd, coef);
170  }
171 
172  pivot = curr.get_pivot();
173  }
174 
175  if (pivot != static_cast<id_index>(-1)) {
176  pivotsToColumn.emplace(pivot, i);
177  _matrix()->get_column(pivot).clear();
178  barcode_.emplace_back(dim - 1, pivot, i);
179  } else {
180  curr.clear();
181  barcode_.emplace_back(dim, i, -1);
182  }
183  }
184  }
185  --dim;
186  }
187 
188  if constexpr (Master_matrix::Option_list::has_removable_columns) {
189  // sort barcode by birth such that a removal is trivial
190  std::sort(barcode_.begin(), barcode_.end(), [](const Bar& b1, const Bar& b2) { return b1.birth < b2.birth; });
191  // map can only be constructed once barcode is sorted
192  for (index i = 0; i < barcode_.size(); ++i) {
193  auto d = barcode_[i].death;
194  if (d != static_cast<pos_index>(-1)) {
195  deathToBar_.emplace(d, i);
196  }
197  }
198  }
199 
200  isReduced_ = true;
201 }
202 
203 template <class Master_matrix>
204 inline void Base_pairing<Master_matrix>::_remove_last(pos_index columnIndex)
205 {
206  static_assert(Master_matrix::Option_list::has_removable_columns, "remove_last not available.");
207 
208  if (isReduced_) {
209  auto it = deathToBar_.find(columnIndex);
210 
211  if (it == deathToBar_.end()) { // birth
212  barcode_.pop_back(); // sorted by birth and columnIndex has to be the heighest one
213  } else { // death
214  barcode_[it->second].death = -1;
215  deathToBar_.erase(it);
216  };
217  }
218 }
219 
220 template <class Master_matrix>
222 {
223  barcode_.swap(other.barcode_);
224  deathToBar_.swap(other.deathToBar_);
225  std::swap(isReduced_, other.isReduced_);
226  return *this;
227 }
228 
229 } // namespace persistence_matrix
230 } // namespace Gudhi
231 
232 #endif // PM_BASE_PAIRING_H
Class managing the barcode for Boundary_matrix if the option was enabled.
Definition: base_pairing.h:49
typename Master_matrix::barcode_type barcode_type
Definition: base_pairing.h:52
typename Master_matrix::Bar Bar
Definition: base_pairing.h:51
typename Master_matrix::index index
Definition: base_pairing.h:54
friend void swap(Base_pairing &pairing1, Base_pairing &pairing2)
Swap operator.
Definition: base_pairing.h:92
Base_pairing & operator=(Base_pairing other)
Assign operator.
Definition: base_pairing.h:221
typename Master_matrix::column_container_type matrix_type
Definition: base_pairing.h:53
typename Master_matrix::dimension_type dimension_type
Definition: base_pairing.h:55
const barcode_type & get_current_barcode()
Reduces the matrix stored in Boundary_matrix and computes the corresponding barcode.
Definition: base_pairing.h:132
Base_pairing()
Default constructor.
Definition: base_pairing.h:116
Gudhi namespace.
Definition: SimplicialComplexForAlpha.h:14
Empty structure. Inheritated instead of Base_pairing, when the computation of the barcode was not ena...
Definition: base_pairing.h:35