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 auto get_position = [&](ID_index pivot) {
135 if constexpr (Master_matrix::Option_list::has_vine_update) {
136 if constexpr (Master_matrix::Option_list::has_map_column_container) {
137 return _matrix()->map_.at(pivot);
138 } else {
139 return _matrix()->map_[pivot];
140 }
141 } else {
142 return pivot;
143 }
144 };
145 Index nullValue = Master_matrix::template get_null_value<Index>();
146
147 birthToCycle_.clear();
148 birthToCycle_.resize(nberColumns, nullValue);
149 representativeCycles_.clear();
150
151#ifdef GUDHI_USE_TBB
152 Index c = 0;
153 for (Index i = 0; i < nberColumns; i++) {
154 auto& col = _matrix()->get_column(_matrix()->get_column_with_pivot(i));
155 if ((dim == Master_matrix::template get_null_value<Dimension>() || _matrix()->get_column_dimension(i) == dim) &&
156 (!col.is_paired() || get_position(i) < get_position(_matrix()->get_pivot(col.get_paired_chain_index())))) {
157 birthToCycle_[get_position(i)] = c;
158 ++c;
159 }
160 }
161
162 representativeCycles_.resize(c);
163 tbb::parallel_for(static_cast<Index>(0), nberColumns, [&](Index i) {
164 auto idx = get_position(i);
165 if (birthToCycle_[idx] != nullValue) {
166 auto& col = _matrix()->get_column(_matrix()->get_column_with_pivot(i));
167 representativeCycles_[birthToCycle_[idx]] =
168 Master_matrix::build_cycle_from_range(col.get_non_zero_content_range());
169 }
170 });
171#else
172 for (ID_index i = 0; i < nberColumns; i++) {
173 auto& col = _matrix()->get_column(_matrix()->get_column_with_pivot(i));
174 if ((dim == Master_matrix::template get_null_value<Dimension>() || _matrix()->get_column_dimension(i) == dim) &&
175 (!col.is_paired() || get_position(i) < get_position(_matrix()->get_pivot(col.get_paired_chain_index())))) {
176 representativeCycles_.push_back(Master_matrix::build_cycle_from_range(col.get_non_zero_content_range()));
177 birthToCycle_[get_position(i)] = representativeCycles_.size() - 1;
178 }
179 }
180#endif
181}
182
183template <class Master_matrix>
185{
186 auto nberColumns = _matrix()->get_number_of_columns();
187 auto get_position = [&](ID_index pivot) {
188 if constexpr (Master_matrix::Option_list::has_vine_update) {
189 if constexpr (Master_matrix::Option_list::has_map_column_container) {
190 return _matrix()->map_.at(pivot);
191 } else {
192 return _matrix()->map_[pivot];
193 }
194 } else {
195 return pivot;
196 }
197 };
198
199 Index nullValue = Master_matrix::template get_null_value<Index>();
200
201 if (birthToCycle_.size() <= bar.birth) {
202 birthToCycle_.resize(bar.birth + 1, nullValue);
203 }
204 if (birthToCycle_[bar.birth] == nullValue) {
205 birthToCycle_[bar.birth] = representativeCycles_.size();
206 representativeCycles_.resize(representativeCycles_.size() + 1);
207 }
208
209 ID_index pivot = bar.birth;
210
211 if constexpr (Master_matrix::Option_list::has_vine_update) {
212 ID_index i = 0;
213 while (i < nberColumns && get_position(i) != bar.birth) ++i;
214 GUDHI_CHECK(i < nberColumns, std::invalid_argument("Given birth value is not valid."));
215 pivot = i;
216 }
217
218 // if bar.birth does not correspond to a valid birth time, get_column_with_pivot will throw an out of range.
219 auto& col = _matrix()->get_column(_matrix()->get_column_with_pivot(pivot));
220 representativeCycles_[birthToCycle_[bar.birth]] =
221 Master_matrix::build_cycle_from_range(col.get_non_zero_content_range());
222}
223
224template <class Master_matrix>
225inline const std::vector<typename Chain_representative_cycles<Master_matrix>::Cycle>&
227{
228 return representativeCycles_;
229}
230
231template <class Master_matrix>
234{
235 return representativeCycles_[birthToCycle_[bar.birth]];
236}
237
238template <class Master_matrix>
239inline void Chain_representative_cycles<Master_matrix>::_reset()
240{
241 representativeCycles_.clear();
242 birthToCycle_.clear();
243}
244
245} // namespace persistence_matrix
246} // namespace Gudhi
247
248#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:233
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:226
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:184
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