Loading...
Searching...
No Matches
chain_rep_cycles.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 Inria
6 *
7 * Modification(s):
8 * - YYYY/MM Author: Description of the modification
9 */
10
17
18#ifndef PM_CHAIN_REP_CYCLES_H
19#define PM_CHAIN_REP_CYCLES_H
20
21#include <vector>
22
23#ifdef GUDHI_USE_TBB
24#include <tbb/parallel_for.h>
25#endif
26
27#include <gudhi/Debug_utils.h>
29
30namespace Gudhi {
31namespace persistence_matrix {
32
41 friend void swap([[maybe_unused]] Dummy_chain_representative_cycles& d1,
42 [[maybe_unused]] Dummy_chain_representative_cycles& d2) noexcept
43 {}
44};
45
54template <class Master_matrix>
56{
57 public:
58 using Bar = typename Master_matrix::Bar;
59 using Cycle = typename Master_matrix::Cycle;
60 using Column_container = typename Master_matrix::Column_container;
61 using Index = typename Master_matrix::Index;
62 using ID_index = typename Master_matrix::ID_index;
63 using Dimension = typename Master_matrix::Dimension;
64
69
76 void update_all_representative_cycles(Dimension dim = Master_matrix::template get_null_value<Dimension>());
77
87 void update_representative_cycle(const Bar& bar);
88
95 const std::vector<Cycle>& get_all_representative_cycles() const;
104 const Cycle& get_representative_cycle(const Bar& bar) const;
105
110 {
111 base1.representativeCycles_.swap(base2.representativeCycles_);
112 base1.birthToCycle_.swap(base2.birthToCycle_);
113 }
114
115 protected:
116 void _reset();
117
118 private:
119 using Master_chain_matrix = typename Master_matrix::Master_chain_matrix;
120
121 std::vector<Cycle> representativeCycles_;
122 std::vector<Index> birthToCycle_;
123
124 // access to inheriting Chain_matrix class
125 constexpr Master_chain_matrix* _matrix() { return static_cast<Master_chain_matrix*>(this); }
126
127 constexpr const Master_chain_matrix* _matrix() const { return static_cast<const Master_chain_matrix*>(this); }
128};
129
130template <class Master_matrix>
132{
133 Index nberColumns = _matrix()->get_number_of_columns();
134 Index nullValue = Master_matrix::template get_null_value<Index>();
135
136 auto get_position = [&](ID_index pivot) {
137 if constexpr (Master_matrix::Option_list::has_vine_update) {
138 if constexpr (Master_matrix::Option_list::has_map_column_container) {
139 return _matrix()->map_.at(pivot);
140 } else {
141 return _matrix()->map_[pivot];
142 }
143 } else {
144 return pivot;
145 }
146 };
147 auto get_col_index = [&](ID_index pivot) -> Index {
148 if constexpr (Master_matrix::Option_list::has_map_column_container) {
149 auto it = _matrix()->pivotToColumnIndex_.find(pivot);
150 return it == _matrix()->pivotToColumnIndex_.end() ? nullValue : it->second;
151 } else {
152 return _matrix()->pivotToColumnIndex_[pivot];
153 }
154 };
155
156 birthToCycle_.clear();
157 birthToCycle_.resize(nberColumns, nullValue);
158 representativeCycles_.clear();
159
160#ifdef GUDHI_USE_TBB
161 Index c = 0;
162 for (Index i = 0; i < nberColumns; i++) {
163 Index colIdx = get_col_index(i);
164 if (colIdx != nullValue) {
165 auto& col = _matrix()->get_column(colIdx);
166 if ((dim == Master_matrix::template get_null_value<Dimension>() || col.get_dimension() == dim) &&
167 (!col.is_paired() || get_position(i) < get_position(_matrix()->get_pivot(col.get_paired_chain_index())))) {
168 birthToCycle_[get_position(i)] = c;
169 ++c;
170 }
171 }
172 }
173
174 representativeCycles_.resize(c);
175 tbb::parallel_for(static_cast<Index>(0), nberColumns, [&](Index i) {
176 Index colIdx = get_col_index(i);
177 // condition order matters
178 if (colIdx != nullValue && birthToCycle_[get_position(i)] != nullValue) {
179 auto& col = _matrix()->get_column(colIdx);
180 representativeCycles_[birthToCycle_[get_position(i)]] =
181 Master_matrix::build_cycle_from_range(col.get_non_zero_content_range());
182 }
183 });
184#else
185 for (ID_index i = 0; i < nberColumns; i++) {
186 Index colIdx = get_col_index(i);
187 if (colIdx != nullValue) {
188 auto& col = _matrix()->get_column(colIdx);
189 if ((dim == Master_matrix::template get_null_value<Dimension>() || col.get_dimension() == dim) &&
190 (!col.is_paired() || get_position(i) < get_position(_matrix()->get_pivot(col.get_paired_chain_index())))) {
191 representativeCycles_.push_back(Master_matrix::build_cycle_from_range(col.get_non_zero_content_range()));
192 birthToCycle_[get_position(i)] = representativeCycles_.size() - 1;
193 }
194 }
195 }
196#endif
197}
198
199template <class Master_matrix>
201{
202 auto nberColumns = _matrix()->get_number_of_columns();
203 auto get_position = [&](ID_index pivot) {
204 if constexpr (Master_matrix::Option_list::has_vine_update) {
205 if constexpr (Master_matrix::Option_list::has_map_column_container) {
206 return _matrix()->map_.at(pivot);
207 } else {
208 return _matrix()->map_[pivot];
209 }
210 } else {
211 return pivot;
212 }
213 };
214
215 Index nullValue = Master_matrix::template get_null_value<Index>();
216
217 if (birthToCycle_.size() <= bar.birth) {
218 birthToCycle_.resize(bar.birth + 1, nullValue);
219 }
220 if (birthToCycle_[bar.birth] == nullValue) {
221 birthToCycle_[bar.birth] = representativeCycles_.size();
222 representativeCycles_.resize(representativeCycles_.size() + 1);
223 }
224
225 ID_index pivot = bar.birth;
226
227 if constexpr (Master_matrix::Option_list::has_vine_update) {
228 ID_index i = 0;
229 while (i < nberColumns && get_position(i) != bar.birth) ++i;
230 GUDHI_CHECK(i < nberColumns, std::invalid_argument("Given birth value is not valid."));
231 pivot = i;
232 }
233
234 // if bar.birth does not correspond to a valid birth time, get_column_with_pivot will throw an out of range.
235 auto& col = _matrix()->get_column(_matrix()->get_column_with_pivot(pivot));
236 representativeCycles_[birthToCycle_[bar.birth]] =
237 Master_matrix::build_cycle_from_range(col.get_non_zero_content_range());
238}
239
240template <class Master_matrix>
241inline const std::vector<typename Chain_representative_cycles<Master_matrix>::Cycle>&
243{
244 return representativeCycles_;
245}
246
247template <class Master_matrix>
250{
251 return representativeCycles_[birthToCycle_[bar.birth]];
252}
253
254template <class Master_matrix>
255inline void Chain_representative_cycles<Master_matrix>::_reset()
256{
257 representativeCycles_.clear();
258 birthToCycle_.clear();
259}
260
261} // namespace persistence_matrix
262} // namespace Gudhi
263
264#endif // PM_CHAIN_REP_CYCLES_H
typename Master_matrix::Bar Bar
Definition chain_rep_cycles.h:58
const Cycle & get_representative_cycle(const Bar &bar) const
Returns the representative cycle corresponding to the given bar. If the matrix was modified since the...
Definition chain_rep_cycles.h:249
typename Master_matrix::Dimension Dimension
Definition chain_rep_cycles.h:63
typename Master_matrix::Cycle Cycle
Definition chain_rep_cycles.h:59
void update_all_representative_cycles(Dimension dim=Master_matrix::template get_null_value< Dimension >())
Computes the current representative cycles of the matrix.
Definition chain_rep_cycles.h:131
typename Master_matrix::Index Index
Definition chain_rep_cycles.h:61
friend void swap(Chain_representative_cycles &base1, Chain_representative_cycles &base2) noexcept
Swap operator.
Definition chain_rep_cycles.h:109
const std::vector< Cycle > & get_all_representative_cycles() const
Returns the current representative cycles. If the matrix was modified since the last call,...
Definition chain_rep_cycles.h:242
Chain_representative_cycles()=default
Default constructor.
void update_representative_cycle(const Bar &bar)
Computes the current representative cycle of the given bar. All other cycles already computed are lef...
Definition chain_rep_cycles.h:200
typename Master_matrix::ID_index ID_index
Definition chain_rep_cycles.h:62
typename Master_matrix::Column_container Column_container
Definition chain_rep_cycles.h:60
Persistence matrix namespace.
Definition FieldOperators.h:18
Gudhi namespace.
Definition SimplicialComplexForAlpha.h:14
Contains the options for the matrix template.
Empty structure. Inherited instead of Chain_representative_cycles, when the computation of the repres...
Definition chain_rep_cycles.h:40