174 template <
class dataType>
180 template <
class dataType>
183 std::vector<std::vector<dataType>> &distanceMatrix2) {
184 for(
unsigned int i = 0; i < distanceMatrix.size(); ++i)
185 for(
unsigned int j = 0; j < distanceMatrix[i].size(); ++j)
186 distanceMatrix[i][j] = mixDistances<dataType>(
187 distanceMatrix[i][j], distanceMatrix2[i][j]);
194 template <
class dataType>
197 std::vector<std::vector<ftm::idNode>> &treeNodeMerged,
198 bool mergeByPersistence =
false) {
199 bool fullMerge = (epsilon == 100);
202 treeNodeMerged.clear();
205 if(mergeByPersistence)
206 ftm::computePersistencePairs<dataType>(
210 dataType maxValue = tree->
getValue<dataType>(0);
211 dataType minValue = tree->
getValue<dataType>(0);
214 dataType iValue = tree->
getValue<dataType>(i);
215 if(mergeByPersistence) {
216 maxValue = (maxValue < iValue) ? iValue : maxValue;
217 minValue = (minValue > iValue) ? iValue : minValue;
220 dataType parentValue = tree->
getValue<dataType>(parent);
221 dataType tempMax = std::max(iValue, parentValue);
222 dataType tempMin = std::min(iValue, parentValue);
223 if((tempMax - tempMin) > (maxValue - minValue)) {
230 double const epsilonOri = epsilon;
231 epsilon = (maxValue - minValue) * epsilon / 100;
245 for(
unsigned int i = 0; i < farthestSaddle.size(); ++i)
246 farthestSaddle[i] = i;
250 std::stack<int> nodeStack;
251 std::queue<ftm::idNode> queue;
252 queue.emplace(tree->
getRoot());
253 while(!queue.empty()) {
256 nodeStack.emplace(node);
257 std::vector<ftm::idNode> children;
259 for(
auto child : children)
260 queue.emplace(child);
263 while(!nodeStack.empty()) {
268 dataType nodeValue = tree->
getValue<dataType>(nodeId);
270 nodeValue = tree->
getValue<dataType>(farthestSaddle[nodeId]);
271 dataType parentNodeValue = tree->
getValue<dataType>(parentNodeId);
272 dataType diffValue = std::max(nodeValue, parentNodeValue)
273 - std::min(nodeValue, parentNodeValue);
274 if(diffValue <= epsilon) {
276 if(mergeByPersistence) {
278 auto birthDeath2 = tree->
getBirthDeath<dataType>(parentNodeId);
280 = std::get<1>(birthDeath1) - std::get<0>(birthDeath1);
282 = std::get<1>(birthDeath2) - std::get<0>(birthDeath2);
283 nodeIdToDelete = (pers1 > pers2) ? parentNodeId : nodeId;
284 nodeIdToKeep = (pers1 > pers2) ? nodeId : parentNodeId;
285 if(nodeIdToDelete == parentNodeId)
286 nodeStack.emplace(nodeId);
288 nodeIdToDelete = nodeId;
289 nodeIdToKeep = parentNodeId;
292 for(
auto node : treeNodeMerged[nodeIdToDelete]) {
293 treeNodeMerged[nodeIdToKeep].push_back(node);
294 if(isFarthest(farthestSaddle[nodeIdToKeep],
298 treeNodeMerged[nodeIdToKeep].push_back(
300 if(isFarthest(farthestSaddle[nodeIdToKeep], nodeIdToDelete))
301 farthestSaddle[nodeIdToKeep] = nodeIdToDelete;
302 treeNodeMerged[nodeIdToDelete].clear();
316 template <
class dataType>
319 double epsilon3 = 100) {
320 bool fullMerge = (epsilon2 == 0);
326 std::queue<ftm::idNode> queue;
327 queue.emplace(tree->
getRoot());
328 while(!queue.empty()) {
334 const double nodeParentPers
336 if(nodePers / nodeParentPers > epsilon2
337 and nodePers / maxPers < epsilon3)
340 std::vector<ftm::idNode> children;
342 for(
auto child : children)
343 queue.emplace(child);
355 template <
class dataType>
357 std::vector<std::tuple<ftm::idNode, ftm::idNode, dataType>> pairs;
360 int const index = std::max((
int)(pairs.size() - n), 0);
361 dataType threshold = std::get<2>(pairs[index]) * (1.0 - 1e-6)
363 persistenceThresholding<dataType>(tree, threshold);
366 template <
class dataType>
368 double persistenceThresholdT,
369 std::vector<ftm::idNode> &deletedNodes) {
372 dataType threshold = persistenceThresholdT / 100 * maxPers;
375 bool keepOneZeroPersistencePair = (secondMax == 0 or maxPers == 0);
376 if(threshold >= secondMax)
377 threshold = (1.0 - 1e-6) * secondMax;
383 if(nodePers == 0 and keepOneZeroPersistencePair
385 keepOneZeroPersistencePair =
false;
388 if((nodePers == 0 or nodePers <= threshold
391 deletedNodes.push_back(i);
396 deletedNodes.push_back(nodeOrigin);
402 template <
class dataType>
404 std::vector<ftm::idNode> &deletedNodes) {
405 persistenceThresholding<dataType>(
409 template <
class dataType>
411 double persistenceThresholdT) {
412 std::vector<ftm::idNode> deletedNodes;
413 persistenceThresholding<dataType>(
414 tree, persistenceThresholdT, deletedNodes);
417 template <
class dataType>
419 std::vector<ftm::idNode> deletedNodes;
420 persistenceThresholding<dataType>(
424 template <
class dataType>
428 std::stringstream ss;
429 std::vector<ftm::idNode> children;
431 ss << i <<
" has no origin (scalar=" << tree->
getValue<dataType>(i)
432 <<
", noChildren=" << children.size()
438 std::stringstream ss2;
439 ss2 <<
"the root has no origin!";
445 template <
class dataType>
447 bool deleteInconsistentNodes =
true) {
448 if(deleteInconsistentNodes) {
472 auto pairs = ftm::computePersistencePairs<dataType>(tree);
474 verifyOrigins<dataType>(tree);
478 template <
class dataType>
481 std::vector<std::vector<ftm::idNode>> &treeNodeMerged) {
494 std::vector<std::vector<ftm::idNode>> treeMultiPers;
499 std::queue<ftm::idNode> queueNodes;
500 queueNodes.emplace(root);
501 while(!queueNodes.empty()) {
505 if(node == nodeOrigin
510 std::vector<std::tuple<ftm::idNode, int>> vecOrigins;
511 for(
auto nodeMergedOrigin : treeNodeMerged[node]) {
512 vecOrigins.emplace_back(nodeMergedOrigin, 0);
513 for(
auto multiPersOrigin :
515 vecOrigins.emplace_back(multiPersOrigin, 1);
518 for(
auto multiPersOrigin : treeMultiPers[node])
519 vecOrigins.emplace_back(multiPersOrigin, 1);
520 vecOrigins.emplace_back(nodeOrigin, 2);
522 bool splitRoot = (vecOrigins.size() != 1 and treeNew->
isRoot(node));
526 for(
auto stackTuple : vecOrigins) {
527 ftm::idNode const nodeOriginT = std::get<0>(stackTuple);
528 int const nodeOriginTID = std::get<1>(stackTuple);
529 if(nodeDone[nodeOriginT]
532 nodeDone[nodeOriginT] =
true;
538 if(nodeOriginTID == 0) {
542 }
else if(nodeOriginTID == 1 or (nodeOriginTID == 2 and splitRoot)) {
543 newParent = nodeOriginT;
548 while(parentNodeOrigin != node) {
551 treeNew->
setParent(parentNodeOrigin, newParent);
552 parentNodeOrigin = oldParentNodeOrigin;
555 if(nodeOriginTID == 1 or (nodeOriginTID == 2 and splitRoot))
560 if(nodeOriginTID == 2 and splitRoot)
564 std::vector<ftm::idNode> childrenNode;
567 if(!treeNew->
isLeaf(children))
568 queueNodes.emplace(children);
578 template <
class dataType>
585 if(nodeIdToDelete != treeRoot
608 std::stringstream ss;
617 std::stringstream ss;
622 template <
class dataType>
625 for(
auto origin : multiPersOrigins)
629 template <
class dataType>
634 bool branchDecompositionT,
637 double persistenceThreshold,
638 std::vector<int> &nodeCorr,
639 bool deleteInconsistentNodes =
true) {
644 preprocessTree<dataType>(tree, deleteInconsistentNodes);
647 persistenceThresholding<dataType>(tree, persistenceThreshold);
650 std::vector<std::vector<ftm::idNode>> treeNodeMerged(
654 mergeSaddle<dataType>(tree, epsilonTree, treeNodeMerged);
659 if(branchDecompositionT
661 tree = computeBranchDecomposition<dataType>(tree, treeNodeMerged);
665 deleteMultiPersPairs<dataType>(tree, branchDecompositionT);
669 if(not useMinMaxPairT)
670 dontUseMinMaxPair<dataType>(tree);
674 persistenceMerging<dataType>(tree, epsilon2Tree, epsilon3Tree);
678 ftm::cleanMergeTree<dataType>(mTree, nodeCorr, branchDecompositionT);
679 tree = &(mTree.
tree);
685 printErr(
"preprocessingPipeline tree->getNumberOfRoot() != 1");
690 std::stringstream ss;
691 ss <<
"TIME PREPROC. = " << t_preproc_time;
695 template <
class dataType>
700 bool branchDecompositionT,
703 std::vector<int> &nodeCorr,
704 bool deleteInconsistentNodes =
true) {
705 preprocessingPipeline<dataType>(
706 mTree, epsilonTree, epsilon2Tree, epsilon3Tree, branchDecompositionT,
708 deleteInconsistentNodes);
713 for(
unsigned int i = 0; i < nodeCorr.size(); ++i)
714 if(nodeCorr[i] >= 0 && nodeCorr[i] < (
int)newNodeCorr.size())
715 newNodeCorr[nodeCorr[i]] = i;
716 nodeCorr = newNodeCorr;
719 template <
class dataType>
722 ttk::ftm::computePersistencePairs<dataType>(tree);
723 persistenceThresholding<dataType>(tree);
724 std::vector<std::vector<ftm::idNode>> treeNodeMerged;
725 mergeSaddle<dataType>(tree, 100.0, treeNodeMerged);
726 computeBranchDecomposition<dataType>(tree, treeNodeMerged);
729 template <
class dataType>
736 std::array<double, 3> stats;
738 auto meanNodes = stats[0];
739 unsigned int const n = trees.size();
740 return meanNodes * n;
746 template <
class dataType>
749 bool setOrigins =
false) {
753 dataType newMax = tree1->
getValue<dataType>(root);
755 dataType newMin = tree1->
getValue<dataType>(rootOrigin);
759 std::vector<dataType> newScalarsVector;
760 ftm::getTreeScalars<dataType>(mTree2, newScalarsVector);
761 newScalarsVector[root2] = newMax;
764 if(root2Origin == (
int)root2)
765 root2Origin = mTree2.
tree.template getMergedRootOrigin<dataType>();
767 newScalarsVector.push_back(newMin);
769 newScalarsVector[root2Origin] = newMin;
772 ftm::setTreeScalars<dataType>(mTree2, newScalarsVector);
788 template <
class dataType>
791 return std::make_tuple(-1, -1);
798 dataType oldOriginValue
802 return std::make_tuple(maxIndex, oldOriginValue);
807 template <
class dataType>
812 std::stringstream
const oriPrintTree = tree->
printTree();
813 std::stringstream
const oriPrintPairs
815 std::stringstream
const oriPrintMultiPers
831 and mergedRootOrigin != treeRoot)
834 printErr(
"branchDecompositionToTree mergedRootOrigin inconsistent");
840 auto comp = [&](
const std::tuple<ftm::idNode, dataType> &a,
841 const std::tuple<ftm::idNode, dataType> &b) {
842 return isJT ? std::get<1>(a) > std::get<1>(b)
843 : std::get<1>(a) < std::get<1>(b);
846 std::vector<ftm::idNode> &children) {
847 while(index >= 0 and treeT->isMultiPersPair(children[index]))
853 std::vector<std::tuple<ftm::idNode, ftm::idNode>> nodeParent;
854 std::queue<ftm::idNode> queue;
855 queue.emplace(treeRoot);
856 while(!queue.empty()) {
863 nodeParent.emplace_back(nodeOrigin, node);
865 nodeParent.emplace_back(node, nodeOrigin);
867 nodeParent.emplace_back(node, nodeOrigin);
873 std::vector<ftm::idNode> childrenOri;
875 std::vector<ftm::idNode> children = childrenOri;
876 std::vector<std::tuple<ftm::idNode, dataType>> childrenScalars;
877 for(
unsigned int i = 0; i < children.size(); ++i) {
878 if(isFM and (
int) children[i] != nodeOrigin)
880 childrenScalars.push_back(std::make_tuple(
881 children[i], tree->
getValue<dataType>(children[i])));
883 std::sort(std::begin(childrenScalars), std::end(childrenScalars), comp);
885 for(
unsigned int i = 0; i < childrenScalars.size(); ++i)
886 children.push_back(std::get<0>(childrenScalars[i]));
889 for(
unsigned int i = 1; i < children.size(); ++i) {
892 int const index = getIndexNotMultiPers(i - 1, tree, children);
894 nodeParent.emplace_back(children[i], children[index]);
897 bool const multiPersPair
899 if(not multiPersPair) {
902 = getIndexNotMultiPers(children.size() - 1, tree, children);
903 nodeParent.emplace_back(nodeOrigin, children[index]);
905 nodeParent.emplace_back(children[0], node);
909 nodeParent.emplace_back(children[0], nodeOrigin);
910 int index = getIndexNotMultiPers(children.size() - 1, tree, children);
912 printErr(
"[branchDecompositionToTree] index < 0");
915 nodeParent.emplace_back(node, children[index]);
919 for(
auto child : childrenOri)
920 queue.emplace(child);
924 for(
auto nodeParentT : nodeParent)
925 tree->
setParent(std::get<0>(nodeParentT), std::get<1>(nodeParentT));
935 std::stringstream ss;
937 ss << i <<
" _ " << iOrigin;
943 printErr(
"[branchDecompositionToTree] 1 up arc and 1 down arc");
948 template <
class dataType>
951 std::queue<ftm::idNode> queue;
952 queue.emplace(tree->
getRoot());
953 while(!queue.empty()) {
958 std::vector<ftm::idNode> children;
960 std::vector<ftm::idNode> lowestNodes;
962 for(
auto child : children) {
964 lowestNodes.push_back(lowestNode);
968 and lowestNodeOrigin != node)
969 branchOrigin = lowestNode;
971 for(
size_t i = 0; i < children.size(); ++i) {
974 if(branchOrigin == lowestNodes[i] or lowestNodeOrigin == node)
976 dataType lowestNodeOriginVal
977 = tree->
getValue<dataType>(lowestNodeOrigin);
981 while(branchRoot != branchOriginT) {
984 if((val > lowestNodeOriginVal and isJT)
985 or (val < lowestNodeOriginVal and not isJT))
991 tree->
setParent(branchOriginT, lowestNodeOrigin);
992 tree->
setParent(children[i], lowestNodeOrigin);
995 std::vector<ftm::idNode> children;
997 for(
auto child : children)
998 queue.emplace(child);
1002 template <
class dataType>
1012 "[postprocessingPipeline] mergedRootOrigin inconsistent id.");
1016 branchDecompositionToTree<dataType>(tree);
1018 putBackMergedNodes<dataType>(tree);
1024 template <
class dataType>
1028 std::vector<std::tuple<ftm::idNode, ftm::idNode, double>>
1030 std::vector<std::tuple<ftm::idNode, ftm::idNode, double>> toAdd;
1031 for(
auto mTuple : outputMatching) {
1034 double const cost = std::get<2>(mTuple);
1039 int const node1OriginLevel = tree1->
getNodeLevel(node1Origin);
1041 int const node2OriginLevel = tree2->
getNodeLevel(node2Origin);
1044 = (node1Level > node1OriginLevel) ? node1 : node1Origin;
1046 = (node1Level > node1OriginLevel) ? node1Origin : node1;
1048 = (node2Level > node2OriginLevel) ? node2 : node2Origin;
1050 = (node2Level > node2OriginLevel) ? node2Origin : node2;
1058 toAdd.emplace_back(node1Higher, node2Higher, cost);
1060 toAdd.emplace_back(node1Lower, node2Lower, cost);
1062 outputMatching.clear();
1063 outputMatching.insert(outputMatching.end(), toAdd.begin(), toAdd.end());
1066 template <
class dataType>
1070 std::vector<std::tuple<ftm::idNode, ftm::idNode>> &outputMatching) {
1071 std::vector<std::tuple<ftm::idNode, ftm::idNode, double>>
1072 realOutputMatching(outputMatching.size());
1073 for(
size_t i = 0; i < outputMatching.size(); ++i) {
1074 const auto &tup{outputMatching[i]};
1075 realOutputMatching[i] = {std::get<0>(tup), std::get<1>(tup), 0.0};
1078 convertBranchDecompositionMatching<dataType>(
1079 tree1, tree2, realOutputMatching);
1081 outputMatching.clear();
1082 for(
auto tup : realOutputMatching)
1083 outputMatching.emplace_back(std::get<0>(tup), std::get<1>(tup));
1086 template <
class dataType>
1090 std::vector<std::tuple<ftm::idNode, ftm::idNode>> &outputMatching,
1091 std::vector<std::tuple<ftm::idNode, ftm::idNode, bool>> &realMatching) {
1092 for(std::tuple<ftm::idNode, ftm::idNode> mTuple : outputMatching) {
1095 dataType relabelCostVal
1096 = relabelCostOnly<dataType>(tree1, tree1Node, tree2, tree2Node);
1097 dataType deleteInsertCostVal = deleteCost<dataType>(tree1, tree1Node)
1098 + insertCost<dataType>(tree2, tree2Node);
1099 bool isRealMatching = (relabelCostVal <= deleteInsertCostVal);
1100 realMatching.emplace_back(tree1Node, tree2Node, isRealMatching);
1107 template <
class dataType>
1109 dataType x1, dataType x2, dataType y1, dataType y2,
double power = 2) {
1112 std::abs((
double)(x1 - y1)), std::abs((
double)(x2 - y2)));
1114 return std::pow(std::abs((
double)(x1 - y1)), power)
1115 + std::pow(std::abs((
double)(x2 - y2)), power);
1118 template <
class dataType>
1121 dataType newMin = 0.0, newMax = 1.0;
1125 ? getNormalizedBirthDeath<dataType>(tree, nodeId, newMin, newMax)
1127 dataType birth = std::get<0>(birthDeath);
1128 dataType death = std::get<1>(birthDeath);
1129 dataType projec = (birth + death) / 2;
1131 cost = computeDistance<dataType>(
1141 template <
class dataType>
1143 return deleteCost<dataType>(tree, nodeId);
1146 template <
class dataType>
1152 dataType newMin = 0.0, newMax = 1.0;
1156 ? getNormalizedBirthDeath<dataType>(tree1, nodeId1, newMin, newMax)
1158 dataType birth1 = std::get<0>(birthDeath1);
1159 dataType death1 = std::get<1>(birthDeath1);
1163 ? getNormalizedBirthDeath<dataType>(tree2, nodeId2, newMin, newMax)
1165 dataType birth2 = std::get<0>(birthDeath2);
1166 dataType death2 = std::get<1>(birthDeath2);
1168 cost = computeDistance<dataType>(
1177 template <
class dataType>
1188 dataType cost = relabelCostOnly<dataType>(tree1, nodeId1, tree2, nodeId2);
1192 dataType deleteInsertCost = deleteCost<dataType>(tree1, nodeId1)
1193 + insertCost<dataType>(tree2, nodeId2);
1194 if(deleteInsertCost < cost)
1195 cost = deleteInsertCost;
1205 paramNames = std::vector<std::string>{
"epsilon1",
1208 "persistenceThreshold",
1209 "branchDecomposition",
1210 "normalizedWasserstein",
1212 "isPersistenceDiagram",
1213 "deleteMultiPersPairs",
1214 "epsilon1UseFarthestSaddle",
1215 "mixtureCoefficient"};
1220 if(paramName ==
"epsilon1")
1222 else if(paramName ==
"epsilon2")
1224 else if(paramName ==
"epsilon3")
1226 else if(paramName ==
"persistenceThreshold")
1228 else if(paramName ==
"branchDecomposition")
1230 else if(paramName ==
"normalizedWasserstein")
1232 else if(paramName ==
"keepSubtree")
1234 else if(paramName ==
"isPersistenceDiagram")
1236 else if(paramName ==
"deleteMultiPersPairs")
1238 else if(paramName ==
"epsilon1UseFarthestSaddle")
1240 else if(paramName ==
"mixtureCoefficient")
1246 if(paramName ==
"epsilon1")
1248 else if(paramName ==
"epsilon2")
1250 else if(paramName ==
"epsilon3")
1252 else if(paramName ==
"persistenceThreshold")
1254 else if(paramName ==
"branchDecomposition")
1256 else if(paramName ==
"normalizedWasserstein")
1258 else if(paramName ==
"keepSubtree")
1260 else if(paramName ==
"isPersistenceDiagram")
1262 else if(paramName ==
"deleteMultiPersPairs")
1264 else if(paramName ==
"epsilon1UseFarthestSaddle")
1266 else if(paramName ==
"mixtureCoefficient")
1271 std::array<double, 3> &stats) {
1272 double avgNodes = 0, avgNodesT = 0;
1273 double avgDepth = 0;
1274 for(
unsigned int i = 0; i < trees.size(); ++i) {
1275 auto noNodesT = trees[i]->getNumberOfNodes();
1276 auto noNodes = trees[i]->getRealNumberOfNodes();
1277 avgNodes += noNodes;
1278 avgNodesT += noNodesT;
1279 avgDepth += trees[i]->getTreeDepth();
1281 avgNodes /= trees.size();
1282 avgNodesT /= trees.size();
1283 avgDepth /= trees.size();
1285 stats = {avgNodes, avgNodesT, avgDepth};
1289 std::array<double, 3> stats;
1291 int avgNodes = stats[0], avgNodesT = stats[1];
1292 double const avgDepth = stats[2];
1293 std::stringstream ss;
1294 ss << trees.size() <<
" trees average [node: " << avgNodes <<
" / "
1295 << avgNodesT <<
", depth: " << avgDepth <<
"]";
1299 template <
class dataType>
1301 std::vector<ftm::FTMTree_MT *> treesT;
1302 ftm::mergeTreeToFTMTree<dataType>(trees, treesT);
1306 template <
class dataType>
1308 std::streamsize
const ssize = std::cout.precision();
1309 std::stringstream ss;
1311 for(
unsigned int j = 0; j < table[0].size(); ++j)
1316 for(
unsigned int i = 0; i < table.size(); ++i) {
1317 ss << std::setw(3) << std::setfill(
'0') << std::internal << i - 1
1319 for(
unsigned int j = 0; j < table[0].size(); ++j) {
1320 ss << std::fixed << std::setprecision(2) << table[i][j] <<
" ";
1325 std::cout.precision(ssize);
1329 template <
class dataType>
1331 std::vector<std::vector<dataType>> vec(nRows, std::vector<dataType>());
1332 for(
int i = 0; i < nRows; ++i)
1333 for(
int j = 0; j < nCols; ++j)
1334 vec[i].push_back(table[i * nCols + j]);
1335 printTableVector<dataType>(vec);
1340 for(
const auto &mTuple : matchings) {
1341 std::stringstream ss;
1342 ss << std::get<0>(mTuple) <<
" - " << std::get<1>(mTuple) <<
" - "
1343 << std::get<2>(mTuple);
1350 std::vector<std::tuple<ftm::idNode, ftm::idNode, double>> &matchings) {
1352 for(
auto mTuple : matchings) {
1353 std::stringstream ss;
1354 ss << std::get<0>(mTuple) <<
" - " << std::get<1>(mTuple);
1361 std::vector<std::tuple<ftm::idNode, ftm::idNode>> &matchings) {
1362 std::vector<std::tuple<ftm::idNode, ftm::idNode, double>> matchingsT(
1364 for(
size_t i = 0; i < matchings.size(); ++i) {
1365 const auto &tup{matchings[i]};
1366 matchingsT[i] = {std::get<0>(tup), std::get<1>(tup), 0.0};
1371 template <
class dataType>
1373 std::vector<std::tuple<SimplexId, SimplexId, dataType>> &treePairs) {
1374 for(
auto pair : treePairs) {
1375 std::stringstream
const ss;
1376 ss << std::get<0>(pair) <<
" _ " << std::get<1>(pair) <<
" _ "
1377 << std::get<2>(pair);
1383 template <
class dataType>
1385 std::vector<std::tuple<ftm::idNode, ftm::idNode>> &outputMatching,
1388 bool computeCosts =
true) {
1392 std::stringstream ss;
1393 for(std::tuple<ftm::idNode, ftm::idNode> matching : outputMatching) {
1398 ss << node0 <<
" - " << node1 <<
" _ [ ";
1399 ss <<
"f(" << node0 <<
")=" << tree1->
getValue<dataType>(node0)
1401 ss <<
"g(" << node1 <<
")=" << tree2->
getValue<dataType>(node1) <<
" ]"
1403 ss <<
"f(" << node0Origin
1404 <<
")=" << tree1->
getValue<dataType>(node0Origin) <<
" _ ";
1405 ss <<
"g(" << node1Origin
1406 <<
")=" << tree2->
getValue<dataType>(node1Origin) <<
" ] ";
1409 dataType tempCost = relabelCost<dataType>(tree1, node0, tree2, node1);
1411 = relabelCostOnly<dataType>(tree1, node0, tree2, node1);
1412 ss <<
"cost = " << tempCost <<
" (" << tempCost2 <<
")" << std::endl;
1416 tree1Done[node0] =
true;
1417 tree2Done[node1] =
true;
1421 if(not tree1Done[i] and not tree1->
isNodeAlone(i)) {
1423 ss <<
"T1 " << i <<
" _ [ f(" << i
1424 <<
") = " << tree1->
getValue<dataType>(i);
1425 ss <<
"_ f(" << nodeOrigin
1426 <<
") = " << tree1->
getValue<dataType>(nodeOrigin);
1429 dataType tempCost = deleteCost<dataType>(tree1, i);
1430 ss <<
" _ cost = " << tempCost << std::endl;
1436 if(not tree2Done[i] and not tree2->
isNodeAlone(i)) {
1438 ss <<
"T2 " << i <<
" _ [ g(" << i
1439 <<
") = " << tree2->
getValue<dataType>(i);
1440 ss <<
"_ g(" << nodeOrigin
1441 <<
") = " << tree2->
getValue<dataType>(nodeOrigin);
1444 dataType tempCost = deleteCost<dataType>(tree2, i);
1445 ss <<
" _ cost = " << tempCost << std::endl;
1451 ss <<
"total cost = " << cost <<
" (" << std::sqrt(cost) <<
")"
Minimalist debugging class.
void setDebugMsgPrefix(const std::string &prefix)
int printErr(const std::string &msg, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cerr) const
void printTable(dataType *table, int nRows, int nCols)
void setBranchDecomposition(bool useBD)
void setNormalizedWasserstein(bool normalizedWasserstein)
void setDistanceSquaredRoot(bool distanceSquaredRoot)
double mixtureCoefficient_
void getTreesStats(std::vector< ftm::FTMTree_MT * > &trees, std::array< double, 3 > &stats)
void setParamValueFromName(std::string ¶mName, double value)
bool epsilon1UseFarthestSaddle_
bool barycenterMergeTree_
void printTreesStats(std::vector< ftm::MergeTree< dataType > > &trees)
void setEpsilon3Tree1(double epsilon)
void setEpsilonTree1(double epsilon)
void setAssignmentSolver(int assignmentSolver)
void persistenceThresholding(ftm::FTMTree_MT *tree)
dataType computeDistance(dataType x1, dataType x2, dataType y1, dataType y2, double power=2)
void deleteMultiPersPairs(ftm::FTMTree_MT *tree, bool useBD)
void printOutputMatching(std::vector< std::tuple< ftm::idNode, ftm::idNode > > &outputMatching, ftm::FTMTree_MT *tree1, ftm::FTMTree_MT *tree2, bool computeCosts=true)
void mtFlattening(ftm::MergeTree< dataType > &mt)
void mergeSaddle(ftm::FTMTree_MT *tree, double epsilon, std::vector< std::vector< ftm::idNode > > &treeNodeMerged, bool mergeByPersistence=false)
void preprocessingPipeline(ftm::MergeTree< dataType > &mTree, double epsilonTree, double epsilon2Tree, double epsilon3Tree, bool branchDecompositionT, bool useMinMaxPairT, bool cleanTreeT, double persistenceThreshold, std::vector< int > &nodeCorr, bool deleteInconsistentNodes=true)
void keepMostImportantPairs(ftm::FTMTree_MT *tree, int n, bool useBD)
double mixDistancesWeight(bool isFirstInput)
dataType relabelCostOnly(ftm::FTMTree_MT *tree1, ftm::idNode nodeId1, ftm::FTMTree_MT *tree2, ftm::idNode nodeId2)
void setNodePerTask(int npt)
void convertBranchDecompositionMatching(ftm::FTMTree_MT *tree1, ftm::FTMTree_MT *tree2, std::vector< std::tuple< ftm::idNode, ftm::idNode, double > > &outputMatching)
std::vector< std::vector< int > > getTreesNodeCorr()
void getParamNames(std::vector< std::string > ¶mNames)
void putBackMergedNodes(ftm::FTMTree_MT *tree)
void dontUseMinMaxPair(ftm::FTMTree_MT *tree)
void setEpsilon2Tree1(double epsilon)
void setEpsilonTree2(double epsilon)
void setBarycenterMergeTree(bool imt)
bool normalizedWasserstein_
ftm::FTMTree_MT * computeBranchDecomposition(ftm::FTMTree_MT *tree, std::vector< std::vector< ftm::idNode > > &treeNodeMerged)
void printMatching(std::vector< std::tuple< ftm::idNode, ftm::idNode, double > > &matchings)
void verifyOrigins(ftm::FTMTree_MT *tree)
double mixDistances(dataType distance1, dataType distance2)
void printMatching(std::vector< std::tuple< ftm::idNode, ftm::idNode > > &matchings)
void persistenceThresholding(ftm::FTMTree_MT *tree, std::vector< ftm::idNode > &deletedNodes)
void branchDecompositionToTree(ftm::FTMTree_MT *tree)
void persistenceThresholding(ftm::FTMTree_MT *tree, double persistenceThresholdT)
double getSizeLimitMetric(std::vector< ftm::FTMTree_MT * > &trees)
bool deleteMultiPersPairs_
dataType insertCost(ftm::FTMTree_MT *tree, ftm::idNode nodeId)
void preprocessingPipeline(ftm::MergeTree< dataType > &mTree, double epsilonTree, double epsilon2Tree, double epsilon3Tree, bool branchDecompositionT, bool useMinMaxPairT, bool cleanTreeT, std::vector< int > &nodeCorr, bool deleteInconsistentNodes=true)
void setPersistenceThreshold(double pt)
void printTreesStats(std::vector< ftm::FTMTree_MT * > &trees)
void postprocessingPipeline(ftm::FTMTree_MT *tree)
bool distanceSquaredRoot_
void printTableVector(std::vector< std::vector< dataType > > &table)
void verifyPairsTree(ftm::FTMTree_MT *tree)
void setNonMatchingWeight(double weight)
void printMatching(std::vector< MatchingType > &matchings)
void printPairs(std::vector< std::tuple< SimplexId, SimplexId, dataType > > &treePairs)
void copyMinMaxPair(ftm::MergeTree< dataType > &mTree1, ftm::MergeTree< dataType > &mTree2, bool setOrigins=false)
double nonMatchingWeight_
dataType deleteCost(ftm::FTMTree_MT *tree, ftm::idNode nodeId)
std::vector< std::vector< int > > treesNodeCorr_
void preprocessTree(ftm::FTMTree_MT *tree, bool deleteInconsistentNodes=true)
void setCleanTree(bool clean)
void reverseNodeCorr(ftm::FTMTree_MT *tree, std::vector< int > &nodeCorr)
void identifyRealMatching(ftm::FTMTree_MT *tree1, ftm::FTMTree_MT *tree2, std::vector< std::tuple< ftm::idNode, ftm::idNode > > &outputMatching, std::vector< std::tuple< ftm::idNode, ftm::idNode, bool > > &realMatching)
void setEpsilon2Tree2(double epsilon)
void setKeepSubtree(bool keepSubtree)
double persistenceThreshold_
void persistenceThresholding(ftm::FTMTree_MT *tree, double persistenceThresholdT, std::vector< ftm::idNode > &deletedNodes)
dataType relabelCost(ftm::FTMTree_MT *tree1, ftm::idNode nodeId1, ftm::FTMTree_MT *tree2, ftm::idNode nodeId2)
void persistenceMerging(ftm::FTMTree_MT *tree, double epsilon2, double epsilon3=100)
void mtsFlattening(std::vector< ftm::MergeTree< dataType > > &mts)
void setEpsilon1UseFarthestSaddle(bool b)
void setDeleteMultiPersPairs(bool deleteMultiPersPairsT)
void setUseMinMaxPair(bool useMinMaxPair)
void setEpsilon3Tree2(double epsilon)
double mixDistancesMinMaxPairWeight(bool isFirstInput)
bool branchDecomposition_
bool isPersistenceDiagram_
void setParallelize(bool para)
double getParamValueFromName(std::string ¶mName)
void setIsPersistenceDiagram(bool isPD)
void convertBranchDecompositionMatching(ftm::FTMTree_MT *tree1, ftm::FTMTree_MT *tree2, std::vector< std::tuple< ftm::idNode, ftm::idNode > > &outputMatching)
std::tuple< int, dataType > fixMergedRootOrigin(ftm::FTMTree_MT *tree)
void mixDistancesMatrix(std::vector< std::vector< dataType > > &distanceMatrix, std::vector< std::vector< dataType > > &distanceMatrix2)
std::vector< ftm::idNode > getMultiPersOrigins(bool useBD)
std::stringstream printMultiPersPairsFromTree(bool useBD=false, bool printPairs=true, bool doPrint=true)
const scalarType & getValue(SimplexId nodeId) const
bool isNodeIdInconsistent(idNode nodeId)
dataType getNodePersistence(idNode nodeId)
idNode getNumberOfNodes() const
dataType getMaximumPersistence()
void setParent(idNode nodeId, idNode newParentNodeId)
bool isNodeMerged(idNode nodeId)
std::tuple< dataType, dataType > getBirthDeath(idNode nodeId)
bool isRoot(idNode nodeId)
void getMultiPersOriginsVectorFromTree(std::vector< std::vector< idNode > > &res)
idNode getParentSafe(idNode nodeId)
bool isNodeOriginDefined(idNode nodeId)
idNode getMergedRootOrigin()
int getNodeLevel(idNode nodeId)
void getPersistencePairsFromTree(std::vector< std::tuple< ftm::idNode, ftm::idNode, dataType > > &pairs, bool useBD)
void getChildren(idNode nodeId, std::vector< idNode > &res)
void deleteNode(idNode nodeId)
bool isMultiPersPair(idNode nodeId)
std::stringstream printPairsFromTree(bool useBD=false, bool printPairs=true, bool doPrint=true)
idNode makeNode(SimplexId vertexId, SimplexId linked=nullVertex)
bool isLeaf(idNode nodeId)
int getRealNumberOfNodes()
bool isNodeAlone(idNode nodeId)
idNode getLowestNode(idNode nodeStart)
Node * getNode(idNode nodeId)
std::stringstream printTree(bool doPrint=true)
dataType getSecondMaximumPersistence()
bool isThereOnlyOnePersistencePair()
idSuperArc getNumberOfDownSuperArcs() const
void setOrigin(SimplexId linked)
SimplexId getOrigin() const
idSuperArc getNumberOfUpSuperArcs() const
unsigned int idNode
Node index in vect_nodes_.
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/|__ _|"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)