79 "MergeTreeBarycenter");
81#ifdef TTK_ENABLE_OPENMP4
82 omp_set_max_active_levels(100);
185 template <
class dataType>
187 std::vector<ftm::FTMTree_MT *> &trees2,
188 std::vector<std::vector<double>> &distanceMatrix,
189 bool useDoubleInput =
false,
190 bool isFirstInput =
true) {
191 distanceMatrix.clear();
192 distanceMatrix.resize(trees.size(), std::vector<double>(trees.size(), 0));
193#ifdef TTK_ENABLE_OPENMP4
194#pragma omp parallel for schedule(dynamic) \
195 num_threads(this->threadNumber_) if(parallelize_)
197 for(
unsigned int i = 0; i < trees.size(); ++i)
198 for(
unsigned int j = i + 1; j < trees.size(); ++j) {
199 std::vector<std::tuple<ftm::idNode, ftm::idNode, double>> matching;
200 std::vector<std::pair<std::pair<ftm::idNode, ftm::idNode>,
201 std::pair<ftm::idNode, ftm::idNode>>>
205 matching_path, distance, useDoubleInput,
207 distanceMatrix[i][j] = distance;
208 distanceMatrix[j][i] = distance;
212 template <
class dataType>
214 std::vector<std::vector<double>> &distanceMatrix,
215 bool useDoubleInput =
false,
216 bool isFirstInput =
true) {
218 trees, trees, distanceMatrix, useDoubleInput, isFirstInput);
221 template <
class dataType>
223 std::vector<ftm::FTMTree_MT *> &trees,
224 unsigned int barycenterMaximumNumberOfPairs,
225 double sizeLimitPercent,
227 mTreesLimited.resize(trees.size());
228#ifdef TTK_ENABLE_OPENMP4
229#pragma omp parallel for schedule(dynamic) \
230 num_threads(this->threadNumber_) if(parallelize_)
232 for(
unsigned int i = 0; i < trees.size(); ++i) {
235 barycenterMaximumNumberOfPairs, sizeLimitPercent);
240 template <
class dataType>
242 std::vector<ftm::FTMTree_MT *> &trees,
243 std::vector<std::vector<double>> &distanceMatrix,
244 unsigned int barycenterMaximumNumberOfPairs,
245 double sizeLimitPercent,
246 bool useDoubleInput =
false,
247 bool isFirstInput =
true) {
248 std::vector<ftm::MergeTree<dataType>> mTreesLimited;
250 trees, barycenterMaximumNumberOfPairs, sizeLimitPercent, mTreesLimited);
251 std::vector<ftm::FTMTree_MT *> treesLimited;
254 trees, treesLimited, distanceMatrix, useDoubleInput, isFirstInput);
257 template <
class dataType>
259 std::vector<ftm::FTMTree_MT *> &trees,
260 std::vector<std::vector<double>> &distanceMatrix,
261 unsigned int barycenterMaximumNumberOfPairs,
262 double sizeLimitPercent,
263 bool useDoubleInput =
false,
264 bool isFirstInput =
true) {
265 if(barycenterMaximumNumberOfPairs <= 0 and sizeLimitPercent <= 0.0)
267 trees, distanceMatrix, useDoubleInput, isFirstInput);
270 trees, distanceMatrix, barycenterMaximumNumberOfPairs,
271 sizeLimitPercent, useDoubleInput, isFirstInput);
274 template <
class dataType>
276 std::vector<ftm::FTMTree_MT *> &trees2,
277 unsigned int barycenterMaximumNumberOfPairs,
278 double sizeLimitPercent,
279 bool distMinimizer =
true) {
282 std::vector<std::vector<double>> distanceMatrix, distanceMatrix2;
283 bool const useDoubleInput = (trees2.size() != 0);
285 barycenterMaximumNumberOfPairs,
286 sizeLimitPercent, useDoubleInput);
287 if(trees2.size() != 0)
289 trees2, distanceMatrix2, barycenterMaximumNumberOfPairs,
290 sizeLimitPercent, useDoubleInput,
false);
294 = distMinimizer ? std::numeric_limits<dataType>::max() : 0;
295 std::vector<int> sizes(trees.size());
296 for(
unsigned int i = 0; i < trees.size(); ++i) {
298 for(
unsigned int j = 0; j < distanceMatrix[i].size(); ++j)
299 value += (not useDoubleInput ? distanceMatrix[i][j]
301 distanceMatrix2[i][j]));
302 if((distMinimizer and value < bestValue)
303 or (not distMinimizer and value > bestValue)) {
308 sizes[i] *= (distMinimizer) ? 1 : -1;
311 std::random_device rd;
312 std::default_random_engine generator(rd());
313 std::discrete_distribution<int> distribution(
314 sizes.begin(), sizes.end());
315 bestIndex = distribution(generator);
320 template <
class dataType>
322 std::vector<ftm::FTMTree_MT *> &trees2,
323 double sizeLimitPercent,
324 bool distMinimizer =
true) {
327 sizeLimitPercent, distMinimizer);
330 template <
class dataType>
332 bool distMinimizer =
true) {
333 std::vector<ftm::FTMTree_MT *> trees2;
339 template <
class dataType>
342 bool distMinimizer =
true) {
375 template <
class dataType>
380 std::vector<dataType> &newScalarsVector,
381 std::vector<std::tuple<ftm::idNode, ftm::idNode, int>> &nodesToProcess,
385 std::queue<std::tuple<ftm::idNode, ftm::idNode>> queue;
386 queue.emplace(nodeId2, nodeId1);
387 nodesToProcess.emplace_back(nodeId2, nodeId1, i);
388 while(!queue.empty()) {
389 auto &queueTuple = queue.front();
393 newScalarsVector.push_back(
395 newScalarsVector.push_back(tree->
getValue<dataType>(node));
397 std::vector<ftm::idNode> children;
399 for(
auto child : children) {
400 queue.emplace(child, nodeCpt + 1);
401 nodesToProcess.emplace_back(child, nodeCpt + 1, i);
409 template <
class dataType>
413 std::vector<std::tuple<ftm::idNode, ftm::idNode, int>> &nodesToProcess,
414 std::vector<std::vector<std::tuple<ftm::idNode, ftm::idNode>>>
419 nodesProcessed.
clear();
420 nodesProcessed.resize(noTrees);
421 for(
auto &processTuple : nodesToProcess) {
422 ftm::idNode const parent = std::get<1>(processTuple);
424 int const index = std::get<2>(processTuple);
425 nodesProcessed[index].emplace_back(
426 nodeTree1 + 1, std::get<0>(processTuple));
436 template <
class dataType>
440 std::vector<std::tuple<ftm::idNode, ftm::idNode, int>> &nodesToProcess,
441 std::vector<dataType> &newScalarsVector,
442 std::vector<std::vector<std::tuple<ftm::idNode, ftm::idNode>>>
462 template <
class dataType>
464 std::vector<ftm::FTMTree_MT *> &trees,
466 std::vector<std::vector<std::tuple<ftm::idNode, ftm::idNode, double>>>
474 std::vector<std::vector<ftm::idNode>> matrixMatchings(trees.size());
476 for(
unsigned int i = 0; i < matchings.size(); ++i) {
477 auto &matching = matchings[i];
478 matrixMatchings[i].resize(trees[i]->getNumberOfNodes(),
479 std::numeric_limits<ftm::idNode>::max());
480 for(
auto &match : matching) {
481 matrixMatchings[i][std::get<1>(match)] = std::get<0>(match);
482 baryMatched[std::get<0>(match)] =
true;
487 std::vector<std::vector<ftm::idNode>> nodesToAdd(trees.size());
488#ifdef TTK_ENABLE_OPENMP4
489#pragma omp parallel for schedule(dynamic) \
490 num_threads(this->threadNumber_) if(parallelize_)
492 for(
unsigned int i = 0; i < trees.size(); ++i) {
494 std::queue<ftm::idNode> queue;
496 while(!queue.empty()) {
499 bool processChildren =
true;
501 if(matrixMatchings[i][node]
502 == std::numeric_limits<ftm::idNode>::max()) {
504 processChildren =
false;
505 nodesToAdd[i].push_back(node);
510 "barycenter with keepSubtree_=true is not implemented yet");
513 if(processChildren) {
514 std::vector<ftm::idNode> children;
515 trees[i]->getChildren(node, children);
516 for(
auto child : children)
517 if(not(trees[i]->isThereOnlyOnePersistencePair()
518 and trees[i]->isLeaf(child)))
519 queue.emplace(child);
524 bool foundRootNotMatched =
false;
525 for(
unsigned int i = 0; i < trees.size(); ++i)
527 matrixMatchings[i][trees[i]->getRoot()]);
528 if(foundRootNotMatched)
529 printWrn(
"[updateBarycenterTreeStructure] an input tree has its root "
534 if(not baryMatched[i])
540 std::vector<std::tuple<ftm::idNode, ftm::idNode, int>> nodesToProcess;
541 std::vector<dataType> newScalarsVector;
543 for(
unsigned int i = 0; i < nodesToAdd.size(); ++i) {
544 for(
auto node : nodesToAdd[i]) {
546 = matrixMatchings[i][trees[i]->getParentSafe(node)];
547 if(matchings[i].size() == 0)
548 parent = baryTreeRoot;
552 and matchings[i].size() != 0) {
553 std::stringstream ss;
554 ss << trees[i]->getParentSafe(node) <<
" _ " << node;
556 printMsg(trees[i]->printTree().str());
557 printMsg(trees[i]->printPairsFromTree<dataType>(
true).str());
559 std::stringstream ss2;
560 ss2 <<
"parent " << parent;
565 std::vector<dataType> addedScalars;
567 parent, trees[i], node, addedScalars, nodesToProcess, nodeCpt, i);
568 newScalarsVector.insert(
569 newScalarsVector.end(), addedScalars.begin(), addedScalars.end());
573 std::vector<std::vector<std::tuple<ftm::idNode, ftm::idNode>>>
576 nodesToProcess, newScalarsVector,
578 for(
unsigned int i = 0; i < matchings.size(); ++i) {
579 std::vector<std::tuple<ftm::idNode, ftm::idNode, double>>
581 for(
auto &tup : nodesProcessed[i])
582 nodesProcessedT.emplace_back(
583 std::get<0>(tup), std::get<1>(tup), -1);
584 matchings[i].insert(matchings[i].
end(), nodesProcessedT.begin(),
585 nodesProcessedT.end());
591 printErr(
"barycenter with keepSubtree_=true is not implemented yet");
595 template <
class dataType>
596 std::tuple<dataType, dataType>
598 std::tuple<dataType, dataType> birthDeath;
608 template <
class dataType>
609 std::tuple<dataType, dataType>
612 std::vector<dataType> &newScalarsVector,
613 std::vector<ftm::FTMTree_MT *> &trees,
614 std::vector<ftm::idNode> &nodes,
615 std::vector<double> &alphas) {
616 dataType newBirth = 0, newDeath = 0;
619 dataType tempBirth = 0, tempDeath = 0;
621 for(
unsigned int i = 0; i < trees.size(); ++i)
622 if(nodes[i] != std::numeric_limits<ftm::idNode>::max())
623 alphaSum += alphas[i];
624 for(
unsigned int i = 0; i < trees.size(); ++i) {
626 if(nodes[i] != std::numeric_limits<ftm::idNode>::max()) {
629 dataType tTempBirth = 0, tTempDeath = 0;
630 tTempBirth += std::get<0>(iBirthDeath);
631 tTempDeath += std::get<1>(iBirthDeath);
632 tempBirth += tTempBirth * alphas[i] / alphaSum;
633 tempDeath += tTempDeath * alphas[i] / alphaSum;
636 dataType
const projec = (tempBirth + tempDeath) / 2;
639 for(
unsigned int i = 0; i < trees.size(); ++i) {
640 dataType iBirth = projec, iDeath = projec;
642 if(nodes[i] != std::numeric_limits<ftm::idNode>::max()) {
645 iBirth = std::get<0>(iBirthDeath);
646 iDeath = std::get<1>(iBirthDeath);
648 newBirth += alphas[i] * iBirth;
649 newDeath += alphas[i] * iDeath;
654 baryTree, nodeId, newScalarsVector,
false);
656 baryTree, nodeId, newScalarsVector);
659 volatile dataType tempBirthT = newBirth * (mu_max - mu_min);
660 volatile dataType tempDeathT = newDeath * (mu_max - mu_min);
661 newBirth = tempBirthT + mu_min;
662 newDeath = tempDeathT + mu_min;
665 return std::make_tuple(newBirth, newDeath);
668 template <
class dataType>
669 std::tuple<dataType, dataType>
675 std::vector<dataType> &newScalarsVector) {
677 dataType newBirth = std::get<0>(birthDeath);
678 dataType newDeath = std::get<1>(birthDeath);
679 dataType
const projec = (newBirth + newDeath) / 2;
681 newBirth = alpha * newBirth + (1 - alpha) * projec;
682 newDeath = alpha * newDeath + (1 - alpha) * projec;
687 baryTree, nodeB, newScalarsVector,
false);
689 baryTree, nodeB, newScalarsVector);
692 volatile dataType tempBirthT = newBirth * (mu_max - mu_min);
693 volatile dataType tempDeathT = newDeath * (mu_max - mu_min);
694 newBirth = tempBirthT + mu_min;
695 newDeath = tempDeathT + mu_min;
698 return std::make_tuple(newBirth, newDeath);
701 template <
class dataType>
703 std::vector<ftm::FTMTree_MT *> &trees,
705 std::vector<double> &alphas,
706 unsigned int indexAddedNodes,
707 std::vector<std::vector<std::tuple<ftm::idNode, ftm::idNode, double>>>
710 bool const isJT = baryTree->
isJoinTree<dataType>();
715 std::vector<std::vector<ftm::idNode>> baryMatching(
717 std::vector<ftm::idNode>(
718 trees.size(), std::numeric_limits<ftm::idNode>::max()));
719 std::vector<std::tuple<int, ftm::idNode>> nodesAddedTree(
721 for(
unsigned int i = 0; i < matchings.size(); ++i) {
722 auto &matching = matchings[i];
723 for(
auto &match : matching) {
724 if(std::get<0>(match) >= indexAddedNodes)
726 nodesAddedTree[std::get<0>(match)]
727 = std::make_tuple(i, std::get<1>(match));
729 baryMatching[std::get<0>(match)][i] = std::get<1>(match);
736 std::queue<ftm::idNode> queue;
738 while(!queue.empty()) {
741 std::tuple<dataType, dataType> newBirthDeath;
742 if(node < indexAddedNodes) {
745 trees, baryMatching[node], alphas);
747 int const i = std::get<0>(nodesAddedTree[node]);
748 ftm::idNode const nodeT = std::get<1>(nodesAddedTree[node]);
750 trees[i], nodeT, alphas[i], baryMergeTree, node, newScalarsVector);
753 = (isJT ? std::get<1>(newBirthDeath) : std::get<0>(newBirthDeath));
754 dataType nodeOriginScalar
755 = (isJT ? std::get<0>(newBirthDeath) : std::get<1>(newBirthDeath));
756 newScalarsVector[node] = nodeScalar;
759 std::vector<ftm::idNode> children;
761 for(
auto child : children)
762 queue.emplace(child);
767 dataType mergedRootOriginScalar = 0.0;
768 for(
unsigned int i = 0; i < trees.size(); ++i)
769 mergedRootOriginScalar += trees[i]->getValue<dataType>(
770 trees[i]->getMergedRootOrigin<dataType>());
771 mergedRootOriginScalar /= trees.size();
772 newScalarsVector[mergedRootOrigin] = mergedRootOriginScalar;
775 setTreeScalars(baryMergeTree, newScalarsVector);
776 std::vector<ftm::idNode> deletedNodesT;
778 &(baryMergeTree.
tree), 0, deletedNodesT);
783 template <
class dataType>
785 std::vector<ftm::FTMTree_MT *> &trees,
787 std::vector<double> &alphas,
788 std::vector<std::vector<std::pair<std::pair<ftm::idNode, ftm::idNode>,
789 std::pair<ftm::idNode, ftm::idNode>>>>
793 for(
unsigned int i = 0; i < trees.size(); ++i)
794 alphaSum += alphas[i];
795 bool joinTrees = trees[0]->isJoinTree<dataType>();
800 std::vector<std::vector<bool>> treeNodesMatched(trees.size());
801 for(
unsigned int i = 0; i < trees.size(); i++) {
804 treeNodesMatched[i].resize(trees[i]->getNumberOfNodes(),
false);
805 for(
auto match : matchings[i]) {
806 baryNodesMatched[match.first.first] =
true;
807 baryNodesMatched[match.first.second] =
true;
808 treeNodesMatched[i][match.second.first] =
true;
809 treeNodesMatched[i][match.second.second] =
true;
813 int newSize = oldSize;
814 for(
unsigned int i = 0; i < treeNodesMatched.size(); i++) {
817 for(
unsigned int j = 0; j < treeNodesMatched[i].size(); j++) {
818 if(!treeNodesMatched[i][j])
835 if(not baryNodesMatched[i]) {
842 std::vector<std::vector<dataType>> parentEdgeLengths(
844 for(
unsigned int i = 0; i < trees.size(); i++) {
847 auto tree = trees[i];
848 for(
auto match : matchings[i]) {
849 dataType bv1 = baryTree->
getValue<dataType>(match.first.first);
850 dataType bv2 = baryTree->
getValue<dataType>(match.first.second);
851 dataType tv1 = tree->getValue<dataType>(match.second.first);
852 dataType tv2 = tree->getValue<dataType>(match.second.second);
853 dataType pathRangeB = bv1 > bv2 ? bv1 - bv2 : bv2 - bv1;
854 dataType pathRangeT = tv1 > tv2 ? tv1 - tv2 : tv2 - tv1;
857 while(lastB != match.first.second) {
858 dataType currValueB = baryTree->
getValue<dataType>(currB);
859 dataType lastValueB = baryTree->
getValue<dataType>(lastB);
860 dataType relativeValueB = lastValueB > currValueB
861 ? lastValueB - currValueB
862 : currValueB - lastValueB;
863 relativeValueB = relativeValueB / pathRangeB;
865 parentEdgeLengths[lastB].emplace_back(relativeValueB
868 parentEdgeLengths[lastB].emplace_back(relativeValueB * pathRangeT
876 std::queue<ftm::idNode> q;
877 q.push(baryTreeNew->
getRoot());
879 std::vector<dataType> newScalars(newSize, 0);
880 newScalars[baryTreeNew->
getRoot()]
883 auto curr = q.front();
885 std::vector<ftm::idNode> children;
887 for(
auto child : children) {
890 auto m = parentEdgeLengths[child].begin()
891 + parentEdgeLengths[child].size() / 2;
892 std::nth_element(parentEdgeLengths[child].
begin(), m,
893 parentEdgeLengths[child].
end());
894 auto medianEdgeLength
895 = parentEdgeLengths[child][parentEdgeLengths[child].size() / 2];
898 + (joinTrees ? -medianEdgeLength : medianEdgeLength);
900 dataType avgEdgeLength = 0;
901 for(
auto l : parentEdgeLengths[child]) {
906 avgEdgeLength = avgEdgeLength / alphaSum;
908 = newScalars[curr] + (joinTrees ? -avgEdgeLength : avgEdgeLength);
912 setTreeScalars(baryMergeTreeNew, newScalars);
915 int currSize = oldSize;
916 for(
unsigned int i = 0; i < trees.size(); i++) {
919 auto tree = trees[i];
920 std::vector<int> newIndices(tree->getNumberOfNodes(), -1);
921 for(
auto match : matchings[i]) {
922 dataType bv1 = baryTreeNew->
getValue<dataType>(match.first.first);
923 dataType bv2 = baryTreeNew->
getValue<dataType>(match.first.second);
924 dataType tv1 = tree->getValue<dataType>(match.second.first);
925 dataType tv2 = tree->getValue<dataType>(match.second.second);
926 dataType pathRangeB = bv1 > bv2 ? bv1 - bv2 : bv2 - bv1;
927 dataType pathRangeT = tv1 > tv2 ? tv1 - tv2 : tv2 - tv1;
929 ftm::idNode currT = tree->getParentSafe(match.second.first);
933 while(currB != match.first.second || currT != match.second.second) {
934 dataType currValueB = baryTreeNew->
getValue<dataType>(currB);
935 dataType currValueT = tree->getValue<dataType>(currT);
936 dataType relativeValueB
937 = bv1 > bv2 ? bv1 - currValueB : currValueB - bv1;
938 dataType relativeValueT
939 = tv1 > tv2 ? tv1 - currValueT : currValueT - tv1;
940 relativeValueB = relativeValueB / pathRangeB;
941 relativeValueT = relativeValueT / pathRangeT;
943 if(relativeValueB < relativeValueT) {
950 else if(relativeValueB > relativeValueT) {
951 q = std::queue<ftm::idNode>();
952 std::vector<ftm::idNode> currChildren;
953 tree->getChildren(currT, currChildren);
954 newIndices[currT] = currSize;
961 + (joinTrees ? relativeValueT * pathRangeB
962 : -relativeValueT * pathRangeB);
968 std::vector<int> nodesWithoutLink;
970 lastNode = newIndices[currT];
971 for(
auto child : currChildren) {
975 newIndices[child] = currSize;
977 nI = newIndices[child];
980 = (joinTrees ? tree->getValue<dataType>(currT)
981 - tree->getValue<dataType>(child)
982 : tree->getValue<dataType>(child)
983 - tree->getValue<dataType>(currT));
988 = newScalars[newIndices[currT]]
989 + (joinTrees ? -edgeLength * (alphas[i] / alphaSum)
990 : edgeLength * (alphas[i] / alphaSum));
992 baryTreeNew->
setParent(nI, newIndices[currT]);
994 if(tree->getNumberOfChildren(child) == 0
995 && newIndices[tree->getNode(child)->getOrigin()] >= 0) {
997 = newIndices[tree->getNode(child)->getOrigin()];
1001 nodesWithoutLink.push_back(nI);
1005 auto currNode = q.front();
1007 currChildren.clear();
1008 tree->getChildren(currNode, currChildren);
1009 for(
auto child : currChildren) {
1011 newIndices[child] = currSize;
1013 nI = newIndices[child];
1016 = (joinTrees ? tree->getValue<dataType>(currNode)
1017 - tree->getValue<dataType>(child)
1018 : tree->getValue<dataType>(child)
1019 - tree->getValue<dataType>(currNode));
1024 = newScalars[newIndices[currNode]]
1025 + (joinTrees ? -edgeLength * (alphas[i] / alphaSum)
1026 : edgeLength * (alphas[i] / alphaSum));
1029 baryTreeNew->
setParent(nI, newIndices[currNode]);
1030 if(tree->getNumberOfChildren(child) == 0
1031 && newIndices[tree->getNode(child)->getOrigin()] >= 0) {
1033 = newIndices[tree->getNode(child)->getOrigin()];
1037 nodesWithoutLink.push_back(nI);
1045 baryTreeNew->
getNode(newIndices[currT])
1053 currT = tree->getParentSafe(currT);
1056 printErr(
"Impossible Matching behaviour.");
1060 currT = tree->getParentSafe(currT);
1064 setTreeScalars(baryMergeTreeNew, newScalars);
1068 baryMergeTree = baryMergeTreeNew;
1071 template <
class dataType>
1073 std::vector<ftm::FTMTree_MT *> &trees,
1075 std::vector<double> &alphas,
1076 std::vector<std::vector<std::tuple<ftm::idNode, ftm::idNode, double>>>
1081 trees, baryMergeTree, alphas, indexAddedNodes, matchings);
1088 template <
class dataType>
1092 std::vector<std::tuple<ftm::idNode, ftm::idNode, double>> &matching,
1093 std::vector<std::pair<std::pair<ftm::idNode, ftm::idNode>,
1094 std::pair<ftm::idNode, ftm::idNode>>>
1097 bool useDoubleInput =
false,
1098 bool isFirstInput =
true) {
1109 baryTree, tree, &matching, &matching_path);
1123 if(useDoubleInput) {
1132 baryTree, tree, matching);
1134 std::stringstream ss, ss2;
1135 ss <<
"distance tree : " << distance;
1137 ss2 <<
"distance²tree : " << distance * distance;
1144 template <
class dataType>
1148 std::vector<std::tuple<ftm::idNode, ftm::idNode, double>> &matching,
1149 std::vector<std::pair<std::pair<ftm::idNode, ftm::idNode>,
1150 std::pair<ftm::idNode, ftm::idNode>>>
1153 bool useDoubleInput =
false,
1154 bool isFirstInput =
true) {
1156 matching_path, distance, useDoubleInput,
1160 template <
class dataType>
1164 std::vector<std::tuple<ftm::idNode, ftm::idNode, double>> &matching,
1165 std::vector<std::pair<std::pair<ftm::idNode, ftm::idNode>,
1166 std::pair<ftm::idNode, ftm::idNode>>>
1169 bool useDoubleInput =
false,
1170 bool isFirstInput =
true) {
1172 matching, matching_path, distance,
1173 useDoubleInput, isFirstInput);
1176 template <
class dataType>
1180 std::vector<std::tuple<ftm::idNode, ftm::idNode, double>> &matching,
1182 bool useDoubleInput =
false,
1183 bool isFirstInput =
true) {
1184 std::vector<std::pair<std::pair<ftm::idNode, ftm::idNode>,
1185 std::pair<ftm::idNode, ftm::idNode>>>
1188 distance, useDoubleInput, isFirstInput);
1191 template <
class dataType>
1195 std::vector<std::tuple<ftm::idNode, ftm::idNode, double>> &matching,
1197 bool useDoubleInput =
false,
1198 bool isFirstInput =
true) {
1199 std::vector<std::pair<std::pair<ftm::idNode, ftm::idNode>,
1200 std::pair<ftm::idNode, ftm::idNode>>>
1203 matching_path, distance, useDoubleInput,
1207 template <
class dataType>
1211 std::vector<std::tuple<ftm::idNode, ftm::idNode, double>> &matching,
1213 bool useDoubleInput =
false,
1214 bool isFirstInput =
true) {
1215 std::vector<std::pair<std::pair<ftm::idNode, ftm::idNode>,
1216 std::pair<ftm::idNode, ftm::idNode>>>
1219 matching, matching_path, distance,
1220 useDoubleInput, isFirstInput);
1223 template <
class dataType>
1225 std::vector<ftm::FTMTree_MT *> &trees,
1227 std::vector<std::vector<std::tuple<ftm::idNode, ftm::idNode, double>>>
1229 std::vector<std::vector<std::pair<std::pair<ftm::idNode, ftm::idNode>,
1230 std::pair<ftm::idNode, ftm::idNode>>>>
1232 std::vector<dataType> &distances,
1233 bool useDoubleInput =
false,
1234 bool isFirstInput =
true) {
1237 distances, useDoubleInput, isFirstInput);
1240 distances, useDoubleInput, isFirstInput);
1243 template <
class dataType>
1245 std::vector<ftm::FTMTree_MT *> &trees,
1247 std::vector<std::vector<std::tuple<ftm::idNode, ftm::idNode, double>>>
1249 std::vector<std::vector<std::pair<std::pair<ftm::idNode, ftm::idNode>,
1250 std::pair<ftm::idNode, ftm::idNode>>>>
1252 std::vector<dataType> &distances,
1253 bool useDoubleInput =
false,
1254 bool isFirstInput =
true) {
1255#ifdef TTK_ENABLE_OPENMP4
1256#pragma omp parallel num_threads(this->threadNumber_) \
1257 shared(baryMergeTree) if(parallelize_)
1259#pragma omp single nowait
1262 distances, useDoubleInput, isFirstInput);
1263#ifdef TTK_ENABLE_OPENMP4
1268 template <
class dataType>
1270 std::vector<ftm::FTMTree_MT *> &trees,
1272 std::vector<std::vector<std::tuple<ftm::idNode, ftm::idNode, double>>>
1274 std::vector<std::vector<std::pair<std::pair<ftm::idNode, ftm::idNode>,
1275 std::pair<ftm::idNode, ftm::idNode>>>>
1277 std::vector<dataType> &distances,
1278 bool useDoubleInput =
false,
1279 bool isFirstInput =
true) {
1280 for(
unsigned int i = 0; i < trees.size(); ++i)
1281#ifdef TTK_ENABLE_OPENMP4
1282#pragma omp task firstprivate(i)
UNTIED() \
1283 shared(baryMergeTree, matchings, matchings_path, distances)
1286 matchings_path[i], distances[i],
1287 useDoubleInput, isFirstInput);
1288#ifdef TTK_ENABLE_OPENMP4
1296 template <
class dataType>
1300 std::vector<ftm::FTMTree_MT *> &oriTrees,
1301 int iterationNumber,
1302 std::vector<std::vector<ftm::idNode>> &deletedNodes) {
1303 deletedNodes.clear();
1304 deletedNodes.resize(oriTrees.size());
1305 unsigned int noTreesUnscaled = 0;
1308 for(
unsigned int i = 0; i < oriTrees.size(); ++i) {
1309 double persistenceThreshold = 50.0;
1310 if(iterationNumber != -1) {
1312 int const noPairs = mergeTrees[i].tree.getRealNumberOfNodes();
1315 std::vector<std::tuple<ftm::idNode, ftm::idNode, dataType>> pairs;
1316 oriTrees[i]->getPersistencePairsFromTree<dataType>(
1320 double const multiplier
1324 int const decrement = multiplier * pairs.size() / 10;
1325 int thresholdIndex = pairs.size() - noPairs - std::max(decrement, 2);
1326 thresholdIndex = std::max(thresholdIndex, 0);
1327 const double persistence = std::get<2>(pairs[thresholdIndex]);
1328 persistenceThreshold
1329 = persistence / std::get<2>(pairs.back()) * 100.0;
1330 if(thresholdIndex == 0) {
1331 persistenceThreshold = 0.;
1335 if(persistenceThreshold != 0.) {
1339 &(mt.
tree), persistenceThreshold, deletedNodes[i]);
1340 if(mergeTrees.size() == 0)
1341 mergeTrees.resize(oriTrees.size());
1343 trees[i] = &(mt.
tree);
1345 trees[i] = oriTrees[i];
1351 return noTreesUnscaled;
1354 template <
class dataType>
1356 std::vector<ftm::FTMTree_MT *> &oriTrees,
1357 std::vector<std::vector<ftm::idNode>> &deletedNodes,
1358 std::vector<dataType> &distances) {
1359 for(
unsigned int i = 0; i < oriTrees.size(); ++i)
1360 for(
auto node : deletedNodes[i])
1367 template <
class dataType>
1369 std::vector<ftm::FTMTree_MT *> &trees,
1371 std::vector<double> &alphas,
1372 std::vector<std::vector<std::tuple<ftm::idNode, ftm::idNode, double>>>
1374 std::vector<std::vector<std::pair<std::pair<ftm::idNode, ftm::idNode>,
1375 std::pair<ftm::idNode, ftm::idNode>>>>
1376 &finalMatchings_path,
1377 bool finalAsgnDoubleInput =
false,
1378 bool finalAsgnFirstInput =
true) {
1384 std::vector<ftm::FTMTree_MT *> oriTrees;
1385 std::vector<ftm::MergeTree<dataType>> scaledMergeTrees;
1386 std::vector<std::vector<ftm::idNode>> deletedNodes;
1388 oriTrees.insert(oriTrees.end(), trees.begin(), trees.end());
1390 trees, scaledMergeTrees, oriTrees, -1, deletedNodes);
1391 std::vector<ftm::idNode> deletedNodesT;
1394 bool treesUnscaled =
false;
1400 bool converged =
false;
1401 dataType frechetEnergy = -1;
1402 dataType minFrechet = std::numeric_limits<dataType>::max();
1404 int NoIteration = 0;
1405 std::stringstream energySequence;
1406 int minBarySize = std::numeric_limits<int>::max();
1407 int maxBarySize = 0;
1415 std::stringstream ss;
1416 ss <<
"Iteration " << NoIteration;
1420 std::vector<std::vector<std::tuple<ftm::idNode, ftm::idNode, double>>>
1421 matchings(trees.size());
1422 std::vector<std::vector<std::pair<std::pair<ftm::idNode, ftm::idNode>,
1423 std::pair<ftm::idNode, ftm::idNode>>>>
1424 matchings_path(trees.size());
1425 std::vector<dataType> distances(trees.size(), -1);
1428 trees, baryMergeTree, matchings, matchings_path, distances);
1429 Timer t_addDeletedNodes;
1432 oriTrees, deletedNodes, distances);
1434 auto t_assignment_time
1443 trees, baryMergeTree, alphas, matchings_path);
1446 trees, baryMergeTree, alphas, matchings);
1449 baryTree = &(baryMergeTree.
tree);
1454 dataType currentFrechetEnergy = 0;
1455 dataType currentFrechetEnergy2 = 0;
1456 for(
unsigned int i = 0; i < trees.size(); ++i) {
1457 currentFrechetEnergy2 += alphas[i] * distances[i];
1458 currentFrechetEnergy += alphas[i] * distances[i] * distances[i];
1461 = std::abs((
double)(frechetEnergy - currentFrechetEnergy));
1462 converged = (frechetDiff <=
tol_);
1464 frechetEnergy = currentFrechetEnergy;
1465 tol_ = frechetEnergy / 125.0;
1466 energySequence << currentFrechetEnergy << std::endl;
1468 std::stringstream ss4, ss5;
1473 ss4 <<
"Frechet energy : " << frechetEnergy;
1474 ss5 <<
"Frechet energy non-squared: " << currentFrechetEnergy2;
1483 minFrechet = std::min(minFrechet, frechetEnergy);
1485 cptBlocked = (minFrechet < frechetEnergy) ? cptBlocked + 1 : 0;
1486 converged = (cptBlocked >= 10);
1493 trees, scaledMergeTrees, oriTrees, NoIteration, deletedNodes);
1494 treesUnscaled = (noTreesUnscaled == oriTrees.size());
1507 std::vector<dataType> distances(trees.size(), -1);
1510 trees, baryMergeTree, finalMatchings, finalMatchings_path, distances);
1513 finalMatchings_path, distances,
1514 finalAsgnDoubleInput, finalAsgnFirstInput);
1516 for(
auto dist : distances)
1518 dataType currentFrechetEnergy = 0;
1519 dataType currentFrechetEnergy2 = 0;
1520 for(
unsigned int i = 0; i < trees.size(); ++i) {
1521 currentFrechetEnergy2 += alphas[i] * distances[i];
1522 currentFrechetEnergy += alphas[i] * distances[i] * distances[i];
1526 std::stringstream ss, ss2;
1527 ss <<
"Frechet energy : " << currentFrechetEnergy;
1528 ss2 <<
"Frechet energy non-squared: " << currentFrechetEnergy2;
1535 std::stringstream ssIt;
1536 ssIt <<
"Number of iterations: " << NoIteration;
1538 std::stringstream ssMin;
1539 ssMin <<
"Min barycenter bize: " << minBarySize;
1541 std::stringstream ssMax;
1542 ssMax <<
"Max barycenter bize: " << maxBarySize;
1547 trees, baryMergeTree, finalMatchings, distances);
1551 scaledMergeTrees.clear();
1553 trees.insert(trees.end(), oriTrees.begin(), oriTrees.end());
1557 template <
class dataType>
1560 std::vector<double> &alphas,
1561 std::vector<std::vector<std::tuple<ftm::idNode, ftm::idNode, double>>>
1563 std::vector<std::vector<std::pair<std::pair<ftm::idNode, ftm::idNode>,
1564 std::pair<ftm::idNode, ftm::idNode>>>>
1565 &finalMatchings_path,
1567 bool finalAsgnDoubleInput =
false,
1568 bool finalAsgnFirstInput =
true) {
1572 for(
unsigned int i = 0; i < trees.size(); ++i) {
1582 std::vector<ftm::FTMTree_MT *> treesT;
1588 finalMatchings_path, finalAsgnDoubleInput,
1589 finalAsgnFirstInput);
1601 std::vector<int>
const allRealNodes(trees.size());
1602 for(
unsigned int i = 0; i < trees.size(); ++i) {
1608 for(
unsigned int i = 0; i < trees.size(); ++i) {
1610 &(baryMergeTree.
tree), treesT[i], finalMatchings[i]);
1615 template <
class dataType>
1618 std::vector<double> &alphas,
1619 std::vector<std::vector<std::tuple<ftm::idNode, ftm::idNode, double>>>
1622 bool finalAsgnDoubleInput =
false,
1623 bool finalAsgnFirstInput =
true) {
1625 std::vector<std::vector<std::pair<std::pair<ftm::idNode, ftm::idNode>,
1626 std::pair<ftm::idNode, ftm::idNode>>>>
1627 finalMatchings_path;
1629 baryMergeTree, finalAsgnDoubleInput,
1630 finalAsgnFirstInput);
1633 template <
class dataType>
1636 std::vector<std::vector<std::tuple<ftm::idNode, ftm::idNode, double>>>
1638 std::vector<std::vector<std::pair<std::pair<ftm::idNode, ftm::idNode>,
1639 std::pair<ftm::idNode, ftm::idNode>>>>
1640 &finalMatchings_path,
1642 bool finalAsgnDoubleInput =
false,
1643 bool finalAsgnFirstInput =
true) {
1644 std::vector<double> alphas;
1645 if(trees.size() != 2) {
1646 for(
unsigned int i = 0; i < trees.size(); ++i)
1647 alphas.push_back(1.0 / trees.size());
1649 alphas.push_back(
alpha_);
1650 alphas.push_back(1 -
alpha_);
1654 baryMergeTree, finalAsgnDoubleInput,
1655 finalAsgnFirstInput);
1658 template <
class dataType>
1661 std::vector<std::vector<std::tuple<ftm::idNode, ftm::idNode, double>>>
1664 bool finalAsgnDoubleInput =
false,
1665 bool finalAsgnFirstInput =
true) {
1666 std::vector<double> alphas;
1667 if(trees.size() != 2) {
1668 for(
unsigned int i = 0; i < trees.size(); ++i)
1669 alphas.push_back(1.0 / trees.size());
1671 alphas.push_back(
alpha_);
1672 alphas.push_back(1 -
alpha_);
1675 std::vector<std::vector<std::pair<std::pair<ftm::idNode, ftm::idNode>,
1676 std::pair<ftm::idNode, ftm::idNode>>>>
1677 finalMatchings_path;
1680 baryMergeTree, finalAsgnDoubleInput,
1681 finalAsgnFirstInput);
1687 template <
class dataType>
1689 std::vector<ftm::FTMTree_MT *> &trees,
1690 unsigned int barycenterMaximumNumberOfPairs,
1692 bool useBD =
true) {
1694 unsigned int percentMaxPairs = metric * percent / 100.0;
1696 unsigned int newNoNodes;
1697 if(barycenterMaximumNumberOfPairs > 0 and percent > 0)
1698 newNoNodes = std::min(barycenterMaximumNumberOfPairs, percentMaxPairs);
1699 else if(barycenterMaximumNumberOfPairs > 0)
1700 newNoNodes = barycenterMaximumNumberOfPairs;
1701 else if(percent > 0)
1702 newNoNodes = percentMaxPairs;
1708 template <
class dataType>
1710 std::vector<ftm::FTMTree_MT *> &trees,
1712 bool useBD =
true) {
1717 template <
class dataType>
1719 std::vector<ftm::FTMTree_MT *> &trees,
1720 bool useBD =
true) {
1728 template <
class dataType>
1735 int maxIndex = std::get<0>(tup);
1736 dataType oldOriginValue = std::get<1>(tup);
1740 std::vector<dataType> newScalarsVector;
1743 if((isJT and tree->
getValue<dataType>(maxIndex) > oldOriginValue)
1745 and tree->
getValue<dataType>(maxIndex) < oldOriginValue)) {
1746 newScalarsVector[treeRoot] = newScalarsVector[maxIndex];
1747 newScalarsVector[maxIndex] = oldOriginValue;
1749 newScalarsVector[treeRoot] = oldOriginValue;
1750 setTreeScalars(barycenter, newScalarsVector);
1761 std::stringstream ss;
1762 ss <<
"Barycenter number of nodes : " << noNodes <<
" / " << noNodesT;
1769 template <
class dataType>
1771 std::vector<ftm::FTMTree_MT *> &trees,
1773 std::vector<std::vector<std::tuple<ftm::idNode, ftm::idNode, double>>>
1775 std::vector<dataType> distances) {
1776 std::vector<std::tuple<ftm::idNode, ftm::idNode, double>> matching;
1777 std::vector<std::pair<std::pair<ftm::idNode, ftm::idNode>,
1778 std::pair<ftm::idNode, ftm::idNode>>>
1782 if(distance != (distances[0] + distances[1])) {
1783 std::stringstream ss, ss2, ss3, ss4;
1784 ss <<
"distance T1 T2 : " << distance;
1786 ss2 <<
"distance T1 T' T2 : " << distances[0] + distances[1];
1788 ss3 <<
"distance T1 T' : " << distances[0];
1790 ss4 <<
"distance T' T2 : " << distances[1];
1795 auto baryTree = &(baryMergeTree.
tree);
1796 std::vector<std::vector<ftm::idNode>> baryMatched(
1797 baryTree->getNumberOfNodes(),
1798 std::vector<ftm::idNode>(
1799 trees.size(), std::numeric_limits<ftm::idNode>::max()));
1800 for(
unsigned int i = 0; i < finalMatchings.size(); ++i)
1801 for(
auto &match : finalMatchings[i])
1802 baryMatched[std::get<0>(match)][i] = std::get<1>(match);
1804 std::queue<ftm::idNode> queue;
1805 queue.emplace(baryTree->getRoot());
1806 while(!queue.empty()) {
1807 auto node = queue.front();
1809 std::vector<dataType> costs(trees.size());
1810 for(
unsigned int i = 0; i < trees.size(); ++i)
1811 if(baryMatched[node][i] != std::numeric_limits<ftm::idNode>::max())
1813 baryTree, node, trees[i], baryMatched[node][i]);
1817 if(baryMatched[node][0] != std::numeric_limits<ftm::idNode>::max()
1818 and baryMatched[node][1] != std::numeric_limits<ftm::idNode>::max())
1820 trees[0], baryMatched[node][0], trees[1], baryMatched[node][1]);
1821 else if(baryMatched[node][0] == std::numeric_limits<ftm::idNode>::max())
1823 else if(baryMatched[node][1] == std::numeric_limits<ftm::idNode>::max())
1827 costs[0] = std::sqrt(costs[0]);
1828 costs[1] = std::sqrt(costs[1]);
1829 cost = std::sqrt(cost);
1830 if(std::abs((
double)(costs[0] - costs[1])) > 1e-7) {
1832 std::stringstream ss, ss2, ss3, ss4;
1833 ss <<
"cost T' T0 : " << costs[0];
1835 ss2 <<
"cost T' T1 : " << costs[1];
1837 ss3 <<
"cost T0 T1 : " << cost;
1839 ss4 <<
"cost T0 T' T1 : " << costs[0] + costs[1];
1841 if(std::abs((
double)((costs[0] + costs[1]) - cost)) > 1e-7) {
1842 std::stringstream ss5;
1844 << std::abs((
double)((costs[0] + costs[1]) - cost));
1847 std::stringstream ss6;
1848 ss6 <<
"diff2 : " << std::abs((
double)(costs[0] - costs[1]));
1852 for(
unsigned int i = 0; i < 2; ++i)
1853 if(baryMatched[node][i]
1854 != std::numeric_limits<ftm::idNode>::max()) {
1856 trees[i]->printNode2<dataType>(baryMatched[node][i]).str());
1858 ->printNode2<dataType>(
1859 trees[i]->getParentSafe(baryMatched[node][i]))
1863 std::vector<ftm::idNode> children;
1864 baryTree->getChildren(node, children);
1865 for(
auto child : children)
1866 queue.emplace(child);
#define UNTIED()
TTK processing package that efficiently computes the contour tree of scalar data and more (data segme...
virtual int setThreadNumber(const int threadNumber)
int printWrn(const std::string &msg, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cerr) const
void setDebugMsgPrefix(const std::string &prefix)
virtual int setDebugLevel(const int &debugLevel)
int printErr(const std::string &msg, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cerr) const
int getBestInitTreeIndex(std::vector< ftm::FTMTree_MT * > &trees, std::vector< ftm::FTMTree_MT * > &trees2, unsigned int barycenterMaximumNumberOfPairs, double sizeLimitPercent, bool distMinimizer=true)
void limitSizeBarycenter(ftm::MergeTree< dataType > &bary, std::vector< ftm::FTMTree_MT * > &trees, unsigned int barycenterMaximumNumberOfPairs, double percent, bool useBD=true)
std::tuple< dataType, dataType > getParametrizedBirthDeath(ftm::FTMTree_MT *tree1, ftm::idNode nodeId1)
double getAddDeletedNodesTime()
void getParametrizedDistanceMatrix(std::vector< ftm::FTMTree_MT * > &trees, std::vector< std::vector< double > > &distanceMatrix, unsigned int barycenterMaximumNumberOfPairs, double sizeLimitPercent, bool useDoubleInput=false, bool isFirstInput=true)
void setUseMedianBarycenter(bool useMedian)
void setIterationLimit(int l)
void verifyBarycenterTwoTrees(std::vector< ftm::FTMTree_MT * > &trees, ftm::MergeTree< dataType > &baryMergeTree, std::vector< std::vector< std::tuple< ftm::idNode, ftm::idNode, double > > > &finalMatchings, std::vector< dataType > distances)
void computeOneDistance(ftm::FTMTree_MT *tree, ftm::FTMTree_MT *baryTree, std::vector< std::tuple< ftm::idNode, ftm::idNode, double > > &matching, dataType &distance, bool useDoubleInput=false, bool isFirstInput=true)
void updateNodesAndScalars(ftm::MergeTree< dataType > &mTree1, int noTrees, std::vector< std::tuple< ftm::idNode, ftm::idNode, int > > &nodesToProcess, std::vector< dataType > &newScalarsVector, std::vector< std::vector< std::tuple< ftm::idNode, ftm::idNode > > > &nodesProcessed)
unsigned int persistenceScaling(std::vector< ftm::FTMTree_MT * > &trees, std::vector< ftm::MergeTree< dataType > > &mergeTrees, std::vector< ftm::FTMTree_MT * > &oriTrees, int iterationNumber, std::vector< std::vector< ftm::idNode > > &deletedNodes)
void fixMergedRootOriginBarycenter(ftm::MergeTree< dataType > &barycenter)
void setAddNodes(bool addNodesT)
void setIsCalled(bool ic)
void setBarycenterMaxIter(int barycenterMaxIter)
void setPreprocess(bool preproc)
void computeOneDistance(ftm::MergeTree< dataType > &baryMergeTree, ftm::MergeTree< dataType > &baryMergeTree2, std::vector< std::tuple< ftm::idNode, ftm::idNode, double > > &matching, dataType &distance, bool useDoubleInput=false, bool isFirstInput=true)
void getDistanceMatrix(std::vector< ftm::FTMTree_MT * > &trees, std::vector< ftm::FTMTree_MT * > &trees2, std::vector< std::vector< double > > &distanceMatrix, bool useDoubleInput=false, bool isFirstInput=true)
double barycenterSizeLimitPercent_
void computeOneDistance(ftm::MergeTree< dataType > &baryMergeTree, ftm::MergeTree< dataType > &baryMergeTree2, std::vector< std::tuple< ftm::idNode, ftm::idNode, double > > &matching, std::vector< std::pair< std::pair< ftm::idNode, ftm::idNode >, std::pair< ftm::idNode, ftm::idNode > > > &matching_path, dataType &distance, bool useDoubleInput=false, bool isFirstInput=true)
void limitSizeBarycenter(ftm::MergeTree< dataType > &bary, std::vector< ftm::FTMTree_MT * > &trees, double percent, bool useBD=true)
std::tuple< dataType, dataType > interpolation(ftm::MergeTree< dataType > &baryMergeTree, ftm::idNode nodeId, std::vector< dataType > &newScalarsVector, std::vector< ftm::FTMTree_MT * > &trees, std::vector< ftm::idNode > &nodes, std::vector< double > &alphas)
int getBestInitTreeIndex(std::vector< ftm::FTMTree_MT * > &trees, bool distMinimizer=true)
void setPostprocess(bool postproc)
std::tuple< dataType, dataType > interpolationAdded(ftm::FTMTree_MT *tree, ftm::idNode nodeId, double alpha, ftm::MergeTree< dataType > &baryMergeTree, ftm::idNode nodeB, std::vector< dataType > &newScalarsVector)
unsigned int barycenterMaximumNumberOfPairs_
double progressiveSpeedDivisor_
void execute(std::vector< ftm::MergeTree< dataType > > &trees, std::vector< std::vector< std::tuple< ftm::idNode, ftm::idNode, double > > > &finalMatchings, std::vector< std::vector< std::pair< std::pair< ftm::idNode, ftm::idNode >, std::pair< ftm::idNode, ftm::idNode > > > > &finalMatchings_path, ftm::MergeTree< dataType > &baryMergeTree, bool finalAsgnDoubleInput=false, bool finalAsgnFirstInput=true)
double getAllDistanceTime()
void setBarycenterInitIndex(int barycenterInitIndex)
void assignmentPara(std::vector< ftm::FTMTree_MT * > &trees, ftm::MergeTree< dataType > &baryMergeTree, std::vector< std::vector< std::tuple< ftm::idNode, ftm::idNode, double > > > &matchings, std::vector< std::vector< std::pair< std::pair< ftm::idNode, ftm::idNode >, std::pair< ftm::idNode, ftm::idNode > > > > &matchings_path, std::vector< dataType > &distances, bool useDoubleInput=false, bool isFirstInput=true)
ftm::idNode getNodesAndScalarsToAdd(ftm::idNode nodeId1, ftm::FTMTree_MT *tree, ftm::idNode nodeId2, std::vector< dataType > &newScalarsVector, std::vector< std::tuple< ftm::idNode, ftm::idNode, int > > &nodesToProcess, ftm::idNode nodeCpt, int i)
Get information about the nodes to add in the barycenter.
void setDeterministic(bool deterministicT)
void assignmentTask(std::vector< ftm::FTMTree_MT * > &trees, ftm::MergeTree< dataType > &baryMergeTree, std::vector< std::vector< std::tuple< ftm::idNode, ftm::idNode, double > > > &matchings, std::vector< std::vector< std::pair< std::pair< ftm::idNode, ftm::idNode >, std::pair< ftm::idNode, ftm::idNode > > > > &matchings_path, std::vector< dataType > &distances, bool useDoubleInput=false, bool isFirstInput=true)
~MergeTreeBarycenter() override=default
void updateBarycenterTreeScalars(std::vector< ftm::FTMTree_MT * > &trees, ftm::MergeTree< dataType > &baryMergeTree, std::vector< double > &alphas, unsigned int indexAddedNodes, std::vector< std::vector< std::tuple< ftm::idNode, ftm::idNode, double > > > &matchings)
void addNodes(ftm::MergeTree< dataType > &mTree1, int noTrees, std::vector< std::tuple< ftm::idNode, ftm::idNode, int > > &nodesToProcess, std::vector< std::vector< std::tuple< ftm::idNode, ftm::idNode > > > &nodesProcessed)
void initBarycenterTree(std::vector< ftm::FTMTree_MT * > &trees, ftm::MergeTree< dataType > &baryTree, bool distMinimizer=true)
void computeBarycenter(std::vector< ftm::FTMTree_MT * > &trees, ftm::MergeTree< dataType > &baryMergeTree, std::vector< double > &alphas, std::vector< std::vector< std::tuple< ftm::idNode, ftm::idNode, double > > > &finalMatchings, std::vector< std::vector< std::pair< std::pair< ftm::idNode, ftm::idNode >, std::pair< ftm::idNode, ftm::idNode > > > > &finalMatchings_path, bool finalAsgnDoubleInput=false, bool finalAsgnFirstInput=true)
void computeOneDistance(ftm::FTMTree_MT *tree, ftm::FTMTree_MT *baryTree, std::vector< std::tuple< ftm::idNode, ftm::idNode, double > > &matching, std::vector< std::pair< std::pair< ftm::idNode, ftm::idNode >, std::pair< ftm::idNode, ftm::idNode > > > &matching_path, dataType &distance, bool useDoubleInput=false, bool isFirstInput=true)
void computeOneDistance(ftm::FTMTree_MT *tree, ftm::MergeTree< dataType > &baryMergeTree, std::vector< std::tuple< ftm::idNode, ftm::idNode, double > > &matching, std::vector< std::pair< std::pair< ftm::idNode, ftm::idNode >, std::pair< ftm::idNode, ftm::idNode > > > &matching_path, dataType &distance, bool useDoubleInput=false, bool isFirstInput=true)
void execute(std::vector< ftm::MergeTree< dataType > > &trees, std::vector< std::vector< std::tuple< ftm::idNode, ftm::idNode, double > > > &finalMatchings, ftm::MergeTree< dataType > &baryMergeTree, bool finalAsgnDoubleInput=false, bool finalAsgnFirstInput=true)
void setProgressiveSpeedDivisor(double progSpeed)
void addScaledDeletedNodesCost(std::vector< ftm::FTMTree_MT * > &oriTrees, std::vector< std::vector< ftm::idNode > > &deletedNodes, std::vector< dataType > &distances)
void updateBarycenterTreeStructure(std::vector< ftm::FTMTree_MT * > &trees, ftm::MergeTree< dataType > &baryMergeTree, std::vector< std::vector< std::tuple< ftm::idNode, ftm::idNode, double > > > &matchings)
void setUseFixedInit(bool useFixedInit)
std::vector< double > finalDistances_
bool useMedianBarycenter_
void execute(std::vector< ftm::MergeTree< dataType > > &trees, std::vector< double > &alphas, std::vector< std::vector< std::tuple< ftm::idNode, ftm::idNode, double > > > &finalMatchings, std::vector< std::vector< std::pair< std::pair< ftm::idNode, ftm::idNode >, std::pair< ftm::idNode, ftm::idNode > > > > &finalMatchings_path, ftm::MergeTree< dataType > &baryMergeTree, bool finalAsgnDoubleInput=false, bool finalAsgnFirstInput=true)
bool progressiveBarycenter_
void setBaseModule(int m)
void setPathMetric(int m)
void getSizeLimitedTrees(std::vector< ftm::FTMTree_MT * > &trees, unsigned int barycenterMaximumNumberOfPairs, double sizeLimitPercent, std::vector< ftm::MergeTree< dataType > > &mTreesLimited)
void printBaryStats(ftm::FTMTree_MT *baryTree, const debug::Priority &priority=debug::Priority::INFO)
void setProgressiveBarycenter(bool progressive)
void updateBarycenterTree_path(std::vector< ftm::FTMTree_MT * > &trees, ftm::MergeTree< dataType > &baryMergeTree, std::vector< double > &alphas, std::vector< std::vector< std::pair< std::pair< ftm::idNode, ftm::idNode >, std::pair< ftm::idNode, ftm::idNode > > > > &matchings)
void limitSizeBarycenter(ftm::MergeTree< dataType > &bary, std::vector< ftm::FTMTree_MT * > &trees, bool useBD=true)
void setBarycenterMaximumNumberOfPairs(unsigned int maxi)
double addDeletedNodesTime_
void computeOneDistance(ftm::FTMTree_MT *tree, ftm::MergeTree< dataType > &baryMergeTree, std::vector< std::tuple< ftm::idNode, ftm::idNode, double > > &matching, dataType &distance, bool useDoubleInput=false, bool isFirstInput=true)
void setAlpha(double alpha)
void setBarycenterSizeLimitPercent(double percent)
void getSizeLimitedDistanceMatrix(std::vector< ftm::FTMTree_MT * > &trees, std::vector< std::vector< double > > &distanceMatrix, unsigned int barycenterMaximumNumberOfPairs, double sizeLimitPercent, bool useDoubleInput=false, bool isFirstInput=true)
void updateBarycenterTree(std::vector< ftm::FTMTree_MT * > &trees, ftm::MergeTree< dataType > &baryMergeTree, std::vector< double > &alphas, std::vector< std::vector< std::tuple< ftm::idNode, ftm::idNode, double > > > &matchings)
std::vector< double > getFinalDistances()
void setFixedInitNumber(int fixedInitNumber)
void getDistanceMatrix(std::vector< ftm::FTMTree_MT * > &trees, std::vector< std::vector< double > > &distanceMatrix, bool useDoubleInput=false, bool isFirstInput=true)
int getBestInitTreeIndex(std::vector< ftm::FTMTree_MT * > &trees, std::vector< ftm::FTMTree_MT * > &trees2, double sizeLimitPercent, bool distMinimizer=true)
void execute(std::vector< ftm::MergeTree< dataType > > &trees, std::vector< double > &alphas, std::vector< std::vector< std::tuple< ftm::idNode, ftm::idNode, double > > > &finalMatchings, ftm::MergeTree< dataType > &baryMergeTree, bool finalAsgnDoubleInput=false, bool finalAsgnFirstInput=true)
void assignment(std::vector< ftm::FTMTree_MT * > &trees, ftm::MergeTree< dataType > &baryMergeTree, std::vector< std::vector< std::tuple< ftm::idNode, ftm::idNode, double > > > &matchings, std::vector< std::vector< std::pair< std::pair< ftm::idNode, ftm::idNode >, std::pair< ftm::idNode, ftm::idNode > > > > &matchings_path, std::vector< dataType > &distances, bool useDoubleInput=false, bool isFirstInput=true)
void setBranchDecomposition(bool useBD)
void setNormalizedWasserstein(bool normalizedWasserstein)
void setDistanceSquaredRoot(bool distanceSquaredRoot)
void setAssignmentSolver(int assignmentSolver)
dataType deleteCost(const ftm::FTMTree_MT *tree, ftm::idNode nodeId)
void keepMostImportantPairs(ftm::FTMTree_MT *tree, int n, bool useBD)
void setNodePerTask(int npt)
void convertBranchDecompositionMatching(ftm::FTMTree_MT *tree1, ftm::FTMTree_MT *tree2, std::vector< std::tuple< ftm::idNode, ftm::idNode, double > > &outputMatching)
bool normalizedWasserstein_
dataType relabelCost(const ftm::FTMTree_MT *tree1, ftm::idNode nodeId1, const ftm::FTMTree_MT *tree2, ftm::idNode nodeId2)
double mixDistances(dataType distance1, dataType distance2)
double getSizeLimitMetric(std::vector< ftm::FTMTree_MT * > &trees)
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 printTreesStats(std::vector< ftm::FTMTree_MT * > &trees)
void postprocessingPipeline(ftm::FTMTree_MT *tree)
void printMatching(std::vector< MatchingType > &matchings)
std::vector< std::vector< int > > treesNodeCorr_
void preprocessTree(ftm::FTMTree_MT *tree, bool deleteInconsistentNodes=true)
void setKeepSubtree(bool keepSubtree)
void persistenceThresholding(ftm::FTMTree_MT *tree, double persistenceThresholdT, std::vector< ftm::idNode > &deletedNodes)
double mixDistancesMinMaxPairWeight(bool isFirstInput)
bool branchDecomposition_
std::tuple< int, dataType > fixMergedRootOrigin(ftm::FTMTree_MT *tree)
void setPreprocess(bool preproc)
void setPostprocess(bool postproc)
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)
void setIsCalled(bool ic)
void setAssignmentSolver(int assignmentSolver)
void setComputeMapping(bool m)
void setPreprocess(bool p)
dataType computeDistance(ftm::FTMTree_MT *tree1, ftm::FTMTree_MT *tree2, std::vector< std::pair< std::pair< ftm::idNode, ftm::idNode >, std::pair< ftm::idNode, ftm::idNode > > > *outputMatching)
Node * getNode(idNode nodeId) const
const scalarType & getValue(SimplexId nodeId) const
void getChildren(idNode nodeId, std::vector< idNode > &res) const
idNode getNumberOfNodes() const
void setParent(idNode nodeId, idNode newParentNodeId)
void copyMergeTreeStructure(const FTMTree_MT *tree)
idNode getParentSafe(idNode nodeId) const
idNode getMergedRootOrigin() const
int getRealNumberOfNodes() const
void deleteNode(idNode nodeId)
std::tuple< dataType, dataType > getBirthDeath(idNode nodeId) const
bool isNodeIdInconsistent(idNode nodeId) const
idNode makeNode(SimplexId vertexId, SimplexId linked=nullVertex)
bool isNodeAlone(idNode nodeId) const
void deleteParent(idNode nodeId)
void setOrigin(SimplexId linked)
SimplexId getOrigin() const
void setTreeScalars(MergeTree< dataType > &mergeTree, std::vector< dataType > &scalarsVector)
MergeTree< dataType > cleanMergeTree(ftm::FTMTree_MT *tree, std::vector< int > &nodeCorr, bool useBD=true)
void getTreeScalars(const ftm::FTMTree_MT *tree, std::vector< dataType > &scalarsVector)
MergeTree< dataType > copyMergeTree(const ftm::FTMTree_MT *tree, bool doSplitMultiPersPairs=false)
void mergeTreeToFTMTree(std::vector< MergeTree< dataType > > &trees, std::vector< ftm::FTMTree_MT * > &treesT)
MergeTree< dataType > createEmptyMergeTree(int scalarSize)
unsigned int idNode
Node index in vect_nodes_.
TTK base package defining the standard types.
std::tuple< dataType, dataType > getNormalizedBirthDeath(const ftm::FTMTree_MT *tree, ftm::idNode nodeId, dataType newMin=0.0, dataType newMax=1.0)
dataType getMinMaxLocalFromVector(ftm::FTMTree_MT *tree, ftm::idNode nodeId, std::vector< dataType > &scalarsVector, bool getMin=true)
T end(std::pair< T, T > &p)
T begin(std::pair< T, T > &p)
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/| (_) |"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)