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 std::vector<idNode> leaves;
134 this->getLeavesFromTree(leaves);
135 return leaves.size();
136 }
137
139 int cpt = 0;
140 for(idNode i = 0; i < this->getNumberOfNodes(); ++i)
141 cpt += this->isNodeAlone(i) ? 1 : 0;
142 return cpt;
143 }
144
146 return this->getNumberOfNodes() - this->getNumberOfNodeAlone();
147 }
148
150 idNode node, std::tuple<std::vector<idNode>, std::vector<idNode>> &res) {
151 std::vector<idNode> branchOrigins, nonBranchOrigins;
152
153 idNode const nodeOrigin = this->getNode(node)->getOrigin();
154 idNode nodeParent = this->getParentSafe(nodeOrigin);
155 while(nodeParent != node) {
156 if(this->isBranchOrigin(nodeParent))
157 branchOrigins.push_back(nodeParent);
158 else
159 nonBranchOrigins.push_back(nodeParent);
160 nodeParent = this->getParentSafe(nodeParent);
161 }
162
163 res = std::make_tuple(branchOrigins, nonBranchOrigins);
164 }
165
167 std::vector<idNode> &branching,
168 std::vector<int> &branchingID,
169 std::vector<std::vector<idNode>> &nodeBranching) {
170 branching = std::vector<idNode>(this->getNumberOfNodes());
171 branchingID = std::vector<int>(this->getNumberOfNodes(), -1);
172 nodeBranching
173 = std::vector<std::vector<idNode>>(this->getNumberOfNodes());
174 int branchID = 0;
175 std::queue<idNode> queue;
176 queue.emplace(this->getRoot());
177 while(!queue.empty()) {
178 idNode const node = queue.front();
179 queue.pop();
180 if(this->isLeaf(node))
181 continue;
182 auto nodeOrigin = this->getNode(node)->getOrigin();
183 idNode parentNodeOrigin = nodeOrigin;
184 while(parentNodeOrigin != node) {
185 branching[parentNodeOrigin] = node;
186 branchingID[parentNodeOrigin] = branchID;
187 nodeBranching[node].push_back(parentNodeOrigin);
188 parentNodeOrigin = this->getParentSafe(parentNodeOrigin);
189 }
190 if(this->isRoot(node)) {
191 branching[node] = node;
192 branchingID[node] = branchID;
193 }
194 ++branchID;
195 std::vector<idNode> children;
196 this->getChildren(node, children);
197 for(idNode const child : children)
198 queue.emplace(child);
199 }
200 }
201
202 void FTMTree_MT::getTreeBranching(std::vector<idNode> &branching,
203 std::vector<int> &branchingID) {
204 std::vector<std::vector<idNode>> nodeBranching;
205 this->getTreeBranching(branching, branchingID, nodeBranching);
206 }
207
208 void FTMTree_MT::getAllRoots(std::vector<idNode> &roots) {
209 roots.clear();
210 for(idNode node = 0; node < this->getNumberOfNodes(); ++node)
211 if(this->isRoot(node) and !this->isLeaf(node))
212 roots.push_back(node);
213 }
214
216 int noRoot = 0;
217 for(idNode node = 0; node < this->getNumberOfNodes(); ++node)
218 if(this->isRoot(node) and !this->isLeaf(node))
219 ++noRoot;
220 return noRoot;
221 }
222
224 return this->getNode(nodeId)->getNumberOfDownSuperArcs();
225 }
226
228 int maxDepth = 0;
229 std::queue<std::tuple<idNode, int>> queue;
230 queue.emplace(this->getRoot(), 0);
231 while(!queue.empty()) {
232 auto tup = queue.front();
233 queue.pop();
234 idNode const node = std::get<0>(tup);
235 int const depth = std::get<1>(tup);
236 maxDepth = std::max(maxDepth, depth);
237 std::vector<idNode> children;
238 this->getChildren(node, children);
239 for(idNode const child : children)
240 queue.emplace(child, depth + 1);
241 }
242 return maxDepth;
243 }
244
246 int level = 0;
247 auto root = this->getRoot();
248 int const noRoot = this->getNumberOfRoot();
249 if(noRoot != 1) {
250 std::stringstream ss;
251 ss << "problem, there is " << noRoot << " root(s)";
252 printErr(ss.str());
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::printSubTree(idNode subRoot) {
435 std::stringstream ss;
436 ss << "Nodes----------" << std::endl;
437 std::queue<idNode> queue;
438 queue.push(subRoot);
439 while(!queue.empty()) {
440 idNode node = queue.front();
441 queue.pop();
442
443 printNodeSS(node, ss);
444
445 std::vector<idNode> children;
446 this->getChildren(node, children);
447 for(idNode child : children)
448 queue.push(child);
449 }
450 return ss;
451 }
452
453 std::stringstream FTMTree_MT::printTree(bool doPrint) {
454 std::stringstream ss;
455 std::vector<idNode> allRoots;
456 this->getAllRoots(allRoots);
457 if(allRoots.size() != 1)
458 ss << allRoots.size() << " roots" << std::endl;
459 for(unsigned int i = 0; i < allRoots.size(); ++i) {
460 if(allRoots.size() != 1)
461 ss << i << " _ ";
462 ss << this->printSubTree(allRoots[i]).str();
463 }
464 if(allRoots.size() == 0)
465 for(unsigned int i = 0; i < this->getNumberOfNodes(); ++i)
466 // if(not tree->isNodeAlone(i))
467 printNodeSS(i, ss);
468
469 if(doPrint)
470 printMsg(ss.str());
471 return ss;
472 }
473
474 std::stringstream FTMTree_MT::printTreeStats(bool doPrint) {
475 auto noNodesT = this->getNumberOfNodes();
476 auto noNodes = this->getRealNumberOfNodes();
477 std::stringstream ss;
478 ss << "tree [node: " << noNodes << " / " << noNodesT;
479 ss << ", depth: " << this->getTreeDepth() << "]";
480 if(doPrint)
481 printMsg(ss.str());
482 return ss;
483 }
484
485 std::stringstream
487 std::stringstream ss;
488 std::vector<std::vector<idNode>> vec;
490 for(unsigned int i = 0; i < vec.size(); ++i)
491 if(vec[i].size() != 0) {
492 ss << i << " : ";
493 for(auto t : vec[i])
494 ss << t << " ";
495 ss << std::endl;
496 }
497
498 if(doPrint)
499 printMsg(ss.str());
500 return ss;
501 }
502
503 // --------------------
504 // Make tree utils
505 // --------------------
507 ftm::idNode treeRoot = 0;
508 for(unsigned int i = 0; i < tree->getNumberOfNodes(); ++i) {
509 if(tree->getNode(i)->getNumberOfDownSuperArcs() != 0
510 and tree->getNode(i)->getNumberOfUpSuperArcs() == 0)
511 treeRoot = i;
512 }
513
514 for(unsigned int i = 0; i < tree->getNumberOfNodes(); ++i)
515 if(tree->getNode(i)->getNumberOfUpSuperArcs() > 1) {
516 ftm::idNode lowestParent = std::numeric_limits<ftm::idNode>::max();
517 for(long unsigned int j = 0;
518 j < tree->getNode(i)->getNumberOfUpSuperArcs(); ++j) {
519 auto tParent
520 = tree->getSuperArc(tree->getNode(i)->getUpSuperArcId(j))
521 ->getUpNodeId();
522 lowestParent = (lowestParent > tParent) ? tParent : lowestParent;
523 }
524
525 for(long unsigned int j = 0;
526 j < tree->getNode(i)->getNumberOfUpSuperArcs(); ++j) {
527 ftm::idSuperArc const nodeArcId
528 = tree->getNode(i)->getUpSuperArcId(j);
529 auto tParent = tree->getSuperArc(nodeArcId)->getUpNodeId();
530 if(tParent != lowestParent) {
531
532 if(tParent == treeRoot) {
533 for(long unsigned int k = 0;
534 k < tree->getNode(i)->getNumberOfDownSuperArcs(); ++k) {
535 ftm::idSuperArc const nodeArcId2
536 = tree->getNode(i)->getDownSuperArcId(k);
537 auto tChildren
538 = tree->getSuperArc(nodeArcId2)->getDownNodeId();
539 if(tChildren > i) {
540 tree->getNode(i)->removeDownSuperArc(nodeArcId2);
541 tree->getNode(tChildren)->removeUpSuperArc(nodeArcId2);
542 tree->makeSuperArc(tChildren, treeRoot);
543 break;
544 }
545 }
546 }
547
548 // Delete down arc from old parent
549 tree->getNode(tParent)->removeDownSuperArc(nodeArcId);
550 // Delete up arc from node
551 tree->getNode(i)->removeUpSuperArc(nodeArcId);
552 }
553 }
554 }
555 }
556
558 for(unsigned int i = 0; i < tree->getNumberOfNodes(); ++i) {
559 for(unsigned int j = 0; j < tree->getNode(i)->getNumberOfUpSuperArcs();
560 ++j) {
561 ftm::idSuperArc const nodeArcId
562 = tree->getNode(i)->getUpSuperArcId(j);
563 auto tParent = tree->getSuperArc(nodeArcId)->getUpNodeId();
564 if(tParent == i) {
565 // Delete down arc
566 tree->getNode(i)->removeDownSuperArc(nodeArcId);
567 // Delete up arc
568 tree->getNode(i)->removeUpSuperArc(nodeArcId);
569 }
570 }
571 }
572 }
573
574 } // namespace ftm
575} // 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)
std::stringstream printSubTree(idNode subRoot)
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)
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)