21 get_species_names(species_names);
23 treePartsPtr =
new TreeParts(*speciesSpacePtr, *
this);
28 GB_ERROR RootSynchronizer::deconstructTree(
int treeIdx,
bool provideProgress) {
29 if (!deconstructionPhase()) beginDeconstructionPhase();
32 if (!valid_tree_index(treeIdx)) {
33 error =
GBS_global_string(
"invalid tree index %i (valid 0-%i)", treeIdx,
int(get_tree_count())-1);
36 if (dtree.size() <=
size_t(treeIdx)) dtree.resize(get_tree_count());
39 if (dtree[treeIdx].isNull()) {
40 const SizeAwareTree *
tree = get_tree(treeIdx);
42 error =
GBS_global_string(
"tree at index #%i vanished (internal error)", treeIdx);
46 error = dtree[treeIdx]->deconstruct_weighted(tree, treePartsPtr->get_tree_PART(treeIdx), get_tree_info(treeIdx).species_count(), 1.0, provideProgress, speciesSpacePtr->get_allSpecies(),
DMODE_ROOTSYNC);
47 if (!error) dtree[treeIdx]->start_sorted_retrieval();
64 const bool deconInTree = !has_deconstructed_tree(inTree);
65 const bool deconAcTree = !has_deconstructed_tree(accordingToTree);
73 if (provideProgress) {
74 const size_t steps = deconInTree + deconAcTree;
78 const bool update = deconAcTree && decon_progress.
isSet();
80 error = deconstructTree(accordingToTree, provideProgress);
84 const bool update = deconInTree && decon_progress.
isSet();
86 error = deconstructTree(inTree, provideProgress);
94 if (provideProgress) progress->
subtitle(
"Searching best matching root");
96 const SizeAwareTree *accordingRoot = get_tree(accordingToTree);
97 const PART *accordingRootPART = dtree[accordingToTree]->find_part(accordingRoot->get_leftson());
101 find_best_matching_PART_in(best_dist, best_idx, accordingRootPART, *dtree[inTree], get_tree_PART(accordingToTree), get_tree_PART(inTree), provideProgress);
111 if (error && provideProgress) progress->
done();
122 if (provideProgress) {
132 if (dist<best_dist) {
136 else if (best_dist == 0) {
140 if (provideProgress) {
142 if (findBestProgress->
aborted())
break;
149 worst_dist = INT_MIN;
159 if (dist>worst_dist) {
173 const int nodes = start.
size();
176 for (
int t = 0; t<nodes; ++t) {
177 leftMoves += movesPerTree[t];
180 for (
int t = 0; t<nodes && best.
isNull(); ++t) {
181 if (movesPerTree[t]>0) {
189 if (!node->is_leaf()) {
190 neighbors.push_back(node->get_leftson());
191 neighbors.push_back(node->get_rightson());
197 if (node->is_son_of_root()) {
198 if (!brother->is_leaf()) {
199 neighbors.push_back(brother->get_leftson());
200 neighbors.push_back(brother->get_rightson());
204 neighbors.push_back(brother);
205 neighbors.push_back(node->get_father());
213 for (ConstSizeAwareTreeVector::const_iterator n = neighbors.begin(); n != neighbors.end() && best.
isNull(); ++n) {
215 modified.replace_node(t, next_node);
218 int mod_distSum = modified.distanceSum(*
this);
219 if (mod_distSum<=best_distSum) {
220 bool takeModified = mod_distSum<best_distSum;
223 const int mod_centerDist = modified.distanceToCenterSum(*
this);
224 if (mod_centerDist<best_centerDist) {
225 #if defined(DUMP_AGAIN)
226 fprintf(stderr,
"- again found mod_distSum=%i (center dist: %i -> %i)\n", mod_distSum, best_centerDist, mod_centerDist);
228 best_centerDist = mod_centerDist;
233 best_distSum = mod_distSum;
238 if (progress && progress->
aborted()) {
242 if (leftMoves>1 && best.
isNull()) {
243 MultirootPtr recursed = find_better_multiroot(modified, best_distSum, best_centerDist, movesPerTree, progress);
244 if (recursed.
isSet()) {
245 int recursed_distSum = recursed->distanceSum(*
this);
246 if (recursed_distSum<=best_distSum) {
247 bool takeRecursed = recursed_distSum<best_distSum;
250 const int rec_centerDist = recursed->distanceToCenterSum(*
this);
251 if (rec_centerDist<best_centerDist) {
252 #if defined(DUMP_AGAIN)
253 fprintf(stderr,
"- again found recursed_distSum=%i (center dist: %i -> %i)\n", recursed_distSum, best_centerDist, rec_centerDist);
255 best_centerDist = rec_centerDist;
260 best_distSum = recursed_distSum;
278 if (provideProgress) {
279 progress =
new arb_progress(
"Deconstructing trees", get_tree_count());
282 const int treeCount = get_tree_count();
284 for (
int t = 0; t<treeCount && !
error; ++t) {
286 error = deconstructTree(t, provideProgress);
290 if (error && provideProgress) progress->
done();
298 GB_ERROR error = deconstruct_all_trees(
false);
310 const int CANDIDATES = 2;
312 int mr_dist[CANDIDATES];
313 int mr_centerDist[CANDIDATES];
316 mr[1] = get_innermost_edges();
320 int best_dist = INT_MAX;
321 int best_centerDist = INT_MAX;
323 for (
int c = 0; c<CANDIDATES; ++c) {
325 mr_dist[c] = mr[c]->distanceSum(*
this);
326 mr_centerDist[c] = mr[c]->distanceToCenterSum(*
this);
328 if (mr_dist[c]<best_dist || (mr_dist[c] == best_dist && mr_centerDist[c]<best_centerDist)) {
330 best_dist = mr_dist[c];
331 best_centerDist = mr_centerDist[c];
342 #if defined(DUMP_DEPTH)
343 fprintf(stderr,
"Aborting recursion (user abort)\n");
349 int cand_checked = 0;
350 for (
int pass = 1; pass<=2 && !done; ++pass) {
351 for (
int c = 0; c<CANDIDATES && !done; ++c) {
352 bool search = pass == 1 ? (c == best_c) : (c != best_c);
354 const int nodes = mr[c]->size();
355 int movesPerTree[nodes];
356 for (
int n = 0; n<nodes; ++n) {
357 movesPerTree[n] = depth+1;
359 MultirootPtr better_mr = find_better_multiroot(*(mr[c]), mr_dist[c], mr_centerDist[c], movesPerTree, progress);
362 #if defined(DUMP_DEPTH)
363 fprintf(stderr,
"Found no better multiroot[%i] at depth=%i (dist=%i; center-dist=%i)\n", c, depth, mr_dist[c], mr_centerDist[c]);
365 if (cand_checked == CANDIDATES) {
366 if (depth == MAX_DEPTH) {
371 #if defined(DUMP_DEPTH)
372 fprintf(stderr,
"Increasing depth to %i\n", depth);
379 mr_dist[c] = better_mr->distanceSum(*
this);
380 mr_centerDist[c] = better_mr->distanceToCenterSum(*
this);
382 #if defined(DUMP_DEPTH)
383 fprintf(stderr,
"Found better multiroot[%i] at depth=%i (dist=%i; center-dist=%i)\n", c, depth, mr_dist[c], mr_centerDist[c]);
386 if (mr_dist[c]<mr_dist[best_c] || (mr_dist[c] == mr_dist[best_c] && mr_centerDist[c]<mr_centerDist[best_c])) {
392 if (depth>0) --depth;
393 #if defined(DUMP_DEPTH)
394 fprintf(stderr,
"[continuing with depth=%i]\n", depth);
410 if (get_tree_count()<2) {
411 error =
"Need at least two trees";
425 for (
size_t i = 0; i<get_tree_count(); ++i) {
426 const PART *innerPart = dtree[i]->find_innermost_part();
430 mr->replace_node(i, innerNode);
445 const PART *p1 = dtree[i1]->find_part(n1);
446 const PART *p2 = dtree[i2]->find_part(n2);
451 const PART *t1 = get_tree_PART(i1);
452 const PART *t2 = get_tree_PART(i2);
458 const PART *t1 = get_tree_PART(i1);
459 const PART *t2 = get_tree_PART(i2);
466 for (
size_t i = 0; i<get_tree_count(); ++i) {
467 for (
size_t j = 0; j<i; ++j) {
468 sum += calcTreeDistance(i, j);
474 int Multiroot::lazy_eval_distance(
const RootSynchronizer& rsync,
int i,
int j)
const {
475 int dist = distance.get(i, j);
476 if (dist == UNKNOWN_DISTANCE) {
478 distance.set(i, j, dist);
488 for (
int i = 0; i<size(); ++i) {
489 for (
int j = 0; j<i; ++j) {
490 sum += lazy_eval_distance(rsync, i, j);
498 for (
int i = 0; i<size(); ++i) {
509 for (
int i = 0; i<size(); ++i) {
511 sum += lazy_eval_distance(rsync, i, idx);
523 for (
int i = 0; i<size(); ++i) {
525 distance.set(i, idx, UNKNOWN_DISTANCE);
const PART * get_edge_PART(int treeIdx, const SizeAwareTree *sonOfEdge) const
const PART * peek_part(int idx) const
void beginDeconstructionPhase()
void showDeconstructingSubtitle(arb_progress &progress, int treeNr)
int distanceSum(const RootSynchronizer &rsync) const
static void find_best_matching_PART_in(int &best_dist, int &best_idx, const PART *part, const DeconstructedTree &in, const PART *tree_part, const PART *tree_in, bool provideProgress)
const TreeNode * get_origin(const PART *part)
bool deconstructionPhase() const
static void find_worst_matching_PART_in(int &worst_dist, int &worst_idx, const PART *part, const DeconstructedTree &in, const PART *tree_part, const PART *tree_in)
int calcEdgeDistance(int i1, const SizeAwareTree *n1, int i2, const SizeAwareTree *n2) const
const char * GBS_global_string(const char *templat,...)
ErrorOrSizeAwareTreePtr find_best_root_candidate(int inTree, int accordingToTree, int &best_dist, bool provideProgress)
ErrorOrMultirootPtr find_good_roots_for_trees(const int MAX_DEPTH, arb_progress *progress=NULp)
int singleTreeDistanceSum(const RootSynchronizer &rsync, int idx)
bool isNull() const
test if SmartPtr is NULp
#define DOWNCAST(totype, expr)
static HelixNrInfo * start
int calcDistance(const PART *e1, const PART *e2, const PART *t1, const PART *t2)
int distanceToCenterSum(const RootSynchronizer &rsync) const
bool isSet() const
test if SmartPtr is not NULp
static void error(const char *msg)
size_t get_part_count() const
GB_ERROR deconstruct_all_trees(bool provideProgress)
ErrorOr< MultirootPtr > ErrorOrMultirootPtr
ErrorOr< ConstSizeAwareTreePtr > ErrorOrSizeAwareTreePtr
MultirootPtr get_innermost_edges() const
ErrorOrMultirootPtr get_current_roots() const
bool represents_existing_edge(const PART *p)
std::vector< ConstSizeAwareTreePtr > ConstSizeAwareTreeVector
void subtitle(const char *stitle)
void replace_node(int idx, ConstSizeAwareTreePtr newNode)
int minDistanceSum() const
int distance_to_tree_center() const
ConstSizeAwareTreePtr get_node(int idx) const
void inc_and_check_user_abort(GB_ERROR &error)
int calcTreeDistance(int i1, int i2) const