Esempio n. 1
0
/*  Standard option - calculate the probability, the matrix of
 * expected information and the diagonal values of the variance
 * Dump these to disk and calculate the determinant of the
 * expectation matrix.*/
void standard(struct treenode *node_p,FILE *file_p,unsigned int e){
#include "variables.h"
  int a,b;

  /*  Make a copy of the tree, fill and calculate the likelihoods*/
  tree2=treecopy(node_p,0);
  filltree(node_p,tree2,0);

  if(sample_file_p!=NULL)
    fprintf(sample_file_p,"#Points 1\n\n");
  
  /*  We aren't altering the rate, so factor is 1*/
  factor=1.0;
  factor_flag=0;

  det=find_information(node_p,tree2,e,factor_flag,factor);

  /*  Print the required output - may be more than one value*/
  b=1;
  if(NOTMODE(DETINDIV) && ISMODE(INDIVIDUAL))
    b=individual;
  
  for(a=0;a<b;a++)
    fprintf(file_p,"%s = %1.11E\n",outstring,det[a]);
  if(ISMODE(HKY) && NOTMODE(NOKAPPA) && NOTMODE(PERCENTILE))
    fprintf(file_p,"Information about Kappa = %1.11E\n",det[b]);

  free(det);
}
Esempio n. 2
0
static void dopush(Dataptr matrix, Treestack *sp, const Branch *const barray, const long root)
/* push tree in barray (of root root) on to stack *sp */
{
    lvb_assert(sp->next <= sp->size);
    if (sp->next == sp->size) upsize(matrix, sp);
    treecopy(matrix, sp->stack[sp->next].tree, barray);
    sp->stack[sp->next].root = root;
    sp->next++;
 
} /* end dopush() */
Esempio n. 3
0
File: racewalk.c Progetto: 8l/go
static int
callinstr(Node **np, NodeList **init, int wr, int skip)
{
	Node *f, *b, *n;
	Type *t;
	int class, hascalls;

	n = *np;
	//print("callinstr for %+N [ %O ] etype=%E class=%d\n",
	//	  n, n->op, n->type ? n->type->etype : -1, n->class);

	if(skip || n->type == T || n->type->etype >= TIDEAL)
		return 0;
	t = n->type;
	if(isartificial(n))
		return 0;

	b = basenod(n);
	// it skips e.g. stores to ... parameter array
	if(isartificial(b))
		return 0;
	class = b->class;
	// BUG: we _may_ want to instrument PAUTO sometimes
	// e.g. if we've got a local variable/method receiver
	// that has got a pointer inside. Whether it points to
	// the heap or not is impossible to know at compile time
	if((class&PHEAP) || class == PPARAMREF || class == PEXTERN
		|| b->op == OINDEX || b->op == ODOTPTR || b->op == OIND || b->op == OXDOT) {
		hascalls = 0;
		foreach(n, hascallspred, &hascalls);
		if(hascalls) {
			n = detachexpr(n, init);
			*np = n;
		}
		n = treecopy(n);
		makeaddable(n);
		if(t->etype == TSTRUCT || isfixedarray(t)) {
			f = mkcall(wr ? "racewriterange" : "racereadrange", T, init, uintptraddr(n),
					nodintconst(t->width));
		} else
			f = mkcall(wr ? "racewrite" : "raceread", T, init, uintptraddr(n));
		*init = list(*init, f);
		return 1;
	}
	return 0;
}
Esempio n. 4
0
long treestack_pop(Dataptr matrix, Branch *barray, long *root, Treestack *sp)
{
    long val;	/* return value */

    if (sp->next >= 1){
        sp->next--;
        treecopy(matrix, barray, sp->stack[sp->next].tree);
        *root = sp->stack[sp->next].root;

        val = 1;
    }
    else{
        val = 0;
    }

    return val;

} /* end treestack_pop() */
Esempio n. 5
0
long treestack_print(Dataptr matrix, Treestack *sp, FILE *const outfp, Lvb_bool onerandom)
{
    const long d_obj1 = 0L;	/* 1st obj. for output trees */
    long root;			/* root of current tree */
    long i;			/* loop counter */
    long lower;			/* lowest index of trees to print */
    long upper;			/* 1 + upper index of trees to print */
    Branch *barray;		/* current unpacked tree */

    /* "local" dynamic heap memory */
    barray = treealloc(matrix);

    if (onerandom == LVB_TRUE)	/* choose one random tree to print */
    {
		lower = randpint(sp->next - 1);
		upper = lower + 1;
    } else {
		lower = 0;
		upper = sp->next;
    }

    for (i = lower; i < upper; i++) {
        treecopy(matrix, barray, sp->stack[i].tree);
        if (sp->stack[i].root != d_obj1) lvb_reroot(barray, sp->stack[i].root, d_obj1);
        root = d_obj1;
        lvb_treeprint(matrix, outfp, barray, root);
    }
    if (fflush(outfp) != 0)
    	crash("file write error when writing best trees");

    /* deallocate "local" dynamic heap memory */
    free(barray);

    return upper - lower;	/* number of trees printed */

} /* end treestack_print() */
Esempio n. 6
0
/*  Routine to vary the length of all branches by the same factor
 * and dump the expected information to disk. Since we are altering 
 * the rate of change, we need to include a factor in all the information
 * calculations*/
void growtree(struct treenode *node_p,FILE *file_p,unsigned int e){
#include "variables.h"
  int steps,a,b,c;
  
  double f_min,f_max,f;

  struct treenode *tree;


/*  Code to get the factors from the users*/
  printf("Altering length of all branches by same factor\n\n");
  printf("Please enter min. factor, max factor and number of points:\n");
  do{
    printf("\tmin. factor:");
    scanf("%lf",&f_min);
  }while(f_min<=0);
  do{
    printf("\tmax. factor:");
    scanf("%lf",&f_max);
  }while(f_min>=f_max);
  do{
    printf("\tnumber of points:");
    scanf("%d",&steps);
  }while(steps<=0);

  /*  Dump text to file explaining what we are about to do*/
  fprintf(file_p,"#Results from Varying length of all branches by factor\n");
  fprintf(file_p,"#Factor\t\t\t%s\n",outstring);
  if(ISMODE(MATRICES))
    fprintf(matrix_file_p,"#Matrices from Varying length of all branches by factor\n");
  if(sample_file_p!=NULL){
    fprintf(sample_file_p,"#Points %d\n",steps);
    fprintf(sample_file_p,"#Samples from varying length of all branches by factor\n");
  }
  if(ISMODE(PROBS))
    fprintf(prob_file_p,"#Probabilities from varying length of all branches by factor\n");
  
/*  Start main loop*/

  /*  Make two copies of the tree*/
  tree2=treecopy(node_p,0);
  tree=treecopy(node_p,0);

  /*  Calculate what factor we need to include in the calculations*/
  for(c=0;c<(steps);c++){
    if(steps==1)  /* Prevent divide by zero if only one step*/
      f=f_min;
    else
      f=f_min+c*(f_max-f_min)/(steps-1);
    factor=f;
    factor_flag=-1; /*  Flag = -1 means that we want to include the
                     * factor on all branches*/

    /*  Add all the information to one copy from the original tree*/
    filltree(node_p,tree,0);

/*  Change all the length in the tree to the scaled version
 * The array branch[] currently points to those of 'tree'*/
    for(b=0;b<branches;b++){
      branch[b]->length[0]=branch[b]->length[0]*f;
      a=findnode(branch[b]->node[0],branch[b]);
      (branch[b]->node[0])->length[a]=branch[b]->length[0];
    }
    /*  Make copy of the tree with scaled branches*/
    filltree(tree,tree2,0);

    /*  Branch[] now points to those in tree2
     * Make leaves point to those on tree*/
    leaves=0;
    doleaf(tree,0);

    printf("Doing factor %E\n",f);

    /*  If we've been asked to print out the intermediate trees, then
     * dump them to all the open files*/
    if(ISMODE(TREES))
      print_tree(tree,file_p,0);
    fprintf(file_p,"%E\n",f);
    if(ISMODE(MATRICES)){
      fprintf(matrix_file_p,"\n#Factor %E\n",f);
      if(ISMODE(TREES))
        print_tree(tree,matrix_file_p,0);
    }
    if(ISMODE(VARIANCE)){
      fprintf(variance_file_p,"\n#Factor %E\n",f);
      if(ISMODE(TREES))
        print_tree(tree,variance_file_p,0);
    }
    if(sample_file_p!=NULL){
      fprintf(sample_file_p,"\n#Factor %E\n",f);
      if(ISMODE(TREES))
	print_tree(tree,sample_file_p,0);
    }
    if(ISMODE(PROBS)){
      fprintf(prob_file_p,"\n#Factor %E\n",f);
      if(ISMODE(TREES))
	print_tree(tree,prob_file_p,0);
    }
    det=find_information(tree,tree2,e,factor_flag,factor);

    /*  Possible may want to print out more than one result*/
    b=1;
    if(ISMODE(INDIVIDUAL))
      b=individual;
    
    if(ISMODE(INDIVIDUAL)){
      if(ISMODE(DETINDIV)){
	fprintf(file_p,"\t\t\t%E\tD(",det[0]);
	for(a=0;a<b-1;a++)
	  fprintf(file_p,"%d,",interesting_branches[a]);
	fprintf(file_p,"%d)\n",interesting_branches[a]);
      }else
	for(a=0;a<b;a++)
	  fprintf(file_p,"\t\t\t%E\t%d\n",det[a],interesting_branches[a]);
    }else
      fprintf(file_p,"\t\t\t%E\tD\n",det[0]);
    
    if(ISMODE(HKY) && NOTMODE(NOKAPPA) && NOTMODE(PERCENTILE))
      fprintf(file_p,"\t\t\t%E\tKappa\n",det[b]);
    free(det);
  }
}
Esempio n. 7
0
/*  Routine to slid one branch of a node along the a branch
 *  The moving node is assumed to be simple!*/
void greasebranch(struct treenode *node_p,FILE *file_p,unsigned int e){
#include "variables.h"
  int steps,a,b,c;
  int slippe,to,from,to_root,to_false_root;
  int sp_case;

  double f_min,f_max,f,l;

  extern int root;
  struct treenode *movingnode,*node_c;
  struct treenode *tree;

  /*  Make two copies of the tree*/
  tree2=treecopy(node_p,0);
  tree=treecopy(node_p,0);
  filltree(node_p,tree,0);

  /*  Print out the tree branches and respective numbers*/
  printf("\n");
  for(a=0;a<branches;a++)
    printf("Branch %d goes from %s to %s\n",a
           ,(branch[a]->node[0])->name,branch[a]->name);

  /*  Get the necessary parameters from the user*/
  do{
    printf("\nWhich branch would you like to move?");
    scanf("%d",&slippe);
  }while(slippe<0 || slippe>branches);

  do{
    printf("\nWhich branch would you like to move branch %d along(towards)?"
                                                                    ,slippe);
    scanf("%d",&to);
    printf("\nWhich branch would you like to move branch %d along(away)?"
                                                                 ,slippe);
    scanf("%d",&from);
  }while(to<0 || to>branches || from<0 || from>branches);

/*  Out of the three parameters given, two of them must point
 * the common node.*/
  movingnode=(branch[to]->node[0]==branch[from]->node[0])
             ?branch[to]->node[0]:branch[slippe]->node[0];

/*  Find which branch in the common node points to each of the
 * parameter branches.*/
  from=findnode(movingnode,branch[from]);
  to=findnode(movingnode,branch[to]);
  slippe=findnode(movingnode,branch[slippe]);

/*  Get the amount of variation from the user*/
  printf("Sliding branch leading to %s\n\n",branch[slippe]->name);
  printf("Please enter min. & max. distance to move and number of points:\n");
  do{
    printf("\tmin. distance:");
    scanf("%lf",&f_min);
  }while(f_min<=-movingnode->length[from] || f_min>=movingnode->length[to]);
  do{
    printf("\tmax. distance:");
    scanf("%lf",&f_max);
  }while(f_min>=f_max || f_max>=movingnode->length[to]);
  do{
    printf("\tnumber of points:");
    scanf("%d",&steps);
  }while(steps<=0);

/*  Are we moving the branch towards the (code) root?*/
  to_false_root=(to==0)?0:1;

/*  Work out where root node is relative to movingnode.
 * Needed to work out whether to increase or decrease branch
 * lengths when moving node*/
  to_root=to_false_root; /*  Correct unless we are between the
                          * two roots in the tree */
  /*  If we have a genetic root...*/
  if(ISMODE(ROOTED)){
    /*  Decide depending on whether the root is floating or not,
     * which node it refers to*/
    node_c=(ISMODE(NODEASROOT))?branch[root]->node[0]:branch[root];

    /*  Iterate from the genetic root to the code root and set
     * "to_root" as appropriate. to_root only differs from to_false_root
     * if we are moving a branch between the two roots*/
    while(node_c!=tree){

      /*  If we reach movingnode without passing either the to or from
       * node first, then we must have come down on of the other branches
       * or our root is the movingnode itself. In either case, we can't 
       * keep evolutionary times fixed - problem*/
      if(node_c==movingnode){
        printf("Moving branch containing root - can't keep evolutionary times fixed\n");
        exit(0);
      }

      /*  We encounter the "to" node first and so must be moving 
       * towards the genetic root*/
      if(node_c==movingnode->node[to]){
        to_root=0;
        break;
      }

      /*  We encounter the from root first and so must be moving
       * away from the genetic node*/
      if(node_c==movingnode->node[from]){
        to_root=1;
        break;
      }

      /*  Iterate up one step*/
      node_c=node_c->node[0];
    }

  /*  If the root is on the branch we are moving, bad things
   * happen (TM) Moving the branch can't be done if evolutionary
   * times are fixed.
   *  We have deal with the case when root is on the moving bit of
   * tree but not the false root.*/
    if(slippe==0){
      /*  Decide where the root is depending on whether it is fixed
       * or floating*/
      node_c=(ISMODE(NODEASROOT))?branch[root]->node[0]:branch[root];
      a=0;

      /*  We may assume that the code root is on the moving branch of
       * the tree. If we have to pass through movingnode to get from
       * the genetic root to the code root then we are fine*/
      while(node_c!=tree){
	if(node_c==movingnode){
          a=1;
          break;
        }
        node_c=node_c->node[0];
      }

      /*  One special case if the movingnode is the fixed root*/
      if(ISMODE(NODEASROOT) && branch[root]->node[0]==movingnode)
        a=0;

      /*  If both the code and genetic roots are on the moving section
       * of tree, complain*/
      if(a==0){
        printf("Moving branch containing root - can't keep evolutionary"
               " times fixed\n");
        exit(0);
      }
    }

/*   If the root of the tree is on the same branch as we are moving across
 * then we'll have trouble when we cross it - give warning*/
    if(NOTMODE(NODEASROOT)) /*  genetic root is floating*/
      if(to_root==0) /*  we are heading towards it*/

        /*  Depending on whether we are going away or towards the
         * code root, see if the genetic root is on the branch we are
         * moving along*/
        if((to_false_root==0 && branch[root]==movingnode)
         ||(to_false_root==1 && branch[root]->node[0]==movingnode))
          fprintf(file_p,"# *** Root in branch moving across. Beware, here be dragons ***\n");
  }

  /*  Dump some information to file informing user what we are about
   * to do*/
  fprintf(file_p,"#Results from sliding branch from %s to"
	  " %s along branch from %s to %s\n"
	  ,movingnode->name,(movingnode->node[slippe])->name
	  ,(movingnode->node[from])->name,(movingnode->node[to])->name);
  fprintf(file_p,"#Distance moved towards %s\t%s\n",(movingnode->node[to])->name,outstring);
  if(ISMODE(MATRICES))
    fprintf(matrix_file_p,"#Matrices from sliding branch from %s to"
	    " %s along branch from %s to %s\n"
	    ,movingnode->name,(movingnode->node[slippe])->name
	    ,(movingnode->node[from])->name,(movingnode->node[to])->name);
  if(sample_file_p!=NULL){
    fprintf(sample_file_p,"#Points %d\n",steps);
    fprintf(sample_file_p,"#Samples from sliding branch from %s to"
	    " %s along branch from %s to %s\n"
	    ,movingnode->name,(movingnode->node[slippe])->name
	    ,(movingnode->node[from])->name,(movingnode->node[to])->name);
  }
  if(ISMODE(PROBS))
    fprintf(prob_file_p,"#Probabilities from sliding branch from %s to"
	    " %s along branch from %s to %s\n"
	    ,movingnode->name,(movingnode->node[slippe])->name
	    ,(movingnode->node[from])->name,(movingnode->node[to])->name);
  
  /*  l is the total length of the "branch" we are moving across*/
  l=movingnode->length[to]+movingnode->length[from];
  
  if(steps==1)
    f=f_min;
  else
    f=(f_max-f_min)/(steps-1);

  /* We aren't changing any rates, so we don't need to apply the
   * factor to any information (so factor=1)*/
  factor=1.0;
  factor_flag=0;
  
  /* Initialise the tree...*/
  movingnode->length[to]-=f_min;
  if(to==0){
    b=findnode(movingnode->node[0],movingnode);
    (movingnode->node[to])->length[b]=movingnode->length[to];
  }
  else
    (movingnode->node[to])->length[0]=movingnode->length[to];

  movingnode->length[from]+=f_min;
  if(from==0){
    b=findnode(movingnode->node[0],movingnode);
    (movingnode->node[from])->length[b]=movingnode->length[from];
  }
  else
    (movingnode->node[from])->length[0]=movingnode->length[from];
  /*  If the tree is rooted, then we must preserve evolutionary 
   * times. This requires adding bits onto any other branches
   * connected to the moving node, bar the to and from branches.*/
  if(ISMODE(ROOTED)){
    /*  Case moving towards the evolutionary root - all branches
     * connected to the moving node, bar from and to need to have 
     * the distance added onto them*/
    sp_case=(movingnode==tree)?1:0;
    if(to_root==0){
      if(sp_case==1 && to!=0 && from!=0){
	b=findnode(movingnode->node[0],movingnode);
	movingnode->length[0]+=f_min;
	(movingnode->node[0])->length[b]=movingnode->length[0];
      }
      for(a=sp_case;a<DOODAH && movingnode->node[a]!=NULL;a++)
	if(a!=to && a!=from){
	  (movingnode->node[a])->length[0]+=f_min;
	  movingnode->length[a]=(movingnode->node[a])->length[0];
        }
    }
    /*  Else we are moving away from it and all branches connected to
     * the moving node need the distance subtracted from them. Same
     * special case as above*/
    else{
      if(sp_case==1 && to!=0 && from!=0){
	b=findnode(movingnode->node[0],movingnode);
	movingnode->length[0]-=f_min;
	(movingnode->node[0])->length[b]=movingnode->length[0];
      }
      for(a=sp_case;a<DOODAH && movingnode->node[a]!=NULL;a++)
	if(a!=to && a!=from){
	(movingnode->node[a])->length[0]-=f_min;
	movingnode->length[a]=(movingnode->node[a])->length[0];
      }
    }
  }  

  
  for(c=0;c<steps;c++){

/*  Adding new lengths - if any of the markers are zero then
 * we have to search for the correct pointer in the parent node*/

    movingnode->length[to]-=(c!=0)*f;
    /*  Also need to update length of branch that leads to this
     * one. If to=0 then we must look up the tree*/
    if(to==0){
      b=findnode(movingnode->node[0],movingnode);
      (movingnode->node[to])->length[b]=movingnode->length[to];
    }
    else
      (movingnode->node[to])->length[0]=movingnode->length[to];

    movingnode->length[from]+=(c!=0)*f;
    /*  Also need to update length of branch that leads to this                 
     * one. If from=0 then we must look up the tree*/
    if(from==0){
      b=findnode(movingnode->node[0],movingnode);
      (movingnode->node[from])->length[b]=movingnode->length[from];
    }
    else
      (movingnode->node[from])->length[0]=movingnode->length[from];

    /*  If the tree is rooted, then we must preserve evolutionary 
     * times. This requires adding bits onto any other branches
     * connected to the moving node, bar the to and from branches.*/
    if(ISMODE(ROOTED)){
      /*  Case moving towards the evolutionary root - all branches
       * connected to the moving node, bar from and to need to have 
       * the distance added onto them*/
      sp_case=(movingnode==tree)?1:0; /*  Is the movingnode the code root?*/

      if(to_root==0){
        if(sp_case==1 && to!=0 && from!=0){
          b=findnode(movingnode->node[0],movingnode);
          movingnode->length[0]+=(c!=0)*f;
          (movingnode->node[0])->length[b]=movingnode->length[0];
        }
	for(a=sp_case;a<DOODAH && movingnode->node[a]!=NULL;a++)
	  if(a!=to && a!=from){
 	    (movingnode->node[a])->length[0]+=(c!=0)*f;
	    movingnode->length[a]=(movingnode->node[a])->length[0];
	  }
      }
      /*  Else we are moving away from it and all branches connected to
       * the moving node need the distance subtracted from them. Same
       * special case as above*/
      else{
        if(sp_case==1 && to!=0 && from!=0){
          b=findnode(movingnode->node[0],movingnode);
          movingnode->length[0]-=(c!=0)*f;
          (movingnode->node[0])->length[b]=movingnode->length[0];
        }
	for(a=sp_case;a<DOODAH && movingnode->node[a]!=NULL;a++)
	  if(a!=to && a!=from){
	    (movingnode->node[a])->length[0]-=(c!=0)*f;
	    movingnode->length[a]=(movingnode->node[a])->length[0];
	  }
      }
    }

    /*  Fill in second copy of tree from first and update the leaf
     * array to point to tree*/
    filltree(tree,tree2,0);
    leaves=0;
    doleaf(tree,0);

    /*  Print a bit of information to all open files*/
    printf("Doing distance %E\n",c*f+f_min);
    if(ISMODE(TREES))
      print_tree(tree,file_p,0);
    fprintf(file_p,"%E\n",c*f+f_min);
    if(ISMODE(MATRICES)){
      fprintf(matrix_file_p,"\n#Distance %E\n",c*f+f_min);
      if(ISMODE(TREES))
        print_tree(tree,matrix_file_p,0);
    }
    if(ISMODE(VARIANCE)){
      fprintf(variance_file_p,"\n#Distance %E\n",c*f+f_min);
      if(ISMODE(TREES))
        print_tree(tree,variance_file_p,0);
    }
    if(sample_file_p!=NULL){
      fprintf(sample_file_p,"\n#Distance %E\n",c*f+f_min);
      if(ISMODE(TREES))
	print_tree(tree,sample_file_p,0);
    }
    if(ISMODE(PROBS)){
      fprintf(prob_file_p,"\n#Distance %E\n",c*f+f_min);
      if(ISMODE(TREES))
	print_tree(tree,prob_file_p,0);
    }
    
    det=find_information(tree,tree2,e,factor_flag,factor);

    /*  Possible may want to print out more than one result*/
    b=1;
    if(ISMODE(INDIVIDUAL))
      b=individual;
    
    if(ISMODE(INDIVIDUAL)){
      if(ISMODE(DETINDIV)){
	fprintf(file_p,"\t\t\t%E\tD(",det[0]);
	for(a=0;a<b-1;a++)
	  fprintf(file_p,"%d,",interesting_branches[a]);
	fprintf(file_p,"%d)\n",interesting_branches[a]);
      }else
	for(a=0;a<b;a++)
	  fprintf(file_p,"\t\t\t%E\t%d\n",det[a],interesting_branches[a]);
    }else
      fprintf(file_p,"\t\t\t%E\tD\n",det[0]);
    
    if(ISMODE(HKY) && NOTMODE(NOKAPPA) && NOTMODE(PERCENTILE))
      fprintf(file_p,"\t\t\t%E\tKappa\n",det[b]);
    free(det);
  }
}
Esempio n. 8
0
/*  Routine to vary the length of one branch though several
 * multipliers. This has little meaning when considering a clock-like
 * (rooted) tree*/
void growbranch(struct treenode *node_p,FILE *file_p,unsigned int e){
#include "variables.h"
  int steps,a,b,c;
  int elastic;

  double f_min,f_max,f;

  struct treenode *tree;

/*  Test to see whether tree is rooted - changing branch 
 * length in unrooted trees doesn't have much experimental
 * meaning                                                  */
  if(((mode&4)|(mode&32))!=0)
    printf("\a\n**Changing branch length in a rooted tree doesn't"
           " have meaning\n**in an experimental design problem!\n\n\a");

  /*  Make two copies of the tree*/
  tree2=treecopy(node_p,0);
  tree=treecopy(node_p,0);
  /*  Fill in the first*/
  filltree(node_p,tree,0);

  /*  Choose branch to stretch - better be elastic*/
  printf("\n");
  for(a=0;a<branches;a++)
    printf("Branch %d goes from %s to %s\n",a
           ,(branch[a]->node[0])->name,branch[a]->name);
  do{
    printf("\nWhich branch would you like to alter?");
    scanf("%d",&elastic);
  }while(elastic<0 || elastic>branches);

  /*  Get length scaling factors from user*/
  printf("Altering length of a branch leading to"
                    " %s by a varying factor\n\n",branch[elastic]->name);
  printf("Please enter min. factor, max factor and number of points:\n");
  do{
    printf("\tmin. factor:");
    scanf("%lf",&f_min);
  }while(f_min<=0);
  do{
    printf("\tmax. factor:");
    scanf("%lf",&f_max);
  }while(f_min>=f_max);
  do{
    printf("\tnumber of points:");
    scanf("%d",&steps);
  }while(steps<=0);

  /*  Dump the necessary information to file*/
  fprintf(file_p,"#Results from varying length of branch"
	  " between %s and %s by factor\n"
	  ,(branch[elastic]->node[0])->name,branch[elastic]->name);
  fprintf(file_p,"#Factor\t\t\t%s\n",outstring);
  if(ISMODE(MATRICES))
    fprintf(matrix_file_p,"#Matrices from varying length of branch"
	    " between %s and %s by factor\n"
	    ,(branch[elastic]->node[0])->name,branch[elastic]->name);
  if(sample_file_p!=NULL){
    fprintf(sample_file_p,"#Points %d\n",steps);
    fprintf(sample_file_p,"#Samples from varying length of branch"
	    " between %s and %s by factor\n"
	    ,(branch[elastic]->node[0])->name,branch[elastic]->name);
  }
  if(ISMODE(PROBS))
    fprintf(prob_file_p,"#Probabilities from varying length of branch"
	    " between %s and %s by factor\n"
	    ,(branch[elastic]->node[0])->name,branch[elastic]->name);
  
  /*  Main loop to stretch the branch*/
  for(c=0;c<steps;c++){
    /*  Calculate the factor wanted and set the flag - we only
     * want to apply the factor to one of the informations this
     * time*/
    if(steps==1)
      f=f_min;
    else
      f=f_min+c*(f_max-f_min)/(steps-1);

    factor=f;
    factor_flag=elastic;

    /*  Fill in first copy from the original*/
    filltree(node_p,tree,0);

   /*  Branch[] points to those of 'tree'
    * Change length of the branch by factor - need to find the node
    * that points from the other side of the branch.*/
    branch[elastic]->length[0]=branch[elastic]->length[0]*f;
    a=findnode(branch[elastic]->node[0],branch[elastic]);
    (branch[elastic]->node[0])->length[a]=branch[elastic]->length[0];

    /*  Fill in the second copy from the first (with the new branch 
     * length and set all the leaves to point to "tree"*/
    filltree(tree,tree2,0);
    leaves=0;
    doleaf(tree,0);

    printf("Doing Factor %E\n",f);
    /*  If we are printing out the intermediate trees, then dump them
     * to every file*/
    if(ISMODE(TREES))
      print_tree(tree,file_p,0);
    fprintf(file_p,"%E\n",f);
    if(ISMODE(MATRICES)){
      fprintf(matrix_file_p,"\n#Factor %E\n",f);
      if(ISMODE(TREES))
        print_tree(tree,matrix_file_p,0);
    }
    if(ISMODE(VARIANCE)){
      fprintf(variance_file_p,"\n#Factor %E\n",f);
      if(ISMODE(TREES))
        print_tree(tree,variance_file_p,0);
    }
    if(sample_file_p!=NULL){
      fprintf(sample_file_p,"\n#Factor %E\n",f);
      if(ISMODE(TREES))
	print_tree(tree,sample_file_p,0);
    }
    if(ISMODE(PROBS)){
      fprintf(prob_file_p,"\n#Factor %E\n",f);
      if(ISMODE(TREES))
	print_tree(tree,prob_file_p,0);
    }
    
    det=find_information(tree,tree2,e,factor_flag,factor);

    /*  Possible may want to print out more than one result*/
    b=1;
    if(ISMODE(INDIVIDUAL))
      b=individual;
    
    if(ISMODE(INDIVIDUAL)){
      if(ISMODE(DETINDIV)){
	fprintf(file_p,"\t\t\t%E\tD(",det[0]);
	for(a=0;a<b-1;a++)
	  fprintf(file_p,"%d,",interesting_branches[a]);
	fprintf(file_p,"%d)\n",interesting_branches[a]);
      }else
	for(a=0;a<b;a++)
	  fprintf(file_p,"\t\t\t%E\t%d\n",det[a],interesting_branches[a]);
    }else
      fprintf(file_p,"\t\t\t%E\tD\n",det[0]);
    
    if(ISMODE(HKY) && NOTMODE(NOKAPPA) && NOTMODE(PERCENTILE))
      fprintf(file_p,"\t\t\t%E\tKappa\n",det[b]);
    free(det);
  }
}
Esempio n. 9
0
long anneal(Treestack *bstackp, const Branch *const inittree, long root,
 const double t0, const double t1, const long maxaccept, const long maxpropose,
 const long maxfail, FILE *const lenfp, unsigned char **bmat, long m, long n,
 const long *weights, long *current_iter, Lvb_bool log_progress)
/* seek parsimonious tree from initial tree in inittree (of root root)
 * with initial temperature t0, and subsequent temperatures obtained by
 * multiplying the current temperature by (t1 / t0) ** n * t0 where n is
 * the ordinal number of this temperature, after at least maxaccept changes
 * have been accepted or maxpropose changes have been proposed, whichever is
 * sooner;
 * return the length of the best tree(s) found after maxfail consecutive
 * temperatures have led to no new accepted solution;
 * lenfp is for output of current tree length and associated details;
 * *current_iter should give the iteration number at the start of this call and
 * will be used in any statistics sent to lenfp, and will be updated on
 * return */
{
    long accepted = 0;		/* changes accespted */
    Lvb_bool dect;		/* should decrease temperature */
    double deltah;		/* change in energy (1 - C.I.) */
    long deltalen;		/* change in length with new tree */
    long failedcnt = 0; 	/* "failed count" for temperatures */
    long iter = 0;		/* iteration of mutate/evaluate loop */
    long len;			/* length of current tree */
    long prev_len = UNSET;	/* length of previous tree */
    long lenbest;		/* bet length found so far */
    long lendash;		/* length of proposed new tree */
    long lenmin;		/* minimum length for any tree */
    double ln_t;		/* ln(current temperature) */
    long t_n = 0;		/* ordinal number of current temperature */
    Lvb_bool newtree;		/* accepted a new configuration */
    double pacc;		/* prob. of accepting new config. */
    Lvb_bool probaccd;		/* have accepted based on Pacc */
    long proposed = 0;		/* trees proposed */
    double r_lenmin;		/* minimum length for any tree */
    long rootdash;		/* root of new configuration */
    double t = t0;		/* current temperature */
    double t1_to_t0;		/* T1:T0 ratio */
    Branch *x;			/* current configuration */
    Branch *xdash;		/* proposed new configuration */
    extern Dataptr matrix;	/* data matrix */

    /* "local" dynamic heap memory */
    x = treealloc(brcnt(matrix->n), matrix->m);
    xdash = treealloc(brcnt(matrix->n), matrix->m);

    treecopy(x, inittree);	/* current configuration */
    len = getplen(x, root, m, n, weights);
    dect = LVB_FALSE;		/* made LVB_TRUE as necessary at end of loop */

    /* if t1_to_t0 is going to be very small, set it to zero without
     * calculating it, to avoid underflow. Use this relation:
     *     if T1 / T0 < eps,
     *     ln (T1/T0) < ln eps
     * i.e.,
     *     ln T1 - ln T0 < ln eps */
    lvb_assert ((t0 >= LVB_EPS) && (t1 >= LVB_EPS) && (t1 <= t0)
     && (t0 <= 1.0));
    if (log_wrapper(t1) - log_wrapper(t0) < log_wrapper(LVB_EPS))
	t1_to_t0 = 0.0;
    else
	t1_to_t0 = t1 / t0;

    lenbest = len;
    treestack_push(bstackp, inittree, root);	/* init. tree initially best */
    if ((log_progress == LVB_TRUE) && (*current_iter == 0))
    {
        fprintf(lenfp, "\nRearrangement: Length:\n");
    }

    lenmin = getminlen(matrix);
    r_lenmin = (double) lenmin;

    while (1)
    {
        if ((log_progress == LVB_TRUE) && ((len != prev_len)
	    || ((*current_iter % STAT_LOG_INTERVAL) == 0)))
        {
	    lenlog(lenfp, *current_iter, len);
        }
	prev_len = len;
	*current_iter += 1;

	/* occasionally re-root, to prevent influence from root position */
	if ((*current_iter % REROOT_INTERVAL) == 0)
	    root = arbreroot(x, root);

	lvb_assert(t > DBL_EPSILON);
	newtree = LVB_FALSE;
	probaccd = LVB_FALSE;

	/* mutation: alternate between the two mutation functions */
	if (iter % 2)
	{
	    rootdash = root;
	    mutate_spr(xdash, x, root);	/* global change */
	}
	else
	{
	    rootdash = root;
	    mutate_nni(xdash, x, root);	/* local change */
	}

	lendash = getplen(xdash, rootdash, m, n, weights);
	lvb_assert (lendash >= 1L);
	deltalen = lendash - len;
	deltah = (r_lenmin / (double) len) - (r_lenmin / (double) lendash);
	if (deltah > 1.0)	/* getminlen() problem with ambiguous sites */
	    deltah = 1.0;
	if (deltalen <= 0)	/* accept the change */
	{
	    if (lendash <= lenbest)	/* store tree if new */
	    {
		if (lendash < lenbest)	/* very best so far */
		treestack_clear(bstackp);	/* discard old bests */
		if (treestack_push(bstackp, xdash, rootdash) == 1)
		newtree = LVB_TRUE;	/* new */
	    }
	    /* update current tree and its stats */
	    prev_len = len;
	    len = lendash;
	    treeswap(&x, &root, &xdash, &rootdash);

	    if (lendash < lenbest)	/* very best so far */
		lenbest = lendash;
	}
	else	/* poss. accept change for the worse */
	{
	    /* Mathematically,
	     *     Pacc = e ** (-1/T * deltaH)
	     *     therefore ln Pacc = -1/T * deltaH
	     *
	     * Computationally, if Pacc is going to be small, we
	     * can assume Pacc is 0 without actually working it
	     * out.
	     * i.e.,
	     *     if ln Pacc < ln eps, let Pacc = 0
	     * substituting,
	     *     if -deltaH / T < ln eps, let Pacc = 0
	     * rearranging,
	     *     if -deltaH < T * ln eps, let Pacc = 0
	     * This lets us work out whether Pacc will be very
	     * close to zero without dividing anything by T. This
	     * should prevent overflow. Since T is no less
	     * than eps and ln eps is going to have greater
	     * magnitude than eps, underflow when calculating
	     * T * ln eps is not possible. */
	    if (-deltah < t * log_wrapper(LVB_EPS))
	    {
		pacc = 0.0;
		/* Call uni() even though its not required. It
		 * would have been called in LVB 1.0A, so this
		 * helps make results identical to results with
		 * that version. */
		(void) uni();
	    }
	    else	/* possibly accept the change */
	    {
		pacc = exp_wrapper(-deltah/t);
		if (uni() < pacc)	/* do accept the change */
		{
		    probaccd = LVB_TRUE;
		    treeswap(&x, &root, &xdash, &rootdash);
		}
	    }
	    if (probaccd == LVB_TRUE)
	    {
		prev_len = len;
		len = lendash;
	    }
	}
	proposed++;
	if (newtree == LVB_TRUE)
	    accepted++;

	/* decide whether to reduce temperature */
	if (accepted >= maxaccept)	/* enough new trees */
	{
	    failedcnt = 0;  /* this temperature a 'success' */
	    dect = LVB_TRUE;
	}
	else if (proposed >= maxpropose)	/* enough proposals */
	{
	    failedcnt++;
	    if (failedcnt >= maxfail)	/* system frozen */
		break;	/* end of cooling */
	    else	/* decrease temp. */
		dect = LVB_TRUE;
	}

	if (dect == LVB_TRUE)
	{
	    t_n++;	/* originally n is 0 */
	    /* near the start of the function we ensure t1_to_t0 is
	     * either zero or no less than LVB_EPS */
	    if (t1_to_t0 < LVB_EPS)
		t = LVB_EPS;
	    else
	    {
		ln_t = ((double) t_n) * log_wrapper(t1_to_t0) + log_wrapper(t0);
		if (ln_t < log_wrapper(LVB_EPS))
		    t = LVB_EPS;
		else
		    t = pow_wrapper(t1_to_t0, (double) t_n) * t0;
	    }
	    proposed = 0;
	    accepted = 0;
	    dect = LVB_FALSE;
	}
	iter++;
    }

    /* free "local" dynamic heap memory */
    free(x);
    free(xdash);

    return lenbest;

} /* end anneal() */