genpt copytree(genpt a){
	genpt temp=a;
	genpt ret,front=NULL;
	genpt final;
	int flag=0;

	while(temp!=NULL){
		if(temp->tag==data){
			ret=getnode(temp->u.c,NULL);
		}
		else
			ret=getnode(NULL,copytree(temp->u.list));
		if(flag==0){
			final=ret;
			flag=1;
		}
		if(front!=NULL)
			front->link=ret;
		ret->tag=temp->tag;
		ret->link=temp->link;
		front=ret;
		temp=temp->link;
	}
Example #2
0
int main() {
	int i,j,n,pt;


#ifdef TEST
	class quadtree<2> testtree,testtree2;
	TinyVector<FLT,2> x1(0.0,0.0),x2(1.0,1.0),x3(1.1,1.1);
	FLT vtest[17][2] = {{0.1,0.1},{0.2,0.4},{.9,0.2},{.125,0.7},{0.51,0.53},{0.85,0.15},{0.25,0.85},{0.99,0.99},{0.001,.3},{0.01,0.3},{0.2,0.1},
	{2.0,2.0},{0.9,0.9},{0.9,0.9},{0.9,0.9},{0.9,0.9},{0.9,0.9}};
	blitz::Array<blitz::TinyVector<FLT,2>,1> vtest2(17);
	FLT dist;

	for(i=0;i<17;++i) {
		vtest2(i)(0) = vtest[i][0];
		vtest2(i)(1) = vtest[i][1];
	}
	
	testtree.init(vtest2, 2000, x1, x2);
	printf("%f %f %f %f\n",testtree.xmin(0),testtree.xmax(0),testtree.xmin(1),testtree.xmax(1));
	for(i=0;i<11;++i) {
		printf("%d\n",i);
		testtree.addpt(i);
	}
	
//	/* Test what happens for point outside domain */
//	printf("point outside test\n");
//	testtree.addpt(11);
//	
//	/* Test what happens for same point 5 times */
//	printf("5 times test\n");
//	for(i=12;i<17;++i)
//		testtree.addpt(i);	

	quadtree<2> copytree(testtree);
			
	dist = testtree.nearpt(9, i); 
	printf("%d %f\n",i,dist);
	dist = copytree.nearpt(9, i); 
	printf("%d %f\n",i,dist);
	
	vtest2(0)[0] = 0.9;
	vtest2(0)[1] = 0.9;
	testtree.update(0,10);

	printf("update ok\n");
	
	testtree.reinit();
	
	dist = testtree.nearpt(vtest2(0), i); 
	printf("%d %f\n",i,dist);  
	
	dist = testtree.nearpt(0, i); 
	printf("%d %f\n",i,dist);
	
	dist = testtree.nearpt(x3.data(), i); 
	printf("%d %f\n",i,dist);
	
	testtree.output("out");
	testtree.output("out",quadtree<2>::text);
	
	/* What happens if I insert point twice? */
	testtree.addpt(0);
	
	
//	class quadtree<3> octtree;
//	FLT y1[3] = {0.0,0.0,0.0},y2[3] ={1.0,1.0,1.0};
//	FLT wtest[9][3] = {{0.1,0.1,0.1},{0.1,0.1,0.9},{0.1,0.9,0.1},{0.1,0.9,0.9},{0.9,0.1,0.1},{0.9,0.1,0.9},{0.9,0.9,0.1},{0.9,0.9,0.9}, {0.9,0.85,0.9}};
//	octtree.init(wtest, 20, y1, y2);
//	for(i=0;i<9;++i) {
//			printf("%d\n",i);
//			octtree.addpt(i);
//	}
//
//	quadtree<3> copytree3(octtree);
//			
//	dist = octtree.nearpt(8, i); 
//	printf("%d %f\n",i,dist);
//	dist = copytree3.nearpt(8, i); 
//	printf("%d %f\n",i,dist);
//	
//	
//	wtest[0][0] = 0.9;
//	wtest[0][1] = 0.9;
//	wtest[0][2] = 0.87;
//	octtree.update(0,9);
//	
//	printf("update ok\n");
//	
//	octtree.reinit();
//	
//	dist = octtree.nearpt(0, i); 
//	printf("%d %f\n",i,dist);
//	
//	octtree.output("out3");
//	octtree.output("out3",quadtree<3>::text);
//
//	/* What happens if I insert 4 points outside of domain? */
//	quadtree<2> bigtree;
//	bigtree.init(vtest,100000, x1, x2);
//		for(i=0;i<16;++i) {
//				printf("%d\n",i);
//				bigtree.addpt(i);
//		}
//	bigtree.output("huh",quadtree<2>::text);


#endif

#ifdef FINDUNIQUE
	int nvrts = 556732;

	class quadtree<3> dups;
	FLT (*vrts)[3];
	FLT xmax[3],xmin[3];
	FLT dist1;
	int tvrtx[3];
	int *ipoint;

	ipoint = new int[nvrts];
	if (ipoint == 0) printf("shit\n");
	vrts = (FLT (*)[3]) malloc(nvrts*3*sizeof(double));
	if (vrts == NULL) printf("shit\n");

	dups.allocate(vrts,nvrts);
	scanf("%lf %lf %lf\n",&vrts[0][0],&vrts[0][1],&vrts[0][2]);
	
	for(n=0;n<3;++n) {
			xmax[n] = vrts[0][n];
			xmin[n] = vrts[0][n];
	}
	
	for(i=1;i<nvrts;++i) {
			scanf("%lf %lf %lf",&vrts[i][0],&vrts[i][1],&vrts[i][2]);
			for(n=0;n<3;++n) {
					xmax[n] = MAX(vrts[i][n],xmax[n]);
					xmin[n] = MIN(vrts[i][n],xmin[n]);
			}
	}
	
	for(i=0;i<nvrts;++i)
			for(n=0;n<3;++n)
					vrts[i][n] -= xmax[n];

	for(n=0;n<3;++n) {
			xmin[n] -= xmax[n];
			xmax[n] = 0.0;
	}

	dups.init(vrts,nvrts,xmin,xmax);
	dups.addpt(0);
	printf("%17.10e %17.10e %17.10e\n",vrts[0][0],vrts[0][1],vrts[0][2]);
	ipoint[0] = 0;
	int count = 1;

	for(i=0;i<nvrts;i+=4) {
			for(j=0;j<3;++j) {
					dist1 = dups.nearpt(vrts[i+j], pt);
					if (fabs((vrts[i+j][0]-vrts[pt][0])/xmin[0]) > 1.0e-4
							 || fabs((vrts[i+j][1]-vrts[pt][1])/xmin[1]) > 1.0e-4
							 || fabs((vrts[i+j][2]-vrts[pt][2])/xmin[2]) > 1.0e-4) {
							printf("%17.10e %17.10e %17.10e\n",vrts[i+j][0],vrts[i+j][1],vrts[i+j][2]);
							dups.addpt(i+j);
							ipoint[i+j] = count;
							pt = count++;
					}
					else {
							pt = ipoint[pt];
					}
					tvrtx[j] = pt;
			}
			printf("# %d %d %d\n",tvrtx[0]+1,tvrtx[1]+1,tvrtx[2]+1);

	}
#endif


	return(0);
}
Example #3
0
int main_test_tree(int argc, char **argv) {
	unsigned int maxloop = 1;
	if (argc > 1)
		maxloop = atoi(argv[1]);

	for (unsigned int j = 0; j < maxloop; ++j) {
		tree<std::string> tr9;
		tr9.set_head("hi");
		tr9.insert(tr9.begin().begin(), "0");
		tr9.insert(tr9.begin().begin(), "1");
		print_tree(tr9, tr9.begin(), tr9.end());

		tree<std::string> tr;
		tree<std::string>::pre_order_iterator html, body, h1, h3, bh1, mv1;

		std::cout << "empty tree to begin with:" << std::endl;
		print_tree(tr, tr.begin(), tr.end());

		html = tr.insert(tr.begin(), "html");
		tr.insert(html, "extra");
//		tr.insert(html,"zextra2");
		body = tr.append_child(html, "body");
		h1 = tr.append_child(body, "h1");
		std::cout << tr.index(h1) << std::endl;
		bh1 = tr.insert(h1, "before h1");
		tr.append_child(h1, "some text");
		tree<std::string>::sibling_iterator more_text = tr.append_child(body,
				"more text");

		std::cout << " 'more text' is sibling " << tr.index(more_text)
				<< " in its sibling range" << std::endl;

		std::cout << "filled tree:" << std::endl;
		print_tree(tr, tr.begin(), tr.end());

		std::cout << "filled tree, post-order traversal:" << std::endl;
		print_tree_post(tr, tr.begin_post(), tr.end_post());

		tr.swap(bh1);
		std::cout << "swapped elements:" << std::endl;
		print_tree(tr, tr.begin(), tr.end());
		tr.swap(h1);
		std::cout << "swapped back:" << std::endl;
		print_tree(tr, tr.begin(), tr.end());

		tree<std::string> copytree(h1);
		std::cout << "copied tree:" << std::endl;
		print_tree(copytree, copytree.begin(), copytree.end());

		// Now test the STL algorithms
		std::cout << "result of search for h1 and kasper:" << std::endl;
		tree<std::string>::pre_order_iterator it;
		it = std::find(tr.begin(), tr.end(), std::string("h1"));
		if (it != tr.end())
			print_tree(tr, it, tr.next_sibling(it));
		else
			std::cout << "h1 not found" << std::endl;
		it = std::find(tr.begin(), tr.end(), std::string("kasper"));
		if (it != tr.end())
			print_tree(tr, it, tr.next_sibling(it));
		else
			std::cout << "kasper not found" << std::endl;
		std::cout << std::endl;

		// remove the h1, replace it with new subtree
		tree<std::string> replacement;
		h3 = replacement.insert(replacement.begin(), "h3");
		replacement.append_child(h3, "text in h3");
		std::cout << "replacement tree:" << std::endl;
		print_tree(replacement, replacement.begin(), replacement.end());
		print_tree(tr, tr.begin(), tr.end());
		h1 = tr.replace(tree<std::string>::sibling_iterator(h1),
				tr.next_sibling(h1), tree<std::string>::sibling_iterator(h3),
				tr.next_sibling(h3));
		std::cout << "filled tree with replacement done:" << std::endl;
		print_tree(tr, tr.begin(), tr.end());

		// replace h3 node while keeping children
		h1 = tr.replace(h1, "<foobar>");
		print_tree(tr, tr.begin(), tr.end());

		// add a sibling to the head
		tr.insert_after(h1, "more");

		// Copy object.
		tree<std::string> tr2 = tr;
		print_tree(tr2, tr2.begin(), tr2.end());
		tree<std::string> tr3(tr);

		// reparent "before h1" to h3 node
		tr.reparent(h1, bh1, tr.next_sibling(bh1));
		std::cout << "moved content:" << std::endl;
		print_tree(tr, tr.begin(), tr.end());

		// iterate over children only
		tree<std::string>::sibling_iterator ch = tr.begin(h1);
		std::cout << "children of h1:" << std::endl;
		while (ch != tr.end(h1)) {
			std::cout << (*ch) << std::endl;
			++ch;
		}
		std::cout << std::endl;

		// flatten the h3 node
		tr.flatten(h1);
		std::cout << "flattened (at h3) tree:" << std::endl;
		print_tree(tr, tr.begin(), tr.end());

		// Erase the subtree of tr below body.
		tr.erase_children(body);
		std::cout << "children of body erased:" << std::endl;
		print_tree(tr, tr.begin(), tr.end());
		it = std::find(tr.begin(), tr.end(), "h1");
		if (it != tr.end())
			print_tree(tr, it, tr.next_sibling(it));
		else
			std::cout << "h1 not found" << std::endl;

		// Erase everything
		tr.erase(tr.begin());
		std::cout << "erased tree:" << std::endl;
		print_tree(tr, tr.begin(), tr.end());

		// The copies are deep, ie. all nodes have been copied.
		std::cout << "copies still exist:" << std::endl;
		print_tree(tr2, tr2.begin(), tr2.end());
		print_tree(tr3, tr3.begin(), tr3.end());

		// Test comparison
		std::cout << "testing comparison functions:" << std::endl;
		std::cout
				<< std::equal(tr2.begin(), tr2.end(), tr3.begin(),
						std::equal_to<std::string>()) << " (should be 1)"
				<< std::endl;
		// modify content but not structure
		tree<std::string>::pre_order_iterator fl3 = tr3.begin();
		fl3 += 4; // pointing to "<foobar>" node
		std::cout << (*fl3) << std::endl;
		std::string tmpfl3 = (*fl3);
		(*fl3) = "modified";
		std::cout
				<< std::equal(tr2.begin(), tr2.end(), tr3.begin(),
						std::equal_to<std::string>()) << " (should be 0)"
				<< std::endl;
		std::cout
				<< tr2.equal(tr2.begin(), tr2.end(), tr3.begin(),
						std::equal_to<std::string>()) << " (should be 0)"
				<< std::endl;
		std::cout << tr2.equal(tr2.begin(), tr2.end(), tr3.begin(), truefunc)
				<< " (should be 1)" << std::endl;
		// modify tr3 structure (but not content)
		(*fl3) = tmpfl3;
		tr3.flatten(fl3);
		std::cout << "tree flattened, test again" << std::endl;
		print_tree(tr3, tr3.begin(), tr3.end());

		// Test comparison again
		std::cout
				<< tr2.equal(tr2.begin(), tr2.end(), tr3.begin(),
						std::equal_to<std::string>()) << " (should be 0)"
				<< std::endl;
		std::cout
				<< std::equal(tr2.begin(), tr2.end(), tr3.begin(),
						std::equal_to<std::string>()) << " (should be 1)"
				<< std::endl;
		// Change content
		(*fl3) = "modified";
		// Test comparison again
		std::cout
				<< std::equal(tr2.begin(), tr2.end(), tr3.begin(),
						std::equal_to<std::string>()) << " (should be 0)"
				<< std::endl;
		std::cout
				<< tr2.equal(tr2.begin(), tr2.end(), tr3.begin(),
						std::equal_to<std::string>()) << " (should be 0)"
				<< std::endl;

		// Testing sort. First add a subtree to one leaf
		tree<std::string>::pre_order_iterator txx3 = tr3.begin();
		txx3 += 5;
		tr3.append_child(txx3, "ccc");
		tr3.append_child(txx3, "bbb");
		tr3.append_child(txx3, "bbb");
		tr3.append_child(txx3, "aaa");
		std::less<std::string> comp;
		tree<std::string>::pre_order_iterator bdy = tr3.begin();
		bdy += 2;
		assert(tr.is_valid(bdy));
		std::cout << "unsorted subtree:" << std::endl;
		print_tree(tr3, tr3.begin(), tr3.end());
		tree<std::string>::sibling_iterator sortit1 = tr3.begin(bdy), sortit2 =
				tr3.begin(bdy);
		sortit1 += 2;
		sortit2 += 4;
		assert(tr.is_valid(sortit1));
		assert(tr.is_valid(sortit2));
		std::cout << "partially sorted subtree: (" << "sorted from "
				<< (*sortit1) << " to " << (*sortit2)
				<< ", excluding the last element)" << std::endl;

		mv1 = tr3.begin();
		++mv1;
		tr3.sort(sortit1, sortit2);
		print_tree(tr3, tr3.begin(), tr3.end());
		tr3.sort(tr3.begin(bdy), tr3.end(bdy), comp, true); // false: no sorting of subtrees
//    Sorting the entire tree, level by level, is much simpler:
//		tr3.sort(tr3.begin(), tr3.end(), true);
		std::cout << "sorted subtree:" << std::endl;
		print_tree(tr3, tr3.begin(), tr3.end());

		// Michael's problem
//		std::cout << mv1.node << ", " << tr3.feet << ", " << tr3.feet->prev_sibling << std::endl;
//		std::cout << mv1.node->next_sibling << ", " << tr3.feet->prev_sibling << ", " << tr3.end().node << std::endl;
//		tr3.sort(tr3.begin(), tr3.end(), true);		
//		std::cout << mv1.node << ", " << tr3.feet << ", " << tr3.feet->prev_sibling << std::endl;
//		std::cout << mv1.node->next_sibling << ", " << tr3.feet->prev_sibling << ", " << tr3.end().node << std::endl;
//		print_tree(tr3, tr3.begin(), tr3.end());
//		tr3.sort(tr3.begin(), tr3.end(), true);
//		std::cout << mv1.node << ", " << tr3.feet << ", " << tr3.feet->prev_sibling << std::endl;
//		std::cout << mv1.node->next_sibling << ", " << tr3.feet->prev_sibling << ", " << tr3.end().node << std::endl;
//		print_tree(tr3, tr3.begin(), tr3.end());
//		return 1;

		// Test merge algorithm.
		std::cout << "test merge" << std::endl;
		tree<std::string> mtree;
		tree<std::string>::pre_order_iterator mt1, mt2, mt3;
		mt1 = mtree.insert(mtree.begin(), "html");
		mt2 = mtree.append_child(mt1, "head");
		mt3 = mtree.append_child(mt1, "body");
// Adding it without head having any children tests whether we can
// insert at the end of an empty list of children. 
		mtree.append_child(mt2, "title");
		mtree.append_child(mt3, "h1");
		mtree.append_child(mt3, "h1");

		tree<std::string> mtBree;
		tree<std::string>::pre_order_iterator mtB1, mtB2;
		mtB1 = mtBree.insert(mtBree.begin(), "head");
		mtB2 = mtBree.append_child(mtB1, "another title");
		print_tree(mtree, mtree.begin(), mtree.end());
		print_tree(mtBree, mtBree.begin(), mtBree.end());

		mtree.merge(mtree.begin(), mtree.end(), mtBree.begin(), mtBree.end(),
				true);
		print_tree(mtree, mtree.begin(), mtree.end());
		mtree.merge(mtree.begin(mtree.begin()), mtree.end(mtree.begin()),
				mtBree.begin(), mtBree.end(), true);
		print_tree(mtree, mtree.begin(), mtree.end());

		// Print tree in reverse (test operator--)
		print_tree_rev(mtree, mtree.end(), mtree.begin());
		print_tree_rev_post(mtree, mtree.end_post(), mtree.begin_post());

		// Breadth-first
		tree<std::string> bft;
		tree<std::string>::iterator bfB, bfC, bfD;
		bft.set_head("A");
		bfB = bft.append_child(bft.begin(), "B");
		bfC = bft.append_child(bft.begin(), "C");
		bfD = bft.append_child(bft.begin(), "D");
		bft.append_child(bfB, "E");
		bft.append_child(bfB, "F");
		bft.append_child(bfC, "G");
		bft.append_child(bfC, "H");
		bft.append_child(bfD, "I");
		tree<std::string>::breadth_first_queued_iterator bfq =
				bft.begin_breadth_first();
		while (bfq != bft.end_breadth_first()) {
			std::cout << *bfq << std::endl;
			++bfq;
		}

		print_tree(bft, bft.begin(), bft.end());
		bft.wrap(bfD, "wrap");
		print_tree(bft, bft.begin(), bft.end());

		tree<std::string>::leaf_iterator li = tr.begin_leaf(bfC);
		while (li != tr.end_leaf(bfC)) {
			std::cout << *li << std::endl;
			++li;
		}

//		test_move_constructor();

	}
	return 0;
}
Example #4
0
double shake(int nb, char** seq, char** seqname, char* ctree, options opt, char** eval_input, int nb_eval_input){

  int nb2, i, j, ii, jj, k, l, *ttree[MAXNSP], **curtree, **newtree, **evaltree, nbbi, nbdclade, nbgclade, print1, print2;
  int nochange, pres_grossiere=-1, l1, l2, restart_d, restart_g, oldmovedist;
  int **dclade, **gclade, **newdclade, **newgclade, **ddist, **gdist, movedist, maxmovedist;
  int **list_tree, lliste, *solid;
  long nblist, nblistmax;
  double *lgbp, *sortedlgbp, *lgbi, *bootvals, fracroot1, lkh, maxlkh, maxlcrossedbranch;
  char *nom[MAXNSP], *nom2[MAXNSP], **dcladename, **gcladename, **list1, **list2, racine, *ctreenew, *ctreenew_nobl, *treedeb, *ctree1, *ctree2;
  FILE* outfile1, *outfile2;
  print_option trueprint, noprint;


  print1=opt->print->PRINT1;
  print2=opt->print->PRINT2;
  noprint=check_alloc(1, sizeof(struct print_option));
  noprint->PRINT3=0;
  if(opt->print->PRINT2)
    noprint->PRINT1=noprint->PRINT2=1;
  else
    noprint->PRINT1=noprint->PRINT2=0;
  if(print1) noprint->PRINT0=1; else noprint->PRINT0=0;
  trueprint=opt->print;
  opt->print=noprint;
  maxlcrossedbranch=opt->SH_MAXLCROSSED;



		/* READ TREE STRING */

  lgbp=(double*)check_alloc(nb+1, sizeof(double));
  sortedlgbp=(double*)check_alloc(nb+1, sizeof(double));
  lgbi=(double*)check_alloc(nb+1, sizeof(double));
  for(i=0;i<nb+1;i++)
    lgbp[i]=lgbi[i]=-1.;

  solid=(int*)check_alloc(nb+1, sizeof(int));
  bootvals=(double*)check_alloc(nb+1, sizeof(double));
  if(nb>=MAXNSP) {printf("Too many sequences\n"); exit(EXIT_FAILURE);}
  for(i=0;i<=nb;i++){
    nom[i]=(char*)check_alloc(MAXLNAME+1, sizeof(char));
    nom2[i]=(char*)check_alloc(MAXLNAME+1, sizeof(char));
    ttree[i]=(int*)check_alloc(nb, sizeof(int));
  }
  list1=check_alloc(nb, sizeof(char*));
  list2=check_alloc(nb, sizeof(char*));
  curtree=(int**)check_alloc(nb+1, sizeof(int*));
  newtree=(int**)check_alloc(nb+1, sizeof(int*));
  evaltree=(int**)check_alloc(nb+1, sizeof(int*));
  for(i=0;i<nb+1;i++) newtree[i]=(int*)check_alloc(nb-2, sizeof(int));
  ctreenew=(char*)check_alloc(2*MAXLNAME*nb, sizeof(char));
  ctree1=(char*)check_alloc(2*MAXLNAME*nb, sizeof(char));
  ctree2=(char*)check_alloc(2*MAXLNAME*nb, sizeof(char));
  ctreenew_nobl=(char*)check_alloc(2*MAXLNAME*nb, sizeof(char));


  nb2=ctot(ctree, ttree, lgbi, lgbp, bootvals, nom, &racine, &nbbi);

  if(nb2<nb){
    printf("More species in sequence file than in tree file\n");
    exit(EXIT_FAILURE);
  }
  if(nb2>nb){
    printf("More species in tree file than in sequence file\n");
    exit(EXIT_FAILURE);
  }


	/* PREPARE TREE : UNROOT, SET LEFT and RIGHT LISTS, SORT TAXA */

  if(racine=='r'){
    unroot(ttree, nb, lgbi, lgbp, bootvals, nom, list1, list2, &l1, &l2, &fracroot1);
  }
  else{
    printf("Tree must be rooted\n");
    exit(EXIT_FAILURE);
  }
  nbbi--;
  if(nbbi!=nb-3){
    printf("Tree must be bifurcating\n");
    exit(EXIT_FAILURE);
  }

  for(i=0;i<nb;i++){
    for(j=0;j<nb;j++){
      if(samename(seqname[i], nom[j])){
	curtree[i]=ttree[j];
	sortedlgbp[i]=lgbp[j];
	break;
      }
    }
  }

  for(i=0;i<nb-3;i++) if(bootvals[i]>opt->SH_MAXBOOTCROSSED) solid[i]=1;

  ctree_noblbs(ctree, ctreenew_nobl, strlen(ctree));

	/* EVALUATE INITIAL TREE */

  if(print1)
    printf("\nEvaluating initial tree : \n%s\n", ctreenew_nobl);
  if(print2)
    printf("\n");

  maxlkh=maxlike(nb, seq, seqname, curtree, lgbi, sortedlgbp, nbbi, l1, list1, l2, list2, opt, NULL, NULL, NULL);
  if(opt->SH_RESTART) save_current_best("current_best_tree", ctreenew_nobl, maxlkh, 1);
  if(opt->SH_RESTART) save_evaluated("evaluated_trees", ctreenew_nobl, maxlkh, 1);

	/* ALLOCATE SHAKE VARIABLES */

  nbdclade=2*l1-1;
  nbgclade=2*l2-1;
  dclade=(int**)check_alloc(nbdclade, sizeof(int*));
  for(i=0;i<nbdclade;i++)
    dclade[i]=(int*)check_alloc(nb, sizeof(int));
  gclade=(int**)check_alloc(2*nb, sizeof(int*));
  for(i=0;i<nbgclade;i++)
    gclade[i]=(int*)check_alloc(nb, sizeof(int));
  newdclade=(int**)check_alloc(nbdclade, sizeof(int*));
  for(i=0;i<nbdclade;i++)
    newdclade[i]=(int*)check_alloc(nb, sizeof(int));
  newgclade=(int**)check_alloc(nbgclade, sizeof(int*));
  for(i=0;i<nbgclade;i++)
    newgclade[i]=(int*)check_alloc(nb, sizeof(int));
  ddist=(int**)check_alloc(nbdclade, sizeof(int*));
  gdist=(int**)check_alloc(nbgclade, sizeof(int*));
  for(i=0;i<nbdclade;i++) ddist[i]=(int*)check_alloc(nbdclade, sizeof(int));
  for(i=0;i<nbgclade;i++) gdist[i]=(int*)check_alloc(nbgclade, sizeof(int));
  dcladename=(char**)check_alloc(nbdclade, sizeof(char*));
  gcladename=(char**)check_alloc(nbgclade, sizeof(char*));
  for(i=0;i<nbdclade;i++)
    dcladename[i]=(char*)check_alloc(nb*(MAXLNAME+3)+1, sizeof(char));
  for(i=0;i<nbgclade;i++)
    gcladename[i]=(char*)check_alloc(nb*(MAXLNAME+3)+1, sizeof(char));
  nblistmax=nb*nb;
  if(nblistmax<MIN_NBLISTMAX) nblistmax=MIN_NBLISTMAX;
  if(nblistmax<nb_eval_input) nblistmax=nb_eval_input;
  if(nblistmax>MAX_NBLISTMAX) nblistmax=MAX_NBLISTMAX;
  while(1){
    lliste=(nblistmax*(nb-3)+lmot-1)/lmot;
    list_tree=(int**)check_alloc(nb, sizeof(int*));
    for(i=0;i<nb;i++)
      list_tree[i]=(int*)calloc(lliste, sizeof(int));
    if(list_tree[nb-1]) break;
    nblistmax/=2;
    if(nblistmax==0){
      printf("Not enough memory\n");
      exit(EXIT_FAILURE);
    }
  }


	/* SET LIST OF EVALUATED TREES */

  if(eval_input){
    nblist=0;
    for(k=0;k<nb_eval_input;k++){
      for(i=0;i<=nb;i++) ttree[i]=check_alloc(nb, sizeof(int));
      nb2=ctot(eval_input[k], ttree, NULL, NULL, NULL, nom2, &racine, NULL);
      if(racine=='r')
        unroot(ttree, nb, NULL, NULL, NULL, nom2, NULL, NULL, NULL, NULL, NULL);
      else{ printf("Evaluated trees must be rooted\n"); exit(EXIT_FAILURE);}
      for(i=0;i<nb;i++){
        for(j=0;j<nb;j++){
          if(samename(seqname[i], nom2[j])){
	    evaltree[i]=ttree[j];
	    break;
          }
        }
      }
      if(deja_evalue(evaltree, nb, list_tree, nblist, nblistmax)) continue;
      addtolist(evaltree, nb, list_tree, nblist, nblistmax);
      nblist++;
    }
    printf("%d already evaluated topologies loaded\n", nblist);
  }
  else{
    addtolist(curtree, nb, list_tree, 0, nblistmax);
    nblist=1;
  }


	/* SHAKE */

  treedeb=ctreenew;
  nochange=1; movedist=0; 
  if(opt->SH_G>0 && opt->SH_G<nb-3) 
    maxmovedist=opt->SH_G;
  else
    maxmovedist=nb-3;

  if(print1)
    printf("\nStarting rearrangements\n");
  
  do{

    oldmovedist=movedist;

    if(nochange==1) movedist++;
    else movedist=1;

    if(print1 && !(nochange==0 && oldmovedist==1)){
      printf("\nCrossing %d internal branch", movedist);
      if(movedist>1) printf("es");
      printf("\n");
    }

    nochange=1;





    while(1){
      setclades(curtree, nb, seqname, l1, list1, l2, list2, dclade, gclade, ddist, gdist, nbdclade, nbgclade, dcladename, gcladename);
      restart_d=0;
      for(i=0;i<nbdclade;i++){
        for(j=0;j<nbdclade;j++){
	  if(abs(ddist[i][j])!=movedist) continue; 
	  if(ddist[i][j]<0) continue;
	  moveclade(dclade, newdclade, nbdclade, nb, ddist, i, j);
	  settree(newdclade, nbdclade, gclade, nbgclade, nb, newtree);

	  if(deja_evalue(newtree, nb, list_tree, nblist, nblistmax))
	    continue;
          if(solid_branch_crossed(newtree, curtree, nb, solid))
	    continue;

	  addtolist(newtree, nb, list_tree, nblist, nblistmax);
  	  nblist++;
	  if(print1){
	    printf("\nMoving %s toward %s\n", dcladename[i], dcladename[j]);
          }
	  if(print2)
	    printf("\n");
	  lkh=maxlike(nb, seq, seqname, newtree, NULL, NULL, nbbi, l1, list1, l2, list2, opt, ctreenew, NULL, NULL);

	  if(lkh>maxlkh){
  	    ctree_noblbs(ctreenew, ctreenew_nobl, strlen(ctreenew));
	    if(print1)
	      printf("New tree is optimal : \n%s\n\nRestarting rearrangements\n", ctreenew_nobl);
	    maxlkh=lkh;
	    copytree(newtree, curtree, nb);
            if(opt->SH_RESTART) save_current_best("current_best_tree", ctreenew_nobl, lkh, 0);
            if(opt->SH_RESTART) save_evaluated("evaluated_trees", ctreenew_nobl, lkh, 0);
	    restart_d=1;
	    nochange=0;
	    ctreenew=treedeb;
	    while(*ctreenew) {*ctreenew=0; ctreenew++; }
	    ctreenew=treedeb;
	    break;
	  }
	  else{
	    if(print1)
	      printf("No improvement:\n");
            ctree_noblbs(ctreenew, ctreenew_nobl, strlen(ctreenew));
            if(print1)
              printf("%s\n", ctreenew_nobl);
            if(opt->SH_RESTART) save_evaluated("evaluated_trees", ctreenew_nobl, lkh, 0);
	  }
	  ctreenew=treedeb;
	  while(*ctreenew) {*ctreenew=0; ctreenew++; }
	  ctreenew=treedeb;
        }
      if(restart_d) break;
      }
      if(!restart_d || movedist>1) break;
    }

    if(restart_d && movedist>1) continue;

    while(1){
      setclades(curtree, nb, seqname, l1, list1, l2, list2, dclade, gclade, ddist, gdist, nbdclade, nbgclade, dcladename, gcladename);
      restart_g=0;
      for(i=0;i<nbgclade;i++){
        for(j=0;j<nbgclade;j++){
	  if(abs(gdist[i][j])!=movedist) continue;
	  if(gdist[i][j]<0) continue;

	  moveclade(gclade, newgclade, nbgclade, nb, gdist, i, j);
	  settree(dclade, nbdclade, newgclade, nbgclade, nb, newtree);

	  if(deja_evalue(newtree, nb, list_tree, nblist, nblistmax))
	    continue;
          if(solid_branch_crossed(newtree, curtree, nb, solid))
	    continue;
	  addtolist(newtree, nb, list_tree, nblist, nblistmax);
	  nblist++;
	  if(print1){
	    printf("\nMoving %s toward %s\n", gcladename[i], gcladename[j]);
          }
	  if(print2){
	    printf("\n");
          }

	  lkh=maxlike(nb, seq, seqname, newtree, NULL, NULL, nbbi, l1, list1, l2, list2, opt, ctreenew, NULL, NULL);

	  if(lkh>maxlkh){
  	    ctree_noblbs(ctreenew, ctreenew_nobl, strlen(ctreenew));
	    if(print1)
	      printf("New tree is optimal : \n%s\n\nRestarting rearrangements\n", ctreenew_nobl);
	    maxlkh=lkh;
	    copytree(newtree, curtree, nb);
	    if(opt->SH_RESTART) save_current_best("current_best_tree", ctreenew_nobl, lkh, 0);
            if(opt->SH_RESTART) save_evaluated("evaluated_trees", ctreenew_nobl, lkh, 0);
            restart_g=1;
	    nochange=0;
	    ctreenew=treedeb;
	    while(*ctreenew) {*ctreenew=0; ctreenew++; }
	    ctreenew=treedeb;
	    break;
	  }
	  else{
	    if(print1)
	      printf("No improvement:\n");
            ctree_noblbs(ctreenew, ctreenew_nobl, strlen(ctreenew));
            if(print1)
              printf("%s\n", ctreenew_nobl);
            if(opt->SH_RESTART) save_evaluated("evaluated_trees", ctreenew_nobl, lkh, 0);
	  }
	  ctreenew=treedeb;
	  while(*ctreenew) {*ctreenew=0; ctreenew++; }
	  ctreenew=treedeb;
        }
      if(restart_g) break;
      }
      if(!restart_g || movedist>1) break;
    }
  } while(nochange==0 || movedist!=maxmovedist);



  	/* FINAL EVALUATION */

  if(print1)
    printf("\nFinal evaluation\n");
  if(print2)
    printf("\n");
  opt->print=trueprint;

  maxlkh=maxlike(nb, seq, seqname, curtree, NULL, NULL, nbbi, l1, list1, l2, list2, opt, NULL, ctree1, ctree2);

  if(ctree1){
    outfile1=fopen("treefile.eqgc", "w");
    outfile2=fopen("treefile.ndgc", "w");
    if(outfile1==NULL || outfile2==NULL){ printf("Cannot write tree file\n"); exit(EXIT_FAILURE); }
    fprintf(outfile1, "%s\n", ctree1);
    fprintf(outfile2, "%s\n", ctree2);
    if(print1){
      printf("Tree is written into files : treefile.eqgc (equilibrium G+C content)\n");
      printf("                             treefile.ndgc (G+C content at each node)\n\n");
    }
  }


  free(lgbp); free(sortedlgbp); free(lgbi);
  free(bootvals);
  for(i=0;i<nb;i++){ free(nom[i]); free(ttree[i]); }
  free(list1); free(list2); free(curtree);

  
  return maxlkh;
}