TTK
Loading...
Searching...
No Matches
FTMTreeUtils.cpp
Go to the documentation of this file.
1#include <FTMTree.h>
2#include <FTMTreeUtils.h>
3#include <iostream>
4
5void ttk::ftm::printTreesStats(std::vector<FTMTree_MT *> &trees) {
6 for(auto tree : trees)
7 tree->printTreeStats();
8}
9
10namespace ttk {
11 namespace ftm {
12
13 // --------------------
14 // Is
15 // --------------------
17 unsigned int const origin
18 = (unsigned int)this->getNode(nodeId)->getOrigin();
19 return origin != nullNodes && origin < this->getNumberOfNodes();
20 }
21
23 return this->getNode(nodeId)->getNumberOfUpSuperArcs() == 0;
24 }
25
27 return this->getNode(nodeId)->getNumberOfDownSuperArcs() == 0;
28 }
29
31 return this->isRoot(nodeId) and this->isLeaf(nodeId);
32 }
33
35 idNode const treeRoot = this->getRoot();
36 return (unsigned int)this->getNode(treeRoot)->getOrigin() == treeRoot;
37 }
38
40 return this->getParentSafe(this->getNode(nodeId)->getOrigin()) != nodeId;
41 }
42
44 bool merged = this->isNodeAlone(nodeId)
45 or this->isNodeAlone(this->getNode(nodeId)->getOrigin());
46 auto nodeIdOrigin = this->getNode(nodeId)->getOrigin();
47 merged
48 = merged or nodeIdOrigin == this->getNode(nodeIdOrigin)->getOrigin();
49 return merged;
50 }
51
53 return nodeId >= this->getNumberOfNodes();
54 }
55
57 idNode const treeRoot = this->getRoot();
58 unsigned int cptNodeAlone = 0;
59 idNode otherNode = treeRoot;
60 for(unsigned int i = 0; i < this->getNumberOfNodes(); ++i)
61 if(this->isNodeAlone(i))
62 cptNodeAlone++;
63 else if(i != treeRoot)
64 otherNode = i;
65 // unsigned int origin = (unsigned
66 // int)tree->getNode(otherNode)->getOrigin();
67 idNode const treeRootOrigin = this->getNode(treeRoot)->getOrigin();
68 return (otherNode != treeRoot
69 and this->getNumberOfNodes() - cptNodeAlone == 2
70 and (treeRootOrigin == otherNode or treeRootOrigin == treeRoot));
71 /*return (otherNode != treeRoot and cptNodeAlone ==
72 tree->getNumberOfNodes()-2 and (origin == treeRoot or otherNode ==
73 origin));*/
74 }
75
76 // Do not normalize node is if root or son of a merged root
78 auto nodeIdParent = this->getParentSafe(nodeId);
79 return this->isRoot(nodeId)
80 or (this->isRoot(nodeIdParent)
81 and nodeIdParent
82 == (unsigned int)this->getNode(nodeIdParent)
83 ->getOrigin());
84 // and nodeIdOrigin == nodeIdParent) )
85 }
86
88 auto nodeOriginOrigin
89 = (unsigned int)this->getNode(this->getNode(nodeId)->getOrigin())
90 ->getOrigin();
91 return nodeOriginOrigin != nodeId;
92 }
93
94 // --------------------
95 // Get
96 // --------------------
98 for(idNode node = 0; node < this->getNumberOfNodes(); ++node)
99 if(this->isRoot(node) and !this->isLeaf(node))
100 return node;
101 return nullNodes;
102 }
103
105 if(!this->isRoot(nodeId)) {
106 // _ Nodes in merge trees should have only one parent
107 idSuperArc const arcId = this->getNode(nodeId)->getUpSuperArcId(0);
108 idNode const parentNodeId = this->getSuperArc(arcId)->getUpNodeId();
109 return parentNodeId;
110 }
111 return nodeId;
112 }
113
115 std::vector<idNode> &childrens) {
116 childrens.clear();
117 for(idSuperArc i = 0;
118 i < this->getNode(nodeId)->getNumberOfDownSuperArcs(); ++i) {
119 idSuperArc const arcId = this->getNode(nodeId)->getDownSuperArcId(i);
120 childrens.push_back(this->getSuperArc(arcId)->getDownNodeId());
121 }
122 }
123
124 void FTMTree_MT::getLeavesFromTree(std::vector<idNode> &treeLeaves) {
125 treeLeaves.clear();
126 for(idNode i = 0; i < this->getNumberOfNodes(); ++i) {
127 if(this->isLeaf(i) and !this->isRoot(i))
128 treeLeaves.push_back(i);
129 }
130 }
131
133 auto leaves = this->getLeaves();
134 return leaves.size();
135 }
136
138 int cpt = 0;
139 for(idNode i = 0; i < this->getNumberOfNodes(); ++i)
140 cpt += this->isNodeAlone(i) ? 1 : 0;
141 return cpt;
142 }
143
145 return this->getNumberOfNodes() - this->getNumberOfNodeAlone();
146 }
147
149 idNode node, std::tuple<std::vector<idNode>, std::vector<idNode>> &res) {
150 std::vector<idNode> branchOrigins, nonBranchOrigins;
151
152 idNode const nodeOrigin = this->getNode(node)->getOrigin();
153 idNode nodeParent = this->getParentSafe(nodeOrigin);
154 while(nodeParent != node) {
155 if(this->isBranchOrigin(nodeParent))
156 branchOrigins.push_back(nodeParent);
157 else
158 nonBranchOrigins.push_back(nodeParent);
159 nodeParent = this->getParentSafe(nodeParent);
160 }
161
162 res = std::make_tuple(branchOrigins, nonBranchOrigins);
163 }
164
166 std::vector<idNode> &branching,
167 std::vector<int> &branchingID,
168 std::vector<std::vector<idNode>> &nodeBranching) {
169 branching = std::vector<idNode>(this->getNumberOfNodes());
170 branchingID = std::vector<int>(this->getNumberOfNodes(), -1);
171 nodeBranching
172 = std::vector<std::vector<idNode>>(this->getNumberOfNodes());
173 int branchID = 0;
174 std::queue<idNode> queue;
175 queue.emplace(this->getRoot());
176 while(!queue.empty()) {
177 idNode const node = queue.front();
178 queue.pop();
179 if(this->isLeaf(node))
180 continue;
181 auto nodeOrigin = this->getNode(node)->getOrigin();
182 idNode parentNodeOrigin = nodeOrigin;
183 while(parentNodeOrigin != node) {
184 branching[parentNodeOrigin] = node;
185 branchingID[parentNodeOrigin] = branchID;
186 nodeBranching[node].push_back(parentNodeOrigin);
187 parentNodeOrigin = this->getParentSafe(parentNodeOrigin);
188 }
189 if(this->isRoot(node)) {
190 branching[node] = node;
191 branchingID[node] = branchID;
192 }
193 ++branchID;
194 std::vector<idNode> children;
195 this->getChildren(node, children);
196 for(idNode const child : children)
197 queue.emplace(child);
198 }
199 }
200
201 void FTMTree_MT::getTreeBranching(std::vector<idNode> &branching,
202 std::vector<int> &branchingID) {
203 std::vector<std::vector<idNode>> nodeBranching;
204 this->getTreeBranching(branching, branchingID, nodeBranching);
205 }
206
207 void FTMTree_MT::getAllRoots(std::vector<idNode> &roots) {
208 roots.clear();
209 for(idNode node = 0; node < this->getNumberOfNodes(); ++node)
210 if(this->isRoot(node) and !this->isLeaf(node))
211 roots.push_back(node);
212 }
213
215 int noRoot = 0;
216 for(idNode node = 0; node < this->getNumberOfNodes(); ++node)
217 if(this->isRoot(node) and !this->isLeaf(node))
218 ++noRoot;
219 return noRoot;
220 }
221
223 return this->getNode(nodeId)->getNumberOfDownSuperArcs();
224 }
225
227 int maxDepth = 0;
228 std::queue<std::tuple<idNode, int>> queue;
229 queue.emplace(this->getRoot(), 0);
230 while(!queue.empty()) {
231 auto tup = queue.front();
232 queue.pop();
233 idNode const node = std::get<0>(tup);
234 int const depth = std::get<1>(tup);
235 maxDepth = std::max(maxDepth, depth);
236 std::vector<idNode> children;
237 this->getChildren(node, children);
238 for(idNode const child : children)
239 queue.emplace(child, depth + 1);
240 }
241 return maxDepth;
242 }
243
245 int level = 0;
246 auto root = this->getRoot();
247 int const noRoot = this->getNumberOfRoot();
248 if(noRoot != 1) {
249 std::stringstream ss;
250 ss << "problem, there is " << noRoot << " root(s)";
251 printErr(ss.str());
252 this->printTree2();
253 this->printTree();
254 }
255 if(this->isNodeAlone(nodeId))
256 return 0;
257 while(nodeId != root) {
258 nodeId = this->getParentSafe(nodeId);
259 ++level;
260 }
261 return level;
262 }
263
264 void FTMTree_MT::getAllNodeLevel(std::vector<int> &allNodeLevel) {
265 allNodeLevel = std::vector<int>(this->getNumberOfNodes());
266 std::queue<std::tuple<idNode, int>> queue;
267 queue.emplace(this->getRoot(), 0);
268 while(!queue.empty()) {
269 auto tup = queue.front();
270 queue.pop();
271 idNode const node = std::get<0>(tup);
272 int const level = std::get<1>(tup);
273 allNodeLevel[node] = level;
274 std::vector<idNode> children;
275 this->getChildren(node, children);
276 for(idNode const child : children)
277 queue.emplace(child, level + 1);
278 }
279 }
280
282 std::vector<std::vector<idNode>> &levelToNode) {
283 std::vector<int> allNodeLevel;
284 this->getAllNodeLevel(allNodeLevel);
285 int const maxLevel
286 = *max_element(allNodeLevel.begin(), allNodeLevel.end());
287 levelToNode = std::vector<std::vector<idNode>>(maxLevel + 1);
288 for(unsigned int i = 0; i < allNodeLevel.size(); ++i) {
289 levelToNode[allNodeLevel[i]].push_back(i);
290 }
291 }
292
293 void FTMTree_MT::getBranchSubtree(std::vector<idNode> &branching,
294 idNode branchRoot,
295 std::vector<idNode> &branchSubtree) {
296 branchSubtree.clear();
297 std::queue<idNode> queue;
298 queue.push(branchRoot);
299 while(!queue.empty()) {
300 idNode const node = queue.front();
301 queue.pop();
302
303 if(branching[node] != branchRoot
304 and this->getParentSafe(node) == branchRoot and node != branchRoot)
305 continue;
306
307 branchSubtree.push_back(node);
308 std::vector<idNode> children;
309 this->getChildren(node, children);
310 for(idNode const child : children)
311 queue.push(child);
312 }
313 }
314
315 // --------------------
316 // Persistence
317 // --------------------
319 std::vector<std::vector<idNode>> &treeMultiPers) {
320 treeMultiPers
321 = std::vector<std::vector<idNode>>(this->getNumberOfNodes());
322 for(unsigned int i = 0; i < this->getNumberOfNodes(); ++i)
323 if(this->isLeaf(i) and this->isNodeOriginDefined(i)
324 and not this->isNodeAlone(i)
325 and this->getNode(this->getNode(i)->getOrigin())->getOrigin()
326 != (int)i)
327 treeMultiPers[this->getNode(i)->getOrigin()].push_back(i);
328 }
329
330 // --------------------
331 // Set
332 // --------------------
333 void FTMTree_MT::setParent(idNode nodeId, idNode newParentNodeId) {
334 this->deleteParent(nodeId);
335 this->makeSuperArc(nodeId, newParentNodeId);
336 }
337
338 // --------------------
339 // Delete
340 // --------------------
341 // Delete node by keeping subtree
343 if(this->isRoot(nodeId) and !this->isLeaf(nodeId))
344 printErr("deletion of root!");
345
346 idNode const parentNodeId = this->getParentSafe(nodeId);
347 if(!this->isRoot(nodeId)) {
348 // Delete down arc from parent node
349 // _ Nodes in trees should have only one parent
350 idSuperArc const nodeArcId = this->getNode(nodeId)->getUpSuperArcId(0);
351 this->getNode(parentNodeId)->removeDownSuperArc(nodeArcId);
352 }
353 // Delete up arc from child nodes
354 for(idSuperArc i = 0;
355 i < this->getNode(nodeId)->getNumberOfDownSuperArcs(); ++i) {
356 idSuperArc const arcId = this->getNode(nodeId)->getDownSuperArcId(i);
357 idNode const childNodeId = this->getSuperArc(arcId)->getDownNodeId();
358 this->getNode(childNodeId)->removeUpSuperArc(arcId);
359 if(!this->isRoot(nodeId))
360 this->makeSuperArc(childNodeId, parentNodeId);
361 }
362 // Reset deleted node
363 this->getNode(nodeId)->clearDownSuperArcs();
364 this->getNode(nodeId)->clearUpSuperArcs();
365 }
366
367 void FTMTree_MT::deleteIthUpArc(idNode nodeId, int arcIth) {
368 idSuperArc const nodeArcId
369 = this->getNode(nodeId)->getUpSuperArcId(arcIth);
370 // Delete down arc from old parent
371 idNode const parentNodeId = this->getSuperArc(nodeArcId)->getUpNodeId();
372 this->getNode(parentNodeId)->removeDownSuperArc(nodeArcId);
373 // Delete up arc from node
374 this->getNode(nodeId)->removeUpSuperArc(nodeArcId);
375 }
376
378 if(!this->isRoot(nodeId)) {
379 // _ Nodes in trees should have only one parent
380 this->deleteIthUpArc(nodeId, 0);
381 }
382 }
383
385 std::queue<idNode> queue;
386 queue.push(nodeId);
387 while(!queue.empty()) {
388 idNode const node = queue.front();
389 queue.pop();
390 std::vector<idNode> children;
391 this->getChildren(node, children);
392 for(idNode const child : children)
393 queue.push(child);
394 this->deleteNode(node);
395 }
396 }
397
398 // --------------------
399 // Create/Delete/Modify Tree
400 // --------------------
402 // Add Nodes
403 for(unsigned int i = 0; i < tree->getNumberOfNodes(); ++i)
404 this->makeNode(i);
405 for(unsigned int i = 0; i < tree->getNumberOfNodes(); ++i)
406 this->getNode(i)->setOrigin(tree->getNode(i)->getOrigin());
407
408 // Add Arcs
409 for(unsigned int i = 0; i < tree->getNumberOfNodes(); ++i) {
410 for(unsigned int j = 0;
411 j < tree->getNode(i)->getNumberOfDownSuperArcs(); ++j) {
412 auto superArcId = tree->getNode(i)->getDownSuperArcId(j);
413 this->makeSuperArc(tree->getSuperArc(superArcId)->getDownNodeId(), i);
414 }
415 }
416 }
417
418 // --------------------
419 // Utils
420 // --------------------
421 void FTMTree_MT::printNodeSS(idNode node, std::stringstream &ss) {
422 ss << "(" << node << ") \\ ";
423
424 std::vector<idNode> children;
425 this->getChildren(node, children);
426 for(idNode const child : children)
427 ss << "+" << child << " ";
428
429 if(!this->isRoot(node))
430 ss << " / +" << this->getParentSafe(node);
431 ss << std::endl;
432 }
433
434 std::stringstream FTMTree_MT::printTree(bool doPrint) {
435 std::stringstream ss;
436 std::vector<idNode> allRoots;
437 this->getAllRoots(allRoots);
438 if(allRoots.size() != 1)
439 ss << allRoots.size() << " roots" << std::endl;
440 for(unsigned int i = 0; i < allRoots.size(); ++i) {
441 if(allRoots.size() != 1)
442 ss << i << " _ ";
443 ss << "Nodes----------" << std::endl;
444 std::queue<idNode> queue;
445 queue.push(allRoots[i]);
446 while(!queue.empty()) {
447 idNode const node = queue.front();
448 queue.pop();
449
450 printNodeSS(node, ss);
451
452 std::vector<idNode> children;
453 this->getChildren(node, children);
454 for(idNode const child : children)
455 queue.push(child);
456 }
457 }
458 if(allRoots.size() == 0)
459 for(unsigned int i = 0; i < this->getNumberOfNodes(); ++i)
460 // if(not tree->isNodeAlone(i))
461 printNodeSS(i, ss);
462
463 if(doPrint)
464 printMsg(ss.str());
465 return ss;
466 }
467
468 std::stringstream FTMTree_MT::printTreeStats(bool doPrint) {
469 auto noNodesT = this->getNumberOfNodes();
470 auto noNodes = this->getRealNumberOfNodes();
471 std::stringstream ss;
472 ss << "tree [node: " << noNodes << " / " << noNodesT;
473 ss << ", depth: " << this->getTreeDepth() << "]";
474 if(doPrint)
475 printMsg(ss.str());
476 return ss;
477 }
478
479 std::stringstream
481 std::stringstream ss;
482 std::vector<std::vector<idNode>> vec;
484 for(unsigned int i = 0; i < vec.size(); ++i)
485 if(vec[i].size() != 0) {
486 ss << i << " : ";
487 for(auto t : vec[i])
488 ss << t << " ";
489 ss << std::endl;
490 }
491
492 if(doPrint)
493 printMsg(ss.str());
494 return ss;
495 }
496
497 // --------------------
498 // Make tree utils
499 // --------------------
501 ftm::idNode treeRoot = 0;
502 for(unsigned int i = 0; i < tree->getNumberOfNodes(); ++i) {
503 if(tree->getNode(i)->getNumberOfDownSuperArcs() != 0
504 and tree->getNode(i)->getNumberOfUpSuperArcs() == 0)
505 treeRoot = i;
506 }
507
508 for(unsigned int i = 0; i < tree->getNumberOfNodes(); ++i)
509 if(tree->getNode(i)->getNumberOfUpSuperArcs() > 1) {
510 ftm::idNode lowestParent = std::numeric_limits<ftm::idNode>::max();
511 for(long unsigned int j = 0;
512 j < tree->getNode(i)->getNumberOfUpSuperArcs(); ++j) {
513 auto tParent
514 = tree->getSuperArc(tree->getNode(i)->getUpSuperArcId(j))
515 ->getUpNodeId();
516 lowestParent = (lowestParent > tParent) ? tParent : lowestParent;
517 }
518
519 for(long unsigned int j = 0;
520 j < tree->getNode(i)->getNumberOfUpSuperArcs(); ++j) {
521 ftm::idSuperArc const nodeArcId
522 = tree->getNode(i)->getUpSuperArcId(j);
523 auto tParent = tree->getSuperArc(nodeArcId)->getUpNodeId();
524 if(tParent != lowestParent) {
525
526 if(tParent == treeRoot) {
527 for(long unsigned int k = 0;
528 k < tree->getNode(i)->getNumberOfDownSuperArcs(); ++k) {
529 ftm::idSuperArc const nodeArcId2
530 = tree->getNode(i)->getDownSuperArcId(k);
531 auto tChildren
532 = tree->getSuperArc(nodeArcId2)->getDownNodeId();
533 if(tChildren > i) {
534 tree->getNode(i)->removeDownSuperArc(nodeArcId2);
535 tree->getNode(tChildren)->removeUpSuperArc(nodeArcId2);
536 tree->makeSuperArc(tChildren, treeRoot);
537 break;
538 }
539 }
540 }
541
542 // Delete down arc from old parent
543 tree->getNode(tParent)->removeDownSuperArc(nodeArcId);
544 // Delete up arc from node
545 tree->getNode(i)->removeUpSuperArc(nodeArcId);
546 }
547 }
548 }
549 }
550
552 for(unsigned int i = 0; i < tree->getNumberOfNodes(); ++i) {
553 for(unsigned int j = 0; j < tree->getNode(i)->getNumberOfUpSuperArcs();
554 ++j) {
555 ftm::idSuperArc const nodeArcId
556 = tree->getNode(i)->getUpSuperArcId(j);
557 auto tParent = tree->getSuperArc(nodeArcId)->getUpNodeId();
558 if(tParent == i) {
559 // Delete down arc
560 tree->getNode(i)->removeDownSuperArc(nodeArcId);
561 // Delete up arc
562 tree->getNode(i)->removeUpSuperArc(nodeArcId);
563 }
564 }
565 }
566 }
567
568 } // namespace ftm
569} // namespace ttk
int printErr(const std::string &msg, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cerr) const
Definition Debug.h:149
bool notNeedToNormalize(idNode nodeId)
void getLevelToNode(std::vector< std::vector< idNode > > &res)
bool isNodeIdInconsistent(idNode nodeId)
SuperArc * getSuperArc(idSuperArc i)
Definition FTMTree_MT.h:367
idNode getNumberOfNodes() const
Definition FTMTree_MT.h:389
void setParent(idNode nodeId, idNode newParentNodeId)
bool isNodeMerged(idNode nodeId)
int getNumberOfChildren(idNode nodeId)
idNode getDownNodeId(const SuperArc *a)
std::stringstream printMultiPersOriginsVectorFromTree(bool doPrint=true)
void getTreeBranching(std::vector< idNode > &branching, std::vector< int > &branchingID, std::vector< std::vector< idNode > > &nodeBranching)
bool isRoot(idNode nodeId)
void getMultiPersOriginsVectorFromTree(std::vector< std::vector< idNode > > &res)
idNode getParentSafe(idNode nodeId)
void getBranchSubtree(std::vector< idNode > &branching, idNode branchRoot, std::vector< idNode > &res)
bool isNodeOriginDefined(idNode nodeId)
void printNodeSS(idNode node, std::stringstream &ss)
void deleteIthUpArc(idNode nodeId, int arcIth)
int getNodeLevel(idNode nodeId)
void getAllRoots(std::vector< idNode > &res)
void getChildren(idNode nodeId, std::vector< idNode > &res)
void deleteNode(idNode nodeId)
const std::vector< idNode > & getLeaves() const
Definition FTMTree_MT.h:407
bool isMultiPersPair(idNode nodeId)
idNode makeNode(SimplexId vertexId, SimplexId linked=nullVertex)
bool isLeaf(idNode nodeId)
void deleteParent(idNode nodeId)
bool isNodeAlone(idNode nodeId)
idSuperArc makeSuperArc(idNode downNodeId, idNode upNodeId)
bool isBranchOrigin(idNode nodeId)
void copyMergeTreeStructure(FTMTree_MT *tree)
void getBranchOriginsFromThisBranch(idNode node, std::tuple< std::vector< idNode >, std::vector< idNode > > &res)
void getLeavesFromTree(std::vector< idNode > &res)
Node * getNode(idNode nodeId)
Definition FTMTree_MT.h:393
void getAllNodeLevel(std::vector< int > &res)
std::stringstream printTree(bool doPrint=true)
void deleteSubtree(idNode nodeId)
bool isThereOnlyOnePersistencePair()
std::stringstream printTreeStats(bool doPrint=true)
idSuperArc getUpSuperArcId(idSuperArc neighborId) const
Definition FTMNode.h:105
idSuperArc clearUpSuperArcs()
Definition FTMNode.h:133
idSuperArc getNumberOfDownSuperArcs() const
Definition FTMNode.h:82
idSuperArc getDownSuperArcId(idSuperArc neighborId) const
Definition FTMNode.h:94
void removeUpSuperArc(idSuperArc idSa)
Definition FTMNode.h:158
idSuperArc clearDownSuperArcs()
Definition FTMNode.h:127
void setOrigin(SimplexId linked)
Definition FTMNode.h:72
void removeDownSuperArc(idSuperArc idSa)
Definition FTMNode.h:146
SimplexId getOrigin() const
Definition FTMNode.h:64
idSuperArc getNumberOfUpSuperArcs() const
Definition FTMNode.h:86
idNode getUpNodeId() const
Definition FTMSuperArc.h:68
idNode getDownNodeId() const
Definition FTMSuperArc.h:72
long unsigned int idSuperArc
SuperArc index in vect_superArcs_.
void removeSelfLink(FTMTree_MT *tree)
void printTreesStats(std::vector< ftm::FTMTree_MT * > &trees)
unsigned int idNode
Node index in vect_nodes_.
void manageInconsistentArcsMultiParent(FTMTree_MT *tree)
The Topology ToolKit.
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/|__ _|"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)