static void setupBranchInfo(nodeptr p, tree *tr, int *counter) { if(!isTip(p->number, tr->mxtips)) { nodeptr q; if(!(isTip(p->back->number, tr->mxtips))) { p->bInf = p->back->bInf = &(tr->bInf[*counter]); p->bInf->oP = p; p->bInf->oQ = p->back; *counter = *counter + 1; } q = p->next; while(q != p) { setupBranchInfo(q->back, tr, counter); q = q->next; } return; } }
static nodeptr selectRandomSubtree(tree *tr) { nodeptr p; do { int exitDirection = rand() % 3; p = tr->nodep[(rand() % (tr->mxtips - 2)) + 1 + tr->mxtips]; switch(exitDirection) { case 0: break; case 1: p = p->next; break; case 2: p = p->next->next; break; default: assert(0); } } while(isTip(p->next->back->number, tr->mxtips) && isTip(p->next->next->back->number, tr->mxtips)); assert(!isTip(p->number, tr->mxtips)); return p; }
static void relabelInnerNodes(nodeptr p, tree *tr, int *number, int *nodeCounter) { if(isTip(p->number, tr->mxtips)) { assert(0); } else { nodeptr q = p->next; int _n = *number; tr->nodep[p->number]->number = _n; p->x = 1; *number = *number + 1; while(q != p) { tr->nodep[q->number]->number = _n; q->x = 0; if(!isTip(q->back->number, tr->mxtips)) { *nodeCounter = *nodeCounter + 1; relabelInnerNodes(q->back, tr, number, nodeCounter); } q = q->next; } } }
void nniSmooth(tree *tr, nodeptr p, int maxtimes) { int i; for(i = 0; i < tr->numBranches; i++) tr->partitionConverged[i] = FALSE; while (--maxtimes >= 0) { for(i = 0; i < tr->numBranches; i++) tr->partitionSmoothed[i] = TRUE; assert(!isTip(p->number, tr->mxtips)); assert(!isTip(p->back->number, tr->mxtips)); update(tr, p); update(tr, p->next); update(tr, p->next->next); update(tr, p->back->next); update(tr, p->back->next->next); if (allSmoothed(tr)) break; } for(i = 0; i < tr->numBranches; i++) { tr->partitionSmoothed[i] = FALSE; tr->partitionConverged[i] = FALSE; } }
static nodeptr selectRandomInnerSubtree(tree *tr) { nodeptr p; int pruned_id; do { pruned_id = (rand() % (tr->mxtips - 2)) + 1 + tr->mxtips ; assert(pruned_id > tr->mxtips); assert(pruned_id <= 2*tr->mxtips - 2); p = tr->nodep[pruned_id]; } while(isTip(p->next->back->number, tr->mxtips) && isTip(p->next->next->back->number, tr->mxtips)); //printBothOpen("Selected %db%d to prune\n", p->number, p->back->number); return p; }
static char *pllTreeToNewickRecomREC(char *treestr, tree *tr, nodeptr q, boolean printBranchLengths) { char *nameptr; double z; nodeptr p = q; int slot; if(isTip(p->number, tr->mxtips)) { nameptr = tr->nameList[p->number]; sprintf(treestr, "%s", nameptr); while (*treestr) treestr++; } else { while(!p->x) p = p->next; *treestr++ = '('; treestr = pllTreeToNewickRecomREC(treestr, tr, q->next->back, printBranchLengths); *treestr++ = ','; treestr = pllTreeToNewickRecomREC(treestr, tr, q->next->next->back, printBranchLengths); if(q == tr->start->back) { *treestr++ = ','; treestr = pllTreeToNewickRecomREC(treestr, tr, q->back, printBranchLengths); } *treestr++ = ')'; // write innernode as nodenum_b_nodenumback sprintf(treestr, "%d", q->number); while (*treestr) treestr++; *treestr++ = 'b'; sprintf(treestr, "%d", p->back->number); while (*treestr) treestr++; } if(q == tr->start->back) { if(printBranchLengths) sprintf(treestr, ":0.0;\n"); else sprintf(treestr, ";\n"); } else { if(printBranchLengths) { //sprintf(treestr, ":%8.20f", getBranchLength(tr, SUMMARIZE_LH, p)); assert(tr->fracchange != -1.0); z = q->z[0]; if (z < zmin) z = zmin; sprintf(treestr, ":%8.20f", -log(z) * tr->fracchange); } else sprintf(treestr, "%s", "\0"); } while (*treestr) treestr++; return treestr; }
static int findRec(nodeptr ref, nodeptr best, int mxtips, int value) { if(isTip(ref->number, mxtips)) { if(ref == best || ref->back == best) return value; else return 0; } else { int d1, d2; if(ref == best || ref->back == best) return value; d1 = findRec(ref->next->back, best, mxtips, value + 1); d2 = findRec(ref->next->next->back, best, mxtips, value + 1); assert((d1 > 0 && d2 == 0) || (d2 > 0 && d1 == 0) || (d1 == 0 && d2 == 0)); return (d1 + d2); } }
static void saveTopolRELLRec(tree *tr, nodeptr p, topolRELL *tpl, int *i, int numsp, int numBranches) { int k; if(isTip(p->number, numsp)) return; else { nodeptr q = p->next; while(q != p) { tpl->connect[*i].p = q; tpl->connect[*i].q = q->back; if(tr->constraintTree) { tpl->connect[*i].cp = tr->constraintVector[q->number]; tpl->connect[*i].cq = tr->constraintVector[q->back->number]; } for(k = 0; k < numBranches; k++) tpl->connect[*i].z[k] = q->z[k]; *i = *i + 1; saveTopolRELLRec(tr, q->back, tpl, i, numsp, numBranches); q = q->next; } } }
static void printMultiFurc(nodeptr p, tree *tr) { if(isTip(p->number, tr->mxtips)) { printf("%s", tr->nameList[p->number]); } else { nodeptr q = p->next; printf("("); while(q != p) { printMultiFurc(q->back, tr); q = q->next; if(q != p) printf(","); } printf(")"); } }
static void setupMask(unsigned int *smallTreeMask, nodeptr p, int numsp) { if(isTip(p->number, numsp)) smallTreeMask[(p->number - 1) / MASK_LENGTH] |= mask32[(p->number - 1) % MASK_LENGTH]; else { nodeptr q = p->next; /* I had to change this function to account for mult-furcating trees. In this case an inner node can have more than 3 cyclically linked elements, because there might be more than 3 outgoing branches from an inner node */ while(q != p) { setupMask(smallTreeMask, q->back, numsp); q = q->next; } //old code below //setupMask(smallTreeMask, p->next->back, numsp); //setupMask(smallTreeMask, p->next->next->back, numsp); } }
static void reorderNodes(tree *tr, nodeptr *np, nodeptr p, int *count) { int i, found = 0; if(isTip(p->number, tr->mxtips)) return; else { for(i = tr->mxtips + 1; (i <= (tr->mxtips + tr->mxtips - 1)) && (found == 0); i++) { if (p == np[i] || p == np[i]->next || p == np[i]->next->next) { if(p == np[i]) tr->nodep[*count + tr->mxtips + 1] = np[i]; else { if(p == np[i]->next) tr->nodep[*count + tr->mxtips + 1] = np[i]->next; else tr->nodep[*count + tr->mxtips + 1] = np[i]->next->next; } found = 1; *count = *count + 1; } } assert(found != 0); reorderNodes(tr, np, p->next->back, count); reorderNodes(tr, np, p->next->next->back, count); } }
unsigned long maxorderEffective(node n) // the maximum number of nodes between this node and a descendant tip // corrected in case of internal named node { unsigned long max,temp; node child; if (!n) return(-1); if (isTip(n) ) {n->order=0; return (0);} else { if (n->isCompactNode) { n->order=0; return 0; } max=0; child=n->firstdesc; SIBLOOP(child) { temp=maxorderEffective(child); if (temp > max) max = temp; } n->order=max+1; return (max+1); } }
static void saveTopolRELLRec(pllInstance *tr, nodeptr p, topolRELL *tpl, int *i, int numsp) { int k; if(isTip(p->number, numsp)) return; else { nodeptr q = p->next; while(q != p) { tpl->connect[*i].p = q; tpl->connect[*i].q = q->back; if(tr->grouped || tr->constrained) { tpl->connect[*i].cp = tr->constraintVector[q->number]; tpl->connect[*i].cq = tr->constraintVector[q->back->number]; } for(k = 0; k < PLL_NUM_BRANCHES; k++) tpl->connect[*i].z[k] = q->z[k]; *i = *i + 1; saveTopolRELLRec(tr, q->back, tpl, i, numsp); q = q->next; } } }
static nodeptr pickMyRandomSubtree(pllInstance *tr) { nodeptr p; //do { /* select a random inner node */ p = tr->nodep[(rand() % (tr->mxtips - 2)) + 1 + tr->mxtips]; /* select a random orientation */ int exitDirection = rand() % 3; switch(exitDirection) { case 0: break; case 1: p = p->next; break; case 2: p = p->next->next; break; default: assert(0); } } //while(isTip(p->next->back->number, tr->mxtips) && isTip(p->next->next->back->number, tr->mxtips)); assert(!isTip(p->number, tr->mxtips)); return p; }
boolean regionalSmooth (tree *tr, nodeptr p, int maxtimes, int region) { nodeptr q; int i; if (isTip(p->number, tr->rdta->numsp)) return FALSE; /* Should be an error */ for(i = 0; i < tr->numBranches; i++) tr->partitionConverged[i] = FALSE; while (--maxtimes >= 0) { for(i = 0; i < tr->numBranches; i++) tr->partitionSmoothed[i] = TRUE; q = p; do { if (! smoothRegion(tr, q, region)) return FALSE; q = q->next; } while (q != p); if (allSmoothed(tr)) break; } for(i = 0; i < tr->numBranches; i++) tr->partitionSmoothed[i] = FALSE; for(i = 0; i < tr->numBranches; i++) tr->partitionConverged[i] = FALSE; return TRUE; } /* localSmooth */
static int checkerPars(tree *tr, nodeptr p) { int group = tr->constraintVector[p->number]; if(isTip(p->number, tr->mxtips)) { group = tr->constraintVector[p->number]; return group; } else { if(group != -9) return group; group = checkerPars(tr, p->next->back); if(group != -9) return group; group = checkerPars(tr, p->next->next->back); if(group != -9) return group; return -9; } }
boolean localSmooth (tree *tr, nodeptr p, int maxtimes) { nodeptr q; int i; if (isTip(p->number, tr->rdta->numsp)) return FALSE; for(i = 0; i < tr->numBranches; i++) tr->partitionConverged[i] = FALSE; while (--maxtimes >= 0) { for(i = 0; i < tr->numBranches; i++) tr->partitionSmoothed[i] = TRUE; q = p; do { if (! update(tr, q)) return FALSE; q = q->next; } while (q != p); if (allSmoothed(tr)) break; } for(i = 0; i < tr->numBranches; i++) { tr->partitionSmoothed[i] = FALSE; tr->partitionConverged[i] = FALSE; } return TRUE; }
unsigned long numdescEffective(node n) // Determine number of descendant leaves, counting any compact node as a leaf and neglecting it's descendeants // This version does traverses from root down through compact nodes and out to leaves. // It stores the actual value of numdescEffective at those compact nodes--rather than 1. // OK, I think this f*****g finally handles leaves, internal nodes, etc. correctly. // NEED TO DO SAME FOR NUMDESC #if 0 { unsigned long sum=0; node child; if (!n) return(-1); if (isTip(n)) { // n->numdescEffective=1; n->numdescEffective=0; return (1); } child=n->firstdesc; SIBLOOP(child) sum+=numdescEffective(child); n->numdescEffective=sum; if (n->isCompactNode) return 1; else return sum; }
static int subtreeSize(nodeptr p, int maxTips) { if(isTip(p->number, maxTips)) return 1; else return (subtreeSize(p->next->back, maxTips) + subtreeSize(p->next->next->back, maxTips)); }
void bitVectorInitravSpecial(unsigned int **bitVectors, nodeptr p, int numsp, unsigned int vectorLength, hashtable *h, int treeNumber, int function, branchInfo *bInf, int *countBranches, int treeVectorLength, boolean traverseOnly, boolean computeWRF) { if(isTip(p->number, numsp)) return; else { nodeptr q = p->next; do { bitVectorInitravSpecial(bitVectors, q->back, numsp, vectorLength, h, treeNumber, function, bInf, countBranches, treeVectorLength, traverseOnly, computeWRF); q = q->next; } while(q != p); newviewBipartitions(bitVectors, p, numsp, vectorLength); assert(p->xBips); assert(!traverseOnly); if(!(isTip(p->back->number, numsp))) { unsigned int *toInsert = bitVectors[p->number]; hashNumberType position = p->hash % h->tableSize; assert(!(toInsert[0] & 1)); assert(!computeWRF); switch(function) { case BIPARTITIONS_RF: insertHashRF(toInsert, h, vectorLength, treeNumber, treeVectorLength, position, 0, computeWRF); *countBranches = *countBranches + 1; break; default: assert(0); } } } }
static void addRecBL(nodeptr p, BL *b, int number, int modulo, int numberOfTips, int numsp) { if(/*p->tip*/ isTip(p->number, numsp)) return; { nodeptr q; if(/*!p->back->tip*/ ! isTip(p->back->number, numsp)) { int *entries; int length = 0; int l, r; l = countTips(p, numsp); if(l < ((numberOfTips/2) + 1)) { entries = (int *)malloc(l * sizeof(int)); getTips(p, &length, entries, numsp); } else { r = numberOfTips - l; entries = (int *)malloc(r * sizeof(int)); getTips(p->back, &length, entries, numsp); } qsort(entries, length, sizeof(int), intCompare); { double t = gettime(); addBipartitionsFaster(b, number, entries, length, modulo); addTime += (gettime() - t); } free(entries); } q = p->next; while(q != p) { addRecBL(q->back, b, number, modulo, numberOfTips, numsp); q = q->next; } return; } }
static void update_all_branches(state * s, boolean resetBL) { int updated_branches = 0; assert(isTip(s->tr->start->number, s->tr->mxtips)); /* visit each branch exactly once */ traverse_branches(s->tr->start->back, &updated_branches, s, resetBL); assert(updated_branches == s->tr->mxtips + s->tr->mxtips - 3); }
static double evaluatePartialGTRCAT(int i, double ki, int counter, traversalInfo *ti, double qz, int w, double *EIGN, double *EI, double *EV, double *tipVector, unsigned char **yVector, int branchReference, int mxtips) { double lz, term; double d[3]; double *x1, *x2; int scale = 0, k; double *lVector = (double *)malloc_aligned(sizeof(double) * 4 * mxtips); traversalInfo *trav = &ti[0]; assert(isTip(trav->pNumber, mxtips)); x1 = &(tipVector[4 * yVector[trav->pNumber][i]]); for(k = 1; k < counter; k++) { double qz = ti[k].qz[branchReference], rz = ti[k].rz[branchReference]; qz = (qz > zmin) ? log(qz) : log(zmin); rz = (rz > zmin) ? log(rz) : log(zmin); computeVectorGTRCAT(lVector, &scale, ki, i, qz, rz, &ti[k], EIGN, EI, EV, tipVector, yVector, mxtips); } x2 = &lVector[4 * (trav->qNumber - mxtips)]; assert(0 <= (trav->qNumber - mxtips) && (trav->qNumber - mxtips) < mxtips); if(qz < zmin) lz = zmin; lz = log(qz); lz *= ki; d[0] = EXP (EIGN[1] * lz); d[1] = EXP (EIGN[2] * lz); d[2] = EXP (EIGN[3] * lz); term = x1[0] * x2[0]; term += x1[1] * x2[1] * d[0]; term += x1[2] * x2[2] * d[1]; term += x1[3] * x2[3] * d[2]; term = LOG(FABS(term)) + (scale * LOG(minlikelihood)); term = term * w; free(lVector); return term; }
static void makeBipartitionsRec(nodeptr p, bList *blThis, int *bCountThis, int numsp) { if(/*p->tip*/ isTip(p->number, numsp)) return; { nodeptr q; int l, r; int c; if(/*!p->back->tip*/ ! isTip(p->back->number, numsp)) { l = countTips(p, numsp); r = countTips(p->back, numsp); c = 0; if(l < r) { blThis[*bCountThis].entries = (int *)malloc(l * sizeof(int)); getTips(p, &c, blThis[*bCountThis].entries, numsp); } else { blThis[*bCountThis].entries = (int *)malloc(r * sizeof(int)); getTips(p->back, &c, blThis[*bCountThis].entries, numsp); } blThis[*bCountThis].length = c; qsort((blThis[*bCountThis].entries), c, sizeof(int), intCompare); blThis[*bCountThis].p = p; blThis[*bCountThis].pNum = p->number; blThis[*bCountThis].qNum = p->back->number; *bCountThis = *bCountThis + 1; } q = p->next; while(q != p) { makeBipartitionsRec(q->back, blThis, bCountThis, numsp); q = q->next; } return; } }
static void naiveInsertionProposal(state *s) { int list_size = 0; if(!isTip(s->nb->number, s->tr->mxtips)) { nodeVisitor(s->nb->next->back, s->tr->mxtips, 1, s->maxradius, s->list, &list_size); nodeVisitor(s->nb->next->next->back, s->tr->mxtips, 1, s->maxradius, s->list, &list_size); } if(!isTip(s->nnb->number, s->tr->mxtips)) { nodeVisitor(s->nnb->next->back, s->tr->mxtips, 1, s->maxradius, s->list, &list_size); nodeVisitor(s->nnb->next->next->back,s->tr->mxtips, 1, s->maxradius, s->list, &list_size); } assert(list_size > 0); s->q = s->list[rand() % list_size]; //printBothOpen(" %d candidates:",list_size); //printBothOpen(" insert at %db%d :",s->q->number, s->q->back->number); assert(s->q != NULL); }
static void nodeVisitor(nodeptr p, int numtips, int radius, int maxradius, nodeptr *list, int *list_size) { //printBothOpen("visited %db%dr%d\n", p->number, p->back->number, radius); if(!isTip(p->back->number,numtips)) { //printBothOpen("Add %db%d\n", p->number, p->back->number); list[*list_size] = p; *list_size += 1; } if(isTip(p->number,numtips) || radius > maxradius) { //printBothOpen(" -r%d\n", radius); return; } else { nodeVisitor(p->next->back, numtips, radius + 1, maxradius, list, list_size); nodeVisitor(p->next->next->back, numtips, radius + 1, maxradius, list, list_size); } return; }
void preOrderVoid(node n,void (*f)(node)) { node child; (*f)(n); if (!isTip(n)) { child=n->firstdesc; SIBLOOP(child) preOrderVoid(child,f); } return ; }
/** @brief Annotes unoriented tree nodes \a tr with their subtree size * * This function recursively updates the subtree size of each inner node. * @note The subtree size of node \a p->number is the number of nodes included in the subtree where node record \a p is the virtual root. * * @param p * Pointer to node * * @param maxTips * Number of tips in the tree * * @param rvec * Recomputation info * * @param count * Number of visited nodes */ void computeTraversalInfoStlen(nodeptr p, int maxTips, recompVectors *rvec, int *count) { if(isTip(p->number, maxTips)) return; else { nodeptr q = p->next->back, r = p->next->next->back; *count += 1; /* set xnode info at this point */ if(isTip(r->number, maxTips) && isTip(q->number, maxTips)) { rvec->stlen[p->number - maxTips - 1] = 2; #ifdef _DEBUG_RECOMPUTATION assert(rvec->stlen[p->number - maxTips - 1] == subtreeSize(p, maxTips)); #endif } else { if(isTip(r->number, maxTips) || isTip(q->number, maxTips)) { nodeptr tmp; if(isTip(r->number, maxTips)) { tmp = r; r = q; q = tmp; } if(!r->x) computeTraversalInfoStlen(r, maxTips, rvec, count); rvec->stlen[p->number - maxTips - 1] = rvec->stlen[r->number - maxTips - 1] + 1; #ifdef _DEBUG_RECOMPUTATION assert(rvec->stlen[p->number - maxTips - 1] == subtreeSize(p, maxTips)); #endif } else { if(!r->x) computeTraversalInfoStlen(r, maxTips, rvec, count); if(!q->x) computeTraversalInfoStlen(q, maxTips, rvec, count); rvec->stlen[p->number - maxTips - 1] = rvec->stlen[q->number - maxTips - 1] + rvec->stlen[r->number - maxTips - 1]; #ifdef _DEBUG_RECOMPUTATION assert(rvec->stlen[p->number - maxTips - 1] == subtreeSize(p, maxTips)); #endif } } } }
double preOrder(node n,double (*f)(node)) { double sum=0; node child; sum+=(*f)(n); if (!isTip(n)) { child=n->firstdesc; SIBLOOP(child) sum += preOrder(child,f); } return (sum); }
static double evaluatePartialGTRCATSECONDARY(int i, double ki, int counter, traversalInfo *ti, double qz, int w, double *EIGN, double *EI, double *EV, double *tipVector, unsigned char **yVector, int branchReference, int mxtips) { double lz, term; double d[16]; double *x1, *x2; int scale = 0, k, l; double *lVector = (double *)rax_malloc(sizeof(double) * 16 * mxtips); traversalInfo *trav = &ti[0]; assert(isTip(trav->pNumber, mxtips)); x1 = &(tipVector[16 * yVector[trav->pNumber][i]]); for(k = 1; k < counter; k++) computeVectorGTRCATSECONDARY(lVector, &scale, ki, i, ti[k].qz[branchReference], ti[k].rz[branchReference], &ti[k], EIGN, EI, EV, tipVector, yVector, mxtips); x2 = &lVector[16 * (trav->qNumber - mxtips)]; assert(0 <= (trav->qNumber - mxtips) && (trav->qNumber - mxtips) < mxtips); if(qz < zmin) lz = zmin; lz = log(qz); lz *= ki; d[0] = 1.0; for(l = 1; l < 16; l++) d[l] = EXP (EIGN[l-1] * lz); term = 0.0; for(l = 0; l < 16; l++) term += x1[l] * x2[l] * d[l]; term = LOG(FABS(term)) + (scale * LOG(minlikelihood)); term = term * w; rax_free(lVector); return term; }