43 double t_assignment_time_ = 0;
45 bool preprocess_ =
true;
46 bool postprocess_ =
true;
47 bool saveTree_ =
false;
48 bool onlyEmptyTreeDistance_ =
false;
50 bool isCalled_ =
false;
52 double auctionEpsilon_ = -1;
53 double auctionEpsilonDiviser_ = 0;
54 int auctionRound_ = -1;
56 double minMaxPairWeight_ = 1.0;
64 std::vector<std::vector<ftm::idNode>> tree2LevelToNode_;
65 std::vector<int> tree1Level_, tree2Level_;
72#ifdef TTK_ENABLE_OPENMP4
73 omp_set_max_active_levels(100);
83 preprocess_ = preproc;
87 postprocess_ = postproc;
99 auctionEpsilon_ = aucEpsilon;
103 auctionEpsilonDiviser_ = aucEpsilonDiviser;
107 auctionRound_ = aucNoRounds;
111 onlyEmptyTreeDistance_ = only;
115 minMaxPairWeight_ = weight;
125 template <
class dataType>
128 std::vector<MatchingType> &matchings) {
134 int const nRows = costMatrix.size() - 1;
135 int const nCols = costMatrix[0].size() - 1;
136 int const max_dim = std::max(nRows, nCols);
137 int const min_dim = std::min(nRows, nCols);
140 if((min_dim <= 2 and max_dim <= 2) or (min_dim <= 1 and max_dim <= 6))
141 assignmentSolverID = 1;
143 switch(assignmentSolverID) {
146 assignmentSolver = &solverExhaustive;
150 assignmentSolver = &solverMunkres;
158 assignmentSolver = &solverAuction;
160 assignmentSolver->
setInput(costMatrix);
162 assignmentSolver->
run(matchings);
165 template <
class dataType>
167 std::vector<ftm::idNode> &children1,
168 std::vector<ftm::idNode> &children2,
169 std::vector<std::vector<dataType>> &costMatrix) {
170 unsigned int nRows = children1.size(), nCols = children2.size();
171 for(
unsigned int i = 0; i < nRows; ++i) {
172 int const forestTableI = children1[i] + 1;
173 for(
unsigned int j = 0; j < nCols; ++j) {
174 int const forestTableJ = children2[j] + 1;
176 costMatrix[i][j] = treeTable[forestTableI][forestTableJ];
177 if(tree1Level_[children1[i]] != tree2Level_[children2[j]]
182 costMatrix[i][nCols] = treeTable[forestTableI][0];
184 for(
unsigned int j = 0; j < nCols; ++j) {
185 int const forestTableJ = children2[j] + 1;
187 costMatrix[nRows][j] = treeTable[0][forestTableJ];
189 costMatrix[nRows][nCols] = 0;
192 template <
class dataType>
194 std::vector<MatchingType> &matchings,
195 std::vector<ftm::idNode> &children1,
196 std::vector<ftm::idNode> &children2,
197 std::vector<std::tuple<int, int>> &forestAssignment) {
199 for(
const auto &mTuple : matchings) {
200 cost += std::get<2>(mTuple);
201 if(std::get<0>(mTuple) >= (
int)children1.size()
202 || std::get<1>(mTuple) >= (
int)children2.size())
204 int const tableId1 = children1[std::get<0>(mTuple)] + 1;
205 int const tableId2 = children2[std::get<1>(mTuple)] + 1;
206 forestAssignment.emplace_back(tableId1, tableId2);
211 template <
class dataType>
215 std::vector<std::vector<dataType>> &treeTable,
216 std::vector<ftm::idNode> &children1,
217 std::vector<ftm::idNode> &children2,
218 std::vector<std::tuple<int, int>> &forestAssignment) {
220 int nRows = children1.size(), nCols = children2.size();
221 std::vector<std::vector<dataType>> costMatrix(
222 nRows + 1, std::vector<dataType>(nCols + 1));
228 std::vector<MatchingType> matchings;
233 matchings, children1, children2, forestAssignment);
238 template <
class dataType>
244 std::vector<std::vector<dataType>> &treeTable,
245 std::vector<std::vector<dataType>> &forestTable,
246 std::vector<std::vector<std::vector<std::tuple<int, int>>>>
248 std::vector<ftm::idNode> &children1,
249 std::vector<ftm::idNode> &children2) {
250 if(children1.size() != 0 && children2.size() != 0) {
251 dataType forestTerm3;
255 std::vector<std::tuple<int, int>> forestAssignment;
257 tree1, tree2, treeTable, children1, children2, forestAssignment);
263 forestTable[i][j] = forestTerm3;
265 forestBackTable[i][j] = forestAssignment;
267 dataType forestTerm1, forestTerm2;
268 std::tuple<dataType, ftm::idNode> forestCoTerm1, forestCoTerm2;
273 forestTerm1 = forestTable[0][j] + std::get<0>(forestCoTerm1);
278 forestTerm2 = forestTable[i][0] + std::get<0>(forestCoTerm2);
282 = std::min(std::min(forestTerm1, forestTerm2), forestTerm3);
285 if(forestTable[i][j] == forestTerm3) {
286 forestBackTable[i][j] = forestAssignment;
287 }
else if(forestTable[i][j] == forestTerm2) {
288 forestBackTable[i][j].push_back(
289 std::make_tuple(std::get<1>(forestCoTerm2), j));
291 forestBackTable[i][j].push_back(
292 std::make_tuple(i, std::get<1>(forestCoTerm1)));
298 = (children1.size() == 0) ? forestTable[0][j] : forestTable[i][0];
305 template <
class dataType>
310 std::vector<std::vector<dataType>> &treeTable,
311 std::vector<std::vector<dataType>> &forestTable) {
312 std::vector<ftm::idNode> children;
314 forestTable[i][0] = 0;
316 forestTable[i][0] += treeTable[child + 1][0];
319 template <
class dataType>
324 std::vector<std::vector<dataType>> &treeTable,
325 std::vector<std::vector<dataType>> &forestTable) {
329 template <
class dataType>
334 std::vector<std::vector<dataType>> &treeTable,
335 std::vector<std::vector<dataType>> &forestTable) {
336 std::vector<ftm::idNode> children;
338 forestTable[0][j] = 0;
340 forestTable[0][j] += treeTable[0][child + 1];
343 template <
class dataType>
348 std::vector<std::vector<dataType>> &treeTable,
349 std::vector<std::vector<dataType>> &forestTable) {
354 template <
class dataType>
355 std::tuple<dataType, ftm::idNode>
358 std::vector<std::vector<dataType>> &table,
360 dataType tempMin = (childrens.size() == 0)
361 ? ((computeTerm1) ? table[ind][0] : table[0][ind])
362 : std::numeric_limits<dataType>::max();
368 temp = table[ind][children] - table[0][children];
370 temp = table[children][ind] - table[children][0];
374 bestIdNode = children;
377 return std::make_tuple(tempMin, bestIdNode);
380 template <
class dataType>
388 std::vector<std::vector<dataType>> &treeTable,
389 std::vector<std::vector<dataType>> &forestTable,
390 std::vector<std::vector<std::tuple<int, int>>> &treeBackTable,
391 std::vector<ftm::idNode> &children1,
392 std::vector<ftm::idNode> &children2) {
401 treeTable[i][j] = treeTerm3;
403 treeBackTable[i][j] = std::make_tuple(i, j);
405 dataType treeTerm1, treeTerm2;
406 std::tuple<dataType, ftm::idNode> treeCoTerm1, treeCoTerm2;
410 treeTerm1 = treeTable[0][j] + std::get<0>(treeCoTerm1);
414 treeTerm2 = treeTable[i][0] + std::get<0>(treeCoTerm2);
417 treeTable[i][j] = std::min(std::min(treeTerm1, treeTerm2), treeTerm3);
420 if(treeTable[i][j] == treeTerm3) {
421 treeBackTable[i][j] = std::make_tuple(i, j);
422 }
else if(treeTable[i][j] == treeTerm2) {
423 treeBackTable[i][j] = std::make_tuple(std::get<1>(treeCoTerm2), j);
425 treeBackTable[i][j] = std::make_tuple(i, std::get<1>(treeCoTerm1));
433 template <
class dataType>
437 std::vector<std::vector<std::tuple<int, int>>> &treeBackTable,
438 std::vector<std::vector<std::vector<std::tuple<int, int>>>>
440 std::vector<std::tuple<ftm::idNode, ftm::idNode, double>> &outputMatching,
443 outputMatching.clear();
444 std::queue<std::tuple<int, int, bool>> backQueue;
445 backQueue.emplace(startR, startC,
true);
446 while(!backQueue.empty()) {
447 std::tuple<int, int, bool> elem = backQueue.front();
449 bool useTreeTable = std::get<2>(elem);
450 int const i = std::get<0>(elem);
451 int const j = std::get<1>(elem);
454 int const tupleI = std::get<0>(treeBackTable[i][j]);
455 int const tupleJ = std::get<1>(treeBackTable[i][j]);
456 if(tupleI != 0 && tupleJ != 0) {
457 useTreeTable = (tupleI != i || tupleJ != j);
458 backQueue.emplace(tupleI, tupleJ, useTreeTable);
459 if(not useTreeTable) {
465 cost =
static_cast<double>(costT);
466 outputMatching.emplace_back(tree1Node, tree2Node, cost);
470 for(std::tuple<int, int> forestBackElem : forestBackTable[i][j]) {
471 int const tupleI = std::get<0>(forestBackElem);
472 int const tupleJ = std::get<1>(forestBackElem);
473 if(tupleI != 0 && tupleJ != 0) {
474 useTreeTable = (tupleI != i && tupleJ != j);
475 backQueue.emplace(tupleI, tupleJ, useTreeTable);
485 template <
class dataType>
489 std::vector<std::tuple<ftm::idNode, ftm::idNode, double>>
496 std::vector<std::vector<dataType>> treeTable(
497 nRows, std::vector<dataType>(nCols));
498 std::vector<std::vector<dataType>> forestTable(
499 nRows, std::vector<dataType>(nCols));
502 std::vector<std::vector<std::tuple<int, int>>> treeBackTable(
503 nRows, std::vector<std::tuple<int, int>>(nCols));
504 std::vector<std::vector<std::vector<std::tuple<int, int>>>>
506 nRows, std::vector<std::vector<std::tuple<int, int>>>(nCols));
508 int const indR = tree1->
getRoot() + 1;
509 int const indC = tree2->
getRoot() + 1;
519 forestBackTable, nRows, nCols);
520 dataType distance = treeTable[indR][indC];
521 if(onlyEmptyTreeDistance_)
522 distance = treeTable[indR][0];
525 if(onlyEmptyTreeDistance_)
531 if(minMaxPairWeight_ != 1.0) {
534 distance = distance - cost + minMaxPairWeight_ * cost;
539 distance = std::sqrt(distance);
545 outputMatching, indR, indC);
550 template <
class dataType>
554 std::vector<std::tuple<ftm::idNode, ftm::idNode>> &outputMatching) {
555 std::vector<std::tuple<ftm::idNode, ftm::idNode, double>>
559 for(
auto tup : realOutputMatching)
560 outputMatching.emplace_back(std::get<0>(tup), std::get<1>(tup));
564 template <
class dataType>
567 std::vector<std::tuple<ftm::idNode, ftm::idNode, double>>
603 tree1 = &(mTree1Int.
tree);
604 tree2 = &(mTree2Int.
tree);
620 tree1, tree2, outputMatching);
627 std::stringstream ss2;
628 ss2 <<
"DISTANCE² = "
631 std::stringstream ss3;
636 std::stringstream ss4;
644 template <
class dataType>
648 std::vector<std::tuple<ftm::idNode, ftm::idNode>> &outputMatching) {
649 std::vector<std::tuple<ftm::idNode, ftm::idNode, double>>
652 for(
auto tup : realOutputMatching)
653 outputMatching.emplace_back(std::get<0>(tup), std::get<1>(tup));
657 template <
class dataType>
661 std::vector<std::vector<dataType>> &treeTable,
662 std::vector<std::vector<dataType>> &forestTable,
663 std::vector<std::vector<std::tuple<int, int>>> &treeBackTable,
664 std::vector<std::vector<std::vector<std::tuple<int, int>>>>
669 t_assignment_time_ = 0;
673 treeBackTable, forestBackTable, nRows, nCols);
677 tree2->
getRoot(), treeTable, forestTable,
678 treeBackTable, forestBackTable, nRows, nCols);
679 if(onlyEmptyTreeDistance_)
683 tree2->
getRoot(), treeTable, forestTable,
684 treeBackTable, forestBackTable, nRows, nCols);
687 tree2->
getRoot(), treeTable, forestTable,
688 treeBackTable, forestBackTable, nRows, nCols);
695 printMsg(
"Assignment problems", 1, t_assignment_time_,
700 template <
class dataType>
705 bool computeEmptyTree,
708 std::vector<std::vector<dataType>> &treeTable,
709 std::vector<std::vector<dataType>> &forestTable,
710 std::vector<std::vector<std::tuple<int, int>>> &treeBackTable,
711 std::vector<std::vector<std::vector<std::tuple<int, int>>>>
716 std::vector<ftm::idNode> childrens;
718 for(
auto children : childrens)
720 children, nodeJ, treeTable, forestTable,
721 treeBackTable, forestBackTable, nRows, nCols);
723 std::vector<ftm::idNode> childrens;
725 for(
auto children : childrens)
727 nodeI, children, treeTable, forestTable,
728 treeBackTable, forestBackTable, nRows, nCols);
732 if(computeEmptyTree) {
733 int const i = nodeI + 1;
739 tree1, nodeI, i, treeTable, forestTable);
742 tree2->
getRoot(), treeTable, forestTable,
743 treeBackTable, forestBackTable, nRows, nCols);
745 int const j = nodeJ + 1;
746 if(computeEmptyTree) {
752 tree2, nodeJ, j, treeTable, forestTable);
754 }
else if(
keepSubtree_ or tree1Level_[nodeI] == tree2Level_[nodeJ]) {
755 int const i = nodeI + 1;
756 std::vector<ftm::idNode> children1;
758 std::vector<ftm::idNode> children2;
762 forestBackTable, children1, children2);
766 forestTable, treeBackTable, children1,
775 template <
class dataType>
779 std::vector<std::vector<dataType>> &treeTable,
780 std::vector<std::vector<dataType>> &forestTable,
781 std::vector<std::vector<std::tuple<int, int>>> &treeBackTable,
782 std::vector<std::vector<std::vector<std::tuple<int, int>>>>
786 std::vector<int> tree1NodeChildSize, tree2NodeChildSize;
788 std::vector<ftm::idNode> children;
790 tree1NodeChildSize.push_back(children.size());
793 std::vector<ftm::idNode> children;
795 tree2NodeChildSize.push_back(children.size());
799 std::vector<ftm::idNode> tree1Leaves;
801 std::vector<ftm::idNode> tree2Leaves;
806 treeTable, forestTable, treeBackTable,
808 if(onlyEmptyTreeDistance_)
812 tree2NodeChildSize, treeTable, forestTable,
813 treeBackTable, forestBackTable);
816 tree1NodeChildSize, tree2Leaves,
817 tree2NodeChildSize, treeTable, forestTable,
818 treeBackTable, forestBackTable,
true);
822 template <
class dataType>
828 std::vector<ftm::idNode> &tree1Leaves,
829 std::vector<int> &tree1NodeChildSize,
830 std::vector<ftm::idNode> &tree2Leaves,
831 std::vector<int> &tree2NodeChildSize,
832 std::vector<std::vector<dataType>> &treeTable,
833 std::vector<std::vector<dataType>> &forestTable,
834 std::vector<std::vector<std::tuple<int, int>>> &treeBackTable,
835 std::vector<std::vector<std::vector<std::tuple<int, int>>>>
837 bool firstCall =
false) {
842 std::queue<ftm::idNode> treeQueue;
846 treeQueue.emplace(leaf);
849 treeQueue.emplace(leaf);
850 else if(tree1Level_[i - 1] < (
int)tree2LevelToNode_.size())
851 for(
ftm::idNode const node : tree2LevelToNode_[tree1Level_[i - 1]])
852 treeQueue.emplace(node);
856 tree1NodeChildSize, tree2Leaves,
857 tree2NodeChildSize, treeTable, forestTable,
858 treeBackTable, forestBackTable, firstCall,
859 nodeT, treeChildDone, treeNodeDone, treeQueue);
862 tree1NodeChildSize, tree2Leaves,
863 tree2NodeChildSize, treeTable, forestTable,
864 treeBackTable, forestBackTable, nodeT,
865 treeChildDone, treeNodeDone, treeQueue);
869 template <
class dataType>
875 std::vector<ftm::idNode> &tree1Leaves,
876 std::vector<int> &tree1NodeChildSize,
877 std::vector<ftm::idNode> &tree2Leaves,
878 std::vector<int> &tree2NodeChildSize,
879 std::vector<std::vector<dataType>> &treeTable,
880 std::vector<std::vector<dataType>> &forestTable,
881 std::vector<std::vector<std::tuple<int, int>>> &treeBackTable,
882 std::vector<std::vector<std::vector<std::tuple<int, int>>>>
886 std::vector<int> &treeChildDone,
887 std::vector<bool> &treeNodeDone,
888 std::queue<ftm::idNode> &treeQueue) {
889#ifdef TTK_ENABLE_OPENMP4
890#pragma omp parallel num_threads(this->threadNumber_) if(firstCall)
892#pragma omp single nowait
895 tree1NodeChildSize, tree2Leaves,
896 tree2NodeChildSize, treeTable, forestTable,
897 treeBackTable, forestBackTable, nodeT,
898 treeChildDone, treeNodeDone, treeQueue);
899#ifdef TTK_ENABLE_OPENMP4
906 template <
class dataType>
912 std::vector<ftm::idNode> &tree1Leaves,
913 std::vector<int> &tree1NodeChildSize,
914 std::vector<ftm::idNode> &tree2Leaves,
915 std::vector<int> &tree2NodeChildSize,
916 std::vector<std::vector<dataType>> &treeTable,
917 std::vector<std::vector<dataType>> &forestTable,
918 std::vector<std::vector<std::tuple<int, int>>> &treeBackTable,
919 std::vector<std::vector<std::vector<std::tuple<int, int>>>>
922 std::vector<int> &treeChildDone,
923 std::vector<bool> &treeNodeDone,
924 std::queue<ftm::idNode> &treeQueue) {
926 while(!treeQueue.empty()) {
927 std::queue<ftm::idNode> taskQueue;
928 nodePerTask = nodePerTask > (int)treeQueue.size() ? treeQueue.size()
930 for(
int j = 0; j < nodePerTask; ++j) {
931 nodeT = treeQueue.front();
933 taskQueue.emplace(nodeT);
935#ifdef TTK_ENABLE_OPENMP4
936#pragma omp task firstprivate(taskQueue, nodeT) UNTIED() \
937 shared(treeTable, forestTable, treeBackTable, forestBackTable, \
938 treeChildDone, treeNodeDone) if(isTree1)
943 while(!taskQueue.empty()) {
944 nodeT = taskQueue.front();
946 int const t = nodeT + 1;
951 tree1, tree2,
false, t, tree1Leaves, tree1NodeChildSize,
952 tree2Leaves, tree2NodeChildSize, treeTable, forestTable,
953 treeBackTable, forestBackTable,
false);
956 or tree1Level_[nodeI] == tree2Level_[nodeT]) {
957 int const j = nodeT + 1;
958 std::vector<ftm::idNode> children1;
960 std::vector<ftm::idNode> children2;
964 forestBackTable, children1, children2);
968 treeTable, forestTable, treeBackTable,
969 children1, children2);
973 and tree1Level_[nodeI] == tree2Level_[nodeT])
978 int const childSize = (isTree1) ? tree1NodeChildSize[nodeTParent]
979 : tree2NodeChildSize[nodeTParent];
980 int oldTreeChildDone;
981#ifdef TTK_ENABLE_OPENMP4
982#pragma omp atomic capture
985 oldTreeChildDone = treeChildDone[nodeTParent];
986 treeChildDone[nodeTParent]++;
987#ifdef TTK_ENABLE_OPENMP4
990 if(not treeNodeDone[nodeTParent]
991 and oldTreeChildDone + 1 == childSize) {
993 taskQueue.emplace(nodeTParent);
994 treeNodeDone[nodeTParent] =
true;
995#ifdef TTK_ENABLE_OPENMP4
1002#ifdef TTK_ENABLE_OPENMP4
1006#ifdef TTK_ENABLE_OPENMP4
1012 template <
class dataType>
1016 std::vector<ftm::idNode> &treeLeaves,
1017 std::vector<int> &treeNodeChildSize,
1018 std::vector<std::vector<dataType>> &treeTable,
1019 std::vector<std::vector<dataType>> &forestTable,
1020 std::vector<std::vector<std::tuple<int, int>>> &treeBackTable,
1021 std::vector<std::vector<std::vector<std::tuple<int, int>>>>
1026 std::queue<ftm::idNode> treeQueue;
1028 treeQueue.emplace(leaf);
1031 treeNodeChildSize, treeTable, forestTable,
1032 treeBackTable, forestBackTable, nodeT,
1033 treeChildDone, treeNodeDone, treeQueue);
1036 treeNodeChildSize, treeTable, forestTable,
1037 treeBackTable, forestBackTable, nodeT,
1038 treeChildDone, treeNodeDone, treeQueue);
1041 template <
class dataType>
1045 std::vector<ftm::idNode> &treeLeaves,
1046 std::vector<int> &treeNodeChildSize,
1047 std::vector<std::vector<dataType>> &treeTable,
1048 std::vector<std::vector<dataType>> &forestTable,
1049 std::vector<std::vector<std::tuple<int, int>>> &treeBackTable,
1050 std::vector<std::vector<std::vector<std::tuple<int, int>>>>
1053 std::vector<int> &treeChildDone,
1054 std::vector<bool> &treeNodeDone,
1055 std::queue<ftm::idNode> &treeQueue) {
1056#ifdef TTK_ENABLE_OPENMP4
1057#pragma omp parallel num_threads(this->threadNumber_)
1059#pragma omp single nowait
1062 treeNodeChildSize, treeTable, forestTable,
1063 treeBackTable, forestBackTable, nodeT,
1064 treeChildDone, treeNodeDone, treeQueue);
1065#ifdef TTK_ENABLE_OPENMP4
1070 template <
class dataType>
1074 std::vector<ftm::idNode> &
ttkNotUsed(treeLeaves),
1075 std::vector<int> &treeNodeChildSize,
1076 std::vector<std::vector<dataType>> &treeTable,
1077 std::vector<std::vector<dataType>> &forestTable,
1078 std::vector<std::vector<std::tuple<int, int>>> &treeBackTable,
1079 std::vector<std::vector<std::vector<std::tuple<int, int>>>>
1082 std::vector<int> &treeChildDone,
1083 std::vector<bool> &treeNodeDone,
1084 std::queue<ftm::idNode> &treeQueue) {
1085 while(!treeQueue.empty()) {
1086 nodeT = treeQueue.front();
1089#ifdef TTK_ENABLE_OPENMP4
1090#pragma omp task firstprivate(nodeT) UNTIED() \
1091 shared(treeTable, forestTable, treeBackTable, forestBackTable, \
1092 treeChildDone, treeNodeDone)
1095 while((
int)nodeT != -1) {
1097 int const i = nodeT + 1;
1100 tree, nodeT, i, treeTable, forestTable);
1104 tree, nodeT, i, treeTable, forestTable);
1106 int const j = nodeT + 1;
1109 tree, nodeT, j, treeTable, forestTable);
1113 tree, nodeT, j, treeTable, forestTable);
1118 int oldTreeChildDone;
1119#ifdef TTK_ENABLE_OPENMP4
1120#pragma omp atomic capture
1123 oldTreeChildDone = treeChildDone[nodeTParent];
1124 treeChildDone[nodeTParent]++;
1125#ifdef TTK_ENABLE_OPENMP4
1128 if(not treeNodeDone[nodeTParent]
1129 and oldTreeChildDone + 1 == treeNodeChildSize[nodeTParent]) {
1130 nodeT = nodeTParent;
1131 treeNodeDone[nodeTParent] =
true;
1132#ifdef TTK_ENABLE_OPENMP4
1133#pragma omp taskyield
1139#ifdef TTK_ENABLE_OPENMP4
1143#ifdef TTK_ENABLE_OPENMP4
1155 for(
auto itr = theMap.begin(); itr != theMap.end(); ++itr) {
1156 std::stringstream ss;
1157 ss <<
'\t' << itr->first <<
'\t' << itr->second;
1163 template <
class dataType>
1165 bool problem =
false;
1167 bool const isJT = tree->
isJoinTree<dataType>();
1168 std::vector<std::tuple<ftm::idNode, ftm::idNode>> problemNodes;
1169 std::queue<ftm::idNode> queue;
1170 queue.emplace(tree->
getRoot());
1171 while(!queue.empty()) {
1175 if(!tree->
isRoot(node)) {
1178 thisProblem = tree->
getValue<dataType>(node)
1181 thisProblem = tree->
getValue<dataType>(node)
1187 problem |= thisProblem;
1190 std::vector<ftm::idNode> children;
1192 for(
auto c : children)
1197 printErr(
"merge tree in input is not valid");
1198 for(
auto tup : problemNodes) {
1199 std::stringstream ss;
1200 ss << std::get<0>(tup) <<
" _ " << std::get<1>(tup);
1211 template <
class dataType>
1214 std::vector<std::tuple<ftm::idNode, ftm::idNode, dataType>> pairs1,
1218 std::vector<std::vector<dataType>> costMatrix(
1219 pairs1.size() + 1, std::vector<dataType>(pairs2.size() + 1));
1220 std::stringstream
const ss;
1221 ss << costMatrix.size() <<
" _ " << costMatrix[0].size();
1223 for(
unsigned int i = 0; i < costMatrix.size() - 1; ++i) {
1224 dataType nodeIValue = tree1->
getValue<dataType>(std::get<0>(pairs1[i]));
1225 dataType nodeIOriginValue
1226 = tree1->
getValue<dataType>(std::get<1>(pairs1[i]));
1227 for(
unsigned int j = 0; j < costMatrix[0].size() - 1; ++j) {
1229 = tree2->
getValue<dataType>(std::get<0>(pairs2[j]));
1230 dataType nodeJOriginValue
1231 = tree2->
getValue<dataType>(std::get<1>(pairs2[j]));
1232 costMatrix[i][j] = std::pow(nodeIValue - nodeJValue, 2)
1233 + std::pow(nodeIOriginValue - nodeJOriginValue, 2);
1235 costMatrix[i][costMatrix[0].size() - 1]
1236 = 2 * std::pow(std::get<2>(pairs1[i]), 2) / (std::pow(2, 2));
1238 for(
unsigned int j = 0; j < costMatrix[0].size() - 1; ++j)
1239 costMatrix[costMatrix.size() - 1][j]
1240 = 2 * std::pow(std::get<2>(pairs2[j]), 2) / (std::pow(2, 2));
1241 std::vector<MatchingType> matchings;
1242 forestAssignmentProblemMunkres(costMatrix, matchings);
1244 for(
auto tuple : matchings)
1245 cost += std::get<2>(tuple);
1246 std::stringstream ss2;
1247 ss2 <<
"cost = " << cost;
1249 std::stringstream ss3;
1250 ss3 <<
"cost sqrt = " << std::sqrt(cost);
#define TTK_FORCE_USE(x)
Force the compiler to use the function/method parameter.
#define ttkNotUsed(x)
Mark function/method parameters that are not used in the function body at all.
void setEpsilon(double eps)
void setEpsilonDiviserMultiplier(double div)
void setNumberOfRounds(int noRounds)
virtual int run(std::vector< MatchingType > &matchings)=0
virtual int setInput(std::vector< std::vector< dataType > > &C_)
virtual void setBalanced(bool balanced)
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
dataType deleteCost(const ftm::FTMTree_MT *tree, ftm::idNode nodeId)
void convertBranchDecompositionMatching(ftm::FTMTree_MT *tree1, ftm::FTMTree_MT *tree2, std::vector< std::tuple< ftm::idNode, ftm::idNode, double > > &outputMatching)
dataType relabelCost(const ftm::FTMTree_MT *tree1, ftm::idNode nodeId1, const ftm::FTMTree_MT *tree2, ftm::idNode nodeId2)
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, bool removeMergedSaddles=false)
void postprocessingPipeline(ftm::FTMTree_MT *tree)
bool distanceSquaredRoot_
std::vector< std::vector< int > > treesNodeCorr_
bool branchDecomposition_
bool isPersistenceDiagram_
dataType insertCost(const ftm::FTMTree_MT *tree, ftm::idNode nodeId)
std::tuple< dataType, ftm::idNode > computeTerm1_2(std::vector< ftm::idNode > &childrens, int ind, std::vector< std::vector< dataType > > &table, bool computeTerm1)
void setOnlyEmptyTreeDistance(double only)
void setPreprocess(bool preproc)
void parallelTreeDistance_v2(const ftm::FTMTree_MT *tree1, const ftm::FTMTree_MT *tree2, bool isTree1, int i, std::vector< ftm::idNode > &tree1Leaves, std::vector< int > &tree1NodeChildSize, std::vector< ftm::idNode > &tree2Leaves, std::vector< int > &tree2NodeChildSize, std::vector< std::vector< dataType > > &treeTable, std::vector< std::vector< dataType > > &forestTable, std::vector< std::vector< std::tuple< int, int > > > &treeBackTable, std::vector< std::vector< std::vector< std::tuple< int, int > > > > &forestBackTable, bool firstCall=false)
void parallelEmptyTreeDistancePara(const ftm::FTMTree_MT *tree, bool isTree1, std::vector< ftm::idNode > &treeLeaves, std::vector< int > &treeNodeChildSize, std::vector< std::vector< dataType > > &treeTable, std::vector< std::vector< dataType > > &forestTable, std::vector< std::vector< std::tuple< int, int > > > &treeBackTable, std::vector< std::vector< std::vector< std::tuple< int, int > > > > &forestBackTable, ftm::idNode nodeT, std::vector< int > &treeChildDone, std::vector< bool > &treeNodeDone, std::queue< ftm::idNode > &treeQueue)
dataType forestAssignmentProblem(const ftm::FTMTree_MT *ttkNotUsed(tree1), const ftm::FTMTree_MT *ttkNotUsed(tree2), std::vector< std::vector< dataType > > &treeTable, std::vector< ftm::idNode > &children1, std::vector< ftm::idNode > &children2, std::vector< std::tuple< int, int > > &forestAssignment)
void runAssignmentProblemSolver(std::vector< std::vector< dataType > > &costMatrix, std::vector< MatchingType > &matchings)
void computeEditDistance(const ftm::FTMTree_MT *tree1, const ftm::FTMTree_MT *tree2, std::vector< std::vector< dataType > > &treeTable, std::vector< std::vector< dataType > > &forestTable, std::vector< std::vector< std::tuple< int, int > > > &treeBackTable, std::vector< std::vector< std::vector< std::tuple< int, int > > > > &forestBackTable, int nRows, int nCols)
void computeMatching(const ftm::FTMTree_MT *tree1, const ftm::FTMTree_MT *tree2, std::vector< std::vector< std::tuple< int, int > > > &treeBackTable, std::vector< std::vector< std::vector< std::tuple< int, int > > > > &forestBackTable, std::vector< std::tuple< ftm::idNode, ftm::idNode, double > > &outputMatching, int startR, int startC)
void setPostprocess(bool postproc)
void computeSubtreeToEmptyDistance(const ftm::FTMTree_MT *tree1, ftm::idNode nodeI, int i, std::vector< std::vector< dataType > > &treeTable, std::vector< std::vector< dataType > > &forestTable)
void setTesting(bool test)
void printMapIntInt(std::map< int, int > theMap)
void setAuctionEpsilonDiviser(double aucEpsilonDiviser)
void parallelEmptyTreeDistance_v2(const ftm::FTMTree_MT *tree, bool isTree1, std::vector< ftm::idNode > &treeLeaves, std::vector< int > &treeNodeChildSize, std::vector< std::vector< dataType > > &treeTable, std::vector< std::vector< dataType > > &forestTable, std::vector< std::vector< std::tuple< int, int > > > &treeBackTable, std::vector< std::vector< std::vector< std::tuple< int, int > > > > &forestBackTable)
void classicEditDistance(const ftm::FTMTree_MT *tree1, const ftm::FTMTree_MT *tree2, bool processTree1, bool computeEmptyTree, ftm::idNode nodeI, ftm::idNode nodeJ, std::vector< std::vector< dataType > > &treeTable, std::vector< std::vector< dataType > > &forestTable, std::vector< std::vector< std::tuple< int, int > > > &treeBackTable, std::vector< std::vector< std::vector< std::tuple< int, int > > > > &forestBackTable, int nRows, int nCols)
void parallelTreeDistancePara(const ftm::FTMTree_MT *tree1, const ftm::FTMTree_MT *tree2, bool isTree1, int i, std::vector< ftm::idNode > &tree1Leaves, std::vector< int > &tree1NodeChildSize, std::vector< ftm::idNode > &tree2Leaves, std::vector< int > &tree2NodeChildSize, std::vector< std::vector< dataType > > &treeTable, std::vector< std::vector< dataType > > &forestTable, std::vector< std::vector< std::tuple< int, int > > > &treeBackTable, std::vector< std::vector< std::vector< std::tuple< int, int > > > > &forestBackTable, bool firstCall, ftm::idNode nodeT, std::vector< int > &treeChildDone, std::vector< bool > &treeNodeDone, std::queue< ftm::idNode > &treeQueue)
void setSaveTree(bool save)
void computeForestToEmptyDistance(const ftm::FTMTree_MT *tree1, ftm::idNode nodeI, int i, std::vector< std::vector< dataType > > &treeTable, std::vector< std::vector< dataType > > &forestTable)
void setAuctionEpsilon(double aucEpsilon)
void computeSubtreesDistance(const ftm::FTMTree_MT *tree1, const ftm::FTMTree_MT *tree2, int i, int j, ftm::idNode nodeI, ftm::idNode nodeJ, std::vector< std::vector< dataType > > &treeTable, std::vector< std::vector< dataType > > &forestTable, std::vector< std::vector< std::tuple< int, int > > > &treeBackTable, std::vector< ftm::idNode > &children1, std::vector< ftm::idNode > &children2)
void setMinMaxPairWeight(double weight)
dataType computeDistance(const ftm::FTMTree_MT *tree1, const ftm::FTMTree_MT *tree2, std::vector< std::tuple< ftm::idNode, ftm::idNode, double > > &outputMatching)
dataType execute(ftm::MergeTree< dataType > &tree1, ftm::MergeTree< dataType > &tree2, std::vector< std::tuple< ftm::idNode, ftm::idNode > > &outputMatching)
void createCostMatrix(std::vector< std::vector< dataType > > &treeTable, std::vector< ftm::idNode > &children1, std::vector< ftm::idNode > &children2, std::vector< std::vector< dataType > > &costMatrix)
void verifyMergeTreeStructure(ftm::FTMTree_MT *tree)
dataType postprocessAssignment(std::vector< MatchingType > &matchings, std::vector< ftm::idNode > &children1, std::vector< ftm::idNode > &children2, std::vector< std::tuple< int, int > > &forestAssignment)
dataType computeDistance(const ftm::FTMTree_MT *tree1, const ftm::FTMTree_MT *tree2, std::vector< std::tuple< ftm::idNode, ftm::idNode > > &outputMatching)
dataType execute(ftm::MergeTree< dataType > &mTree1, ftm::MergeTree< dataType > &mTree2, std::vector< std::tuple< ftm::idNode, ftm::idNode, double > > &outputMatching)
void computeEmptyToForestDistance(const ftm::FTMTree_MT *tree2, ftm::idNode nodeJ, int j, std::vector< std::vector< dataType > > &treeTable, std::vector< std::vector< dataType > > &forestTable)
void computeEmptyToSubtreeDistance(const ftm::FTMTree_MT *tree2, ftm::idNode nodeJ, int j, std::vector< std::vector< dataType > > &treeTable, std::vector< std::vector< dataType > > &forestTable)
void classicalPersistenceAssignmentProblem(ftm::FTMTree_MT *tree1, ftm::FTMTree_MT *tree2)
void parallelTreeDistanceTask(const ftm::FTMTree_MT *tree1, const ftm::FTMTree_MT *tree2, bool isTree1, int i, std::vector< ftm::idNode > &tree1Leaves, std::vector< int > &tree1NodeChildSize, std::vector< ftm::idNode > &tree2Leaves, std::vector< int > &tree2NodeChildSize, std::vector< std::vector< dataType > > &treeTable, std::vector< std::vector< dataType > > &forestTable, std::vector< std::vector< std::tuple< int, int > > > &treeBackTable, std::vector< std::vector< std::vector< std::tuple< int, int > > > > &forestBackTable, ftm::idNode nodeT, std::vector< int > &treeChildDone, std::vector< bool > &treeNodeDone, std::queue< ftm::idNode > &treeQueue)
void parallelEmptyTreeDistanceTask(const ftm::FTMTree_MT *tree, bool isTree1, std::vector< ftm::idNode > &ttkNotUsed(treeLeaves), std::vector< int > &treeNodeChildSize, std::vector< std::vector< dataType > > &treeTable, std::vector< std::vector< dataType > > &forestTable, std::vector< std::vector< std::tuple< int, int > > > &treeBackTable, std::vector< std::vector< std::vector< std::tuple< int, int > > > > &forestBackTable, ftm::idNode nodeT, std::vector< int > &treeChildDone, std::vector< bool > &treeNodeDone, std::queue< ftm::idNode > &treeQueue)
void computeForestsDistance(const ftm::FTMTree_MT *tree1, const ftm::FTMTree_MT *tree2, int i, int j, std::vector< std::vector< dataType > > &treeTable, std::vector< std::vector< dataType > > &forestTable, std::vector< std::vector< std::vector< std::tuple< int, int > > > > &forestBackTable, std::vector< ftm::idNode > &children1, std::vector< ftm::idNode > &children2)
void parallelEditDistance(const ftm::FTMTree_MT *tree1, const ftm::FTMTree_MT *tree2, std::vector< std::vector< dataType > > &treeTable, std::vector< std::vector< dataType > > &forestTable, std::vector< std::vector< std::tuple< int, int > > > &treeBackTable, std::vector< std::vector< std::vector< std::tuple< int, int > > > > &forestBackTable, int ttkNotUsed(nRows), int ttkNotUsed(nCols))
void setAuctionNoRounds(double aucNoRounds)
void setIsCalled(bool ic)
~MergeTreeDistance() override=default
std::stringstream printTree(bool doPrint=true) const
const scalarType & getValue(SimplexId nodeId) const
void getChildren(idNode nodeId, std::vector< idNode > &res) const
idNode getNumberOfNodes() const
std::stringstream printTreeScalars(bool printNodeAlone=true, bool doPrint=true) const
idNode getParentSafe(idNode nodeId) const
void getLevelToNode(std::vector< std::vector< idNode > > &res) const
void getAllNodeLevel(std::vector< int > &res) const
void getLeavesFromTree(std::vector< idNode > &res) const
bool isRoot(idNode nodeId) const
void getPersistencePairsFromTree(std::vector< std::tuple< ftm::idNode, ftm::idNode, dataType > > &pairs, bool useBD) const
MergeTree< dataType > copyMergeTree(const ftm::FTMTree_MT *tree, bool doSplitMultiPersPairs=false)
unsigned int idNode
Node index in vect_nodes_.
TTK base package defining the standard types.
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/| (_) |"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)