void BMEcalcNewvAverages(meTree *T, meNode *v, double **D, double **A) { /*loop over edges*/ /*depth-first search*/ meEdge *e; e = NULL; e = depthFirstTraverse(T,e); /*the downward averages need to be calculated from bottom to top */ while(NULL != e) { BMEcalcDownAverage(T,v,e,D,A); e = depthFirstTraverse(T,e); } e = topFirstTraverse(T,e); /*the upward averages need to be calculated from top to bottom */ while(NULL != e) { BMEcalcUpAverage(T,v,e,D,A); e = topFirstTraverse(T,e); } }
meTree *BMEaddSpecies(meTree *T,meNode *v, double **D, double **A) /*the key function of the program addSpeices inserts the meNode v to the meTree T. It uses testEdge to see what the relative weight would be if v split a particular edge. Once insertion point is found, v is added to T, and A is updated. Edge weights are not assigned until entire meTree is build*/ { meTree *T_e; meEdge *e; /*loop variable*/ meEdge *e_min; /*points to best meEdge seen thus far*/ double w_min = 0.0; /*used to keep track of meTree weights*/ /*initialize variables as necessary*/ /*CASE 1: T is empty, v is the first node*/ if (NULL == T) /*create a meTree with v as only vertex, no edges*/ { T_e = newTree(); T_e->root = v; /*note that we are rooting T arbitrarily at a leaf. T->root is not the phylogenetic root*/ v->index = 0; T_e->size = 1; return(T_e); } /*CASE 2: T is a single-vertex tree*/ if (1 == T->size) { v->index = 1; e = makeEdge("",T->root,v,0.0); sprintf(e->label,"E1"); A[v->index][v->index] = D[v->index2][T->root->index2]; T->root->leftEdge = v->parentEdge = e; T->size = 2; return(T); } /*CASE 3: T has at least two nodes and an edge. Insert new node by breaking one of the edges*/ v->index = T->size; BMEcalcNewvAverages(T,v,D,A); /*calcNewvAverages will update A for the row and column include the meNode v. Will do so using pre-existing averages in T and information from A,D*/ e_min = T->root->leftEdge; e = e_min->head->leftEdge; while (NULL != e) { BMEtestEdge(e,v,A); /*testEdge tests weight of meTree if loop variable e is the meEdge split, places this value in the e->totalweight field */ if (e->totalweight < w_min) { e_min = e; w_min = e->totalweight; } e = topFirstTraverse(T,e); } /*e_min now points at the meEdge we want to split*/ if (verbose) printf("Inserting %s between %s and %s on %s\n",v->label,e_min->tail->label, e_min->head->label,e_min->label); BMEsplitEdge(T,v,e_min,A); return(T); }
void NNIupdateAverages(double **A, edge *e, edge *par, edge *skew, edge *swap, edge *fixed, tree *T) { node *v; edge *elooper; v = e->head; /*first, v*/ A[e->head->index][e->head->index] = (swap->bottomsize* ((skew->bottomsize*A[skew->head->index][swap->head->index] + fixed->bottomsize*A[fixed->head->index][swap->head->index]) / e->bottomsize) + par->topsize* ((skew->bottomsize*A[skew->head->index][par->head->index] + fixed->bottomsize*A[fixed->head->index][par->head->index]) / e->bottomsize) ) / e->topsize; elooper = findBottomLeft(e); /*next, we loop over all the edges which are below e*/ while (e != elooper) { A[e->head->index][elooper->head->index] = A[elooper->head->index][v->index] = (swap->bottomsize*A[elooper->head->index][swap->head->index] + par->topsize*A[elooper->head->index][par->head->index]) / e->topsize; elooper = depthFirstTraverse(T,elooper); } elooper = findBottomLeft(swap); /*next we loop over all the edges below and including swap*/ while (swap != elooper) { A[e->head->index][elooper->head->index] = A[elooper->head->index][e->head->index] = (skew->bottomsize * A[elooper->head->index][skew->head->index] + fixed->bottomsize*A[elooper->head->index][fixed->head->index]) / e->bottomsize; elooper = depthFirstTraverse(T,elooper); } /*now elooper = skew */ A[e->head->index][elooper->head->index] = A[elooper->head->index][e->head->index] = (skew->bottomsize * A[elooper->head->index][skew->head->index] + fixed->bottomsize* A[elooper->head->index][fixed->head->index]) / e->bottomsize; /*finally, we loop over all the edges in the tree on the far side of parEdge*/ elooper = T->root->leftEdge; while ((elooper != swap) && (elooper != e)) /*start a top-first traversal*/ { A[e->head->index][elooper->head->index] = A[elooper->head->index][e->head->index] = (skew->bottomsize * A[elooper->head->index][skew->head->index] + fixed->bottomsize* A[elooper->head->index][fixed->head->index]) / e->bottomsize; elooper = topFirstTraverse(T,elooper); } /*At this point, elooper = par. We finish the top-first traversal, excluding the subtree below par*/ elooper = moveUpRight(par); while (NULL != elooper) { A[e->head->index][elooper->head->index] = A[elooper->head->index][e->head->index] = (skew->bottomsize * A[elooper->head->index][skew->head->index] + fixed->bottomsize* A[elooper->head->index][fixed->head->index]) / e->bottomsize; elooper = topFirstTraverse(T,elooper); } }