void bNNIRetestEdge(int *p, int *q, meEdge *e,meTree *T, double **avgDistArray, double *weights, int *location, int *possibleSwaps) { int tloc; tloc = location[e->head->index+1]; location[e->head->index+1] = bNNIEdgeTest(e,T,avgDistArray,weights + e->head->index+1); if (NONE == location[e->head->index+1]) { if (NONE != tloc) popHeap(p,q,weights,(*possibleSwaps)--,q[e->head->index+1]); } else { if (NONE == tloc) pushHeap(p,q,weights,(*possibleSwaps)++,q[e->head->index+1]); else reHeapElement(p,q,weights,*possibleSwaps,q[e->head->index+1]); } }
//void bNNI(tree *T, double **avgDistArray, int *count) void bNNI(tree *T, double **avgDistArray, int *count, double **D, int numSpecies) { edge *e;//, *centerEdge deleted by EP, 2013-09-26, see also below edge **edgeArray; int *p, *location, *q; int i,j; int possibleSwaps; double *weights; p = initPerm(T->size+1); q = initPerm(T->size+1); edgeArray = (edge **) malloc((T->size+1)*sizeof(double)); weights = (double *) malloc((T->size+1)*sizeof(double)); location = (int *) malloc((T->size+1)*sizeof(int)); double epsilon = 0.0; for (i=0; i<numSpecies; i++) for (j=0; j<numSpecies; j++) epsilon += D[i][j]; epsilon = (epsilon / (numSpecies * numSpecies)) * EPSILON; for (i=0;i<T->size+1;i++) { weights[i] = 0.0; location[i] = NONE; } /* if (verbose) { assignBMEWeights(T,avgDistArray); weighTree(T); }*/ e = findBottomLeft(T->root->leftEdge); while (NULL != e) { edgeArray[e->head->index+1] = e; location[e->head->index+1] = bNNIEdgeTest(e,T,avgDistArray,weights + e->head->index + 1); e = depthFirstTraverse(T,e); } possibleSwaps = makeThreshHeap(p,q,weights,T->size+1,0.0); permInverse(p,q,T->size+1); /*we put the negative values of weights into a heap, indexed by p with the minimum value pointed to by p[1]*/ /*p[i] is index (in edgeArray) of edge with i-th position in the heap, q[j] is the position of edge j in the heap */ while (weights[p[1]] + epsilon < 0) { /* centerEdge = edgeArray[p[1]]; apparently unused later, deleted by EP, 2013-09-26 */ (*count)++; /* if (verbose) { T->weight = T->weight + weights[p[1]]; printf("New tree weight is %lf.\n",T->weight); }*/ bNNItopSwitch(T,edgeArray[p[1]],location[p[1]],avgDistArray); location[p[1]] = NONE; weights[p[1]] = 0.0; /*after the bNNI, this edge is in optimal configuration*/ popHeap(p,q,weights,possibleSwaps--,1); /*but we must retest the other edges of T*/ /*CHANGE 2/28/2003 expanding retesting to _all_ edges of T*/ e = depthFirstTraverse(T,NULL); while (NULL != e) { bNNIRetestEdge(p,q,e,T,avgDistArray,weights,location,&possibleSwaps); e = depthFirstTraverse(T,e); } } free(p); free(q); free(location); free(edgeArray); free(weights); assignBMEWeights(T,avgDistArray); }
void bNNI(meTree *T, double **avgDistArray, int *count) { meEdge *e, *centerEdge; meEdge **edgeArray; int *p, *location, *q; int i; int possibleSwaps; double *weights; p = initPerm(T->size+1); q = initPerm(T->size+1); edgeArray = (meEdge **) malloc((T->size+1)*sizeof(double)); weights = (double *) malloc((T->size+1)*sizeof(double)); location = (int *) malloc((T->size+1)*sizeof(int)); for (i=0;i<T->size+1;i++) { weights[i] = 0.0; location[i] = NONE; } if (verbose) { assignBalWeights(T,avgDistArray); weighTree(T); } e = findBottomLeft(T->root->leftEdge); while (NULL != e) { edgeArray[e->head->index+1] = e; location[e->head->index+1] = bNNIEdgeTest(e,T,avgDistArray,weights + e->head->index + 1); e = depthFirstTraverse(T,e); } possibleSwaps = makeThreshHeap(p,q,weights,T->size+1,0.0); permInverse(p,q,T->size+1); /*we put the negative values of weights into a heap, indexed by p with the minimum value pointed to by p[1]*/ /*p[i] is index (in edgeArray) of edge with i-th position in the heap, q[j] is the position of edge j in the heap */ /*NOTE: the loop below should test that weights[p[1]] < 0, but if compiled with optimization it is possible that weights[p[1]] ends up negative and very small, so that changes to the heap become cyclic and the loop becomes infinite. To avoid this behavior, stop the loop short of 0.0. This is a workaround until the roundoff sensitivity is removed algorithmically */ while (weights[p[1]] < -1e-8) { centerEdge = edgeArray[p[1]]; (*count)++; if (verbose) { T->weight = T->weight + weights[p[1]]; printf("New tree weight is %lf.\n",T->weight); } bNNItopSwitch(T,edgeArray[p[1]],location[p[1]],avgDistArray); location[p[1]] = NONE; weights[p[1]] = 0.0; /*after the bNNI, this edge is in optimal configuration*/ popHeap(p,q,weights,possibleSwaps--,1); /*but we must retest the other edges of T*/ /*CHANGE 2/28/2003 expanding retesting to _all_ edges of T*/ e = depthFirstTraverse(T,NULL); while (NULL != e) { bNNIRetestEdge(p,q,e,T,avgDistArray,weights,location,&possibleSwaps); e = depthFirstTraverse(T,e); } } free(p); free(q); free(location); free(edgeArray); assignBalWeights(T,avgDistArray); }
void bNNI (tree *T, double **avgDistArray, int *count, FILE *statfile) { edge *e; edge **edgeArray; int *p, *location, *q; int i; int possibleSwaps; double *weights; p = initPerm (T->size+1); q = initPerm (T->size+1); edgeArray = (edge **) mCalloc ((T->size+1), sizeof (edge *)); weights = (double *) mCalloc ((T->size+1), sizeof (double)); location = (int *) mCalloc ((T->size+1), sizeof (int)); for (i=0; i<T->size+1; i++) { weights[i] = 0.0; location[i] = NONE; } assignBMEWeights (T, avgDistArray); weighTree (T); if (!isBoostrap) { if (statfile) fprintf (statfile, "\tBefore NNI: tree length is %f.\n", T->weight); if (verbose > 2) Debug ( (char*)"Before NNI: tree length is %f.", T->weight); else if (verbose > 1) Message ( (char*)". Before NNI: tree length is %f.", T->weight); } e = findBottomLeft (T->root->leftEdge); while (NULL != e) { edgeArray[e->head->index+1] = e; location[e->head->index+1] = bNNIEdgeTest (e, T, avgDistArray, weights + e->head->index + 1); e = depthFirstTraverse (T,e); } possibleSwaps = makeThreshHeap (p, q, weights, T->size+1,0.0); permInverse (p, q, T->size+1); /* We put the negative values of weights into a heap, indexed by p * with the minimum value pointed to by p[1] * p[i] is index (in edgeArray) of edge with i-th position in the * heap, q[j] is the position of edge j in the heap */ while (weights[p[1]] < -DBL_EPSILON) { (*count)++; T->weight = T->weight + weights[p[1]]; if (!isBoostrap) { if (statfile) fprintf (statfile, "\tNNI %5d: new tree length is %f.\n", *count, T->weight); if (verbose > 2) Debug ( (char*)"NNI %5d: new tree length is %f.", *count, T->weight); else if (verbose > 1) Message ( (char*)". NNI %5d: new tree length is %f.", *count, T->weight); } bNNItopSwitch (edgeArray[p[1]], location[p[1]], avgDistArray); location[p[1]] = NONE; weights[p[1]] = 0.0; //after the bNNI, this edge is in optimal configuration popHeap (p, q, weights, possibleSwaps--, 1); /* but we must retest the other edges of T */ /* CHANGE 2/28/2003 expanding retesting to _all_ edges of T */ e = depthFirstTraverse (T, NULL); while (NULL != e) { bNNIRetestEdge (p, q, e, T, avgDistArray, weights, location, &possibleSwaps); e = depthFirstTraverse (T, e); } } free (p); free (q); free (location); free (edgeArray); free (weights); assignBMEWeights (T, avgDistArray); return; }