TTK
Loading...
Searching...
No Matches
Graph_Template.h
Go to the documentation of this file.
1#pragma once
2
3#ifndef NDEBUG
4// #include<sstream>
5// #define DEBUG(msg) {std::stringstream s; s << msg << std::endl; std::cout <<
6// s.str();}
7#define DEBUG(msg)
8#else
9#define DEBUG(msg)
10#endif
11
12#include "Graph.h"
13
14#include <unordered_map>
15
16namespace ttk {
17 namespace ftr {
18 template <typename ScalarType>
20 std::unordered_map<idSuperArc, idSuperArc> mapArcs;
21 std::map<std::pair<idVertex, idVertex>, idSuperArc> masterArcs;
22
23 // int totalArc = getNumberOfArcs();
24
25 // Arc created by increasing and decreasing tasks are reversed in
26 // terms of up/down node. We use this property to merge such arcs. in
27 // order to distinguish between arcs around a loop, and arc is
28 // described by the first and last vertex of its segmentation if any.
29 // Otherwise by its up / last node.
30
31 const idSuperArc nbArcs = arcs_.size();
32 for(idSuperArc arcId = 0; arcId < nbArcs; ++arcId) {
33 const SuperArc &arc = getArc(arcId);
34 if(getArc(arcId).isVisible()) {
35 idNode upNodeId = getArc(arcId).getUpNodeId();
36 const idNode downNodeId = getArc(arcId).getDownNodeId();
37 if(upNodeId == nullNode) {
38 if(getArc(arcId).getEnd() != nullVertex) {
39 upNodeId = getNodeId(getArc(arcId).getEnd());
40 if(upNodeId == nullNode) {
41 upNodeId = makeNode(getArc(arcId).getEnd());
42 }
43 getArc(arcId).setUpNodeId(upNodeId);
44 } else {
45 getArc(arcId).hide();
46 continue;
47 }
48 }
49 std::pair<idVertex, idVertex> arcVerts;
50 if(getArc(arcId).isEmpty()) {
51 arcVerts
52 = std::make_pair(getNode(upNodeId).getVertexIdentifier(),
53 getNode(downNodeId).getVertexIdentifier());
54 } else {
55 arcVerts = std::make_pair(
56 getArc(arcId).getFirstReg(), getArc(arcId).getLastReg());
57 }
58 auto revertArcVerts
59 = std::make_pair(std::get<1>(arcVerts), std::get<0>(arcVerts));
60 if(masterArcs.count(revertArcVerts)) {
61 getArc(arcId).merge(masterArcs[revertArcVerts]);
62 DEBUG("Merge " << printArc(arcId) << " in "
63 << printArc(masterArcs[revertArcVerts]));
64 DEBUG(" using " << std::get<0>(revertArcVerts) << " "
65 << std::get<1>(revertArcVerts));
66 } else {
67 masterArcs[arcVerts] = arcId;
68 }
69 }
70
71 if(arc.merged()) {
72 const idSuperArc target = arc.mergedIn();
73 if(mapArcs.count(target) == 0) {
74 mapArcs[arcId] = target;
75 consolidateArc<ScalarType>(target, arcId, s);
76 }
77 }
78 }
79
80 if(!mapArcs.size())
81 return;
82
83#ifdef TTK_ENABLE_OPENMP
84#pragma omp parallel for
85#endif
86 for(idVertex v = 0; v < nbElmt_; ++v) {
87 const idSuperArc vArc = segmentation_[v].corArc;
88 if(mapArcs.count(vArc)) {
89 segmentation_[v].corArc = mapArcs[vArc];
90 }
91 }
92 }
93
94 template <typename ScalarType>
96 const idSuperArc nbArcs = getNumberOfArcs();
97 const idNode nbNodes = getNumberOfNodes();
98
99 // fix up down
100 for(idSuperArc arcId = 0; arcId < nbArcs; ++arcId) {
101 if(!getArc(arcId).isVisible())
102 continue;
103
104 const idNode upNodeId = getArc(arcId).getUpNodeId();
105 const idNode downNodeId = getArc(arcId).getDownNodeId();
106
107#ifndef TTK_ENABLE_KAMIKAZE
108 if(upNodeId == nullNode || downNodeId == nullNode) {
109 continue;
110 }
111#endif
112
113 const idVertex upVertId = getNode(upNodeId).getVertexIdentifier();
114 const idVertex downVertId = getNode(downNodeId).getVertexIdentifier();
115
116 if(s->isLower(upVertId, downVertId)) {
117 getArc(arcId).setUpNodeId(downNodeId);
118 getArc(arcId).setDownNodeId(upNodeId);
119 } else {
120 getArc(arcId).setUpNodeId(upNodeId);
121 getArc(arcId).setDownNodeId(downNodeId);
122 }
123 }
124
125 // reserve good size
126 std::vector<valence> upVal(nbNodes, 0), downVal(nbNodes, 0);
127 // count
128 for(idSuperArc arcId = 0; arcId < nbArcs; ++arcId) {
129 if(!getArc(arcId).isVisible())
130 continue;
131
132 const idNode upNodeId = getArc(arcId).getUpNodeId();
133 const idNode downNodeId = getArc(arcId).getDownNodeId();
134
135#ifndef TTK_ENABLE_KAMIKAZE
136 if(upNodeId == nullNode || downNodeId == nullNode) {
137 continue;
138 }
139#endif
140
141 ++downVal[upNodeId];
142 ++upVal[downNodeId];
143 }
144 // alloc
145 for(idNode nodeId = 0; nodeId < nbNodes; ++nodeId) {
146 getNode(nodeId).reserveUpArc(upVal[nodeId]);
147 getNode(nodeId).reserveDownArc(downVal[nodeId]);
148 }
149
150 // set the id
151 for(idSuperArc arcId = 0; arcId < nbArcs; ++arcId) {
152 if(!getArc(arcId).isVisible())
153 continue;
154
155 const idNode upNodeId = getArc(arcId).getUpNodeId();
156 const idNode downNodeId = getArc(arcId).getDownNodeId();
157
158#ifndef TTK_ENABLE_KAMIKAZE
159 if(upNodeId == nullNode || downNodeId == nullNode) {
160 continue;
161 }
162#endif
163
164 getNode(upNodeId).addDownArc(arcId);
165 getNode(downNodeId).addUpArc(arcId);
166 }
167 }
168
169 template <typename ScalarType>
171 const idVertex nbVerts = s->getSize();
172 const idSuperArc nbArcs = getNumberOfArcs();
173 std::vector<idVertex> arcSizes(getNumberOfArcs(), 0);
174 this->printMsg("Building arc segmentation");
175
176#ifdef TTK_ENABLE_OPENMP
177#pragma omp parallel for
178#endif
179 for(idVertex v = 0; v < nbVerts; ++v) {
180#ifndef TTK_ENABLE_KAMIKAZE
181 if(segmentation_[v].corArc == nullSuperArc) {
182 std::cout << "[Graph]: build segmentation, null arc on vertex: " << v
183 << std::endl;
184 continue;
185 }
186#endif
187#ifdef TTK_ENABLE_OPENMP
188#pragma omp atomic update
189#endif
190 arcSizes[segmentation_[v].corArc]++;
191 }
192
193 // alloc
194 for(idSuperArc i = 0; i < nbArcs; ++i) {
195 getArc(i).segmentation().reserve(arcSizes[i]);
196 }
197
198 // sorted list
199 for(idVertex v = 0; v < nbVerts; ++v) {
200 const idVertex regV = s->getSortedVert(v);
201 const idSuperArc corArc = segmentation_[regV].corArc;
202 getArc(corArc).segmentation().emplace_back(regV);
203 }
204 }
205
206 template <typename ScalarType>
207 void Graph::consolidateArc(const idSuperArc mainArc,
208 const idSuperArc mergedArc,
209 const Scalars<ScalarType> *const s) {
210 const idNode mainDown = getArc(mainArc).getDownNodeId();
211 const idNode mergedDown = getArc(mergedArc).getDownNodeId();
212
213#ifndef TTK_ENABLE_KAMIKAZE
214 if(mainDown == nullNode || mergedDown == nullNode) {
215 std::cout << "[Graph]: consolidate error, arc have a null down node"
216 << std::endl;
217 }
218#endif
219
220 // std::cout << "arc before " << printArc(mainArc) << std::endl;
221
222 const idVertex vMainDown = getNode(mainDown).getVertexIdentifier();
223 const idVertex vMergedDown = getNode(mergedDown).getVertexIdentifier();
224 if(s->isLower(vMainDown, vMergedDown)) {
225 // getArc(mainArc).setDownNodeId(mainDown); // already the case
226 getArc(mainArc).setUpNodeId(mergedDown);
227 } else {
228 getArc(mainArc).setDownNodeId(mergedDown);
229 getArc(mainArc).setUpNodeId(mainDown);
230 }
231 getArc(mainArc).restore();
232
233 // std::cout << "arc after " << printArc(mainArc) << std::endl;
234 }
235
236 } // namespace ftr
237
238} // namespace ttk
#define DEBUG(msg)
idVertex nbElmt_
Allocation may depends on the number of vertices.
Definition FTRCommon.h:50
idNode makeNode(const idVertex v)
Definition Graph.h:248
idNode getNumberOfNodes() const
Definition Graph.h:84
void arcs2nodes(const Scalars< ScalarType > *const s)
void buildArcSegmentation(const Scalars< ScalarType > *const s)
idSuperArc getNumberOfArcs() const
Definition Graph.h:88
std::string printArc(const idSuperArc arcId) const
Definition Graph.cpp:54
const SuperArc & getArc(const idSuperArc id) const
Definition Graph.h:121
const Node & getNode(const idNode id) const
Definition Graph.h:113
idNode getNodeId(const idVertex v) const
Definition Graph.h:210
void mergeArcs(const Scalars< ScalarType > *const s)
idVertex getVertexIdentifier() const
Definition FTRNode.h:34
void addUpArc(const idSuperArc arcId)
Definition FTRNode.h:93
void reserveDownArc(const idSuperArc nbDownArcs)
Definition FTRNode.h:97
void reserveUpArc(const idSuperArc nbUpArc)
Definition FTRNode.h:81
void addDownArc(const idSuperArc arcId)
Definition FTRNode.h:109
idVertex getSortedVert(const idVertex i) const
Definition FTRScalars.h:52
bool isLower(const idVertex a, const idVertex b) const
Definition FTRScalars.h:119
idVertex getSize() const
Definition FTRScalars.h:44
TTK FTRGraph graph arc.
Definition FTRSuperArc.h:30
void setUpNodeId(const idNode id)
Definition FTRSuperArc.h:53
idSuperArc mergedIn() const
idNode getUpNodeId() const
Definition FTRSuperArc.h:48
idNode getDownNodeId() const
Definition FTRSuperArc.h:57
const decltype(segmentation_) & segmentation() const
void setDownNodeId(const idNode id)
Definition FTRSuperArc.h:66
bool merged() const
void merge(const idSuperArc arc)
long unsigned int idSuperArc
SuperArc index in vect_superArcs_.
SimplexId idVertex
Vertex index in scalars_.
unsigned int idNode
Node index in vect_nodes_.
The Topology ToolKit.
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/|__ _|"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)