TTK
Loading...
Searching...
No Matches
PersistentSimplexPairs.cpp
Go to the documentation of this file.
2
4 this->setDebugMsgPrefix("PersistentSimplexPairs");
5}
6
7ttk::SimplexId ttk::PersistentSimplexPairs::eliminateBoundaries(
8 const Simplex &c,
9 VisitedMask &boundary,
10 const std::vector<SimplexId> &filtOrder,
11 const std::vector<Simplex> &partners) const {
12
13 this->addCellBoundary(c, boundary);
14
15 while(!boundary.visitedIds_.empty()) {
16 // youngest cell on boundary
17 const auto tau{*std::max_element(
18 boundary.visitedIds_.begin(), boundary.visitedIds_.end(),
19 [&filtOrder, &c, this](const SimplexId a, const SimplexId b) {
20 return filtOrder[this->getCellId(c.dim_ - 1, a)]
21 < filtOrder[this->getCellId(c.dim_ - 1, b)];
22 })};
23 const auto &partnerTau{partners[this->getCellId(c.dim_ - 1, tau)]};
24 if(partnerTau.dim_ == -1 || partnerTau.id_ == -1) {
25 return tau;
26 }
27 this->addCellBoundary(partnerTau, boundary);
28 }
29
30 return -1;
31}
32
33int ttk::PersistentSimplexPairs::pairCells(
34 std::vector<PersistencePair> &pairs,
35 std::array<std::vector<bool>, 3> &boundaries,
36 const std::vector<Simplex> &filtration,
37 const std::vector<SimplexId> &filtOrder) const {
38
39 // for VisitedMask
40 std::vector<SimplexId> visitedIds{};
41 // paired simplices
42 std::vector<Simplex> partners(filtration.size());
43
44 Timer tm{};
45
46 this->printMsg("Computing pairs", 0, 0, 1, ttk::debug::LineMode::REPLACE);
47
48 for(size_t i = 0; i < filtration.size(); ++i) {
49
50 const auto &c{filtration[i]};
51
52 // skip vertices
53 if(c.dim_ == 0) {
54 continue;
55 }
56
57 // store the boundary cells
58 VisitedMask vm{boundaries[c.dim_ - 1], visitedIds};
59
60 const auto partner = this->eliminateBoundaries(c, vm, filtOrder, partners);
61 if(partner != -1) {
62 const auto &pc{
63 filtration[filtOrder[this->getCellId(c.dim_ - 1, partner)]]};
64 partners[c.cellId_] = pc;
65 partners[pc.cellId_] = c;
66
67 // only record pairs with non-null persistence
68 if(c.vertsOrder_[0] != pc.vertsOrder_[0]) {
69 pairs.emplace_back(partner, c.id_, c.dim_ - 1);
70 }
71 }
72
73 if(filtration.size() > 10 && i % (filtration.size() / 10) == 0) {
74 this->printMsg(
75 "Computing pairs",
76 std::round(10 * i / static_cast<float>(filtration.size())) / 10.0f,
77 tm.getElapsedTime(), 1, ttk::debug::LineMode::REPLACE);
78 }
79 }
80
81 const auto nRegPairs{pairs.size()};
82
83 this->printMsg("Computed " + std::to_string(nRegPairs) + " regular pair"
84 + (nRegPairs > 1 ? "s" : ""),
85 1.0, tm.getElapsedTime(), 1);
86
87 // get infinite pairs
88 for(SimplexId i = 0; i < this->nVerts_; ++i) {
89 if(partners[i].id_ == -1) {
90 pairs.emplace_back(i, -1, 0);
91 }
92 }
93 for(SimplexId i = 0; i < this->nEdges_; ++i) {
94 if(partners[i + this->nVerts_].id_ == -1) {
95 pairs.emplace_back(i, -1, 1);
96 }
97 }
98 for(SimplexId i = 0; i < this->nTri_; ++i) {
99 if(partners[i + this->nVerts_ + this->nEdges_].id_ == -1) {
100 pairs.emplace_back(i, -1, 2);
101 }
102 }
103 for(SimplexId i = 0; i < this->nTetra_; ++i) {
104 if(partners[i + this->nVerts_ + this->nEdges_ + this->nTri_].id_ == -1) {
105 pairs.emplace_back(i, -1, 3);
106 }
107 }
108
109 const auto nInfPairs{pairs.size() - nRegPairs};
110
111 this->printMsg("Detected " + std::to_string(nInfPairs) + " infinite pair"
112 + (nInfPairs > 1 ? "s" : ""));
113
114 return 0;
115}
void setDebugMsgPrefix(const std::string &prefix)
Definition: Debug.h:364
int SimplexId
Identifier type for simplices of any dimension.
Definition: DataTypes.h:22
Auto-cleaning re-usable graph propagations data structure.
Definition: VisitedMask.h:27
std::vector< SimplexId > & visitedIds_
Definition: VisitedMask.h:29
printMsg(debug::output::GREEN+"                           "+debug::output::ENDCOLOR+debug::output::GREEN+"▒"+debug::output::ENDCOLOR+debug::output::GREEN+"▒▒▒▒▒▒▒▒▒▒▒▒▒░"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)