static void insertParsimony (tree *tr, nodeptr p, nodeptr q) { nodeptr r; r = q->back; hookupDefault(p->next, q, tr->numBranches); hookupDefault(p->next->next, r, tr->numBranches); newviewParsimony(tr, p); }
static void restoreTreeParsimony(tree *tr, nodeptr p, nodeptr q) { nodeptr r = q->back; int counter = 4; hookupDefault(p->next, q, tr->numBranches); hookupDefault(p->next->next, r, tr->numBranches); computeTraversalInfoParsimony(p, tr->ti, &counter, tr->mxtips, FALSE); tr->ti[0] = counter; newviewParsimonyIterativeFast(tr); }
static void addMultifurcation (FILE *fp, tree *tr, nodeptr _p, analdef *adef, int *nextnode) { nodeptr p, initial_p; int n, ch, fres; if ((ch = treeGetCh(fp)) == '(') { int i = 0; nextNodeOutOfBounds(tr, *nextnode); initial_p = p = tr->nodep[*nextnode]; *nextnode = *nextnode + 1; do { nextNodeOutOfBounds(tr, *nextnode); p->next = tr->nodep[*nextnode]; *nextnode = *nextnode + 1; p = p->next; addMultifurcation(fp, tr, p, adef, nextnode); i++; } while((ch = treeGetCh(fp)) == ','); ungetc(ch, fp); p->next = initial_p; if (! treeNeedCh(fp, ')', "in")) assert(0); treeFlushLabel(fp); } else { ungetc(ch, fp); if ((n = treeFindTipName(fp, tr, FALSE)) <= 0) assert(0); p = tr->nodep[n]; initial_p = p; tr->start = p; (tr->ntips)++; } fres = treeFlushLen(fp, tr); if(!fres) assert(0); hookupDefault(initial_p, _p, tr->numBranches); }
static nodeptr buildNewTip (tree *tr, nodeptr p) { nodeptr q; q = tr->nodep[(tr->nextnode)++]; hookupDefault(p, q, tr->numBranches); q->next->back = (nodeptr)NULL; q->next->next->back = (nodeptr)NULL; return q; }
static nodeptr removeNodeParsimony (nodeptr p, tree *tr) { nodeptr q, r; q = p->next->back; r = p->next->next->back; hookupDefault(q, r, tr->numBranches); p->next->next->back = p->next->back = (node *) NULL; return q; }
static void buildSimpleTree (tree *tr, int ip, int iq, int ir) { nodeptr p, s; int i; i = MIN(ip, iq); if (ir < i) i = ir; tr->start = tr->nodep[i]; tr->ntips = 3; p = tr->nodep[ip]; hookupDefault(p, tr->nodep[iq], tr->numBranches); s = buildNewTip(tr, tr->nodep[ir]); insertParsimony(tr, s, p); }
void parsimonySPR(nodeptr p, tree *tr) { int i; double p1z[NUM_BRANCHES], p2z[NUM_BRANCHES]; nodeptr p1 = p->next->back, p2 = p->next->next->back; unsigned int score = evaluateParsimony(tr, p, TRUE); printf("parsimonyScore: %u\n", score); for(i = 0; i < tr->numBranches; i++) { p1z[i] = p1->z[i]; p2z[i] = p2->z[i]; } tr->bestParsimony = INT_MAX; hookupDefault(p1, p2, tr->numBranches); p->next->next->back = p->next->back = (node *) NULL; if (p1->number > tr->mxtips) { addTraverseParsimony(tr, p, p1->next->back, 0, 0, TRUE, TRUE); addTraverseParsimony(tr, p, p1->next->next->back, 0, 0, TRUE, TRUE); } if(p2->number > tr->mxtips) { addTraverseParsimony(tr, p, p2->next->back, 0, 0, TRUE, TRUE); addTraverseParsimony(tr, p, p2->next->next->back, 0, 0, TRUE, TRUE); } printf("best %u nodes %d %d\n",tr->bestParsimony, tr->insertNode->number, tr->insertNode->back->number); hookup(p1, p->next, p1z, tr->numBranches); hookup(p2, p->next->next, p2z, tr->numBranches); }
static double testInsertThorough(tree *tr, nodeptr r, nodeptr q, boolean useVector) { double result, qz[NUM_BRANCHES], z[NUM_BRANCHES]; nodeptr x = q->back, s = r->back; int j; for(j = 0; j < tr->numBranches; j++) { qz[j] = q->z[j]; z[j] = sqrt(qz[j]); if(z[j] < zmin) z[j] = zmin; if(z[j] > zmax) z[j] = zmax; } hookup(r->next, q, z, tr->numBranches); hookup(r->next->next, x, z, tr->numBranches); hookupDefault(r, s, tr->numBranches); newviewGeneric(tr, r); localSmooth(tr, r, smoothings); if(useVector) result = evaluateGenericVector(tr, r); else result = evaluateGeneric(tr, r); hookup(q, x, qz, tr->numBranches); r->next->next->back = r->next->back = (nodeptr) NULL; return result; }
void pllMakeParsimonyTreeFast(tree *tr) { nodeptr p, f; int i, nextsp, *perm = (int *)malloc((size_t)(tr->mxtips + 1) * sizeof(int)); unsigned int randomMP, startMP; assert(!tr->constrained); makePermutationFast(perm, tr->mxtips, tr); tr->ntips = 0; tr->nextnode = tr->mxtips + 1; buildSimpleTree(tr, perm[1], perm[2], perm[3]); f = tr->start; while(tr->ntips < tr->mxtips) { nodeptr q; tr->bestParsimony = INT_MAX; nextsp = ++(tr->ntips); p = tr->nodep[perm[nextsp]]; q = tr->nodep[(tr->nextnode)++]; p->back = q; q->back = p; if(tr->grouped) { int number = p->back->number; tr->constraintVector[number] = -9; } stepwiseAddition(tr, q, f->back); { nodeptr r = tr->insertNode->back; int counter = 4; hookupDefault(q->next, tr->insertNode, tr->numBranches); hookupDefault(q->next->next, r, tr->numBranches); computeTraversalInfoParsimony(q, tr->ti, &counter, tr->mxtips, FALSE); tr->ti[0] = counter; newviewParsimonyIterativeFast(tr); } } printf("ADD: %d\n", tr->bestParsimony); nodeRectifierPars(tr); randomMP = tr->bestParsimony; do { startMP = randomMP; nodeRectifierPars(tr); for(i = 1; i <= tr->mxtips + tr->mxtips - 2; i++) { rearrangeParsimony(tr, tr->nodep[i], 1, 20, FALSE); if(tr->bestParsimony < randomMP) { restoreTreeRearrangeParsimony(tr); randomMP = tr->bestParsimony; } } } while(randomMP < startMP); printf("OPT: %d\n", tr->bestParsimony); }
static int rearrangeParsimony(tree *tr, nodeptr p, int mintrav, int maxtrav, boolean doAll) { nodeptr p1, p2, q, q1, q2; int mintrav2; boolean doP = TRUE, doQ = TRUE; if (maxtrav > tr->ntips - 3) maxtrav = tr->ntips - 3; assert(mintrav == 1); if(maxtrav < mintrav) return 0; q = p->back; if(tr->constrained) { if(! tipHomogeneityCheckerPars(tr, p->back, 0)) doP = FALSE; if(! tipHomogeneityCheckerPars(tr, q->back, 0)) doQ = FALSE; if(doQ == FALSE && doP == FALSE) return 0; } if((p->number > tr->mxtips) && doP) { p1 = p->next->back; p2 = p->next->next->back; if ((p1->number > tr->mxtips) || (p2->number > tr->mxtips)) { removeNodeParsimony(p, tr); if ((p1->number > tr->mxtips)) { addTraverseParsimony(tr, p, p1->next->back, mintrav, maxtrav, doAll, FALSE); addTraverseParsimony(tr, p, p1->next->next->back, mintrav, maxtrav, doAll, FALSE); } if ((p2->number > tr->mxtips)) { addTraverseParsimony(tr, p, p2->next->back, mintrav, maxtrav, doAll, FALSE); addTraverseParsimony(tr, p, p2->next->next->back, mintrav, maxtrav, doAll, FALSE); } hookupDefault(p->next, p1, tr->numBranches); hookupDefault(p->next->next, p2, tr->numBranches); newviewParsimony(tr, p); } } if ((q->number > tr->mxtips) && (maxtrav > 0) && doQ) { q1 = q->next->back; q2 = q->next->next->back; if ( ( (q1->number > tr->mxtips) && ((q1->next->back->number > tr->mxtips) || (q1->next->next->back->number > tr->mxtips)) ) || ( (q2->number > tr->mxtips) && ((q2->next->back->number > tr->mxtips) || (q2->next->next->back->number > tr->mxtips)) ) ) { removeNodeParsimony(q, tr); mintrav2 = mintrav > 2 ? mintrav : 2; if ((q1->number > tr->mxtips)) { addTraverseParsimony(tr, q, q1->next->back, mintrav2 , maxtrav, doAll, FALSE); addTraverseParsimony(tr, q, q1->next->next->back, mintrav2 , maxtrav, doAll, FALSE); } if ((q2->number > tr->mxtips)) { addTraverseParsimony(tr, q, q2->next->back, mintrav2 , maxtrav, doAll, FALSE); addTraverseParsimony(tr, q, q2->next->next->back, mintrav2 , maxtrav, doAll, FALSE); } hookupDefault(q->next, q1, tr->numBranches); hookupDefault(q->next->next, q2, tr->numBranches); newviewParsimony(tr, q); } } return 1; }
static void testInsertParsimony (tree *tr, nodeptr p, nodeptr q, boolean saveBranches) { unsigned int mp; nodeptr r = q->back; boolean doIt = TRUE; if(tr->grouped) { int rNumber = tr->constraintVector[r->number], qNumber = tr->constraintVector[q->number], pNumber = tr->constraintVector[p->number]; doIt = FALSE; if(pNumber == -9) pNumber = checkerPars(tr, p->back); if(pNumber == -9) doIt = TRUE; else { if(qNumber == -9) qNumber = checkerPars(tr, q); if(rNumber == -9) rNumber = checkerPars(tr, r); if(pNumber == rNumber || pNumber == qNumber) doIt = TRUE; } } if(doIt) { double z[NUM_BRANCHES]; if(saveBranches) { int i; for(i = 0; i < tr->numBranches; i++) z[i] = q->z[i]; } insertParsimony(tr, p, q); mp = evaluateParsimony(tr, p->next->next, FALSE); if(mp < tr->bestParsimony) { tr->bestParsimony = mp; tr->insertNode = q; tr->removeNode = p; } if(saveBranches) hookup(q, r, z, tr->numBranches); else hookupDefault(q, r, tr->numBranches); p->next->next->back = p->next->back = (nodeptr) NULL; } return; }
static boolean addElementLenString(const char *fp, tree *tr, nodeptr p, int *position) { nodeptr q; int n, fres; char ch; if ((ch = fp[(*position)++]) == '(') { n = (tr->nextnode)++; if (n > 2*(tr->mxtips) - 2) { if (tr->rooted || n > 2*(tr->mxtips) - 1) { printf("ERROR: Too many internal nodes. Is tree rooted?\n"); printf(" Deepest splitting should be a trifurcation.\n"); return FALSE; } else { tr->rooted = TRUE; } } q = tr->nodep[n]; if (!addElementLenString(fp, tr, q->next, position)) return FALSE; if (!treeNeedString(fp, ',', position)) return FALSE; if (!addElementLenString(fp, tr, q->next->next, position)) return FALSE; if (!treeNeedString(fp, ')', position)) return FALSE; treeFlushLabelString(fp, position); } else { (*position)--; if ((n = treeFindTipNameString(fp, tr, position)) <= 0) return FALSE; q = tr->nodep[n]; if (tr->start->number > n) tr->start = q; (tr->ntips)++; } fres = treeFlushLenString(fp, position); if(!fres) return FALSE; hookupDefault(p, q, tr->numBranches); return TRUE; }
static boolean addElementLen (FILE *fp, tree *tr, nodeptr p, boolean readBranchLengths, boolean readNodeLabels, int *lcount, analdef *adef, boolean storeBranchLabels) { nodeptr q; int n, ch, fres; if ((ch = treeGetCh(fp)) == '(') { n = (tr->nextnode)++; if (n > 2*(tr->mxtips) - 2) { if (tr->rooted || n > 2*(tr->mxtips) - 1) { printf("ERROR: Too many internal nodes. Is tree rooted?\n"); printf(" Deepest splitting should be a trifurcation.\n"); return FALSE; } else { if(readNodeLabels) { printf("The program will exit with an error in the next source code line\n"); printf("You are probably trying to read in rooted trees with a RAxML option \n"); printf("that for some reason expects unrooted binary trees\n\n"); } assert(!readNodeLabels); tr->rooted = TRUE; } } q = tr->nodep[n]; if (! addElementLen(fp, tr, q->next, readBranchLengths, readNodeLabels, lcount, adef, storeBranchLabels)) return FALSE; if (! treeNeedCh(fp, ',', "in")) return FALSE; if (! addElementLen(fp, tr, q->next->next, readBranchLengths, readNodeLabels, lcount, adef, storeBranchLabels)) return FALSE; if (! treeNeedCh(fp, ')', "in")) return FALSE; if(readNodeLabels) { char label[64]; int support; if(treeGetLabel (fp, label, 10)) { int val = sscanf(label, "%d", &support); assert(val == 1); /*printf("LABEL %s Number %d\n", label, support);*/ p->support = q->support = support; /*printf("%d %d %d %d\n", p->support, q->support, p->number, q->number);*/ assert(p->number > tr->mxtips && q->number > tr->mxtips); *lcount = *lcount + 1; } } else (void) treeFlushLabel(fp); } else { ungetc(ch, fp); if ((n = treeFindTipName(fp, tr, TRUE)) <= 0) return FALSE; q = tr->nodep[n]; if (tr->start->number > n) tr->start = q; (tr->ntips)++; } if(readBranchLengths) { double branch; int startCounter = tr->branchLabelCounter, endCounter, branchLabel = -1; if (! treeNeedCh(fp, ':', "in")) return FALSE; if (! treeProcessLength(fp, &branch, &branchLabel, storeBranchLabels, tr)) return FALSE; endCounter = tr->branchLabelCounter; /*printf("Branch %8.20f %d\n", branch, tr->numBranches);*/ if(adef->mode == CLASSIFY_ML) { double x[NUM_BRANCHES]; assert(tr->NumberOfModels == 1); assert(adef->useBinaryModelFile); assert(tr->numBranches == 1); x[0] = exp(-branch / tr->fracchange); hookup(p, q, x, tr->numBranches); } else hookup(p, q, &branch, tr->numBranches); if(storeBranchLabels && (endCounter > startCounter)) { assert(!isTip(p->number, tr->mxtips) && !isTip(q->number, tr->mxtips)); assert(branchLabel >= 0); p->support = q->support = branchLabel; } } else { fres = treeFlushLen(fp, tr); if(!fres) return FALSE; hookupDefault(p, q, tr->numBranches); } return TRUE; }
int readMultifurcatingTree(FILE *fp, tree *tr, analdef *adef) { nodeptr p, initial_p; int innerNodeNumber, innerBranches = 0, nextnode, i, ch, tips = tr->mxtips, inter = tr->mxtips - 1; //clean up before parsing ! for (i = 1; i < tips + 3 * inter; i++) { tr->nodep[i]->back = (node *) NULL; tr->nodep[i]->next = (node *) NULL; tr->nodep[i]->x = 0; } for(i = tips + 1; i < tips + 3 * inter; i++) tr->nodep[i]->number = i; tr->ntips = 0; nextnode = tr->mxtips + 1; while((ch = treeGetCh(fp)) != '('); i = 0; do { if(i == 0) { nextNodeOutOfBounds(tr, nextnode); initial_p = p = tr->nodep[nextnode]; nextnode++; } else { nextNodeOutOfBounds(tr, nextnode); p->next = tr->nodep[nextnode]; p = p->next; nextnode++; } addMultifurcation(fp, tr, p, adef, &nextnode); i++; } while((ch = treeGetCh(fp)) == ','); if(i < 2) assert(0); else { if(i == 2) { nodeptr q = initial_p->back, r = initial_p->next->back; //printBothOpen("you provided a rooted tree, we need an unrooted one, RAxML will remove the root!\n"); assert(initial_p->next->next == (node *)NULL); assert(tr->start != initial_p); assert(tr->start != initial_p->next); assert(tr->start->back != initial_p); assert(tr->start->back != initial_p->next); hookupDefault(q, r, tr->numBranches); } } /* if(i < 3) { printBothOpen("You need to provide unrooted input trees!\n"); assert(0); } */ ungetc(ch, fp); if(i > 2) p->next = initial_p; if (! treeNeedCh(fp, ')', "in")) assert(0); (void)treeFlushLabel(fp); if (! treeFlushLen(fp, tr)) assert(0); if (! treeNeedCh(fp, ';', "at end of")) assert(0); //printf("%d tips found, %d inner nodes used start %d maxtips %d\n", tr->ntips, nextnode - tr->mxtips, tr->start->number, tr->mxtips); assert(isTip(tr->start->number, tr->mxtips)); innerNodeNumber = tr->mxtips + 1; relabelInnerNodes(tr->start->back, tr, &innerNodeNumber, &innerBranches); //printf("Inner node number: %d\n", innerNodeNumber); //printf("Inner branches %d\n", innerBranches); if(0) { printf("("); printMultiFurc(tr->start, tr); printf(","); printMultiFurc(tr->start->back, tr); printf(");\n"); } return innerBranches; }
static boolean addElementLenMULT (FILE *fp, tree *tr, nodeptr p, int partitionCounter) { nodeptr q, r, s; int n, ch, fres, rn; double randomResolution; int old; tr->constraintVector[p->number] = partitionCounter; if ((ch = treeGetCh(fp)) == '(') { partCount++; old = partCount; n = (tr->nextnode)++; if (n > 2*(tr->mxtips) - 2) { if (tr->rooted || n > 2*(tr->mxtips) - 1) { printf("ERROR: Too many internal nodes. Is tree rooted?\n"); printf(" Deepest splitting should be a trifurcation.\n"); return FALSE; } else { tr->rooted = TRUE; } } q = tr->nodep[n]; tr->constraintVector[q->number] = partCount; if (! addElementLenMULT(fp, tr, q->next, old)) return FALSE; if (! treeNeedCh(fp, ',', "in")) return FALSE; if (! addElementLenMULT(fp, tr, q->next->next, old)) return FALSE; hookupDefault(p, q, tr->numBranches); while((ch = treeGetCh(fp)) == ',') { n = (tr->nextnode)++; if (n > 2*(tr->mxtips) - 2) { if (tr->rooted || n > 2*(tr->mxtips) - 1) { printf("ERROR: Too many internal nodes. Is tree rooted?\n"); printf(" Deepest splitting should be a trifurcation.\n"); return FALSE; } else { tr->rooted = TRUE; } } r = tr->nodep[n]; tr->constraintVector[r->number] = partCount; rn = randomInt(10000); if(rn == 0) randomResolution = 0; else randomResolution = ((double)rn)/10000.0; if(randomResolution < 0.5) { s = q->next->back; r->back = q->next; q->next->back = r; r->next->back = s; s->back = r->next; addElementLenMULT(fp, tr, r->next->next, old); } else { s = q->next->next->back; r->back = q->next->next; q->next->next->back = r; r->next->back = s; s->back = r->next; addElementLenMULT(fp, tr, r->next->next, old); } } if(ch != ')') { printf("Missing /) in treeReadLenMULT\n"); exit(-1); } (void) treeFlushLabel(fp); } else { ungetc(ch, fp); if ((n = treeFindTipName(fp, tr, TRUE)) <= 0) return FALSE; q = tr->nodep[n]; tr->constraintVector[q->number] = partitionCounter; if (tr->start->number > n) tr->start = q; (tr->ntips)++; hookupDefault(p, q, tr->numBranches); } fres = treeFlushLen(fp, tr); if(!fres) return FALSE; return TRUE; }
static boolean addElementLen (FILE *fp, tree *tr, nodeptr p, boolean readBranchLengths, boolean readNodeLabels, int *lcount) { nodeptr q; int n, ch, fres; if ((ch = treeGetCh(fp)) == '(') { n = (tr->nextnode)++; if (n > 2*(tr->mxtips) - 2) { if (tr->rooted || n > 2*(tr->mxtips) - 1) { printf("ERROR: Too many internal nodes. Is tree rooted?\n"); printf(" Deepest splitting should be a trifurcation.\n"); return FALSE; } else { assert(!readNodeLabels); tr->rooted = TRUE; } } q = tr->nodep[n]; if (! addElementLen(fp, tr, q->next, readBranchLengths, readNodeLabels, lcount)) return FALSE; if (! treeNeedCh(fp, ',', "in")) return FALSE; if (! addElementLen(fp, tr, q->next->next, readBranchLengths, readNodeLabels, lcount)) return FALSE; if (! treeNeedCh(fp, ')', "in")) return FALSE; if(readNodeLabels) { char label[64]; int support; if(treeGetLabel (fp, label, 10)) { int val = sscanf(label, "%d", &support); assert(val == 1); /*printf("LABEL %s Number %d\n", label, support);*/ /*p->support = q->support = support;*/ /*printf("%d %d %d %d\n", p->support, q->support, p->number, q->number);*/ assert(p->number > tr->mxtips && q->number > tr->mxtips); *lcount = *lcount + 1; } } else (void) treeFlushLabel(fp); } else { ungetc(ch, fp); if ((n = treeFindTipName(fp, tr)) <= 0) return FALSE; q = tr->nodep[n]; if (tr->start->number > n) tr->start = q; (tr->ntips)++; } if(readBranchLengths) { double branch; if (! treeNeedCh(fp, ':', "in")) return FALSE; if (! treeProcessLength(fp, &branch)) return FALSE; /*printf("Branch %8.20f %d\n", branch, tr->numBranches);*/ hookup(p, q, &branch, tr->numBranches); } else { fres = treeFlushLen(fp); if(!fres) return FALSE; hookupDefault(p, q, tr->numBranches); } return TRUE; }
static nodeptr uprootTree (tree *tr, nodeptr p, boolean readBranchLengths, boolean readConstraint) { nodeptr q, r, s, start; int n, i; for(i = tr->mxtips + 1; i < 2 * tr->mxtips - 1; i++) assert(i == tr->nodep[i]->number); if(isTip(p->number, tr->mxtips) || p->back) { printf("ERROR: Unable to uproot tree.\n"); printf(" Inappropriate node marked for removal.\n"); assert(0); } assert(p->back == (nodeptr)NULL); tr->nextnode = tr->nextnode - 1; assert(tr->nextnode < 2 * tr->mxtips); n = tr->nextnode; assert(tr->nodep[tr->nextnode]); if (n != tr->mxtips + tr->ntips - 1) { printf("ERROR: Unable to uproot tree. Inconsistent\n"); printf(" number of tips and nodes for rooted tree.\n"); assert(0); } q = p->next->back; /* remove p from tree */ r = p->next->next->back; assert(p->back == (nodeptr)NULL); if(readBranchLengths) { double b[NUM_BRANCHES]; int i; for(i = 0; i < tr->numBranches; i++) b[i] = (r->z[i] + q->z[i]); hookup (q, r, b, tr->numBranches); } else hookupDefault(q, r, tr->numBranches); if(readConstraint && tr->grouped) { if(tr->constraintVector[p->number] != 0) { printf("Root node to remove should have top-level grouping of 0\n"); assert(0); } } assert(!(isTip(r->number, tr->mxtips) && isTip(q->number, tr->mxtips))); assert(p->number > tr->mxtips); if(tr->ntips > 2 && p->number != n) { q = tr->nodep[n]; /* transfer last node's conections to p */ r = q->next; s = q->next->next; if(readConstraint && tr->grouped) tr->constraintVector[p->number] = tr->constraintVector[q->number]; hookup(p, q->back, q->z, tr->numBranches); /* move connections to p */ hookup(p->next, r->back, r->z, tr->numBranches); hookup(p->next->next, s->back, s->z, tr->numBranches); q->back = q->next->back = q->next->next->back = (nodeptr) NULL; } else p->back = p->next->back = p->next->next->back = (nodeptr) NULL; assert(tr->ntips > 2); start = findAnyTip(tr->nodep[tr->mxtips + 1], tr->mxtips); assert(isTip(start->number, tr->mxtips)); tr->rooted = FALSE; return start; }
void TreeRandomizer::createStepwiseAdditionParsimonyTree(TreeAln &traln, ParallelSetup& pl ) { auto *tr = &(traln.getTrHandle()); auto *pr = &(traln.getPartitionsHandle()); assert(tr->fastParsimony == PLL_FALSE); nodeptr p, f; int nextsp; auto perm = std::vector<int>(tr->mxtips+1, 0); assert(!tr->constrained); makePermutationFast(perm.data(), tr->mxtips, tr); tr->ntips = 0; tr->nextnode = tr->mxtips + 1; buildSimpleTree(tr, pr, perm[1], perm[2], perm[3]); f = tr->start; while(tr->ntips < tr->mxtips) { nodeptr q; tr->bestParsimony = std::numeric_limits<nat>::max(); nextsp = ++(tr->ntips); p = tr->nodep[perm[nextsp]]; q = tr->nodep[(tr->nextnode)++]; p->back = q; q->back = p; if(tr->grouped) { int number = p->back->number; tr->constraintVector[number] = -9; } stepwiseAddition(tr, pr, q, f->back, pl); // std::cout << SyncOut() << "bestPars: "<< tr->bestParsimony << std::endl; { nodeptr r = tr->insertNode->back; int counter = 4; hookupDefault(q->next, tr->insertNode); hookupDefault(q->next->next, r); computeTraversalInfoParsimony(q, tr->ti, &counter, tr->mxtips, PLL_FALSE); tr->ti[0] = counter; newviewParsimonyIterativeFast(tr, pr); } } }