int treeOptimizeThorough(tree *tr, int mintrav, int maxtrav) { int i; bestlist *bestT; nodeRectifier(tr); bestT = (bestlist *) malloc(sizeof(bestlist)); bestT->ninit = 0; initBestTree(bestT, 1, tr->mxtips); if (maxtrav > tr->ntips - 3) maxtrav = tr->ntips - 3; tr->startLH = tr->endLH = tr->likelihood; for(i = 1; i <= tr->mxtips + tr->mxtips - 2; i++) { tr->bestOfNode = unlikely; if(rearrangeBIG(tr, tr->nodep[i], mintrav, maxtrav)) { if((tr->endLH > tr->startLH) && (tr->bestOfNode != unlikely)) { restoreTreeFast(tr); quickSmoothLocal(tr, 3); tr->startLH = tr->endLH = tr->likelihood; } else { if(tr->bestOfNode != unlikely) { resetBestTree(bestT); saveBestTree(bestT, tr); restoreTreeFast(tr); quickSmoothLocal(tr, 3); if(tr->likelihood < tr->startLH) { int res; res = recallBestTree(bestT, 1, tr); assert(res > 0); } else tr->startLH = tr->endLH = tr->likelihood; } } } } freeBestTree(bestT); free(bestT); return 1; }
double treeOptimizeRapid(tree *tr, int mintrav, int maxtrav, analdef *adef, bestlist *bt) { int i, index, *perm = (int*)NULL; nodeRectifier(tr); if (maxtrav > tr->ntips - 3) maxtrav = tr->ntips - 3; resetInfoList(); resetBestTree(bt); tr->startLH = tr->endLH = tr->likelihood; if(tr->doCutoff) { if(tr->bigCutoff) { if(tr->itCount == 0) tr->lhCutoff = 0.5 * (tr->likelihood / -1000.0); else tr->lhCutoff = 0.5 * ((tr->lhAVG) / ((double)(tr->lhDEC))); } else { if(tr->itCount == 0) tr->lhCutoff = tr->likelihood / -1000.0; else tr->lhCutoff = (tr->lhAVG) / ((double)(tr->lhDEC)); } tr->itCount = tr->itCount + 1; tr->lhAVG = 0; tr->lhDEC = 0; } if(adef->permuteTreeoptimize) { int n = tr->mxtips + tr->mxtips - 2; perm = (int *)rax_malloc(sizeof(int) * (n + 1)); makePermutation(perm, n, adef); } for(i = 1; i <= tr->mxtips + tr->mxtips - 2; i++) { tr->bestOfNode = unlikely; if(adef->permuteTreeoptimize) index = perm[i]; else index = i; if(rearrangeBIG(tr, tr->nodep[index], mintrav, maxtrav)) { if(Thorough) { if(tr->endLH > tr->startLH) { restoreTreeFast(tr); tr->startLH = tr->endLH = tr->likelihood; saveBestTree(bt, tr); } else { if(tr->bestOfNode != unlikely) restoreTopologyOnly(tr, bt); } } else { insertInfoList(tr->nodep[index], tr->bestOfNode); if(tr->endLH > tr->startLH) { restoreTreeFast(tr); tr->startLH = tr->endLH = tr->likelihood; } } } } if(!Thorough) { Thorough = 1; for(i = 0; i < iList.valid; i++) { tr->bestOfNode = unlikely; if(rearrangeBIG(tr, iList.list[i].node, mintrav, maxtrav)) { if(tr->endLH > tr->startLH) { restoreTreeFast(tr); tr->startLH = tr->endLH = tr->likelihood; saveBestTree(bt, tr); } else { if(tr->bestOfNode != unlikely) { restoreTopologyOnly(tr, bt); } } } } Thorough = 0; } if(adef->permuteTreeoptimize) rax_free(perm); return tr->startLH; }
static double linearSPRs(tree *tr, int radius, boolean veryFast) { int numberOfSubtrees = (tr->mxtips - 2) * 3, count = 0, k, i; double fourScores[4]; nodeptr *ptr = (nodeptr *)rax_malloc(sizeof(nodeptr) * numberOfSubtrees); fourLikelihoods *fourLi = (fourLikelihoods *)rax_malloc(sizeof(fourLikelihoods) * 4); insertions *ins = (insertions*)rax_malloc(sizeof(insertions)); ins->count = 0; ins->maxCount = 2048; ins->s = (scores *)rax_malloc(sizeof(scores) * ins->maxCount); /* recursively compute the roots of all subtrees in the current tree and store them in ptr */ getSubtreeRoots(tr->start->back, ptr, &count, tr->mxtips); assert(count == numberOfSubtrees); tr->startLH = tr->endLH = tr->likelihood; /* loop over subtrees, i.e., execute a full SPR cycle */ for(i = 0; i < numberOfSubtrees; i++) { nodeptr p = ptr[i], p1 = p->next->back, p2 = p->next->next->back; double p1z[NUM_BRANCHES], p2z[NUM_BRANCHES]; ins->count = 0; /*printf("Node %d %d\n", p->number, i);*/ tr->bestOfNode = unlikely; for(k = 0; k < 4; k++) fourScores[k] = unlikely; assert(!isTip(p->number, tr->rdta->numsp)); if(!isTip(p1->number, tr->rdta->numsp) || !isTip(p2->number, tr->rdta->numsp)) { double max = unlikely; int maxInt = -1; for(k = 0; k < tr->numBranches; k++) { p1z[k] = p1->z[k]; p2z[k] = p2->z[k]; } /* remove the current subtree */ removeNodeBIG(tr, p, tr->numBranches); /* pre score with fast insertions */ if(veryFast) Thorough = 1; else Thorough = 0; if (!isTip(p1->number, tr->rdta->numsp)) { fourScores[0] = testInsertFast(tr, p, p1->next->back, ins, veryFast); fourScores[1] = testInsertFast(tr, p, p1->next->next->back, ins, veryFast); } if (!isTip(p2->number, tr->rdta->numsp)) { fourScores[2] = testInsertFast(tr, p, p2->next->back, ins, veryFast); fourScores[3] = testInsertFast(tr, p, p2->next->next->back, ins, veryFast); } if(veryFast) Thorough = 1; else Thorough = 0; /* find the most promising direction */ if(!veryFast) { int j = 0, validEntries = 0; double lmax = unlikely, posterior = 0.0; for(k = 0; k < 4; k++) { fourLi[k].direction = k; fourLi[k].likelihood = fourScores[k]; } qsort(fourLi, 4, sizeof(fourLikelihoods), fourCompare); for(k = 0; k < 4; k++) if(fourLi[k].likelihood > unlikely) validEntries++; lmax = fourLi[0].likelihood; while(posterior <= POSTERIOR_THRESHOLD && j < validEntries) { double all = 0.0, prob = 0.0; for(k = 0; k < validEntries; k++) all += exp(fourLi[k].likelihood - lmax); posterior += (prob = (exp(fourLi[j].likelihood - lmax) / all)); switch(fourLi[j].direction) { case 0: insertBeyond(tr, p, p1->next->back, radius, ins, veryFast); break; case 1: insertBeyond(tr, p, p1->next->next->back, radius, ins, veryFast); break; case 2: insertBeyond(tr, p, p2->next->back, radius, ins, veryFast); break; case 3: insertBeyond(tr, p, p2->next->next->back, radius, ins, veryFast); break; default: assert(0); } j++; } qsort(ins->s, ins->count, sizeof(scores), scoreCompare); Thorough = 1; for(k = 0; k < MIN(ins->count, 20); k++) testInsertCandidates(tr, p, ins->s[k].p); } else { Thorough = 1; for(k = 0; k < 4; k++) { if(max < fourScores[k]) { max = fourScores[k]; maxInt = k; } } /* descend into this direction and re-insert subtree there */ if(maxInt >= 0) { switch(maxInt) { case 0: insertBeyond(tr, p, p1->next->back, radius, ins, veryFast); break; case 1: insertBeyond(tr, p, p1->next->next->back, radius, ins, veryFast); break; case 2: insertBeyond(tr, p, p2->next->back, radius, ins, veryFast); break; case 3: insertBeyond(tr, p, p2->next->next->back, radius, ins, veryFast); break; default: assert(0); } } } /* repair branch and reconnect subtree to its original position from which it was pruned */ hookup(p->next, p1, p1z, tr->numBranches); hookup(p->next->next, p2, p2z, tr->numBranches); /* repair likelihood vectors */ newviewGeneric(tr, p); /* if the rearrangement of subtree rooted at p yielded a better likelihood score restore the altered topology and use it from now on */ if(tr->endLH > tr->startLH) { restoreTreeFast(tr); tr->startLH = tr->endLH = tr->likelihood; } } } return tr->startLH; }
int determineRearrangementSetting(tree *tr, analdef *adef, bestlist *bestT, bestlist *bt) { int i, mintrav, maxtrav, bestTrav, impr, index, MaxFast, *perm = (int*)NULL; double startLH; boolean cutoff; MaxFast = 26; startLH = tr->likelihood; cutoff = tr->doCutoff; tr->doCutoff = FALSE; mintrav = 1; maxtrav = 5; bestTrav = maxtrav = 5; impr = 1; resetBestTree(bt); if(adef->permuteTreeoptimize) { int n = tr->mxtips + tr->mxtips - 2; perm = (int *)rax_malloc(sizeof(int) * (n + 1)); makePermutation(perm, n, adef); } while(impr && maxtrav < MaxFast) { recallBestTree(bestT, 1, tr); nodeRectifier(tr); if (maxtrav > tr->ntips - 3) maxtrav = tr->ntips - 3; tr->startLH = tr->endLH = tr->likelihood; for(i = 1; i <= tr->mxtips + tr->mxtips - 2; i++) { if(adef->permuteTreeoptimize) index = perm[i]; else index = i; tr->bestOfNode = unlikely; if(rearrangeBIG(tr, tr->nodep[index], mintrav, maxtrav)) { if(tr->endLH > tr->startLH) { restoreTreeFast(tr); tr->startLH = tr->endLH = tr->likelihood; } } } treeEvaluate(tr, 0.25); saveBestTree(bt, tr); /*printf("DETERMINE_BEST: %d %f\n", maxtrav, tr->likelihood);*/ if(tr->likelihood > startLH) { startLH = tr->likelihood; printLog(tr, adef, FALSE); bestTrav = maxtrav; impr = 1; } else { impr = 0; } maxtrav += 5; if(tr->doCutoff) { tr->lhCutoff = (tr->lhAVG) / ((double)(tr->lhDEC)); tr->itCount = tr->itCount + 1; tr->lhAVG = 0; tr->lhDEC = 0; } } recallBestTree(bt, 1, tr); tr->doCutoff = cutoff; if(adef->permuteTreeoptimize) rax_free(perm); return bestTrav; }