source: tags/initial/GDE/PHYLIP/fitch.c

Last change on this file was 2, checked in by oldcode, 24 years ago

Initial revision

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 44.2 KB
Line 
1#include "phylip.h"
2
3/* version 3.56c. (c) Copyright 1993 by Joseph Felsenstein.
4   Written by Joseph Felsenstein, Akiko Fuseki, Sean Lamont, and Andrew Keeffe.
5   Permission is granted to copy and use this program provided no fee is
6   charged for it and provided that this copyright notice is not removed. */
7
8#define smoothings      4    /* number of passes through smoothing algorithm */
9#define namelength      10   /* number of characters max. in species name    */
10#define epsilon         0.000001   /* a very small but not too small number  */
11
12#define ibmpc0          false
13#define ansi0           true
14#define vt520           false
15
16typedef double *vector;
17typedef short *intvector;
18typedef Char naym[namelength];
19typedef short longer[6];
20
21typedef struct node {
22  struct node *next, *back;
23  boolean tip, iter;
24  short number;
25  naym nayme;
26  vector d, w;
27  double v, dist;
28  short xcoord, ycoord, ymin, ymax;
29} node;
30
31typedef struct tree {
32  node **nodep;
33  double likelihood;
34  node *start;
35} tree;
36
37
38FILE *infile, *outfile, *treefile;
39short numsp,numsp1,numsp2,nums,inseed,outgrno,col,datasets,ith,
40             i, j, l, jumb, njumble=0;
41vector *x;
42intvector *reps;
43naym *nayms;
44boolean global,jumble,lengths,usertree,lower,upper, negallowed,
45               outgropt,replicates, trout,  printdata, progress, treeprint,
46               mulsets, ibmpc, vt52, ansi, firstset=false;
47double power;
48longer seed;
49short *enterorder;
50tree curtree, priortree, bestree, bestree2;
51Char ch;
52
53
54openfile(fp,filename,mode,application,perm)
55FILE **fp;
56char *filename;
57char *mode;
58char *application;
59char *perm;
60{
61  FILE *of;
62  char file[100];
63  strcpy(file,filename);
64  while (1){
65    of = fopen(file,mode);
66    if (of)
67      break;
68    else {
69      switch (*mode){
70      case 'r':
71        printf("%s:  can't read %s\n",application,file);
72        file[0] = '\0';
73        while (file[0] =='\0'){
74          printf("Please enter a new filename>");
75          gets(file);}
76        break;
77      case 'w':
78        printf("%s: can't write %s\n",application,file);
79        file[0] = '\0';
80        while (file[0] =='\0'){
81          printf("Please enter a new filename>");
82          gets(file);}
83        break;
84      }
85    }
86  }
87  *fp=of;
88  if (perm != NULL)
89    strcpy(perm,file);
90}
91
92
93double randum(seed)
94short *seed;
95{
96  /* random number generator -- slow but machine independent */
97  short i,j,k,sum;
98  longer mult, newseed;
99  double x;
100
101  mult[0] = 13;
102  mult[1] = 24;
103  mult[2] = 22;
104  mult[3] = 6;
105
106  for (i = 0; i <= 5; i++)
107    newseed[i] = 0;
108  for (i = 0; i <= 5; i++) {
109    sum = newseed[i];
110    k = i;
111    if (i > 3)
112      k = 3;
113    for (j = 0; j <= k; j++)
114      sum += mult[j] * seed[i - j];
115    newseed[i] = sum;
116    for (j = i; j <= 4; j++) {
117      newseed[j + 1] += newseed[j] / 64;
118      newseed[j] &= 63;
119    }
120  }
121  memcpy(seed, newseed, sizeof(longer));
122  seed[5] &= 3;
123  x = 0.0;
124  for (i = 0; i <= 5; i++)
125    x = x / 64.0 + seed[i];
126  x /= 4.0;
127  return x;
128}  /* randum */
129
130void uppercase(ch)
131Char *ch;
132{
133  /* convert a character to upper case -- either ASCII or EBCDIC */
134   *ch = (islower(*ch) ?  toupper(*ch) : (*ch));
135}  /* uppercase */
136
137
138void getnums()
139{
140  /* read species number */
141  fscanf(infile, "%hd", &numsp);
142  fprintf(outfile, "\n%4hd Populations\n", numsp);
143  numsp1 = numsp + 1;
144  numsp2 = numsp * 2 - 2;
145}  /* getnums */
146
147void getoptions()
148{
149  /* interactively set options */
150  short i, inseed0=0;
151  Char ch;
152  boolean done=false, done1=false;
153
154  fprintf(outfile, "\nFitch-Margoliash method version %s\n\n",VERSION);
155  putchar('\n');
156  global = false;
157  jumble = false;
158  njumble = 1;
159  lengths = false;
160  lower = false;
161  negallowed = false;
162  outgrno = 1;
163  outgropt = false;
164  power = 2.0;
165  replicates = false;
166  trout = true;
167  upper = false;
168  usertree = false;
169  printdata = false;
170  progress = true;
171  treeprint = true;
172  do {
173    printf(ansi ? "\033[2J\033[H" :
174           vt52 ? "\033E\033H"    : "\n");
175    printf("\nFitch-Margoliash method version %s\n\n",VERSION);
176    printf("Settings for this run:\n");
177    printf("  U                 Search for best tree?  %s\n",
178           (usertree ? "No, use user trees in input file" : "Yes"));
179    if (usertree) {
180      printf("  N          Use lengths from user trees?  %s\n",
181             (lengths ? "Yes" : "No"));
182    }
183    printf("  P                                Power?%9.5f\n",power);
184    printf("  -      Negative branch lengths allowed?  %s\n",
185           negallowed ? "Yes" : "No");
186    printf("  O                        Outgroup root?");
187    if (outgropt)
188      printf("  Yes, at species number%3hd\n", outgrno);
189    else
190      printf("  No, use as outgroup species%3hd\n", outgrno);
191    printf("  L         Lower-triangular data matrix?");
192    if (lower)
193      printf("  Yes\n");
194    else
195      printf("  No\n");
196    printf("  R         Upper-triangular data matrix?");
197    if (upper)
198      printf("  Yes\n");
199    else
200      printf("  No\n");
201    printf("  S                        Subreplicates?");
202    if (replicates)
203      printf("  Yes\n");
204    else
205      printf("  No\n");
206    if (!usertree) {
207      printf("  G                Global rearrangements?");
208      if (global)
209        printf("  Yes\n");
210      else
211        printf("  No\n");
212      printf("  J     Randomize input order of species?");
213      if (jumble)
214        printf("  Yes (seed =%8hd,%3hd times)\n", inseed0, njumble);
215      else
216        printf("  No. Use input order\n");
217    }
218    printf("  M           Analyze multiple data sets?");
219    if (mulsets)
220      printf("  Yes, %2hd sets\n", datasets);
221    else
222      printf("  No\n");
223    printf("  0   Terminal type (IBM PC, VT52, ANSI)?");
224    if (ibmpc)
225      printf("  IBM PC\n");
226    if (ansi)
227      printf("  ANSI\n");
228    if (vt52)
229      printf("  VT52\n");
230    if (!(ibmpc || vt52 || ansi))
231      printf("  (none)\n");
232    printf("  1    Print out the data at start of run");
233    if (printdata)
234      printf("  Yes\n");
235    else
236      printf("  No\n");
237    printf("  2  Print indications of progress of run");
238    if (progress)
239      printf("  Yes\n");
240    else
241      printf("  No\n");
242    printf("  3                        Print out tree");
243    if (treeprint)
244      printf("  Yes\n");
245    else
246      printf("  No\n");
247    printf("  4       Write out trees onto tree file?");
248    if (trout)
249      printf("  Yes\n");
250    else
251      printf("  No\n");
252    printf(
253   "\nAre these settings correct? (type Y or the letter for one to change)\n");
254    scanf("%c%*[^\n]", &ch);
255    getchar();
256    uppercase(&ch);
257    done = (ch == 'Y');
258   if (!done) {
259      if (ch == 'J' || ch == 'O' || ch == 'U' || ch == 'N' || ch == 'P' ||
260          ch == 'G' || ch == '-' || ch == 'L' || ch == 'R' || ch == 'S' ||
261          ch == 'M' || ch == '0' || ch == '1' || ch == '2' || ch == '3' ||
262          ch == '4') {
263        switch (ch) {
264
265        case '-':
266          negallowed = !negallowed;
267          break;
268
269        case 'G':
270          global = !global;
271          break;
272
273        case 'J':
274          jumble = !jumble;
275          if (jumble) {
276            do {
277              printf("Random number seed (must be odd)?\n");
278              scanf("%hd%*[^\n]", &inseed);
279              getchar();
280            } while (!(inseed & 1));
281            inseed0 = inseed;
282            for (i = 0; i <= 5; i++)
283              seed[i] = 0;
284            i = 0;
285            do {
286              seed[i] = inseed & 63;
287              inseed /= 64;
288              i++;
289            } while (inseed != 0);
290            printf("Number of times to jumble?\n");
291            scanf("%hd%*[^\n]", &njumble);
292            getchar();
293          }
294          else njumble = 1;
295          break;
296
297        case 'L':
298          lower = !lower;
299          break;
300
301        case 'N':
302          lengths = !lengths;
303          break;
304
305        case 'O':
306          outgropt = !outgropt;
307          if (outgropt) {
308            done1 = true;
309            do {
310              printf("Type number of the outgroup:\n");
311              scanf("%hd%*[^\n]", &outgrno);
312              getchar();
313              done1 = (outgrno >= 1 && outgrno <= numsp);
314              if (!done1) {
315                printf("BAD OUTGROUP NUMBER: %4hd\n", outgrno);
316                printf("  Must be in range 1 -%2hd\n", numsp);
317              }
318            } while (done1 != true);
319          }
320          break;
321
322        case 'P':
323          printf("New power?\n");
324          scanf("%lf%*[^\n]", &power);
325          getchar();
326          break;
327
328        case 'R':
329          upper = !upper;
330          break;
331
332        case 'S':
333          replicates = !replicates;
334          break;
335
336        case 'U':
337          usertree = !usertree;
338          break;
339
340        case 'M':
341          mulsets = !mulsets;
342          if (mulsets) {
343            done1 = false;
344            do {
345              printf("How many data sets?\n");
346              scanf("%hd%*[^\n]", &datasets);
347              getchar();
348              done1 = (datasets >= 1);
349              if (!done1)
350                printf("BAD DATA SETS NUMBER:  it must be greater than 1\n");
351            } while (done1 != true);
352          }
353          break;
354
355        case '0':
356          if (ibmpc) {
357            ibmpc = false;
358            vt52 = true;
359          } else {
360            if (vt52) {
361              vt52 = false;
362              ansi = true;
363            } else if (ansi)
364              ansi = false;
365            else
366              ibmpc = true;
367          }
368          break;
369
370        case '1':
371          printdata = !printdata;
372          break;
373
374        case '2':
375          progress = !progress;
376          break;
377
378        case '3':
379          treeprint = !treeprint;
380          break;
381
382        case '4':
383          trout = !trout;
384          break;
385        }
386      } else
387        printf("Not a possible option!\n");
388    }
389  } while (!done);
390}  /* getoptions */
391
392
393void doinit()
394{
395  /* initializes variables */
396  short i=0, j=0, k=0, n=0;
397  node *p, *q;
398
399  getnums(); /* set numsp1/numsp2 */
400  /* initialize the X structure */
401  x = (vector *)Malloc(numsp*sizeof(vector));
402  reps = (intvector *)Malloc(numsp*sizeof(intvector));
403  for (i=0;i<numsp;++i){
404    x[i]=(vector)Malloc(numsp2 * sizeof(double));
405    reps[i]=(intvector)Malloc(numsp * sizeof(short));
406  }
407
408  getoptions();
409  curtree.nodep = (node **)Malloc(numsp2*sizeof(node *));
410  for (i = 0; i < numsp; i++){
411    curtree.nodep[i] = (node *)Malloc(sizeof(node));
412    if (curtree.nodep[i] == NULL)
413      memerror();
414    curtree.nodep[i]->d = (vector)Malloc(numsp2 * sizeof(double));
415    if (!curtree.nodep[i]->d)
416      memerror();
417    curtree.nodep[i]->w = (vector)Malloc(numsp2 * sizeof(double));
418    if (!curtree.nodep[i]->w)
419      memerror();  }
420
421  n = 1;
422  if (!usertree) {
423    bestree.nodep = (node **)Malloc(numsp2*sizeof(node *));
424    for (i = 0; i < numsp; i++){
425      bestree.nodep[i] = (node *)Malloc(sizeof(node));
426      if (bestree.nodep[i]==NULL)
427        memerror();
428      bestree.nodep[i]->d = (vector)Malloc(numsp2 * sizeof(double));
429      if (!bestree.nodep[i]->d)
430        memerror();
431      bestree.nodep[i]->w = (vector)Malloc(numsp2 * sizeof(double));
432      if (!bestree.nodep[i]->w)
433        memerror();}
434
435    priortree.nodep = (node **)Malloc(numsp2*sizeof(node *));
436    for (i = 0; i < numsp; i++){
437      priortree.nodep[i] = (node *)Malloc(sizeof(node));
438      if (priortree.nodep[i]==NULL)
439        memerror();
440      priortree.nodep[i]->d = (double *)Malloc(numsp2 * sizeof(double));
441      if (!priortree.nodep[i]->d)
442        memerror();
443      priortree.nodep[i]->w = (double *)Malloc(numsp2 * sizeof(double));
444      if (!priortree.nodep[i]->w)
445        memerror(); }
446    n = 3;
447
448    if (njumble > 1) {
449      bestree2.nodep = (node **)Malloc(numsp2*sizeof(node *));
450      for (i = 0; i < numsp; i++){
451        bestree2.nodep[i] = (node *)Malloc(sizeof(node));
452        if (bestree2.nodep[i]==NULL)
453          memerror();
454        bestree2.nodep[i]->d = (double *)Malloc(numsp2 * sizeof(double));
455        if (!bestree2.nodep[i]->d)
456          memerror();
457        bestree2.nodep[i]->w = (double *)Malloc(numsp2 * sizeof(double));
458        if (!bestree2.nodep[i]->w)
459          memerror();}
460      n = 4;
461    }
462  }
463  for (k = 1; k <= n; k++) {
464    for (i = numsp1 - 1; i < numsp2; i++) {
465      q = NULL;
466      for (j = 1; j <= 3; j++) {
467        p = (node *)Malloc(sizeof(node));
468        if (!p)
469          memerror();
470        p->d = (double *)Malloc(numsp2 * sizeof(double));
471        if (!p->d)
472          memerror();
473        p->w = (double *)Malloc(numsp2 * sizeof(double));
474        if (!p->w)
475          memerror();
476      p->next = q;
477      q = p;
478      }
479      p->next->next->next = p;
480      if (k == 1)
481        curtree.nodep[i] = p;
482      else if (n > 1) {
483        if (k == 2)
484          bestree.nodep[i] = p;
485        else if (k == 3)
486          priortree.nodep[i] = p;
487        else
488          bestree2.nodep[i] = p;
489      }
490    }
491  }
492}  /* doinit */
493
494
495void inputoptions()
496{
497  /* read options information */
498  Char ch;
499  short cursp=0;
500
501  if (!firstset) {
502    if (eoln(infile)) {
503      fscanf(infile, "%*[^\n]");
504      getc(infile);
505    }
506    fscanf(infile, "%hd", &cursp);
507    if (cursp != numsp) {
508      printf("\nERROR: INCONSISTENT NUMBER OF SPECIES IN DATA SET %4hd\n",ith);
509      exit(-1);
510    }
511  }
512  while (!(eoln(infile))) {
513    ch = getc(infile);
514    uppercase(&ch);
515    if (ch != ' ') {
516      printf("BAD OPTION CHARACTER: %c\n", ch);
517      exit(-1);
518    }
519  }
520  fprintf(outfile, "                  __ __             2\n");
521  fprintf(outfile, "                  \\  \\   (Obs - Exp)\n");
522  fprintf(outfile, "Sum of squares =  /_ /_  ------------\n");
523  fprintf(outfile, "                               ");
524  if (power == (short)power)
525    fprintf(outfile, "%2hd\n", (short)power);
526  else
527    fprintf(outfile, "%4.1f\n", power);
528  fprintf(outfile, "                   i  j      Obs\n\n");
529  fprintf(outfile, "Negative branch lengths ");
530  if (!negallowed)
531    fprintf(outfile, "not ");
532  fprintf(outfile, "allowed\n\n");
533  if (global)
534    fprintf(outfile, "global optimization\n\n");
535}  /* inputoptions */
536
537
538Static void getinput()
539{
540  /* reads the input data */
541  inputoptions();
542}  /* getinput */
543
544
545
546#define down            2
547#define over            60
548
549
550void setuptree(a)
551tree *a;
552{
553  /* initialize a tree */
554  short i=0, j=0;
555  node *p;
556
557  for (i = 1; i <= numsp; i++) {
558    a->nodep[i - 1]->tip = true;
559    a->nodep[i - 1]->iter = true;
560    a->nodep[i - 1]->number = i;
561  }
562  for (i = numsp1; i <= numsp2; i++) {
563    p = a->nodep[i - 1];
564    for (j = 1; j <= 3; j++) {
565      p->tip = false;
566      p->iter = true;
567      p->number = i;
568      p = p->next;
569    }
570  }
571  a->likelihood = -1.0;
572  a->start = a->nodep[0];
573}  /* setuptree */
574
575void getdata()
576{
577  /* read in distance matrix */
578  short i=0, j=0, k=0, columns=0;
579  boolean skipit=false, skipother=false;
580
581  if (replicates)
582    columns = 4;
583  else
584    columns = 6;
585  if (printdata) {
586    fprintf(outfile, "\nName                       Distances");
587    if (replicates)
588      fprintf(outfile, " (replicates)");
589    fprintf(outfile, "\n----                       ---------");
590    if (replicates)
591      fprintf(outfile, "-------------");
592    fprintf(outfile, "\n\n");
593  }
594  for (i = 0; i < numsp; i++) {
595    x[i][i] = 0.0;
596    fscanf(infile, "%*[^\n]");
597    getc(infile);
598    for (j = 0; j < namelength; j++) {
599      if (eoln(infile))
600        nayms[i][j] = ' ';
601      else
602        nayms[i][j] = getc(infile);
603    }
604    for (j = 0; j < numsp; j++) {
605      skipit = ((lower && j + 1 >= i + 1) || (upper && j + 1 <= i + 1));
606      skipother = ((lower && i + 1 >= j + 1) || (upper && i + 1 <= j + 1));
607      if (!skipit) {
608        if (eoln(infile)) {
609          fscanf(infile, "%*[^\n]");
610          getc(infile);
611        }
612        fscanf(infile, "%lf", &x[i][j]);
613        if (replicates) {
614          if (eoln(infile)) {
615            fscanf(infile, "%*[^\n]");
616            getc(infile);
617          }
618          fscanf(infile, "%hd", &reps[i][j]);
619        } else
620          reps[i][j] = 1;
621      }
622      if (!skipit && skipother) {
623          x[j][i] = x[i][j];
624          reps[j][i] = reps[i][j];
625        }
626    }
627  }
628  fscanf(infile, "%*[^\n]");
629  getc(infile);
630  if (!printdata)
631    return;
632  for (i = 0; i < numsp; i++) {
633    for (j = 0; j < namelength; j++)
634      putc(nayms[i][j], outfile);
635    putc(' ', outfile);
636    for (j = 1; j <= numsp; j++) {
637      fprintf(outfile, "%10.5f", x[i][j - 1]);
638      if (replicates)
639        fprintf(outfile, " (%3hd)", reps[i][j - 1]);
640      if (j % columns == 0 && j < numsp) {
641        putc('\n', outfile);
642        for (k = 1; k <= namelength + 1; k++)
643          putc(' ', outfile);
644      }
645    }
646    putc('\n', outfile);
647  }
648  putc('\n', outfile);
649}  /* getdata */
650
651void hookup(p, q)
652node *p, *q;
653{
654  /* hook together two nodes */
655  p->back = q;
656  q->back = p;
657}  /* hookup */
658
659
660
661void secondtraverse(q, y, nx,sum)
662node *q;
663double y;
664short *nx;          /* comes from firsttraverse                              */
665double *sum;        /* comes from evaluate via firsttraverse                 */
666{
667  /* from each of those places go back to all others */
668  double z=0.0, TEMP=0.0;
669
670  z = y + q->v;
671  if (q->tip) {
672    TEMP = q->d[(*nx) - 1] - z;
673    *sum += q->w[(*nx) - 1] * (TEMP * TEMP);
674  } else {
675    secondtraverse(q->next->back, z, nx, sum);
676    secondtraverse(q->next->next->back, z, nx,sum);
677  }
678}  /* secondtraverse */
679
680void firsttraverse(p, nx,sum)
681node *p;
682short *nx;
683double *sum;
684{
685  /* go through tree calculating branch lengths */
686  if (p->tip) {
687    *nx = p->number;
688  secondtraverse(p->back, 0.0, nx,sum);
689
690  } else {
691    firsttraverse(p->next->back, nx,sum);
692    firsttraverse(p->next->next->back, nx,sum);
693  }
694}  /* firsttraverse */
695
696double evaluate(t)
697tree *t;
698{
699  double sum=0.0;
700  short nx=0;
701  /* evaluate likelihood of a tree */
702  firsttraverse(t->start->back->back,&nx,&sum);
703  firsttraverse(t->start->back, &nx,&sum);
704  if (replicates && (lower || upper))
705    sum /= 2;
706  t->likelihood = -sum;
707  return (-sum);
708}  /* evaluate */
709
710void nudists(x, y)
711node *x, *y;
712{
713  /* compute distance between an interior node and tips */
714  short nq=0, nr=0, nx=0, ny=0;
715  double dil=0, djl=0, wil=0, wjl=0, vi=0, vj=0;
716  node *qprime, *rprime;
717
718  qprime = x->next;
719  rprime = qprime->next->back;
720  qprime = qprime->back;
721  ny = y->number;
722  dil = qprime->d[ny - 1];
723  djl = rprime->d[ny - 1];
724  wil = qprime->w[ny - 1];
725  wjl = rprime->w[ny - 1];
726  vi = qprime->v;
727  vj = rprime->v;
728  x->w[ny - 1] = wil + wjl;
729  if (wil + wjl <= 0.0)
730    x->d[ny - 1] = 0.0;
731  else
732    x->d[ny - 1] = ((dil - vi) * wil + (djl - vj) * wjl) / (wil + wjl);
733  nx = x->number;
734  nq = qprime->number;
735  nr = rprime->number;
736  dil = y->d[nq - 1];
737  djl = y->d[nr - 1];
738  wil = y->w[nq - 1];
739  wjl = y->w[nr - 1];
740  y->w[nx - 1] = wil + wjl;
741  if (wil + wjl <= 0.0)
742    y->d[nx - 1] = 0.0;
743  else
744    y->d[nx - 1] = ((dil - vi) * wil + (djl - vj) * wjl) / (wil + wjl);
745}  /* nudists */
746
747
748void makedists(p)
749node *p;
750{
751  /* compute distances among three neighbors of a node */
752  short i=0, nr=0, ns=0;
753  node *q, *r, *s;
754
755
756  r = p->back;
757  nr = r->number;
758  for (i = 1; i <= 3; i++) {
759    q = p->next;
760    s = q->back;
761    ns = s->number;
762
763    if (s->w[nr - 1] + r->w[ns - 1] <= 0.0)
764      p->dist = 0.0;
765    else
766      p->dist = (s->w[nr - 1] * s->d[nr - 1] + r->w[ns - 1] * r->d[ns - 1]) /
767                (s->w[nr - 1] + r->w[ns - 1]);
768    p = q;
769    r = s;
770    nr = ns;
771  }
772}  /* makedists */
773
774void makebigv(p)
775node *p;
776{
777  /* make new branch length */
778  short i=0;
779  node *temp, *q, *r;
780
781  q = p->next;
782  r = q->next;
783  for (i = 1; i <= 3; i++) {
784    if (p->iter) {
785      p->v = (p->dist + r->dist - q->dist) / 2.0;
786      p->back->v = p->v;
787    }
788    temp = p;
789    p = q;
790    q = r;
791    r = temp;
792  }
793}  /* makebigv */
794
795void correctv(p)
796node *p;
797{
798  /* iterate branch lengths if some are to be zero */
799  node *q, *r, *temp;
800  short i=0, j=0, n=0, nq=0, nr=0, ntemp=0;
801  double wq=0.0, wr=0.0;
802
803  q = p->next;
804  r = q->next;
805  n = p->back->number;
806  nq = q->back->number;
807  nr = r->back->number;
808  for (i = 1; i <= smoothings; i++) {
809    for (j = 1; j <= 3; j++) {
810      if (p->iter) {
811        wr = r->back->w[n - 1] + p->back->w[nr - 1];
812        wq = q->back->w[n - 1] + p->back->w[nq - 1];
813        if (wr + wq <= 0.0 && !negallowed)
814          p->v = 0.0;
815        else
816          p->v = ((p->dist - q->v) * wq + (r->dist - r->v) * wr) / (wr + wq);
817        if (p->v < 0 && !negallowed)
818          p->v = 0.0;
819        p->back->v = p->v;
820      }
821      temp = p;
822      p = q;
823      q = r;
824      r = temp;
825      ntemp = n;
826      n = nq;
827      nq = nr;
828      nr = ntemp;
829    }
830  }
831}  /* correctv */
832
833void alter(x, y)
834node *x, *y;
835{
836  /* traverse updating these views */
837  nudists(x, y);
838  if (!y->tip) {
839    alter(x, y->next->back);
840    alter(x, y->next->next->back);
841  }
842}  /* alter */
843
844void nuview(p)
845node *p;
846{
847  /* renew information about subtrees */
848  short i=0;
849  node *q, *r, *pprime, *temp;
850
851  q = p->next;
852  r = q->next;
853  for (i = 1; i <= 3; i++) {
854    temp = p;
855    pprime = p->back;
856    alter(p, pprime);
857    p = q;
858    q = r;
859    r = temp;
860  }
861}  /* nuview */
862
863void update(p)
864node *p;
865{
866  /* update branch lengths around a node */
867
868  if (p->tip)
869    return;
870  makedists(p);
871  if (p->iter || p->next->iter || p->next->next->iter) {
872    makebigv(p);
873    correctv(p);
874  }
875  nuview(p);
876}  /* update */
877
878void smooth(p)
879node *p;
880{
881  /* go through tree getting new branch lengths and views */
882  if (p->tip)
883    return;
884  update(p);
885  smooth(p->next->back);
886  smooth(p->next->next->back);
887}  /* smooth */
888
889void filltraverse(pb, qb,contin)
890node *pb, *qb;
891boolean contin;
892{
893  if (qb->tip)
894    return;
895  if (contin) {
896    filltraverse(pb, qb->next->back,contin);
897    filltraverse(pb, qb->next->next->back,contin);
898    nudists(qb, pb);
899    return;
900  }
901  if (!qb->next->back->tip)
902    nudists(qb->next->back, pb);
903  if (!qb->next->next->back->tip)
904    nudists(qb->next->next->back, pb);
905}  /* filltraverse */
906
907void fillin(pa, qa,contin)
908node *pa, *qa;
909boolean contin;
910{
911  if (!pa->tip) {
912    fillin(pa->next->back, qa, contin);
913    fillin(pa->next->next->back, qa, contin);
914  }
915  filltraverse(pa, qa, contin);
916}  /* fillin */
917
918void insert_(p, q, contin_)
919node *p, *q;
920boolean contin_;
921{
922  /* put p and q together and iterate info. on resulting tree */
923  short i=0;
924  double x=0.0;
925  hookup(p->next->next, q->back);
926  hookup(p->next, q);
927  x = q->v / 2.0;
928  p->v = 0.0;
929  p->back->v = 0.0;
930  p->next->v = x;
931  p->next->back->v = x;
932  p->next->next->back->v = x;
933  p->next->next->v = x;
934  fillin(p->back, p, contin_);
935  for (i = 1; i <= smoothings; i++) {
936    smooth(p);
937    smooth(p->back);
938  }
939}  /* insert */
940
941void copynode(c, d)
942node *c, *d;
943{
944  /* make a copy of a node */
945
946  memcpy(d->nayme, c->nayme, sizeof(naym));
947  memcpy(d->d, c->d, numsp2*sizeof(double));
948  memcpy(d->w, c->w, numsp2*sizeof(double));
949  d->v = c->v;
950  d->iter = c->iter;
951  d->dist = c->dist;
952  d->xcoord = c->xcoord;
953  d->ycoord = c->ycoord;
954  d->ymin = c->ymin;
955  d->ymax = c->ymax;
956}  /* copynode */
957
958void copy_(a, b)
959tree *a, *b;
960{
961  /* make a copy of a tree */
962  short i, j=0;
963  node *p, *q;
964
965  for (i = 0; i < numsp; i++) {
966    copynode(a->nodep[i], b->nodep[i]);
967    if (a->nodep[i]->back) {
968      if (a->nodep[i]->back == a->nodep[a->nodep[i]->back->number - 1])
969        b->nodep[i]->back = b->nodep[a->nodep[i]->back->number - 1];
970      else if (a->nodep[i]->back
971                 == a->nodep[a->nodep[i]->back->number - 1]->next)
972        b->nodep[i]->back = b->nodep[a->nodep[i]->back->number - 1]->next;
973      else
974        b->nodep[i]->back
975          = b->nodep[a->nodep[i]->back->number - 1]->next->next;
976    }
977    else b->nodep[i]->back = NULL;
978  }
979  for (i = numsp; i < numsp2; i++) {
980    p = a->nodep[i];
981    q = b->nodep[i];
982    for (j = 1; j <= 3; j++) {
983      copynode(p, q);
984      if (p->back) {
985        if (p->back == a->nodep[p->back->number - 1])
986          q->back = b->nodep[p->back->number - 1];
987        else if (p->back == a->nodep[p->back->number - 1]->next)
988          q->back = b->nodep[p->back->number - 1]->next;
989        else
990          q->back = b->nodep[p->back->number - 1]->next->next;
991      }
992      else
993        q->back = NULL;
994      p = p->next;
995      q = q->next;
996    }
997  }
998  b->likelihood = a->likelihood;
999  b->start = a->start;
1000}  /* copy */
1001
1002void setuptip(m,t)
1003short m;
1004tree *t;
1005{
1006  /* initialize branch lengths and views in a tip */
1007  short i=0;
1008  intvector n=(short *)Malloc(numsp * sizeof(short)); 
1009  node *WITH;
1010
1011  WITH = t->nodep[m - 1];
1012  memcpy(WITH->d, x[m - 1], (numsp2 * sizeof(double)));
1013  memcpy(n, reps[m - 1], (numsp * sizeof(short)));
1014
1015  for (i = 0; i < numsp; i++) {
1016    if (i + 1 != m && n[i] > 0) {
1017      if (WITH->d[i] < epsilon)
1018        WITH->d[i] = epsilon;
1019      WITH->w[i] = n[i] / exp(power * log(WITH->d[i]));
1020    } else {
1021      WITH->w[m - 1] = 0.0;
1022      WITH->d[m - 1] = 0.0;
1023    }
1024  }
1025  for (i = numsp; i < numsp2; i++) {
1026    WITH->w[i] = 1.0;
1027    WITH->d[i] = 0.0;
1028  }
1029  WITH->number = m;
1030  memcpy(WITH->nayme, nayms[m - 1], sizeof(naym));
1031  if (WITH->iter) WITH->v = 0.0;
1032  free(n);
1033}  /* setuptip */
1034
1035void buildnewtip(m, t,nextsp)
1036short m;
1037tree *t;
1038short nextsp;
1039{
1040  /* initialize and hook up a new tip */
1041  node *p;
1042  setuptip(m, t);
1043  p = t->nodep[nextsp + numsp - 3];
1044  hookup(t->nodep[m - 1], p);
1045}  /* buildnewtip */
1046
1047void buildsimpletree(t,nextsp)
1048tree *t;
1049short nextsp;
1050{
1051  /* make and initialize a three-species tree */
1052  setuptip(enterorder[0], t);
1053  setuptip(enterorder[1], t);
1054  hookup(t->nodep[enterorder[0] - 1], t->nodep[enterorder[1] - 1]);
1055  buildnewtip(enterorder[2], t, nextsp);
1056  insert_(t->nodep[enterorder[2] - 1]->back, t->nodep[enterorder[0] - 1],
1057          false);
1058}  /* buildsimpletree */
1059
1060void addtraverse(p, q, contin, numtrees,succeeded)
1061node *p, *q;
1062boolean contin,*succeeded;
1063short *numtrees;
1064{
1065 /* traverse through a tree, finding best place to add p */
1066  insert_(p, q, true);
1067  (*numtrees)++;
1068  if (evaluate(&curtree) > bestree.likelihood){
1069    copy_(&curtree, &bestree);
1070    (*succeeded)=true;
1071  }
1072  copy_(&priortree, &curtree);
1073  if (!q->tip && contin) {
1074    addtraverse(p, q->next->back, contin,numtrees,succeeded);
1075    addtraverse(p, q->next->next->back, contin,numtrees,succeeded);
1076  }
1077}  /* addtraverse */
1078
1079
1080void re_move(p, q)
1081node **p, **q;
1082{
1083  /* re_move p and record in q where it was */
1084  *q = (*p)->next->back;
1085  hookup(*q, (*p)->next->next->back);
1086  (*p)->next->back = NULL;
1087  (*p)->next->next->back = NULL;
1088  update(*q);
1089  update((*q)->back);
1090}  /* re_move */
1091
1092void rearrange(p, numtrees,nextsp,succeeded)
1093node *p;
1094short *numtrees,*nextsp;
1095boolean *succeeded;
1096{
1097  node *q, *r;
1098  if (!p->tip && !p->back->tip) {
1099    r = p->next->next;
1100    re_move(&r, &q);
1101    copy_(&curtree, &priortree);
1102    addtraverse(r, q->next->back, global && ((*nextsp) == numsp),
1103                numtrees,succeeded);
1104    addtraverse(r, q->next->next->back, global && ((*nextsp) == numsp),
1105                numtrees,succeeded);
1106    copy_(&bestree, &curtree);
1107    if (global && ((*nextsp) == numsp))
1108      putchar('.');
1109    if (global && ((*nextsp) == numsp) && !(*succeeded)) {
1110      if (r->back->tip) {
1111        r = r->next->next;
1112        re_move(&r, &q);
1113        q = q->back;
1114        copy_(&curtree, &priortree);
1115        if (!q->tip) {
1116          addtraverse(r, q->next->back, true, numtrees,succeeded);
1117          addtraverse(r, q->next->next->back, true, numtrees,succeeded);
1118        }
1119        q = q->back;
1120        if (!q->tip) {
1121          addtraverse(r, q->next->back, true, numtrees,succeeded);
1122          addtraverse(r, q->next->next->back, true, numtrees,succeeded);
1123        }
1124        copy_(&bestree, &curtree);
1125      }
1126    }
1127  }
1128  if (!p->tip) {
1129    rearrange(p->next->back, numtrees,nextsp,succeeded);
1130    rearrange(p->next->next->back, numtrees,nextsp,succeeded);
1131  }
1132}  /* rearrange */
1133
1134
1135void coordinates(p, lengthsum, tipy,tipmax)
1136node *p;
1137double lengthsum;
1138short *tipy;
1139double *tipmax;
1140{
1141  /* establishes coordinates of nodes */
1142  node *q, *first, *last;
1143  if (p->tip) {
1144    p->xcoord = (short)((double)over * lengthsum + 0.5);
1145    p->ycoord = *tipy;
1146    p->ymin = *tipy;
1147    p->ymax = *tipy;
1148    (*tipy) += down;
1149    if (lengthsum > *tipmax){
1150      *tipmax = lengthsum;}
1151    return;
1152  }
1153  q = p->next;
1154   do {
1155    coordinates(q->back, lengthsum + q->v, tipy,tipmax);
1156    q = q->next;
1157  } while ((p == curtree.start->back || p != q) &&
1158           (p != curtree.start->back || p->next != q));
1159  first = p->next->back;
1160  q = p;
1161  while (q->next != p)
1162    q = q->next;
1163  last = q->back;
1164  p->xcoord = (short)((double)over * lengthsum + 0.5);
1165  if (p == curtree.start->back)
1166    p->ycoord = p->next->next->back->ycoord;
1167  else
1168    p->ycoord = (first->ycoord + last->ycoord) / 2;
1169  p->ymin = first->ymin;
1170  p->ymax = last->ymax;
1171}  /* coordinates */
1172
1173void drawline(i, scale)
1174short i;
1175double scale;
1176{
1177  /* draws one row of the tree diagram by moving up tree */
1178  node *p, *q;
1179  short n=0, j=0;
1180  boolean extra=false, trif=false;
1181  node *r, *first, *last;
1182  boolean done=false;
1183
1184  p = curtree.start->back;
1185  q = curtree.start->back;
1186  extra = false;
1187  trif = false;
1188  if (i == p->ycoord && p == curtree.start->back) {
1189    if (p->number - numsp >= 10)
1190      fprintf(outfile, "-%2hd", p->number - numsp);
1191    else
1192      fprintf(outfile, "--%hd", p->number - numsp);
1193    extra = true;
1194    trif = true;
1195  } else
1196    fprintf(outfile, "  ");
1197  do {
1198    if (!p->tip) {
1199      r = p->next;
1200      done = false;
1201      do {
1202        if (i >= r->back->ymin && i <= r->back->ymax) {
1203          q = r->back;
1204          done = true;
1205        }
1206        r = r->next;
1207      } while (!(done || (p != curtree.start->back && r == p) ||
1208                 (p == curtree.start->back && r == p->next)));
1209      first = p->next->back;
1210      r = p;
1211      while (r->next != p)
1212        r = r->next;
1213      last = r->back;
1214      if (p == curtree.start->back)
1215        last = p->back;
1216    }
1217    done = (p->tip || p == q);
1218    n = (short)(scale * (double)(q->xcoord - p->xcoord) + 0.5);
1219    if (n < 3 && !q->tip)
1220      n = 3;
1221    if (extra) {
1222      n--;
1223      extra = false;
1224    }
1225    if (q->ycoord == i && !done) {
1226      if (p->ycoord != q->ycoord)
1227        putc('+', outfile);
1228      if (trif) {
1229        n++;
1230        trif = false;
1231      }
1232      if (!q->tip) {
1233        for (j = 1; j <= n - 2; j++)
1234          putc('-', outfile);
1235        if (q->number - numsp >= 10)
1236          fprintf(outfile, "%2hd", q->number - numsp);
1237        else
1238          fprintf(outfile, "-%hd", q->number - numsp);
1239        extra = true;
1240      } else {
1241        for (j = 1; j < n; j++)
1242          putc('-', outfile);
1243      }
1244    } else if (!p->tip) {
1245      if (last->ycoord > i && first->ycoord < i && i != p->ycoord) {
1246        putc('!', outfile);
1247        for (j = 1; j < n; j++)
1248          putc(' ', outfile);
1249      } else {
1250        for (j = 1; j <= n; j++)
1251          putc(' ', outfile);
1252        trif = false;
1253      }
1254    }
1255    if (q != p)
1256      p = q;
1257  } while (!done);
1258  if (p->ycoord == i && p->tip) {
1259    for (j = 0; j < namelength; j++)
1260      putc(p->nayme[j], outfile);
1261  }
1262  putc('\n', outfile);
1263}  /* drawline */
1264
1265void printree()
1266{
1267  /* prints out diagram of the tree */
1268  short i=0;
1269  short tipy=0;
1270  double scale=0.0,tipmax=0.0,divisor=0.0;
1271
1272  if (!treeprint)
1273    return;
1274  putc('\n', outfile);
1275  tipy = 1;
1276  tipmax = 0.0;
1277  coordinates(curtree.start->back, 0.0, &tipy,&tipmax);
1278  divisor = ((short)(tipmax + 1.000));
1279  scale = 1.0 / (double)divisor;
1280  for (i = 1; i <= (tipy - down); i++)
1281    drawline(i, scale);
1282  putc('\n', outfile);
1283}  /* printree */
1284
1285
1286void treeout(p)
1287node *p;
1288{
1289  /* write out file with representation of final tree */
1290  short i=0, n=0, w=0;
1291  Char c;
1292  double x=0.0;
1293
1294  if (p->tip) {
1295    n = 0;
1296    for (i = 1; i <= namelength; i++) {
1297      if (p->nayme[i - 1] != ' ')
1298        n = i;
1299    }
1300    for (i = 0; i < n; i++) {
1301      c = p->nayme[i];
1302      if (c == ' ')
1303        c = '_';
1304      putc(c, treefile);
1305    }
1306    col += n;
1307  } else {
1308    putc('(', treefile);
1309    col++;
1310    treeout(p->next->back);
1311    putc(',', treefile);
1312    col++;
1313    if (col > 55) {
1314      putc('\n', treefile);
1315      col = 0;
1316    }
1317    treeout(p->next->next->back);
1318    if (p == curtree.start->back) {
1319      putc(',', treefile);
1320      treeout(p->back);
1321    }
1322    putc(')', treefile);
1323    col++;
1324  }
1325  x = p->v;
1326  if (x > 0.0)
1327    w = (short)(0.43429445222 * log(x));
1328  else if (x == 0.0)
1329    w = 0;
1330  else
1331    w = (short)(0.43429445222 * log(-x)) + 1;
1332  if (w < 0)
1333    w = 0;
1334  if (p == curtree.start->back)
1335    fprintf(treefile, ";\n");
1336  else {
1337    fprintf(treefile, ":%*.5f", w + 7, x);
1338    col += w + 8;
1339  }
1340}  /* treeout */
1341
1342void describe(p)
1343node *p;
1344{
1345  /* print out information for one branch */
1346  short i=0;
1347  node *q;
1348
1349  q = p->back;
1350  fprintf(outfile, "%4hd          ", q->number - numsp);
1351  if (p->tip) {
1352    for (i = 0; i < namelength; i++)
1353      putc(p->nayme[i], outfile);
1354  } else
1355    fprintf(outfile, "%4hd      ", p->number - numsp);
1356  fprintf(outfile, "%15.5f\n", q->v);
1357  if (!p->tip) {
1358    describe(p->next->back);
1359    describe(p->next->next->back);
1360  }
1361}  /* describe */
1362
1363void summarize(numtrees)
1364short numtrees;
1365{
1366  /* print out branch lengths etc. */
1367  short i, j, totalnum;
1368
1369  fprintf(outfile, "\nremember:");
1370  if (outgropt)
1371    fprintf(outfile, " (although rooted by outgroup)");
1372  fprintf(outfile, " this is an unrooted tree!\n\n");
1373  fprintf(outfile, "Sum of squares = %11.5f\n\n", -curtree.likelihood);
1374  if (power == 2.0) {
1375    totalnum = 0;
1376    for (i = 1; i <= nums; i++) {
1377      for (j = 1; j <= nums; j++) {
1378        if (i != j)
1379          totalnum += reps[i - 1][j - 1];
1380      }
1381    }
1382    fprintf(outfile, "Average percent standard deviation = ");
1383    fprintf(outfile, "%11.5f\n\n",
1384            100 * sqrt(curtree.likelihood / (2 - totalnum)));
1385  }
1386  if (!usertree)
1387    fprintf(outfile, "examined %4hd trees\n\n", numtrees);
1388  fprintf(outfile, "Between        And            Length\n");
1389  fprintf(outfile, "-------        ---            ------\n");
1390  describe(curtree.start->back->next->back);
1391  describe(curtree.start->back->next->next->back);
1392  describe(curtree.start);
1393  fprintf(outfile, "\n\n");
1394  if (trout) {
1395    col = 0;
1396    treeout(curtree.start->back);
1397  }
1398}  /* summarize */
1399
1400
1401void getch(c)
1402Char *c;
1403{
1404  /* get next nonblank character */
1405  do {
1406    if (eoln(infile)) {
1407      fscanf(infile, "%*[^\n]");
1408      getc(infile);
1409    }
1410    *c = getc(infile);
1411    if (*c == '\n')
1412      *c = ' ';
1413  } while (*c == ' ');
1414}  /* getch */
1415
1416void findch(c, lparens,rparens)
1417Char c;
1418short *lparens,*rparens;
1419{
1420  /* skip forward in user tree until find character c */
1421  boolean done;
1422
1423  done = false;
1424  while (!(done)) {
1425    if (c == ',') {
1426      if (ch == '(' || ch == ')' || ch == ':' || ch == ';') {
1427        printf(
1428             "\nERROR IN USER TREE: UNMATCHED PARENTHESIS OR MISSING COMMA\n");
1429        printf(" OR NOT TRIFURCATED BASE\n");
1430        exit(-1);
1431      } else if (ch == ',')
1432        done = true;
1433    } else if (c == ')') {
1434      if (ch == '(' || ch == ',' || ch == ':' || ch == ';') {
1435        printf("\nERROR IN USER TREE:");
1436        printf(" UNMATCHED PARENTHESIS OR NON-BIFURCATED NODE\n");
1437        exit(-1);
1438      } else if (ch == ')') {
1439        (*rparens)++;
1440        if (*lparens > 0 && *lparens == *rparens ) {
1441          if (*lparens == numsp - 2) {
1442            if (eoln(infile)) {
1443              fscanf(infile, "%*[^\n]");
1444              getc(infile);
1445            }
1446            ch = getc(infile);
1447            if (ch != ';') {
1448              printf("\nERROR IN USER TREE:");
1449              printf(" UNMATCHED PARENTHESIS OR MISSING SEMICOLON\n");
1450              exit(-1);
1451            }
1452          }
1453        }
1454        done = true;
1455      }
1456    }
1457    if ((done && ch == ')') || !(done)) {
1458      if (eoln(infile)) {
1459        fscanf(infile, "%*[^\n]");
1460        getc(infile);
1461      }
1462      ch = getc(infile);
1463    }
1464  }
1465}  /* findch */
1466
1467void processlength(p)
1468node *p;
1469{
1470  short digit, ordzero;
1471  double valyew, divisor;
1472  boolean pointread;
1473
1474  ordzero = '0';
1475  pointread = false;
1476  valyew = 0.0;
1477  divisor = 1.0;
1478  getch(&ch);
1479  digit = ch - ordzero;
1480  while (((unsigned short)digit <= 9) || (ch == '.')) {
1481    if (ch == '.')
1482      pointread = true;
1483    else {
1484      valyew = valyew * 10.0 + digit;
1485      if (pointread)
1486        divisor *= 10.0;
1487    }
1488    getch(&ch);
1489    digit = ch - ordzero;
1490  }
1491  if (lengths) {
1492    p->v = valyew / divisor;
1493    p->back->v = p->v;
1494    p->iter = false;
1495    p->back->iter = false;
1496   }
1497}  /* processlength */
1498
1499#undef point
1500
1501void addelement(p,nextnode,lparens,rparens,names,nolengths)
1502node *p;
1503short *nextnode,*lparens,*rparens;
1504boolean *names;                             /* a boolean array               */
1505boolean *nolengths;
1506{
1507                                            /* add one node to the user tree */
1508  node *q;
1509  short i=0, n=0;
1510  boolean found=false;
1511  Char str[namelength];
1512
1513  strcpy(str,"");
1514  do {
1515    if (eoln(infile)) {
1516      fscanf(infile, "%*[^\n]");
1517      getc(infile);
1518    }
1519    ch = getc(infile);
1520  } while (ch == ' ');
1521  if (ch == '(') {
1522    (*lparens)++;
1523    (*nextnode)++;
1524    q = curtree.nodep[(*nextnode) - 1];
1525    hookup(p, q);
1526    addelement(q->next,nextnode,lparens,rparens,names,nolengths);
1527    findch(',', lparens,rparens);
1528    addelement(q->next->next,nextnode,lparens,rparens,names,nolengths);
1529    findch(')', lparens,rparens);
1530  }
1531  else {
1532    for (i = 0; i < namelength; i++)
1533      str[i] = ' ';
1534    n = 1;
1535    do {
1536      if (ch == '_')
1537        ch = ' ';
1538      str[n - 1] = ch;
1539      if (eoln(infile)) {
1540        fscanf(infile, "%*[^\n]");
1541        getc(infile);
1542      }
1543      ch = getc(infile);
1544      n++;
1545    } while (ch != ':' && ch != ',' && ch != ')' &&
1546             n <= namelength);
1547    n = 1;
1548    do {
1549      found = true;
1550      for (i = 0; i < namelength; i++)
1551        found = (found && str[i] == nayms[n - 1][i]);
1552      if (found) {
1553        if (names[n - 1] == false)
1554          names[n - 1] = true;
1555        else {
1556          printf("\nERROR IN USER TREE: DUPLICATE NAME FOUND -- ");
1557          for (i = 0; i < namelength; i++)
1558            putchar(curtree.nodep[n - 1]->nayme[i]);
1559          putchar('\n');
1560          exit(-1);
1561        }
1562      } else
1563        n++;
1564    } while (!(n > numsp || found));
1565    if (n > numsp) {
1566      printf("Cannot find species: ");
1567      for (i = 0; i < namelength; i++)
1568        putchar(str[i]);
1569      putchar('\n');
1570    }
1571    nums++;
1572    hookup(curtree.nodep[n - 1], p);
1573    if (curtree.start->number > n)
1574      curtree.start = curtree.nodep[n - 1];
1575  }
1576  if (ch == ':') {
1577    processlength(p);
1578    *nolengths = false;
1579  }
1580}  /* addelement */
1581
1582void treeread()
1583{
1584  /* read in a user tree */
1585  node *p;
1586  short i=0;
1587  short nextnode=0,lparens=0,rparens=0;
1588  boolean *names, nolengths;
1589
1590  nums = 0;
1591  curtree.start = curtree.nodep[numsp - 1];
1592  do {
1593    ch = getc(infile);
1594  } while (ch == ' ');
1595  if (ch != '(')
1596    return;
1597  names = (boolean *)Malloc(numsp*sizeof(boolean));
1598  for (i = 0; i < numsp; i++)
1599    names[i] = false;
1600  lparens = 1;
1601  rparens = 0;
1602  nolengths = true;
1603  nextnode = numsp + 1;
1604  p = curtree.nodep[nextnode - 1];
1605  for (i = 1; i <= 2; i++) {
1606    addelement(p, &nextnode,&lparens,&rparens,names,&nolengths);
1607    p = p->next;
1608    findch(',', &lparens,&rparens);
1609  }
1610  addelement(p, &nextnode,&lparens,&rparens,names,&nolengths);
1611  if (nolengths && lengths)
1612    printf("\nNO LENGTHS FOUND IN INPUT FILE WITH LENGTH OPTION CHOSEN\n");
1613  findch(')', &lparens,&rparens);
1614  fscanf(infile, "%*[^\n]");
1615  getc(infile);
1616  free(names);
1617}  /* treeread */
1618
1619void nodeinit(p)
1620node *p;
1621{
1622  /* initialize a node */
1623  short i, j;
1624
1625  for (i = 1; i <= 3; i++) {
1626    for (j = 0; j < numsp2; j++) {
1627      p->w[j] = 1.0;
1628      p->d[j] = 0.0;
1629    }
1630    p = p->next;
1631  }
1632  if (p->iter)
1633    p->v = 1.0;
1634  if (p->back->iter)
1635    p->back->v = 1.0;
1636}  /* nodeinit */
1637
1638void initrav(p)
1639node *p;
1640{
1641  /* traverse to initialize */
1642  if (p->tip)
1643    return;
1644  nodeinit(p);
1645  initrav(p->next->back);
1646  initrav(p->next->next->back);
1647}  /* initrav */
1648
1649void treevaluate()
1650{
1651  /* evaluate user-defined tree, iterating branch lengths */
1652  short i;
1653  double dummy;
1654
1655  for (i = 1; i <= numsp; i++)
1656    setuptip(i, &curtree);
1657  initrav(curtree.start);
1658  if (curtree.start->back != NULL) {
1659    initrav(curtree.start->back);
1660    for (i = 1; i <= smoothings * 4; i++)
1661      smooth(curtree.start->back);
1662  }
1663  dummy = evaluate(&curtree);
1664}  /* treevaluate */
1665
1666
1667void  maketree()
1668{
1669  /* contruct the tree */
1670  short nextsp,numtrees;
1671  boolean succeeded=false;
1672  short i,j,k,which;
1673
1674  if (usertree) {
1675    getdata();
1676    setuptree(&curtree);
1677    for (which = 1; which <= numsp; which++)
1678      setuptip(which, &curtree);
1679    if (eoln(infile)) {
1680      fscanf(infile, "%*[^\n]");
1681      getc(infile);
1682    }
1683    fscanf(infile, "%hd%*[^\n]", &numtrees);
1684    getc(infile);
1685    if (treeprint) {
1686      fprintf(outfile, "User-defined tree");
1687      if (numtrees > 1)
1688        putc('s', outfile);
1689      fprintf(outfile, ":\n\n");
1690    }
1691    which = 1;
1692    while (which <= numtrees) {
1693      treeread();
1694      curtree.start = curtree.nodep[outgrno - 1];
1695      treevaluate();
1696      printree();
1697      summarize(numtrees);
1698      which++;
1699    }
1700  } else {
1701    if (jumb == 1) {
1702      getdata();
1703      setuptree(&curtree);
1704      setuptree(&priortree);
1705      setuptree(&bestree);
1706      if (njumble > 1) setuptree(&bestree2);
1707    }
1708    for (i = 1; i <= numsp; i++)
1709      enterorder[i - 1] = i;
1710    if (jumble) {
1711      for (i = 0; i < numsp; i++) {
1712        j = (short)(randum(seed) * (double)numsp) + 1;
1713        k = enterorder[j - 1];
1714        enterorder[j - 1] = enterorder[i];
1715        enterorder[i] = k;
1716      }
1717    }
1718    nextsp = 3;
1719    buildsimpletree(&curtree, nextsp);
1720    curtree.start = curtree.nodep[enterorder[0] - 1];
1721    if (jumb == 1) numtrees = 1;
1722    nextsp = 4;
1723    if (progress) {
1724      printf("\nAdding species:\n");
1725      printf("   ");
1726      for (i = 0; i < namelength; i++)
1727        putchar(nayms[enterorder[0] - 1][i]);
1728      printf("\n   ");
1729      for (i = 0; i < namelength; i++)
1730        putchar(nayms[enterorder[1] - 1][i]);
1731      printf("\n   ");
1732      for (i = 0; i < namelength; i++)
1733        putchar(nayms[enterorder[2] - 1][i]);
1734      putchar('\n');
1735    }
1736    while (nextsp <= numsp) {
1737      nums = nextsp;
1738      buildnewtip(enterorder[nextsp - 1], &curtree, nextsp);
1739      copy_(&curtree, &priortree);
1740      bestree.likelihood = -99999.0;
1741      addtraverse(curtree.nodep[enterorder[nextsp - 1] - 1]->back,
1742                  curtree.start->back, true, &numtrees,&succeeded);
1743      copy_(&bestree, &curtree);
1744      if (progress) {
1745        printf("   ");
1746        for (j = 0; j < namelength; j++)
1747          putchar(nayms[enterorder[nextsp - 1] - 1][j]);
1748        putchar('\n');
1749      }
1750      if (global && nextsp == numsp) {
1751        if (progress) {
1752          printf("Doing global rearrangements\n");
1753          printf("  !");
1754          for (j = 1; j <= (numsp - 2); j++)
1755            putchar('-');
1756          printf("!\n");
1757          printf("   ");
1758        }
1759      }
1760      succeeded = true;
1761      while (succeeded) {
1762        succeeded = false;
1763        rearrange(curtree.start->back,
1764                  &numtrees,&nextsp,&succeeded);
1765        if (global && nextsp == numsp)
1766          putc('\n', outfile);
1767      }
1768      if (njumble > 1) {
1769        if (jumb == 1 && nextsp == numsp)
1770          copy_(&bestree, &bestree2);
1771        else if (nextsp == numsp) {
1772          if (bestree2.likelihood < bestree.likelihood)
1773            copy_(&bestree, &bestree2);
1774        }
1775      }
1776      if (nextsp == numsp && jumb == njumble) {
1777        if (njumble > 1) copy_(&bestree2, &curtree);
1778        curtree.start = curtree.nodep[outgrno - 1];
1779        printree();
1780        summarize(numtrees);
1781      }
1782      nextsp++;
1783    }
1784  }
1785  if (jumb == njumble && progress) {
1786    printf("\nOutput written to output file\n\n");
1787    if (trout)
1788      printf("Tree also written onto file\n");
1789    putchar('\n');
1790  }
1791}  /* maketree */
1792
1793
1794main(argc, argv)
1795int argc;
1796Char *argv[];
1797{
1798  int i;
1799  char infilename[100],outfilename[100],trfilename[100];
1800#ifdef MAC
1801  macsetup("Fitch","");
1802#endif
1803  openfile(&infile,INFILE,"r",argv[0],infilename);
1804  openfile(&outfile,OUTFILE,"w",argv[0],outfilename);
1805
1806
1807  ibmpc = ibmpc0;
1808  ansi = ansi0;
1809  vt52 = vt520;
1810  mulsets = false;
1811  datasets = 1;
1812  firstset = true;
1813  doinit();
1814  if (trout)
1815    openfile(&treefile,TREEFILE,"w",argv[0],trfilename);
1816  nayms = (naym *)Malloc(numsp*sizeof(naym));
1817  enterorder = (short *)Malloc(numsp*sizeof(short));
1818  for (i=0;i<numsp;++i){
1819    enterorder[i]=0;}
1820  for (ith = 1; ith <= datasets; ith++) {
1821    if (datasets > 1) {
1822      fprintf(outfile, "Data set # %hd:\n\n",ith);
1823      if (progress)
1824        printf("\nData set # %hd:\n",ith);
1825    }
1826    getinput();
1827    for (jumb = 1; jumb <= njumble; jumb++)
1828        maketree();
1829    firstset = false;
1830    if (eoln(infile)) {
1831      fscanf(infile, "%*[^\n]");
1832      getc(infile);
1833    }
1834  }
1835  if (trout)
1836    FClose(treefile);
1837  FClose(outfile);
1838  FClose(infile);
1839#ifdef MAC
1840  fixmacfile(outfilename);
1841  fixmacfile(trfilename);
1842#endif
1843  exit(0);
1844}
1845
1846int eof(f)
1847FILE *f;
1848{
1849    register int ch;
1850
1851    if (feof(f))
1852        return 1;
1853    if (f == stdin)
1854        return 0;
1855    ch = getc(f);
1856    if (ch == EOF)
1857        return 1;
1858    ungetc(ch, f);
1859    return 0;
1860}
1861
1862
1863int eoln(f)
1864FILE *f;
1865{
1866    register int ch;
1867
1868    ch = getc(f);
1869    if (ch == EOF)
1870        return 1;
1871    ungetc(ch, f);
1872    return (ch == '\n');
1873}
1874
1875void memerror()
1876{
1877printf("Error allocating memory\n");
1878exit(-1);
1879}
1880
1881MALLOCRETURN *mymalloc(x)
1882long  x;
1883{
1884MALLOCRETURN *mem;
1885mem = (MALLOCRETURN *)calloc(1,x);
1886if (!mem)
1887  memerror();
1888else
1889  return (MALLOCRETURN *)mem;
1890}
1891
Note: See TracBrowser for help on using the repository browser.