All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
filtered_zigzag_persistence.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): Clément Maria
4 *
5 * Copyright (C) 2021 Inria
6 *
7 * Modification(s):
8 * - 2023/05 Hannah Schreiber: Rework of the interface, reorganization and debug
9 * - 2023/05 Hannah Schreiber: Addition of infinite bars
10 * - 2024/06 Hannah Schreiber: Separation of the zigzag algorithm from the filtration value management
11 * - YYYY/MM Author: Description of the modification
12 */
13
22#ifndef FILTERED_ZIGZAG_PERSISTENCE_H_
23#define FILTERED_ZIGZAG_PERSISTENCE_H_
24
25#include <cmath>
26#include <limits>
27#include <unordered_map>
28#include <utility>
29#include <vector>
30
31#include <gudhi/Debug_utils.h>
34
35namespace Gudhi {
36namespace zigzag_persistence {
37
44 using Cell_key = int;
45 using Filtration_value = double;
46};
47
119template <class FilteredZigzagOptions = Default_filtered_zigzag_options>
121{
122 public:
125 using Cell_key = typename Options::Cell_key;
127 using Dimension = typename Options::Dimension;
137
152 Filtered_zigzag_persistence_with_storage(unsigned int preallocationSize = 0, int ignoreCyclesAboveDim = -1)
153 : dimMax_(ignoreCyclesAboveDim),
154 persistenceDiagram_(),
155 numArrow_(-1),
156 previousFiltrationValue_(std::numeric_limits<Filtration_value>::infinity()),
157 pers_(
158 [&](Dimension dim, Internal_key birth, Internal_key death) {
159 if (dimMax_ == -1 || (dimMax_ != -1 && dim < dimMax_)) { // don't record intervals over max dim
160 persistenceDiagram_.emplace_back(birth, death, dim);
161 }
162 },
163 preallocationSize) {}
164
179 template <class BoundaryRange = std::initializer_list<Cell_key> >
181 const BoundaryRange& boundary,
182 Dimension dimension,
183 Filtration_value filtrationValue)
184 {
185 if (dimMax_ != -1 && dimension > dimMax_) {
186 return apply_identity();
187 }
188
189 ++numArrow_;
190
191 _store_filtration_value(filtrationValue);
192
193 [[maybe_unused]] auto res = handleToKey_.try_emplace(cellID, numArrow_);
194
195 GUDHI_CHECK(res.second, "Zigzag_persistence::insert_cell - cell already in the complex");
196
197 // Compute the keys of the cells of the boundary.
198 std::vector<Internal_key> translatedBoundary;
199 translatedBoundary.reserve(dimension * 2); // boundary does not have to have `size()`
200 for (auto b : boundary) {
201 translatedBoundary.push_back(handleToKey_.at(b)); // TODO: add possibilities of coefficients
202 }
203 std::sort(translatedBoundary.begin(), translatedBoundary.end());
204
205 pers_.insert_cell(translatedBoundary, dimension);
206
207 return numArrow_;
208 }
209
222 auto it = handleToKey_.find(cellID);
223
224 if (it == handleToKey_.end()) {
225 return apply_identity();
226 }
227
228 ++numArrow_;
229
230 _store_filtration_value(filtrationValue);
231
232 pers_.remove_cell(it->second);
233 handleToKey_.erase(it);
234
235 return numArrow_;
236 }
237
245 ++numArrow_;
246 pers_.apply_identity();
247 return numArrow_;
248 }
249
257 const std::vector<Index_interval>& get_index_persistence_diagram() const { return persistenceDiagram_; }
258
267 // lower_bound(x) returns leftmost y s.t. x <= y
268 auto itBirth =
269 std::lower_bound(filtrationValues_.begin(),
270 filtrationValues_.end(),
271 idx,
272 [](std::pair<Internal_key, Filtration_value> p, Internal_key k) { return p.first < k; });
273 if (itBirth == filtrationValues_.end() || itBirth->first > idx) {
274 --itBirth;
275 }
276 return itBirth->second;
277 };
278
286 std::vector<Filtration_value_interval> get_persistence_diagram(Filtration_value shortestInterval = 0.,
287 bool includeInfiniteBars = true) {
288 std::vector<Filtration_value_interval> diag = _get_persistence_diagram(shortestInterval);
289
290 if (includeInfiniteBars) {
291 _retrieve_infinite_bars(diag);
292 }
293
294 return diag;
295 }
296
297 private:
298 std::unordered_map<Cell_key, Internal_key> handleToKey_;
299 Dimension dimMax_;
300 std::vector<Index_interval> persistenceDiagram_;
301 Internal_key numArrow_;
302 Filtration_value previousFiltrationValue_;
308 std::vector<std::pair<Internal_key, Filtration_value> > filtrationValues_;
317 void _store_filtration_value(Filtration_value filtrationValue) {
318 if (filtrationValue != previousFiltrationValue_) // check whether the filt value has changed
319 {
320 // consecutive pairs (i,f), (j,f') mean cells of index k in [i,j-1] have filtration value f
321 previousFiltrationValue_ = filtrationValue;
322 filtrationValues_.emplace_back(numArrow_, previousFiltrationValue_);
323 }
324 }
325
332 std::vector<Filtration_value_interval> _get_persistence_diagram(Filtration_value shortestInterval) {
333 std::vector<Filtration_value_interval> diag;
334 diag.reserve(persistenceDiagram_.size());
335
336 // std::stable_sort(filtrationValues_.begin(), filtrationValues_.end(),
337 // [](std::pair<Internal_key, Filtration_value> p1, std::pair<Internal_key, Filtration_value> p2) {
338 // return p1.first < p2.first;
339 // });
340
341 for (auto bar : persistenceDiagram_) {
344 if (birth > death) {
345 std::swap(birth, death);
346 }
347
348 if (death - birth > shortestInterval) {
349 diag.emplace_back(birth, death, bar.dim);
350 }
351 }
352
353 return diag;
354 }
355
361 void _retrieve_infinite_bars(std::vector<Filtration_value_interval>& diag) {
362 auto stream_infinite_interval = [&](Dimension dim, Internal_key birthIndex) {
363 if (dimMax_ == -1 || (dimMax_ != -1 && dim < dimMax_))
364 diag.emplace_back(get_filtration_value_from_index(birthIndex), Filtration_value_interval::inf, dim);
365 };
366
367 pers_.get_current_infinite_intervals(stream_infinite_interval);
368 }
369}; // end class Filtered_zigzag_persistence_with_storage
370
441template <class FilteredZigzagOptions = Default_filtered_zigzag_options>
443 public:
446 using Cell_key = typename Options::Cell_key;
448 using Dimension = typename Options::Dimension;
467 template <typename F>
468 Filtered_zigzag_persistence(F&& stream_interval, unsigned int preallocationSize = 0)
469 : handleToKey_(preallocationSize),
470 numArrow_(-1),
471 keyToFiltrationValue_(preallocationSize),
472 pers_(
473 [&, stream_interval = std::forward<F>(stream_interval)](Dimension dim,
474 Internal_key birth,
475 Internal_key death) {
476 auto itB = keyToFiltrationValue_.find(birth);
477 auto itD = keyToFiltrationValue_.find(death);
478 if (itB->second != itD->second) stream_interval(dim, itB->second, itD->second);
479 keyToFiltrationValue_.erase(itB);
480 keyToFiltrationValue_.erase(itD);
481 },
482 preallocationSize) {}
483
497 template <class BoundaryRange = std::initializer_list<Cell_key> >
499 const BoundaryRange& boundary,
500 Dimension dimension,
501 Filtration_value filtrationValue)
502 {
503 ++numArrow_;
504
505 [[maybe_unused]] auto res = handleToKey_.try_emplace(cellID, numArrow_);
506
507 GUDHI_CHECK(res.second, "Zigzag_persistence::insert_cell - cell already in the complex");
508
509 keyToFiltrationValue_.try_emplace(numArrow_, filtrationValue);
510
511 // Compute the keys of the cells of the boundary.
512 std::vector<Internal_key> translatedBoundary;
513 translatedBoundary.reserve(dimension * 2); // boundary does not have to have `size()`
514 for (auto b : boundary) {
515 translatedBoundary.push_back(handleToKey_.at(b)); // TODO: add possibilities of coefficients
516 }
517 std::sort(translatedBoundary.begin(), translatedBoundary.end());
518
519 pers_.insert_cell(translatedBoundary, dimension);
520
521 return numArrow_;
522 }
523
533 ++numArrow_;
534
535 auto it = handleToKey_.find(cellID);
536 GUDHI_CHECK(it != handleToKey_.end(), "Zigzag_persistence::remove_cell - cell not in the complex");
537
538 keyToFiltrationValue_.try_emplace(numArrow_, filtrationValue);
539
540 pers_.remove_cell(it->second);
541 handleToKey_.erase(it);
542
543 return numArrow_;
544 }
545
552 ++numArrow_;
553 pers_.apply_identity();
554 return numArrow_;
555 }
556
564 template <typename F>
565 void get_current_infinite_intervals(F&& stream_infinite_interval) {
567 [&](Dimension dim, Internal_key birth) { stream_infinite_interval(dim, keyToFiltrationValue_.at(birth)); });
568 }
569
570 private:
571 template <typename key_type, typename value_type>
572 using Dictionary = std::unordered_map<key_type, value_type>; // TODO: benchmark with other map types
573
574 Dictionary<Cell_key, Internal_key> handleToKey_;
575 Internal_key numArrow_;
576 Dictionary<Internal_key, Filtration_value> keyToFiltrationValue_;
578}; // end class Filtered_zigzag_persistence
579
580} // namespace zigzag_persistence
581} // namespace Gudhi
582
583#endif // FILTERED_ZIGZAG_PERSISTENCE_H_
Class computing the zigzag persistent homology of a zigzag filtration. Algorithm based on ....
Definition: filtered_zigzag_persistence.h:121
Internal_key remove_cell(Cell_key cellID, Filtration_value filtrationValue)
Updates the zigzag persistence diagram after the removal of the given cell if the cell was contained ...
Definition: filtered_zigzag_persistence.h:221
typename Options::Internal_key Internal_key
Definition: filtered_zigzag_persistence.h:124
Filtered_zigzag_persistence_with_storage(unsigned int preallocationSize=0, int ignoreCyclesAboveDim=-1)
Constructor.
Definition: filtered_zigzag_persistence.h:152
typename Options::Filtration_value Filtration_value
Definition: filtered_zigzag_persistence.h:126
Internal_key apply_identity()
To use when a cell is neither inserted nor removed, but the filtration moves along the identity opera...
Definition: filtered_zigzag_persistence.h:244
std::vector< Filtration_value_interval > get_persistence_diagram(Filtration_value shortestInterval=0., bool includeInfiniteBars=true)
Returns the current persistence diagram.
Definition: filtered_zigzag_persistence.h:286
typename Options::Dimension Dimension
Definition: filtered_zigzag_persistence.h:127
typename Options::Cell_key Cell_key
Definition: filtered_zigzag_persistence.h:125
const std::vector< Index_interval > & get_index_persistence_diagram() const
Returns the "index persistence diagram" of the current filtration, that is, the pairs of atomic arrow...
Definition: filtered_zigzag_persistence.h:257
Internal_key insert_cell(Cell_key cellID, const BoundaryRange &boundary, Dimension dimension, Filtration_value filtrationValue)
Updates the zigzag persistence diagram after the insertion of the given cell.
Definition: filtered_zigzag_persistence.h:180
Filtration_value get_filtration_value_from_index(Internal_key idx)
Returns the filtration value associated to the index returned by get_index_persistence_diagram.
Definition: filtered_zigzag_persistence.h:266
Class computing the zigzag persistent homology of a zigzag filtration. Algorithm based on .
Definition: filtered_zigzag_persistence.h:442
void get_current_infinite_intervals(F &&stream_infinite_interval)
Outputs through the given callback method all current infinite bars.
Definition: filtered_zigzag_persistence.h:565
typename Options::Cell_key Cell_key
Definition: filtered_zigzag_persistence.h:446
typename Options::Filtration_value Filtration_value
Definition: filtered_zigzag_persistence.h:447
Internal_key remove_cell(Cell_key cellID, Filtration_value filtrationValue)
Updates the zigzag persistence diagram after the removal of the given cell. preallocationSize.
Definition: filtered_zigzag_persistence.h:532
typename Options::Dimension Dimension
Definition: filtered_zigzag_persistence.h:448
typename Options::Internal_key Internal_key
Definition: filtered_zigzag_persistence.h:445
Filtered_zigzag_persistence(F &&stream_interval, unsigned int preallocationSize=0)
Constructor.
Definition: filtered_zigzag_persistence.h:468
Internal_key insert_cell(Cell_key cellID, const BoundaryRange &boundary, Dimension dimension, Filtration_value filtrationValue)
Updates the zigzag persistence diagram after the insertion of the given cell.
Definition: filtered_zigzag_persistence.h:498
Internal_key apply_identity()
To use when a cell is neither inserted nor removed, but the filtration moves along the identity opera...
Definition: filtered_zigzag_persistence.h:551
Class computing the zigzag persistent homology of a zigzag sequence. Algorithm based on .
Definition: zigzag_persistence.h:149
Index remove_cell(Index arrowNumber)
Updates the zigzag persistence diagram after the removal of the given cell.
Definition: zigzag_persistence.h:300
Index insert_cell(const BoundaryRange &boundary, Dimension dimension)
Updates the zigzag persistence diagram after the insertion of the given cell.
Definition: zigzag_persistence.h:288
Index apply_identity()
To use when a cell is neither inserted nor removed, but the filtration moves along the identity opera...
Definition: zigzag_persistence.h:312
void get_current_infinite_intervals(F &&stream_infinite_interval)
Outputs through the given callback method all birth indices which are currently not paired with a dea...
Definition: zigzag_persistence.h:323
Gudhi namespace.
Definition: SimplicialComplexForAlpha.h:14
STL namespace.
Contains Gudhi::persistence_matrix::Persistence_interval class.
Value type for a filtration function on a cell complex.
Definition: FiltrationValue.h:20
Type for an interval in a persistent diagram or barcode. Stores the birth, death and dimension of the...
Definition: persistence_interval.h:40
static constexpr Event_value inf
Stores the infinity value for birth and death events. Its value depends on the template parameter Eve...
Definition: persistence_interval.h:50
Default options for Filtered_zigzag_persistence_with_storage and Filtered_zigzag_persistence.
Definition: filtered_zigzag_persistence.h:43
int Cell_key
Definition: filtered_zigzag_persistence.h:44
double Filtration_value
Definition: filtered_zigzag_persistence.h:45
Default options for Zigzag_persistence.
Definition: zigzag_persistence.h:64
List of options used for the filtered zigzag persistence computation.
Definition: ZigzagOptions.h:27
unspecified Dimension
Type for the dimension values.
Definition: ZigzagOptions.h:47
unspecified Filtration_value
Type for filtration values.
Definition: ZigzagOptions.h:42
unspecified Internal_key
Numerical type for the cell IDs used internally and other indexations. It must be signed.
Definition: ZigzagOptions.h:31
unspecified Cell_key
Type for the cell IDs used at insertion and in the boundaries given as argument. Has to be usable as ...
Definition: ZigzagOptions.h:37
Contains the implementation of the Gudhi::zigzag_persistence::Zigzag_persistence class.