Пример #1
0
Файл: SPR.c Проект: cran/ape
void assignUpWeights(edge *etest, node *vtest, node *va, edge *back, node *cprev, double oldD_AB, double coeff, double **A,
		     double ***swapWeights)
{
	/*SPR performed on tree above vtest...*/
	/*same idea as above, with appropriate selections of edges and nodes*/
  edge *sib, *left, *right;
  /*B is above vtest, A is other tree below vtest unioned with trees in path to vtest*/
  /*sib is tree C being passed by B*/
  /*D is tree below etest*/
  double D_AB, D_CD, D_AC, D_BD;
  // double thisWeight; deleted by EP, 2013-09-16, also below
  sib = siblingEdge(etest);
  left = etest->head->leftEdge;
  right = etest->head->rightEdge;
  if (NULL == back) /*first recursive call*/
    {
      if (NULL == left)
	return;
      else /*start the process of assigning weights recursively*/
	{
	  assignUpWeights(left,vtest,va,etest,va,A[va->index][vtest->index],0.5,A,swapWeights);
	  assignUpWeights(right,vtest,va,etest,va,A[va->index][vtest->index],0.5,A,swapWeights);
	}
    }
  else /*second or later recursive call*/
    {
      D_BD = A[vtest->index][etest->head->index];
      D_CD = A[sib->head->index][etest->head->index];
      D_AC = A[back->head->index][sib->head->index] + coeff*(A[va->index][sib->head->index] - A[vtest->index][sib->head->index]);
      D_AB = 0.5*(oldD_AB + A[vtest->index][cprev->index]);
      // thisWeight =  deleted by EP, 2013-09-16
      swapWeights[1][vtest->index][etest->head->index] = swapWeights[1][vtest->index][back->head->index] + (D_AC + D_BD - D_AB - D_CD);
      if (NULL != left)
	{
	  assignUpWeights(left,vtest, va, etest, sib->head, D_AB, 0.5*coeff, A, swapWeights);
	  assignUpWeights(right,vtest, va, etest, sib->head, D_AB, 0.5*coeff, A, swapWeights);
	}
    }
}
Пример #2
0
void BalWFext(meEdge *e, double **A) /*works except when e is the one edge
				  inserted to new vertex v by firstInsert*/
{
  meEdge *f, *g;
  if ((leaf(e->head)) && (leaf(e->tail)))
    e->distance = A[e->head->index][e->head->index];
  else if (leaf(e->head))
    {
      f = e->tail->parentEdge;
      g = siblingEdge(e);
      e->distance = 0.5*(A[e->head->index][g->head->index]
			 + A[e->head->index][f->head->index]
			 - A[g->head->index][f->head->index]);
    }
  else
    {
      f = e->head->leftEdge;
      g = e->head->rightEdge;
      e->distance = 0.5*(A[g->head->index][e->head->index]
			 + A[f->head->index][e->head->index]
			 - A[f->head->index][g->head->index]);
    }
}
Пример #3
0
void assignDownWeightsDown (edge *etest, node *vtest, node *va, edge *back,
	node *cprev, double oldD_AB, double coeff, double **A, double ***swapWeights)
{
	/* again the same general idea */

	edge *sib, *left, *right;
	/* sib here = par in assignDownWeightsSkew
	 * rest is the same as assignDownWeightsSkew */

	double D_AB, D_CD, D_AC, D_BD;
	/* B is below vtest, A is below va unioned with all trees already passed by B
	 * C is subtree being passed - below sib
	 * D is tree below etest */

	sib = siblingEdge (etest);
	left = etest->head->leftEdge;
	right = etest->head->rightEdge;
	D_BD = A[vtest->index][etest->head->index];
	D_CD = A[sib->head->index][etest->head->index];
	D_AC = A[sib->head->index][back->head->index] +
		coeff * (A[sib->head->index][va->index] -
		A[sib->head->index][vtest->index]);
	D_AB = 0.5 * (oldD_AB + A[vtest->index][cprev->index]);
	swapWeights[0][vtest->index][etest->head->index] =
		swapWeights[0][vtest->index][back->head->index] +
		( D_AC + D_BD - D_AB - D_CD);

	if (NULL != left)
	{
		assignDownWeightsDown (left, vtest, va, etest, sib->head, D_AB,
			0.5 * coeff, A, swapWeights);
		assignDownWeightsDown (right, vtest, va, etest, sib->head, D_AB,
			0.5 * coeff, A, swapWeights);
	}

	return;
}
Пример #4
0
void bNNItopSwitch(meTree *T, meEdge *e, int direction, double **A)
{
  meEdge *down, *swap, *fixed;
  meNode *u, *v;
  if (verbose)
    {
      printf("Performing branch swap across edge %s ",e->label);
      printf("with ");
      if (LEFT == direction)
	printf("left ");
      else printf("right ");
      printf("subtree.\n");
    }
  down = siblingEdge(e);
  u = e->tail;
  v = e->head;
  if (LEFT == direction)
    {
      swap = e->head->leftEdge;
      fixed = e->head->rightEdge;
      v->leftEdge = down;
    }
  else
    {
      swap = e->head->rightEdge;
      fixed = e->head->leftEdge;
      v->rightEdge = down;
    }
  swap->tail = u;
  down->tail = v;
  if(e->tail->leftEdge == e)
    u->rightEdge = swap;
  else
    u->leftEdge = swap;
  bNNIupdateAverages(A, v, e->tail->parentEdge, down, swap, fixed);
}
Пример #5
0
Файл: TBR.c Проект: Ward9250/ape
void TBR(tree *T, double **D, double **A)
{
  int i;
  edge *esplit, *etop, *eBestTop, *eBestBottom, *eBestSplit;
  edge *eout, *block;
  edge *left, *right, *par, *sib;
  double **dXTop; /*dXTop[i][j] is average distance from subtree rooted at i to tree above split edge, if
		    SPR above split edge cuts edge whose head has index j*/
  double bestWeight;
  double ***TBRWeights;
  dXTop = initDoubleMatrix(T->size);
  weighTree(T);
  TBRWeights = (double ***)calloc(T->size,sizeof(double **));
  for(i=0;i<T->size;i++)
    TBRWeights[i] = initDoubleMatrix(T->size);
  do
    {
      zero3DMatrix(TBRWeights,T->size,T->size,T->size);
      bestWeight = 0.0;
      eBestSplit = eBestTop = eBestBottom = NULL;
      for(esplit=depthFirstTraverse(T,NULL);NULL!=esplit;esplit=depthFirstTraverse(T,esplit))
	{
	  par = esplit->tail->parentEdge;
	  if (NULL != par)
	    {
	      sib = siblingEdge(esplit);
	      /*next two lines calculate the possible improvements for any SPR above esplit*/
	      assignTBRDownWeightsUp(par,esplit->head,sib->head,NULL,NULL,0.0,1.0,A,TBRWeights,&bestWeight,&eBestSplit,&eBestTop,&eBestBottom);
	      assignTBRDownWeightsSkew(sib,esplit->head,sib->tail,NULL,NULL,0.0,1.0,A,TBRWeights,&bestWeight,&eBestSplit,&eBestTop,&eBestBottom);
	      calcTBRaverages(T,esplit,A,dXTop); /*calculates the average distance from any subtree
						   below esplit to the entire subtree above esplit,
						   after any possible SPR above*/
	      /*for etop above esplit, we loop using information from above to calculate values
		for all possible SPRs below esplit*/
	    }

	  right = esplit->head->rightEdge;
	  if (NULL != right)
	    {
	      left = esplit->head->leftEdge;
	      /*test case: etop = null means only do bottom SPR*/
	      assignTBRUpWeights(left,esplit->head,right->head,NULL,NULL,0.0,1.0,A,dXTop,TBRWeights,NULL,&bestWeight,&eBestSplit,&eBestTop,&eBestBottom);
	      assignTBRUpWeights(right,esplit->head,left->head,NULL,NULL,0.0,1.0,A,dXTop,TBRWeights,NULL,&bestWeight,&eBestSplit,&eBestTop,&eBestBottom);

	      block = esplit;
	      while (NULL != block)
		{
		  if (block != esplit)
		    {
		      etop = block;
		      assignTBRUpWeights(left,esplit->head,right->head,NULL,NULL,0.0,1.0,A,dXTop,TBRWeights,etop,&bestWeight,&eBestSplit,&eBestTop,&eBestBottom);
		      assignTBRUpWeights(right,esplit->head,left->head,NULL,NULL,0.0,1.0,A,dXTop,TBRWeights,etop,&bestWeight,&eBestSplit,&eBestTop,&eBestBottom);
		    }
		  eout = siblingEdge(block);
		  if (NULL != eout)
		    {
		      etop = findBottomLeft(eout);
		      while (etop->tail != eout->tail)
			{
			  /*for ebottom below esplit*/

			  assignTBRUpWeights(left,esplit->head,right->head,NULL,NULL,0.0,1.0,A,dXTop,TBRWeights,etop,&bestWeight,&eBestSplit,&eBestTop,&eBestBottom);
			  assignTBRUpWeights(right,esplit->head,left->head,NULL,NULL,0.0,1.0,A,dXTop,TBRWeights,etop,&bestWeight,&eBestSplit,&eBestTop,&eBestBottom);
			  etop = depthFirstTraverse(T,etop);
			}

		      /*etop == eout*/

		      assignTBRUpWeights(left,esplit->head,right->head,NULL,NULL,0.0,1.0,A,dXTop,TBRWeights,etop,&bestWeight,&eBestSplit,&eBestTop,&eBestBottom);
		      assignTBRUpWeights(right,esplit->head,left->head,NULL,NULL,0.0,1.0,A,dXTop,TBRWeights,etop,&bestWeight,&eBestSplit,&eBestTop,&eBestBottom);
		    }
		  block = block->tail->parentEdge;
		}
	    } /*if NULL != right*/
	} /*for esplit*/
      /*find bestWeight, best split edge, etc.*/
      if (bestWeight < -EPSILON)
	{
//	  if (verbose)
//	    {
//	      printf("TBR #%d: Splitting edge %s: top edge %s, bottom edge %s\n",*count+1,
//		     eBestSplit->label, eBestTop->label,eBestBottom->label);
//	      printf("Old tree weight is %lf, new tree weight should be %lf\n",T->weight, T->weight + 0.25*bestWeight);
//	    }
	  TBRswitch(T,eBestSplit,eBestTop,eBestBottom);
	  makeBMEAveragesTable(T,D,A);
	  assignBMEWeights(T,A);
	  weighTree(T);
//	  if (verbose)
//	    printf("TBR: new tree weight is %lf\n\n",T->weight);<
//	  (*count)++;
	}
      else
	bestWeight = 1.0;
    } while (bestWeight < -EPSILON);
  for(i=0;i<T->size;i++)
    freeMatrix(TBRWeights[i],T->size);
  freeMatrix(dXTop,T->size);
}
Пример #6
0
Файл: TBR.c Проект: Ward9250/ape
void assignTBRUpWeights(edge *ebottom, node *vtest, node *va, edge *back, node *cprev, double oldD_AB, double coeff, double **A,
						double **dXTop, double ***swapWeights, edge *etop, double *bestWeight,
						edge **bestSplit, edge **bestTop, edge **bestBottom)
						/*function assigns the value for etop if the tree below vtest is moved to be below etop*/
						/*and SPR for tree bottom tree splits ebottom*/
						/*recursive function searching over values of ebottom*/
						/*minor variant of SPR.c's assignUpWeights
						difference is the index assignment in the array swapWeights, which has a different meaning
						for the TBR routines*/
/*also using dXTop to assign value of average distance to tree above vtest*/
{ /*SPR performed on tree above vtest...*/
  edge *sib, *left, *right;
  /*B is above vtest, A is other tree below vtest unioned with trees in path to vtest*/
  /*sib is tree C being passed by B*/
  /*D is tree below etest*/
  double D_AB, D_CD, D_AC, D_BD;
  sib = siblingEdge(ebottom);
  left = ebottom->head->leftEdge;
  right = ebottom->head->rightEdge;
  if (NULL == etop)
    {
      if (NULL == back) /*first recursive call*/
	{
	  if (NULL == left)
	    return; /*no subtree below for SPR*/
	  else       /*NULL == back and NULL == etop*/
	    {
	      assignTBRUpWeights(left,vtest,va,ebottom,va,A[va->index][vtest->index],0.5,A,dXTop,swapWeights,NULL,bestWeight,bestSplit,bestTop,bestBottom);
	      assignTBRUpWeights(right,vtest,va,ebottom,va,A[va->index][vtest->index],0.5,A,dXTop,swapWeights,NULL,bestWeight,bestSplit,bestTop,bestBottom);
	    }
	}
      else /*NULL != back*/
	{
	  D_BD = A[ebottom->head->index][vtest->index];
	  /*B is tree above vtest, D is tree below ebottom*/
	  D_CD = A[sib->head->index][ebottom->head->index]; /*C is tree below sib*/
	  D_AC = A[back->head->index][sib->head->index] +
	    coeff*(A[va->index][sib->head->index] - A[vtest->index][sib->head->index]);
	  /*va is root of subtree skew back at vtest*/
	  /*A is union of tree below va and all subtrees already passed in path from vtest to ebottom*/
	  D_AB = 0.5*(oldD_AB + A[vtest->index][cprev->index]);
	  swapWeights[vtest->index][ebottom->head->index][ebottom->head->index] = swapWeights[vtest->index][back->head->index][back->head->index] + (D_AC + D_BD - D_AB - D_CD);
	  if (swapWeights[vtest->index][ebottom->head->index][ebottom->head->index] < *bestWeight)
	    {
	      *bestSplit = vtest->parentEdge;
	      *bestTop = NULL;
	      *bestBottom = ebottom;
	      *bestWeight = swapWeights[vtest->index][ebottom->head->index][ebottom->head->index];
	    }
	  if (NULL != left)
	    {
	      assignTBRUpWeights(left,vtest,va,ebottom,sib->head,D_AB,0.5*coeff,A,dXTop,swapWeights,NULL,bestWeight,bestSplit,bestTop,bestBottom);
	      assignTBRUpWeights(right,vtest,va,ebottom,sib->head,D_AB,0.5*coeff,A,dXTop,swapWeights,NULL,bestWeight,bestSplit,bestTop,bestBottom);
	    }
	}
    }
  else /*NULL != etop*/
    {
      if (NULL == back) /*first recursive call*/
	{
	  if (swapWeights[vtest->index][etop->head->index][etop->head->index]< *bestWeight)
	    /*this represents value of SPR from esplit to etop, with no SPR in bottom tree*/
	    {
	      *bestSplit = vtest->parentEdge;
	      *bestTop = etop;
	      *bestBottom = NULL;
	      *bestWeight = swapWeights[vtest->index][etop->head->index][etop->head->index];
	    }
	  if (NULL == left)
	    return; /*no subtree below for SPR*/
	  else if (NULL != etop)/*start the process of assigning weights recursively*/
	    {
	      assignTBRUpWeights(left,vtest,va,ebottom,va,dXTop[va->index][etop->head->index],0.5,A,dXTop,swapWeights,etop,bestWeight,bestSplit,bestTop,bestBottom);
	      assignTBRUpWeights(right,vtest,va,ebottom,va,dXTop[va->index][etop->head->index],0.5,A,dXTop,swapWeights,etop,bestWeight,bestSplit,bestTop,bestBottom);
	    }
	} /*NULL == back*/
      /*in following bit, any average distance of form A[vtest->index][x->index] is
	replaced by dXTop[x->index][etop->head->index]*/
      else /*second or later recursive call, NULL != etop*/
	{
	  D_BD = dXTop[ebottom->head->index][etop->head->index]; /*B is tree above vtest - it is in configuration
								   indexed by etop*/
	  /*D is tree below ebottom*/
	  D_CD = A[sib->head->index][ebottom->head->index]; /*C is tree below sib*/
	  D_AC = A[back->head->index][sib->head->index] +
	    coeff*(A[va->index][sib->head->index] - A[sib->head->index][vtest->index]);
	  /*it is correct to use A[][] here because the bad average distances involving B from the first term will
	    be cancelled by the bad average distances involving B in the subtracted part*/
	  /*va is root of subtree skew back at vtest*/
	  /*A is union of tree below va and all subtrees already passed in path from vtest to ebottom*/
	  D_AB = 0.5*(oldD_AB + dXTop[cprev->index][etop->head->index]);
	  swapWeights[vtest->index][ebottom->head->index][etop->head->index] = swapWeights[vtest->index][back->head->index][etop->head->index]  + (D_AC + D_BD - D_AB - D_CD);
	  if (swapWeights[vtest->index][ebottom->head->index][etop->head->index] + swapWeights[vtest->index][etop->head->index][etop->head->index]< *bestWeight)
	    /*first term is contribution of second SPR, second term is contribution of first SPR*/
	    {
	      *bestSplit = vtest->parentEdge;
	      *bestTop = etop;
	      *bestBottom = ebottom;
	      *bestWeight = swapWeights[vtest->index][ebottom->head->index][etop->head->index] + swapWeights[vtest->index][etop->head->index][etop->head->index];
	    }
	  if (NULL != left)
	    {
	      assignTBRUpWeights(left,vtest, va, ebottom, sib->head, D_AB, 0.5*coeff, A, dXTop, swapWeights,etop,bestWeight,bestSplit,bestTop,bestBottom);
	      assignTBRUpWeights(right,vtest, va, ebottom, sib->head, D_AB, 0.5*coeff, A, dXTop, swapWeights,etop,bestWeight,bestSplit,bestTop,bestBottom);
	    }
	} /*else NULL != back, etop*/
    }
}
Пример #7
0
/* An inelegant iterative version */
void SPRUpShift (node *vmove, edge *esplit)
{
	edge *f;
	edge **EPath;
	edge **sib;
	node **v;
	int i;
	int pathLength;

	for (f=esplit->tail->parentEdge,pathLength=1; f->tail != vmove; f=f->tail->parentEdge)
		pathLength++;
	/* count number of edges to vmove
	 * note that pathLength > 0 will hold */

	EPath = (edge **) mCalloc (pathLength, sizeof(edge *));
	v = (node **) mCalloc (pathLength, sizeof(edge *));
	sib = (edge **) mCalloc ((pathLength+1), sizeof(edge *));
	/* there are pathLength + 1 side trees, one at the head and tail of each edge in the path */

	sib[pathLength] = siblingEdge (esplit);
	i = pathLength;
	f = esplit->tail->parentEdge;
	while (i > 0)
	{
		i--;
		EPath[i] = f;
		sib[i] = siblingEdge (f);
		v[i] = f->head;
		f = f->tail->parentEdge;
	}
	/* indexed so head of Epath is v[i], tail is v[i-1] and sibling edge is sib[i]
	 * need to assign head, tail of each edge in path
	 * as well as have proper values for the left and right fields */

	if (esplit == esplit->tail->leftEdge)
	{
		vmove->leftEdge = esplit;
		vmove->rightEdge = EPath[pathLength-1];
	}
	else
	{
		vmove->rightEdge = esplit;
		vmove->leftEdge = EPath[pathLength-1];
	}
	esplit->tail = vmove;
	/* espilt->head remains unchanged
	 * vmove has the proper fields for left, right, and parentEdge */

	for(i=0; i<(pathLength-1); i++)
		EPath[i]->tail = v[i+1];

	/* this bit flips the orientation along the path
	 * the tail of Epath[i] is now v[i+1] instead of v[i-1] */

	EPath[pathLength-1]->tail = vmove;

	for (i=1; i<pathLength; i++)
	{
		if (sib[i+1] == v[i]->leftEdge)
			v[i]->rightEdge = EPath[i-1];

		else
			v[i]->leftEdge = EPath[i-1];
	}

	if (sib[1] == v[0]->leftEdge)
		v[0]->rightEdge = sib[0];

	else
		v[0]->leftEdge = sib[0];

	sib[0]->tail = v[0];

	free(EPath);
	free(v);
	free(sib);

	return;
}
Пример #8
0
Файл: NNI.c Проект: Ward9250/ape
int NNIEdgeTest(edge *e, tree *T, double **A, double *weight)
{
  int a,b,c,d;
  edge *f;
  double *lambda;
  double D_LR, D_LU, D_LD, D_RD, D_RU, D_DU;
  double w1,w2,w0;

  if ((leaf(e->tail)) || (leaf(e->head)))
    return(NONE);
  lambda = (double *)malloc(3*sizeof(double));
  a = e->tail->parentEdge->topsize;
  f = siblingEdge(e);
  b = f->bottomsize;
  c = e->head->leftEdge->bottomsize;
  d = e->head->rightEdge->bottomsize;

  lambda[0] = ((double) b*c + a*d)/((a + b)*(c+d));
  lambda[1] = ((double) b*c + a*d)/((a + c)*(b+d));
  lambda[2] = ((double) c*d + a*b)/((a + d)*(b+c));

  D_LR = A[e->head->leftEdge->head->index][e->head->rightEdge->head->index];
  D_LU = A[e->head->leftEdge->head->index][e->tail->index];
  D_LD = A[e->head->leftEdge->head->index][f->head->index];
  D_RU = A[e->head->rightEdge->head->index][e->tail->index];
  D_RD = A[e->head->rightEdge->head->index][f->head->index];
  D_DU = A[e->tail->index][f->head->index];

  w0 = wf2(lambda[0],D_RU,D_LD,D_LU,D_RD,D_DU,D_LR);
  w1 = wf2(lambda[1],D_RU,D_LD,D_DU,D_LR,D_LU,D_RD);
  w2 = wf2(lambda[2],D_DU,D_LR,D_LU,D_RD,D_RU,D_LD);
  free(lambda);
  if (w0 <= w1)
    {
      if (w0 <= w2) /*w0 <= w1,w2*/
	{
	  *weight = 0.0;
	  return(NONE);
	}
      else /*w2 < w0 <= w1 */
	{
	  *weight = w2 - w0;
/*	  if (verbose)
	    {
	      printf("Swap across %s. ",e->label);
	      printf("Weight dropping by %lf.\n",w0 - w2);
	      printf("New weight should be %lf.\n",T->weight + w2 - w0);
	    }*/
	  return(RIGHT);
	}
    }
  else if (w2 <= w1) /*w2 <= w1 < w0*/
    {
      *weight = w2 - w0;
/*      if (verbose)
	{
	  printf("Swap across %s. ",e->label);
	  printf("Weight dropping by %lf.\n",w0 - w2);
	  printf("New weight should be %lf.\n",T->weight + w2 - w0);
	}*/
      return(RIGHT);
    }
  else /*w1 < w2, w0*/
    {
      *weight = w1 - w0;
/*      if (verbose)
	{
	  printf("Swap across %s. ",e->label);
	  printf("Weight dropping by %lf.\n",w0 - w1);
	  printf("New weight should be %lf.\n",T->weight + w1 - w0);
	}*/
      return(LEFT);
    }
}
Пример #9
0
Файл: NNI.c Проект: Ward9250/ape
//void NNI(tree *T, double **avgDistArray, int *count)
void NNI(tree *T, double **avgDistArray, int *count, double **D, int numSpecies)
{
  edge *e, *centerEdge;
  edge **edgeArray;
  int *location;
  int *p,*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;
    }
  e = findBottomLeft(T->root->leftEdge);
  /* *count = 0; */
  while (NULL != e)
    {
      edgeArray[e->head->index+1] = e;
      location[e->head->index+1] =
	NNIEdgeTest(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]];
      (*count)++;
      T->weight = T->weight + weights[p[1]];
      NNItopSwitch(T,edgeArray[p[1]],location[p[1]],avgDistArray);
      location[p[1]] = NONE;
      weights[p[1]] = 0.0;  /*after the NNI, this edge is in optimal
			      configuration*/
      popHeap(p,q,weights,possibleSwaps--,1);
      /*but we must retest the other four edges*/
      e = centerEdge->head->leftEdge;
      NNIRetestEdge(p,q,e,T,avgDistArray,weights,location,&possibleSwaps);
      e = centerEdge->head->rightEdge;
      NNIRetestEdge(p,q,e,T,avgDistArray,weights,location,&possibleSwaps);
      e = siblingEdge(centerEdge);
      NNIRetestEdge(p,q,e,T,avgDistArray,weights,location,&possibleSwaps);
      e = centerEdge->tail->parentEdge;
      NNIRetestEdge(p,q,e,T,avgDistArray,weights,location,&possibleSwaps);
    }
  free(p);
  free(q);
  free(location);
  free(edgeArray);
}
Пример #10
0
int bNNIEdgeTest(meEdge *e, meTree *T, double **A, double *weight)
{
  meEdge *f;
  double D_LR, D_LU, D_LD, D_RD, D_RU, D_DU;
  double w1,w2,w0;
  /*if (verbose)
    printf("Branch swap: testing edge %s.\n",e->label);*/
  if ((leaf(e->tail)) || (leaf(e->head)))
    return(NONE);

  f = siblingEdge(e);

  D_LR = A[e->head->leftEdge->head->index][e->head->rightEdge->head->index];
  D_LU = A[e->head->leftEdge->head->index][e->tail->index];
  D_LD = A[e->head->leftEdge->head->index][f->head->index];
  D_RU = A[e->head->rightEdge->head->index][e->tail->index];
  D_RD = A[e->head->rightEdge->head->index][f->head->index];
  D_DU = A[e->tail->index][f->head->index];

  w0 = wf5(D_RU,D_LD,D_LU,D_RD,D_DU,D_LR); /*weight of current config*/
  w1 = wf5(D_RU,D_LD,D_DU,D_LR,D_LU,D_RD); /*weight with L<->D switch*/
  w2 = wf5(D_DU,D_LR,D_LU,D_RD,D_RU,D_LD); /*weight with R<->D switch*/
  if (w0 <= w1)
    {
      if (w0 <= w2) /*w0 <= w1,w2*/
	{
	  *weight = 0.0;
	  return(NONE);
	}
      else /*w2 < w0 <= w1 */
	{
	  *weight = w2 - w0;
	  if (verbose)
	    {
	      printf("Possible swap across %s. ",e->label);
	      printf("Weight dropping by %lf.\n",w0 - w2);
	      printf("New weight would be %lf.\n",T->weight + w2 - w0);
	    }
	  return(RIGHT);
	}
    }
  else if (w2 <= w1) /*w2 <= w1 < w0*/
    {
      *weight = w2 - w0;
      if (verbose)
	{
	  printf("Possible swap across %s. ",e->label);
	  printf("Weight dropping by %lf.\n",w0 - w2);
	  printf("New weight should be %lf.\n",T->weight + w2 - w0);
	}
      return(RIGHT);
    }
  else /*w1 < w2, w0*/
    {
      *weight = w1 - w0;
      if (verbose)
	{
	  printf("Possible swap across %s. ",e->label);
	  printf("Weight dropping by %lf.\n",w0 - w1);
	  printf("New weight should be %lf.\n",T->weight + w1 - w0);
	}
      return(LEFT);
    }
}
Пример #11
0
int bNNIEdgeTest (edge *e, tree *T, double **A, double *weight)
{
	edge *f;
	double D_LR, D_LU, D_LD, D_RD, D_RU, D_DU;
	double w1, w2, w0;

	if ((leaf(e->tail)) || (leaf(e->head)))
		return (NONE);

	f = siblingEdge (e);

	D_LR = A[e->head->leftEdge->head->index][e->head->rightEdge->head->index];
	D_LU = A[e->head->leftEdge->head->index][e->tail->index];
	D_LD = A[e->head->leftEdge->head->index][f->head->index];
	D_RU = A[e->head->rightEdge->head->index][e->tail->index];
	D_RD = A[e->head->rightEdge->head->index][f->head->index];
	D_DU = A[e->tail->index][f->head->index];

	w0 = wf5 (D_RU, D_LD, D_LU, D_RD, D_DU, D_LR);	// weight of current config
	w1 = wf5 (D_RU, D_LD, D_DU, D_LR, D_LU, D_RD);	// weight with L<->D switch
	w2 = wf5 (D_DU, D_LR, D_LU, D_RD, D_RU, D_LD);	// weight with R<->D switch

	if (w0 <= w1)
	{
		if (w0 <= w2)	// w0 <= w1,w2
		{
			*weight = 0.0;
			return (NONE);
		}
		else			// w2 < w0 <= w1
		{
			*weight = w2 - w0;
			if (verbose > 2 && !isBoostrap)
			{
				Debug ( (char*)"Possible swap across '%s'. Weight dropping by %f.", e->label, w0 - w2);
				Debug ( (char*)"New tree length should be %f.", T->weight + w2 - w0);
			}
			return (RIGHT);
		}
	}
	else if (w2 <= w1)	// w2 <= w1 < w0
	{
		*weight = w2 - w0;
		if (verbose > 2 && !isBoostrap)
		{
			Debug ( (char*)"Possible swap across '%s'. Weight dropping by %f.", e->label, w0 - w2);
			Debug ( (char*)"New tree length should be %f.", T->weight + w2 - w0);
		}
		return(RIGHT);
	}
	else				// w1 < w2, w0
	{
		*weight = w1 - w0;
		if (verbose > 2 && !isBoostrap)
		{
			Debug ( (char*)"Possible swap across '%s'. Weight dropping by %f.", e->label, w0 - w1);
			Debug ( (char*)"New tree length should be %f.", T->weight + w1 - w0);
		}
		return(LEFT);
	}
}
Пример #12
0
void updateSubTreeAfterNNI (double **A, node *v, edge *rootEdge,
	node *closer, node *further, double dcoeff, int direction)
{
	edge *sib;

	switch (direction)
	{
		case UP :	/* rootEdge is below the center edge of the NNI
					 * recursive calls to subtrees, if necessary */
			if (NULL != rootEdge->head->leftEdge)
				updateSubTreeAfterNNI (A, v, rootEdge->head->leftEdge,
					closer, further, 0.5 * dcoeff, UP);

			if (NULL != rootEdge->head->rightEdge)
				updateSubTreeAfterNNI (A, v, rootEdge->head->rightEdge,
					closer, further, 0.5 * dcoeff, UP);

			updatePair (A, rootEdge, rootEdge, closer, further, dcoeff, UP);
			sib = siblingEdge (v->parentEdge);
			A[rootEdge->head->index][v->index] =
			A[v->index][rootEdge->head->index] =
				0.5 * A[rootEdge->head->index][sib->head->index] +
				0.5 * A[rootEdge->head->index][v->parentEdge->tail->index];
			break;

		case DOWN :	/* rootEdge is above the center edge of the NNI */
			sib = siblingEdge (rootEdge);
			if (NULL != sib)
				updateSubTreeAfterNNI (A, v, sib, closer, further,
					0.5 * dcoeff, SKEW);

			if (NULL != rootEdge->tail->parentEdge)
				updateSubTreeAfterNNI (A, v, rootEdge->tail->parentEdge,
					closer, further, 0.5 * dcoeff, DOWN);

			updatePair (A, rootEdge, rootEdge, closer, further, dcoeff, DOWN);
			A[rootEdge->head->index][v->index] =
			A[v->index][rootEdge->head->index] =
				0.5 * A[rootEdge->head->index][v->leftEdge->head->index] +
				0.5 * A[rootEdge->head->index][v->rightEdge->head->index];
			break;

		case SKEW :	/* rootEdge is in subtree skew to v */
			if (NULL != rootEdge->head->leftEdge)
				updateSubTreeAfterNNI (A, v, rootEdge->head->leftEdge,
					closer, further, 0.5 * dcoeff, SKEW);

			if (NULL != rootEdge->head->rightEdge)
				updateSubTreeAfterNNI (A, v, rootEdge->head->rightEdge,
					closer, further, 0.5 * dcoeff, SKEW);

			updatePair (A, rootEdge, rootEdge, closer, further, dcoeff, UP);
			A[rootEdge->head->index][v->index] =
			A[v->index][rootEdge->head->index] =
				0.5 * A[rootEdge->head->index][v->leftEdge->head->index] +
				0.5 * A[rootEdge->head->index][v->rightEdge->head->index];
			break;
	}

	return;
}