18#ifndef PM_RU_REP_CYCLES_H
19#define PM_RU_REP_CYCLES_H
26#include <tbb/parallel_for.h>
55template <
class Master_matrix>
59 using Index =
typename Master_matrix::Index;
60 using Bar =
typename Master_matrix::Bar;
61 using Cycle =
typename Master_matrix::Cycle;
62 using Dimension =
typename Master_matrix::Dimension;
107 base1.representativeCycles_.swap(base2.representativeCycles_);
108 base1.birthToCycle_.swap(base2.birthToCycle_);
115 using Master_RU_matrix =
typename Master_matrix::Master_RU_matrix;
116 using Inverse_column =
Cycle;
117 using Content_range =
typename Master_matrix::Column::Content_range;
119 std::vector<Cycle> representativeCycles_;
120 std::vector<Index> birthToCycle_;
122 constexpr Master_RU_matrix* _matrix() {
return static_cast<Master_RU_matrix*
>(
this); }
123 constexpr const Master_RU_matrix* _matrix()
const {
return static_cast<const Master_RU_matrix*
>(
this); }
125 void _retrieve_cycle_from_r(Index colIdx, Index repIdx);
126 void _retrieve_cycle_from_u(Index colIdx, Index repIdx);
127 Inverse_column _get_inverse(Index c);
130template <
class Master_matrix>
133 Index nberColumns = _matrix()->reducedMatrixR_.get_number_of_columns();
134 Index nullValue = Master_matrix::template get_null_value<Index>();
135 representativeCycles_.clear();
136 birthToCycle_.clear();
137 birthToCycle_.resize(nberColumns, nullValue);
140 for (
Index i = 0; i < nberColumns; i++) {
141 if ((dim == Master_matrix::template get_null_value<Dimension>() ||
142 _matrix()->reducedMatrixR_.get_column_dimension(i) == dim) &&
143 _matrix()->reducedMatrixR_.is_zero_column(i)) {
144 birthToCycle_[i] = c;
149 representativeCycles_.resize(c);
151 tbb::parallel_for(
static_cast<Index>(0), nberColumns, [&](
Index i) {
152 if (birthToCycle_[i] != nullValue) {
153 Index colIdx = _matrix()->_get_column_with_pivot(i);
154 if (colIdx == nullValue) {
155 _retrieve_cycle_from_u(i, birthToCycle_[i]);
157 _retrieve_cycle_from_r(colIdx, birthToCycle_[i]);
162 for (
Index i = 0; i < nberColumns; ++i) {
163 if (birthToCycle_[i] != nullValue) {
164 Index colIdx = _matrix()->_get_column_with_pivot(i);
165 if (colIdx == nullValue) {
166 _retrieve_cycle_from_u(i, birthToCycle_[i]);
168 _retrieve_cycle_from_r(colIdx, birthToCycle_[i]);
175template <
class Master_matrix>
178 Index nullValue = Master_matrix::template get_null_value<Index>();
180 if (birthToCycle_.size() <= bar.birth) {
181 birthToCycle_.resize(bar.birth + 1, nullValue);
183 if (birthToCycle_[bar.birth] == nullValue) {
184 birthToCycle_[bar.birth] = representativeCycles_.size();
185 representativeCycles_.resize(representativeCycles_.size() + 1);
188 Index colIdx = _matrix()->_get_column_with_pivot(bar.birth);
189 if (colIdx == nullValue) {
190 _retrieve_cycle_from_u(bar.birth, birthToCycle_[bar.birth]);
192 _retrieve_cycle_from_r(colIdx, birthToCycle_[bar.birth]);
196template <
class Master_matrix>
197inline const std::vector<typename RU_representative_cycles<Master_matrix>::Cycle>&
200 return representativeCycles_;
203template <
class Master_matrix>
207 return representativeCycles_[birthToCycle_[bar.birth]];
210template <
class Master_matrix>
211inline void RU_representative_cycles<Master_matrix>::_retrieve_cycle_from_r(Index colIdx, Index repIdx)
213 auto& col = _matrix()->reducedMatrixR_.get_column(colIdx);
214 representativeCycles_[repIdx] = Master_matrix::build_cycle_from_range(col.get_non_zero_content_range());
217template <
class Master_matrix>
218inline void RU_representative_cycles<Master_matrix>::_retrieve_cycle_from_u(Index colIdx, Index repIdx)
221 representativeCycles_[repIdx] = _get_inverse(colIdx);
224template <
class Master_matrix>
225inline typename RU_representative_cycles<Master_matrix>::Inverse_column
226RU_representative_cycles<Master_matrix>::_get_inverse(Index c)
228 using E =
typename Master_matrix::Element;
229 auto& matrix = _matrix()->mirrorMatrixU_;
230 auto size = matrix.get_number_of_columns();
231 [[maybe_unused]]
const auto& op = _matrix()->operators_;
234 auto _last_diagonal_value = [&]() -> E {
235 auto& col = matrix.get_column(size - 1);
236 if (col.is_empty())
return 0;
238 if constexpr (Master_matrix::Option_list::is_z2) {
241 return op->get_inverse(matrix.get_column(size - 1).get_pivot_value());
245 auto _push_cell = [&](
auto i, E e) ->
void {
246 if constexpr (Master_matrix::Option_list::is_z2) {
247 if (e) res.push_back(i);
249 if (e != op->get_additive_identity()) res.push_back({i, e});
253 auto _substract = [&](E& e,
auto resIt,
const auto& cell) ->
void {
254 if (resIt != res.rend() && Master_matrix::get_row_index(*resIt) == cell.get_row_index()) {
255 if constexpr (Master_matrix::Option_list::is_z2) {
258 op->subtract_inplace_front(e, cell.get_element() * Master_matrix::get_element(*resIt));
263 auto _multiply = [&](E& e, E m) ->
void {
264 if constexpr (Master_matrix::Option_list::is_z2) {
267 op->multiply_inplace(e, op->get_inverse(m));
271 auto _translate = [&](std::size_t i) ->
void {
272 const auto& map = _matrix()->positionToID_;
273 auto& idx = Master_matrix::get_row_index(res[i]);
274 auto it = map.find(idx);
275 if (it != map.end()) idx = it->second;
278 if (c == size - 1) _push_cell(size - 1, _last_diagonal_value());
279 for (
int i = size - 2; i >= 0; --i) {
280 E e =
static_cast<int>(c) == i;
281 auto& line = matrix.get_column(i);
282 Content_range r = line.get_non_zero_content_range();
283 auto resIt = res.rbegin();
284 auto lineIt = r.begin();
286 if (
static_cast<int>(lineIt->get_row_index()) == i) {
287 diag = lineIt->get_element();
290 while (lineIt != r.end() && resIt != res.rend()) {
291 while (resIt != res.rend() && Master_matrix::get_row_index(*resIt) < lineIt->get_row_index()) ++resIt;
292 _substract(e, resIt, *lineIt);
300 for (std::size_t incr = 0, decr = res.size() - 1; incr < decr; ++incr, --decr) {
303 std::swap(res[incr], res[decr]);
309template <
class Master_matrix>
310inline void RU_representative_cycles<Master_matrix>::_reset()
312 representativeCycles_.clear();
313 birthToCycle_.clear();
void update_representative_cycle(const Bar &bar)
Computes the current representative cycle of the given bar. All other cycles already computed are lef...
Definition ru_rep_cycles.h:176
typename Master_matrix::Index Index
Definition ru_rep_cycles.h:59
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 ru_rep_cycles.h:205
typename Master_matrix::Bar Bar
Definition ru_rep_cycles.h:60
typename Master_matrix::Dimension Dimension
Definition ru_rep_cycles.h:62
RU_representative_cycles()=default
Default constructor.
typename Master_matrix::Cycle Cycle
Definition ru_rep_cycles.h:61
const std::vector< Cycle > & get_all_representative_cycles() const
Returns the current representative cycles. If the matrix was modified since the last call,...
Definition ru_rep_cycles.h:198
friend void swap(RU_representative_cycles &base1, RU_representative_cycles &base2) noexcept
Swap operator.
Definition ru_rep_cycles.h:105
void update_all_representative_cycles(Dimension dim=Master_matrix::template get_null_value< Dimension >())
Computes the current representative cycles of the matrix.
Definition ru_rep_cycles.h:131
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 RU_representative_cycles, when the computation of the represent...
Definition ru_rep_cycles.h:41