source: tags/initial/GDE/PHYLIP/mix2.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: 32.8 KB
Line 
1#include "phylip.h"
2
3/* version 3.52c. (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 nmlngth         10   /* number of characters in species name    */
9#define maxtrees        100  /* maximum number of tied trees stored     */
10#define maxuser         10   /* maximum number of user-defined trees    */
11
12#define ibmpc0          false
13#define ansi0           true
14#define vt520           false
15#define down            2
16
17typedef long *bitptr;
18/* nodes will form a binary tree */
19
20typedef struct node {           /* describes a tip species or an ancestor */
21  struct node *next, *back;     /* pointers to nodes                      */
22  long index;                   /* number of the node                     */
23  boolean tip, bottom,visited;  /* present species are tips of tree       */
24  bitptr fulstte1, fulstte0;  /* see in PROCEDURE fillin                */
25  bitptr empstte1, empstte0;  /* see in PROCEDURE fillin                */
26  bitptr fulsteps,empsteps;
27  long xcoord, ycoord, ymin;    /* used by printree                       */
28  long ymax;
29} node;
30
31typedef long *steptr;
32typedef node **pointptr;
33typedef long longer[6];
34typedef long *placeptr;
35typedef struct gbit {
36  bitptr bits_;
37  struct gbit *next;
38} gbit;
39
40
41/* Local variables for maketree: */
42long nextree, which, minwhich;
43double like, bestyet, bestlike, bstlike2, minsteps;
44boolean lastrearr,full;
45double nsteps[maxuser];
46node *there;
47long fullset;
48bitptr steps, zeroanc, oneanc,fulzeroanc,empzeroanc;
49long *place,col;
50
51/* defined in main object module */
52extern FILE     *infile,*outfile,*treefile;
53extern node     *root;
54extern steptr    numsteps,numsone,numszero,extras,weight;
55extern long    **bestrees;
56extern char     *guess;
57extern double  **fsteps;
58extern long     *enterorder;
59extern longer    seed;
60extern bitptr    wagner;
61extern double   *threshwt;
62extern char    **nayme;
63extern boolean  *ancone,*anczero;
64extern pointptr treenode;
65extern boolean  jumble,usertree,questions,trout,noroot,outgropt,didreroot,
66                progress,treeprint,stepbox,ancseq,weights;
67extern char     ch;
68extern long     chars,words,spp,nonodes,jumb,njumble,outgrno;
69extern long      bits;
70
71double randum();
72
73void add(below, newtip, newfork)
74node *below, *newtip, *newfork;
75{
76  /* inserts the nodes newfork and its left descendant, newtip,
77    to the tree.  below becomes newfork's right descendant */
78  node *p;
79
80  if (below != treenode[below->index - 1])
81    below = treenode[below->index - 1];
82  if (below->back != NULL)
83    below->back->back = newfork;
84  newfork->back = below->back;
85  below->back = newfork->next->next;
86  newfork->next->next->back = below;
87  newfork->next->back = newtip;
88  newtip->back = newfork->next;
89  if (root == below)
90    root = newfork;
91  root->back = NULL;
92  p = newfork;
93  while (p != NULL) {
94    p->visited = false;
95    p = p->back;
96    if (p != NULL)
97      p = treenode[p->index - 1];
98  }
99}  /* add */
100
101
102void re_move(item, fork)
103node **item, **fork;
104{
105  /* removes nodes item and its ancestor, fork, from the tree.
106    the new descendant of fork's ancestor is made to be
107    fork's second descendant (other than item).  Also
108    returns pointers to the deleted nodes, item and fork */
109  node *p, *q;
110
111  if ((*item)->back == NULL) {
112    *fork = NULL;
113    return;
114  }
115  *fork = treenode[(*item)->back->index - 1];
116  if (root == *fork) {
117    if (*item == (*fork)->next->back)
118      root = (*fork)->next->next->back;
119    else
120      root = (*fork)->next->back;
121  }
122  p = (*item)->back->next->back;
123  q = (*item)->back->next->next->back;
124  if (p != NULL)
125    p->back = q;
126  if (q != NULL)
127    q->back = p;
128  q = (*fork)->back;
129  (*fork)->back = NULL;
130  p = (*fork)->next;
131  while (p != *fork) {
132    p->back = NULL;
133    p = p->next;
134  }
135  (*item)->back = NULL;
136  if (q != NULL)
137    q = treenode[q->index - 1];
138  while (q != NULL) {
139    q->visited = false;
140    q = q->back;
141    if (q != NULL)
142      q = treenode[q->index - 1];
143  }
144}  /* re_move */
145
146void fillin(p)
147node *p;
148{
149  /* Sets up for each node in the tree two statesets.
150    state1 and state0 are the sets of character
151    states that must be 1 or must be 0, respectively,
152    in a most parsimonious reconstruction, based on the
153    information at or above this node.  Note that this
154    state assignment may change based on information further
155    down the tree.  If a character is in both sets it is in
156    state "P".  If in neither, it is "?". */
157  long i;
158  long l0, l1, r0, r1, st, wa, za;
159  long FORLIM;
160
161  for (i = 0; i < words; i++) {
162    if (full) {
163      l0 = p->next->back->fulstte0[i];
164      l1 = p->next->back->fulstte1[i];
165      r0 = p->next->next->back->fulstte0[i];
166      r1 = p->next->next->back->fulstte1[i];
167    }
168    else {
169      l0 = p->next->back->empstte0[i];
170      l1 = p->next->back->empstte1[i];
171      r0 = p->next->next->back->empstte0[i];
172      r1 = p->next->next->back->empstte1[i];
173    }
174    wa = wagner[i];
175    st = (l1 & r0) | (l0 & r1);
176    if (full) {
177      za = fulzeroanc[i];
178      p->fulstte1[i] = (l1 | r1) & (~(st & (wa | za)));
179      p->fulstte0[i] = (l0 | r0) & (~(st & (wa | (fullset & (~za)))));
180      p->fulsteps[i] = st;
181    }
182    else {
183      za = empzeroanc[i];
184      p->empstte1[i] = (l1 | r1) & (~(st & (wa | za)));
185      p->empstte0[i] = (l0 | r0) & (~(st & (wa | (fullset & (~za)))));
186      p->empsteps[i] = st;
187    }
188  }
189}  /* fillin */
190
191
192void count(stps)
193long *stps;
194{
195  /* counts the number of steps in a fork of the tree.
196    The program spends much of its time in this PROCEDURE */
197  long i, j, l;
198
199  j = 1;
200  l = 0;
201  for (i = 0; i < (chars); i++) {
202    l++;
203    if (l > bits) {
204      l = 1;
205      j++;
206    }
207    if ((unsigned long)l < 32 && ((1L << l) & stps[j - 1]) != 0) {
208      if ((unsigned long)l < 32 && ((1L << l) & zeroanc[j - 1]) != 0)
209        numszero[i] += weight[i];
210      else
211        numsone[i] += weight[i];
212    }
213  }
214}  /* count */
215
216void postorder(p)
217node *p;
218{
219  /* traverses a binary tree, calling PROCEDURE fillin at a
220    node's descendants before calling fillin at the node */
221  if (p->tip)
222    return;
223  postorder(p->next->back);
224  postorder(p->next->next->back);
225  if (p->visited)
226    return;
227  fillin(p);
228  if (!full)
229    p->visited = true;
230}  /* postorder */
231
232
233void cpostorder(p)
234node *p;
235{
236  /* traverses a binary tree, calling PROCEDURE count at a
237    node's descendants before calling count at the node */
238  if (p->tip)
239    return;
240  cpostorder(p->next->back);
241  cpostorder(p->next->next->back);
242  if (full)
243    count(p->fulsteps);
244  else
245    count(p->empsteps);
246}  /* cpostorder */
247
248void evaluate(r)
249node *r;
250{
251  /* Determines the number of steps needed for a tree.
252    This is the minimum number needed to evolve chars on
253    this tree */
254  long i, stepnum, smaller;
255  double sum, term;
256
257  sum = 0.0;
258  for (i = 0; i < (chars); i++) {
259    numszero[i] = 0;
260    numsone[i] = 0;
261  }
262  full = true;
263  for (i = 0; i < (words); i++)
264    zeroanc[i] = fullset;
265  postorder(r);
266  cpostorder(r);
267  count(r->fulstte1);
268  for (i = 0; i < (words); i++)
269    zeroanc[i] = 0;
270  full = false;
271  postorder(r);
272  cpostorder(r);
273  count(r->empstte0);
274  for (i = 0; i < (chars); i++) {
275    smaller = spp * weight[i];
276    numsteps[i] = smaller;
277    if (anczero[i]) {
278      numsteps[i] = numszero[i];
279      smaller = numszero[i];
280    }
281    if (ancone[i] && numsone[i] < smaller)
282      numsteps[i] = numsone[i];
283    stepnum = numsteps[i] + extras[i];
284    if (stepnum <= threshwt[i])
285      term = stepnum;
286    else
287      term = threshwt[i];
288    sum += term;
289    if (usertree && which <= maxuser)
290      fsteps[which - 1][i] = term;
291    guess[i] = '?';
292    if (!ancone[i] || (anczero[i] && numszero[i] < numsone[i]))
293      guess[i] = '0';
294    else if (!anczero[i] || (ancone[i] && numsone[i] < numszero[i]))
295      guess[i] = '1';
296  }
297  if (usertree && which <= maxuser) {
298    nsteps[which - 1] = sum;
299    if (which == 1) {
300      minwhich = 1;
301      minsteps = sum;
302    } else if (sum < minsteps) {
303      minwhich = which;
304      minsteps = sum;
305    }
306  }
307  like = -sum;
308}  /* evaluate */
309
310
311void reroot(outgroup)
312node *outgroup;
313{
314  /* reorients tree, putting outgroup in desired position. */
315  node *p, *q;
316
317  if (outgroup->back->index == root->index)
318    return;
319  p = root->next;
320  q = root->next->next;
321  p->back->back = q->back;
322  q->back->back = p->back;
323  p->back = outgroup;
324  q->back = outgroup->back;
325  outgroup->back->back = q;
326  outgroup->back = p;
327}  /* reroot */
328
329void savetraverse(p)
330node *p;
331{
332  /* sets BOOLEANs that indicate which way is down */
333  p->bottom = true;
334  if (p->tip)
335    return;
336  p->next->bottom = false;
337  savetraverse(p->next->back);
338  p->next->next->bottom = false;
339  savetraverse(p->next->next->back);
340}  /* savetraverse */
341
342void savetree()
343{
344  /* record in place where each species has to be
345    added to reconstruct this tree */
346  long i, j;
347  node *p;
348  boolean done;
349
350  if (noroot)
351    reroot(treenode[outgrno - 1]);
352  savetraverse(root);
353  for (i = 0; i < (nonodes); i++)
354   place[i] = 0;
355  place[root->index - 1] = 1;
356  for (i = 1; i <= (spp); i++) {
357    p = treenode[i - 1];
358    while (place[p->index - 1] == 0) {
359      place[p->index - 1] = i;
360      while (!p->bottom)
361        p = p->next;
362      p = p->back;
363    }
364    if (i > 1) {
365      place[i - 1] = place[p->index - 1];
366      j = place[p->index - 1];
367      done = false;
368      while (!done) {
369        place[p->index - 1] = spp + i - 1;
370        while (!p->bottom)
371          p = p->next;
372        p = p->back;
373        done = (p == NULL);
374        if (!done)
375          done = (place[p->index - 1] != j);
376      }
377    }
378  }
379}  /* savetree */
380
381void findtree(pos,found)
382long *pos;
383boolean *found;
384{
385  /* finds tree given by ARRAY place in ARRAY
386    bestrees by binary search */
387  long i, lower, upper;
388  boolean below, done;
389
390  below = false;
391  lower = 1;
392  upper = nextree - 1;
393  *found = false;
394  while (!(*found) && lower <= upper) {
395    *pos = (lower + upper) / 2;
396    i = 3;
397    done = false;
398    while (!done) {
399      done = (i > spp);
400      if (!done)
401        done = (place[i - 1] != bestrees[*pos - 1][i - 1]);
402      if (!done)
403        i++;
404    }
405    *found = (i > spp);
406    if (*found)
407      break;
408    else
409      below = (place[i - 1] < bestrees[*pos - 1][i - 1]);
410    if (below)
411      upper = (*pos) - 1;
412    else
413      lower = (*pos) + 1;
414  }
415  if (!(*found) && !below)
416    (*pos)++;
417}  /* findtree */
418
419void addtree(pos)
420long *pos;
421{
422  /* puts tree from ARRAY place in its proper position
423    in ARRAY bestrees */
424  long i;
425  for (i =nextree - 1; i >= (*pos); i--)
426    memcpy(bestrees[i], bestrees[i - 1], spp*sizeof(long));
427  for (i = 0; i < (spp); i++)
428    bestrees[(*pos) - 1][i] = place[i];
429  nextree++;
430}  /* addtree */
431
432void tryadd(p, item,nufork)
433node *p,**item,**nufork;
434{
435  /* temporarily adds one fork and one tip to the tree.
436    if the location where they are added yields greater
437    "likelihood" than other locations tested up to that
438    time, then keeps that location as there */
439
440  long pos;
441  boolean found;
442  node *rute;
443
444  add(p, *item, *nufork);
445  evaluate(root);
446  if (lastrearr) {
447    if (like >= bstlike2) {
448      rute = root->next->back;
449      savetree();
450      reroot(rute);
451      if (like > bstlike2) {
452        bestlike = bstlike2 = like;
453        pos = 1;
454        nextree = 1;
455        addtree(&pos);
456      } else {
457        pos = 0;
458        findtree(&pos,&found);
459        if (!found) {
460          if (nextree <= maxtrees)
461            addtree(&pos);
462        }
463      }
464    }
465  }
466  if (like > bestyet) {
467    bestyet = like;
468    there = p;
469  }
470  re_move(item, nufork);
471}  /* tryadd */
472
473void addpreorder(p, item, nufork)
474node *p, *item, *nufork;
475{
476  /* traverses a binary tree, calling PROCEDURE tryadd
477    at a node before calling tryadd at its descendants */
478  /* Local variables for addpreorder: */
479
480  if (p == NULL)
481    return;
482  tryadd(p, &item,&nufork);
483  if (!p->tip) {
484    addpreorder(p->next->back, item, nufork);
485    addpreorder(p->next->next->back, item, nufork);
486  }
487}  /* addpreorder */
488
489void tryrearr(p, r,success)
490node *p,**r;
491boolean *success;
492{
493  /* evaluates one rearrangement of the tree.
494    if the new tree has greater "likelihood" than the old
495    one sets success := TRUE and keeps the new tree.
496    otherwise, restores the old tree */
497  node *frombelow, *whereto, *forknode;
498  double oldlike;
499
500  if (p->back == NULL)
501    return;
502  forknode = treenode[p->back->index - 1];
503  if (forknode->back == NULL)
504    return;
505  oldlike = bestyet;
506  if (p->back->next->next == forknode)
507    frombelow = forknode->next->next->back;
508  else
509    frombelow = forknode->next->back;
510  whereto = treenode[forknode->back->index - 1];
511  re_move(&p, &forknode);
512  add(whereto, p, forknode);
513  evaluate(*r);
514  if (like <= oldlike) {
515    re_move(&p, &forknode);
516    add(frombelow, p, forknode);
517  } else {
518    *success = true;
519    bestyet = like;
520  }
521}  /* tryrearr */
522
523void repreorder(p, r,success)
524node *p,**r;
525boolean *success;
526{
527  /* traverses a binary tree, calling PROCEDURE tryrearr
528    at a node before calling tryrearr at its descendants */
529  if (p == NULL)
530    return;
531  tryrearr(p, r,success);
532  if (!p->tip) {
533    repreorder(p->next->back, r,success);
534    repreorder(p->next->next->back, r,success);
535  }
536}  /* repreorder */
537
538void rearrange(r)
539node **r;
540{
541  /* traverses the tree (preorder), finding any local
542    rearrangement which decreases the number of steps.
543    if traversal succeeds in increasing the tree's
544    "likelihood", PROCEDURE rearrange runs traversal again */
545  boolean success=true;
546  while (success) {
547    success = false;
548    repreorder(*r,r,&success);
549  }
550}  /* rearrange */
551
552
553void findch(c)
554Char c;
555{
556  /* scan forward until find character c */
557  boolean done;
558
559  done = false;
560  while (!done) {
561    if (c == ',') {
562      if (ch == '(' || ch == ')' || ch == ';') {
563      printf("\nERROR IN USER TREE: UNMATCHED PARENTHESIS OR MISSING COMMA\n");
564      exit(-1);
565      } else if (ch == ',')
566        done = true;
567    } else if (c == ')') {
568      if (ch == '(' || ch == ',' || ch == ';') {
569        printf("\nERROR IN USER TREE: ");
570        printf("UNMATCHED PARENTHESIS OR NOT BIFURCATED NODE\n");
571        exit(-1);
572      } else {
573        if (ch == ')')
574          done = true;
575      }
576    } else if (c == ';') {
577      if (ch != ';') {
578        printf("\nERROR IN USER TREE:");
579        printf(" UNMATCHED PARENTHESIS OR MISSING SEMICOLON\n");
580        exit(-1);
581      } else
582        done = true;
583    }
584    if (done && ch != ')')
585      continue;
586    if (eoln(infile)) {
587      fscanf(infile, "%*[^\n]");
588      getc(infile);
589    }
590    ch = getc(infile);
591    if (ch == '\n')
592      ch = ' ';
593  }
594}  /* findch */
595
596void addelement(p, nextnode, lparens,naymes)
597node **p;
598long *nextnode,*lparens;
599boolean *naymes;
600{
601  /* recursive procedure adds nodes to user-defined tree */
602  node *q;
603  long i, n;
604  boolean found;
605  Char str[nmlngth];
606
607  do {
608    if (eoln(infile)) {
609      fscanf(infile, "%*[^\n]");
610      getc(infile);
611    }
612    ch = getc(infile);
613    if (ch == '\n')
614      ch = ' ';
615  } while (ch == ' ');
616  if (ch == '(' ) {
617    if ((*lparens) >= spp - 1) {
618      printf("\nERROR IN USER TREE: TOO MANY LEFT PARENTHESES\n");
619      exit(-1);
620    }
621    (*nextnode)++;
622    (*lparens)++;
623    q = treenode[(*nextnode) - 1];
624    addelement(&q->next->back, nextnode,lparens,naymes);
625    q->next->back->back = q->next;
626    findch(',');
627    addelement(&q->next->next->back, nextnode,lparens,naymes);
628    q->next->next->back->back = q->next->next;
629    findch(')');
630    *p = q;
631    return;
632  }
633  for (i = 0; i < nmlngth; i++)
634    str[i] = ' ';
635  n = 1;
636  do {
637    if (ch == '_')
638      ch = ' ';
639    str[n - 1] =ch;
640    if (eoln(infile)) {
641      fscanf(infile, "%*[^\n]");
642      getc(infile);
643    }
644    ch = getc(infile);
645    if (ch == '\n')
646      ch = ' ';
647    n++;
648  } while (ch != ',' && ch != ')' && ch != ':' && n <= nmlngth);
649  n = 1;
650  do {
651    found = true;
652    for (i = 0; i < nmlngth; i++)
653      found = (found && str[i] == nayme[n - 1][i]);
654    if (found) {
655      if (naymes[n - 1] == false) {
656        *p = treenode[n - 1];
657        naymes[n - 1] = true;
658      } else {
659        printf("\nERROR IN USER TREE: DUPLICATE NAME FOUND -- ");
660        for (i = 0; i < nmlngth; i++)
661          putchar(nayme[n - 1][i]);
662        putchar('\n');
663        exit(-1);
664      }
665    } else
666      n++;
667  } while (!(n > spp || found ));
668  if (n <= spp)
669    return;
670  printf("CANNOT FIND SPECIES: ");
671  for (i = 0; i < nmlngth; i++)
672    putchar(str[i]);
673  putchar('\n');
674}  /* addelement */
675
676void treeread()
677{
678  /* read in user-defined tree and set it up */
679/* Local variables for treeread: */
680  long nextnode, lparens;
681  boolean *naymes;
682  long i;
683
684  root = treenode[spp];
685  nextnode = spp;
686  root->back = NULL;
687  naymes = (boolean *)Malloc(spp*sizeof(boolean));
688  for (i = 0; i < (spp); i++)
689    naymes[i] = false;
690  lparens = 0;
691  addelement(&root, &nextnode,&lparens,naymes);
692  findch(';');
693  if (progress)
694    printf("\n\n");
695  fscanf(infile, "%*[^\n]");
696  getc(infile);
697  free(naymes);
698}  /* treeread */
699
700
701void coordinates(p, tipy)
702node *p;
703long *tipy;
704{
705  /* establishes coordinates of nodes */
706  node *q, *first, *last;
707
708  if (p->tip) {
709    p->xcoord = 0;
710    p->ycoord = *tipy;
711    p->ymin = *tipy;
712    p->ymax = *tipy;
713    (*tipy) += down;
714    return;
715  }
716  q = p->next;
717  do {
718    coordinates(q->back, tipy);
719    q = q->next;
720  } while (p != q);
721  first = p->next->back;
722  q = p->next;
723  while (q->next != p)
724    q = q->next;
725  last = q->back;
726  p->xcoord = last->ymax - first->ymin;
727  p->ycoord = (first->ycoord + last->ycoord) / 2;
728  p->ymin = first->ymin;
729  p->ymax = last->ymax;
730}  /* coordinates */
731
732void drawline(i, scale)
733long i;
734double scale;
735{
736  /* draws one row of the tree diagram by moving up tree */
737  node *p, *q, *r, *first, *last;
738  long n, j;
739  boolean extra, done;
740
741  p = root;
742  q = root;
743  extra = false;
744  if (i == p->ycoord && p == root) {
745    if (p->index - spp >= 10)
746      fprintf(outfile, "-%2ld", p->index - spp);
747    else
748      fprintf(outfile, "--%ld", p->index - spp);
749    extra = true;
750  } else
751    fprintf(outfile, "  ");
752  do {
753    if (!p->tip) {
754      r = p->next;
755      done = false;
756      do {
757        if (i >= r->back->ymin && i <= r->back->ymax) {
758          q = r->back;
759          done = true;
760        }
761        r = r->next;
762      } while (!(done || r == p));
763      first = p->next->back;
764      r = p->next;
765      while (r->next != p)
766        r = r->next;
767      last = r->back;
768    }
769    done = (p == q);
770    n = (long)(scale * (p->xcoord - q->xcoord) + 0.5);
771    if (n < 3 && !q->tip)
772      n = 3;
773    if (extra) {
774      n--;
775      extra = false;
776    }
777    if (q->ycoord == i && !done) {
778      putc('+', outfile);
779      if (!q->tip) {
780        for (j = 1; j <= n - 2; j++)
781          putc('-', outfile);
782        if (q->index - spp >= 10)
783          fprintf(outfile, "%2ld", q->index - spp);
784        else
785          fprintf(outfile, "-%ld", q->index - spp);
786        extra = true;
787      } else {
788        for (j = 1; j < n; j++)
789          putc('-', outfile);
790      }
791    } else if (!p->tip) {
792      if (last->ycoord > i && first->ycoord < i && i != p->ycoord) {
793        putc('!', outfile);
794        for (j = 1; j < n; j++)
795          putc(' ', outfile);
796      } else {
797        for (j = 1; j <= n; j++)
798          putc(' ', outfile);
799      }
800    } else {
801      for (j = 1; j <= n; j++)
802        putc(' ', outfile);
803    }
804    if (p != q)
805      p = q;
806  } while (!done);
807  if (p->ycoord == i && p->tip) {
808    for (j = 0; j < nmlngth; j++)
809      putc(nayme[p->index - 1][j], outfile);
810  }
811  putc('\n', outfile);
812}  /* drawline */
813
814void printree()
815{
816  /* prints out diagram of the tree */
817  long tipy;
818  double scale;
819  long i;
820
821  putc('\n', outfile);
822  if (!treeprint)
823    return;
824  putc('\n', outfile);
825  tipy = 1;
826  coordinates(root, &tipy);
827  scale = 1.5;
828  putc('\n', outfile);
829  for (i = 1; i <= (tipy - down); i++)
830    drawline(i, scale);
831  if (noroot) {
832    fprintf(outfile, "\n  remember:");
833    if (didreroot)
834      fprintf(outfile, " (although rooted by outgroup)");
835    fprintf(outfile, " this is an unrooted tree!\n");
836  }
837  putc('\n', outfile);
838}  /* printree */
839
840
841void filltrav(r)
842node *r;
843{
844  /* traverse to fill in interior node states */
845  if (r->tip)
846    return;
847  filltrav(r->next->back);
848  filltrav(r->next->next->back);
849  fillin(r);
850}  /* filltrav */
851
852
853void hyprint(r,bottom,nonzero,unknown,maybe,zerobelow,onebelow)
854node *r;
855boolean bottom,nonzero,unknown,maybe;
856gbit *zerobelow,*onebelow;
857{
858  /* print out states at node */
859  long i, j, k;
860  char l;
861  boolean dot, a0, a1, s0, s1;
862
863  if (bottom) {
864    if (noroot && !didreroot)
865      fprintf(outfile, "       ");
866    else
867      fprintf(outfile, "root   ");
868  } else
869    fprintf(outfile, "%3ld    ", r->back->index - spp);
870  if (r->tip) {
871    for (i = 0; i < nmlngth; i++)
872      putc(nayme[r->index - 1][i], outfile);
873  } else
874    fprintf(outfile, "%4ld      ", r->index - spp);
875  if (bottom && noroot && !didreroot)
876    fprintf(outfile, "          ");
877  else if (nonzero)
878    fprintf(outfile, "   yes    ");
879  else if (unknown)
880    fprintf(outfile, "    ?     ");
881  else if (maybe)
882    fprintf(outfile, "  maybe   ");
883  else
884    fprintf(outfile, "   no     ");
885  for (j = 1; j <= (chars); j++) {
886    newline(j, 40L, nmlngth + 17L);
887    k = (j - 1) / bits + 1;
888    l = (j - 1) % bits + 1;
889    dot = (((1L << l) & wagner[k - 1]) == 0 && guess[j - 1] == '?');
890    s0 = (((1L << l) & r->fulstte0[k - 1]) != 0);
891    s1 = (((1L << l) & r->fulstte1[k - 1]) != 0);
892    a0 = (((1L << l) & zerobelow->bits_[k - 1]) != 0);
893    a1 = (((1L << l) & onebelow->bits_[k - 1]) != 0);
894    dot = (dot || ((!bottom || !noroot || didreroot) && a1 == s1 &&
895                   a0 == s0 && s0 != s1));
896    if (dot)
897      putc('.', outfile);
898    else {
899      if (s0)
900        putc('0', outfile);
901      else if (s1)
902        putc('1', outfile);
903      else
904        putc('?', outfile);
905    }
906    if (j % 5 == 0)
907      putc(' ', outfile);
908  }
909  putc('\n', outfile);
910}  /* hyprint */
911
912void hyptrav(r, dohyp,unknown)
913node *r;
914bitptr dohyp;
915boolean unknown;
916{
917  /*  compute, print out states at one interior node */
918  /* Local variables for hyptrav: */
919  boolean bottom, maybe, nonzero;
920  gbit *zerobelow, *onebelow;
921  long i;
922  long l0, l1, r0, r1, s0, s1, a0, a1, temp, dh, wa;
923
924  gnu(&zerobelow);
925  gnu(&onebelow);
926  bottom = (r->back == NULL);
927  maybe = false;
928  nonzero = false;
929  if (bottom) {
930    memcpy(zerobelow->bits_, zeroanc, words*sizeof(long));
931    memcpy(onebelow->bits_, oneanc, words*sizeof(long));
932  } else {
933    memcpy(zerobelow->bits_, treenode[r->back->index - 1]->fulstte0,
934           words*sizeof(long));
935    memcpy(onebelow->bits_, treenode[r->back->index - 1]->fulstte1,
936           words*sizeof(long));
937  }
938  for (i = 0; i < (words); i++) {
939    dh = dohyp[i];
940    s0 = r->fulstte0[i];
941    s1 = r->fulstte1[i];
942    a0 = zerobelow->bits_[i];
943    a1 = onebelow->bits_[i];
944    if (!r->tip) {
945      wa = wagner[i];
946      l0 = r->next->back->fulstte0[i];
947      l1 = r->next->back->fulstte1[i];
948      r0 = r->next->next->back->fulstte0[i];
949      r1 = r->next->next->back->fulstte1[i];
950      s0 = (wa & ((a0 & l0) | (a0 & r0) | (l0 & r0))) |
951           (dh & fullset & (~wa) & s0);
952      s1 = (wa & ((a1 & l1) | (a1 & r1) | (l1 & r1))) |
953           (dh & fullset & (~wa) & s1);
954      temp = fullset & (~(s0 | s1 | l1 | l0 | r1 | r0));
955      s0 |= temp & a0;
956      s1 |= temp & a1;
957      r->fulstte0[i] = s0;
958      r->fulstte1[i] = s1;
959    }
960    maybe = (maybe || (dh & (s0 | s1)) != (a0 | a1));
961    nonzero = (nonzero || ((s1 & a0) | (s0 & a1)) != 0);
962  }
963  hyprint(r,bottom,nonzero,unknown,maybe,zerobelow,onebelow);
964  if (!r->tip) {
965    hyptrav(r->next->back, dohyp,unknown);
966    hyptrav(r->next->next->back, dohyp,unknown);
967  }
968  chuck(zerobelow);
969  chuck(onebelow);
970}  /* hyptrav */
971
972void hypstates()
973{
974  /* fill in and describe states at interior nodes */
975/* Local variables for hypstates: */
976  boolean unknown;
977  bitptr dohyp;
978  long i, j, k;
979
980
981  for (i = 0; i < (words); i++) {
982    zeroanc[i] = 0;
983    oneanc[i] = 0;
984  }
985  unknown = false;
986  for (i = 0; i < (chars); i++) {
987    j = i / bits + 1;
988    k = i % bits + 1;
989    if (guess[i] == '0')
990      zeroanc[j - 1] = ((long)zeroanc[j - 1]) |
991                                   (1L << ((int)k));
992    if (guess[i] == '1')
993      oneanc[j - 1] = ((long)oneanc[j - 1]) | (1L << ((int)k));
994    unknown = (unknown ||
995        (((unsigned long)k >= 32 || ((1L << k) & wagner[j - 1]) == 0) &&
996         guess[i] == '?'));
997  }
998  dohyp = (bitptr)Malloc(words*sizeof(long));
999  for (i = 0; i < (words); i++)
1000    dohyp[i] = wagner[i] | zeroanc[i] | oneanc[i];
1001  filltrav(root);
1002  fprintf(outfile, "From    To     Any Steps?");
1003  fprintf(outfile, "    State at upper node\n");
1004  fprintf(outfile, "                            ");
1005  fprintf(outfile, " ( . means same as in the node below it on tree)\n\n");
1006  hyptrav(root, dohyp,unknown);
1007  free(dohyp);
1008}  /* hypstates */
1009
1010void treeout(p)
1011node *p;
1012{
1013  /* write out file with representation of final tree */
1014  long i, n;
1015  Char c;
1016
1017  if (p->tip) {
1018    n = 0;
1019    for (i = 1; i <= nmlngth; i++) {
1020      if (nayme[p->index - 1][i - 1] != ' ')
1021        n = i;
1022    }
1023    for (i = 0; i < n; i++) {
1024      c = nayme[p->index - 1][i];
1025      if (c == ' ')
1026        c = '_';
1027      putc(c, treefile);
1028    }
1029    col += n;
1030  } else {
1031    putc('(', treefile);
1032    col++;
1033    treeout(p->next->back);
1034    putc(',', treefile);
1035    col++;
1036    if (col > 65) {
1037      putc('\n', treefile);
1038      col = 0;
1039    }
1040    treeout(p->next->next->back);
1041    putc(')', treefile);
1042    col++;
1043  }
1044  if (p != root)
1045    return;
1046  if (nextree > 2)
1047    fprintf(treefile, "[%6.4f];\n", 1.0 / (nextree - 1));
1048  else
1049    fprintf(treefile, ";\n");
1050}  /* treeout */
1051
1052void describe()
1053{
1054  /* prints ancestors, steps and table of numbers of steps in
1055    each character */
1056  long i, j, k;
1057
1058  if (treeprint)
1059    fprintf(outfile, "\nrequires a total of %10.3f\n", -like);
1060  if (stepbox) {
1061    putc('\n', outfile);
1062    if (weights)
1063      fprintf(outfile, " weighted");
1064    fprintf(outfile, " steps in each character:\n");
1065    fprintf(outfile, "      ");
1066    for (i = 0; i <= 9; i++)
1067      fprintf(outfile, "%4ld", i);
1068    fprintf(outfile, "\n     *-----------------------------------------\n");
1069    for (i = 0; i <= (chars / 10); i++) {
1070      fprintf(outfile, "%5ld", i * 10);
1071      putc('!', outfile);
1072      for (j = 0; j <= 9; j++) {
1073        k = i * 10 + j;
1074        if (k == 0 || k > chars)
1075          fprintf(outfile, "    ");
1076        else
1077          fprintf(outfile, "%4ld", numsteps[k - 1] + extras[k - 1]);
1078      }
1079      putc('\n', outfile);
1080    }
1081  }
1082  putc('\n', outfile);
1083  if (questions && (!noroot || didreroot)) {
1084    fprintf(outfile, "best guesses of ancestral states:\n");
1085    fprintf(outfile, "      ");
1086    for (i = 0; i <= 9; i++)
1087      fprintf(outfile, "%2ld", i);
1088    fprintf(outfile, "\n     *--------------------\n");
1089    for (i = 0; i <= (chars / 10); i++) {
1090      putc(' ', outfile);
1091      fprintf(outfile, "%4ld!", i * 10);
1092      for (j = 0; j <= 9; j++) {
1093        if (i * 10 + j == 0 || i * 10 + j > chars)
1094          fprintf(outfile, "  ");
1095        else
1096          fprintf(outfile, " %c", guess[i * 10 + j - 1]);
1097      }
1098      putc('\n', outfile);
1099    }
1100    putc('\n', outfile);
1101  }
1102  if (ancseq) {
1103    hypstates();
1104    putc('\n', outfile);
1105  }
1106  putc('\n', outfile);
1107  if (trout) {
1108    col = 0;
1109    treeout(root);
1110  }
1111}  /* describe */
1112
1113
1114void maketree()
1115{
1116  /* constructs a binary tree from the pointers in treenode.
1117    adds each node at location which yields highest "likelihood"
1118    then rearranges the tree for greatest "likelihood" */
1119  long i, j, k, numtrees, num, sumw;
1120  double gotlike, sum, sum2, sd;
1121  node *item, *nufork, *dummy;
1122  double TEMP;
1123  place = (long *)Malloc(nonodes*sizeof(long));
1124  steps = (bitptr)Malloc(words*sizeof(long));
1125  zeroanc = (bitptr)Malloc(words*sizeof(long));
1126  oneanc = (bitptr)Malloc(words*sizeof(long));
1127  fulzeroanc = (bitptr)Malloc(words*sizeof(long));
1128  empzeroanc = (bitptr)Malloc(words*sizeof(long));
1129
1130  fullset = (1L << (bits + 1)) - (1L << 1);
1131  for (i=0 ; i<words ; ++i){
1132    fulzeroanc[i]=fullset;
1133    empzeroanc[i]= 0;}
1134  if (!usertree) {
1135    for (i = 1; i <= (spp); i++)
1136      enterorder[i - 1] = i;
1137    if (jumble) {
1138      for (i = 0; i < (spp); i++) {
1139        j = (long)(randum(seed) * spp) + 1;
1140        k = enterorder[j - 1];
1141        enterorder[j - 1] = enterorder[i];
1142        enterorder[i] = k;
1143      }
1144    }
1145    root = treenode[enterorder[0] - 1];
1146    add(treenode[enterorder[0] - 1], treenode[enterorder[1] - 1],
1147        treenode[spp]);
1148    if (progress) {
1149      printf("\nAdding species:\n");
1150      printf("   ");
1151      for (i = 0; i < nmlngth; i++)
1152        putchar(nayme[enterorder[0] - 1][i]);
1153      printf("\n   ");
1154      for (i = 0; i < nmlngth; i++)
1155        putchar(nayme[enterorder[1] - 1][i]);
1156      putchar('\n');
1157    }
1158    lastrearr = false;
1159    for (i = 3; i <= (spp); i++) {
1160      bestyet = -32000.0;
1161      item = treenode[enterorder[i - 1] - 1];
1162      nufork = treenode[spp + i - 2];
1163      addpreorder(root, item, nufork);
1164      add(there, item, nufork);
1165      like = bestyet;
1166      rearrange(&root);
1167      if (progress) {
1168        printf("   ");
1169        for (j = 0; j < nmlngth; j++)
1170          putchar(nayme[enterorder[i - 1] - 1][j]);
1171        putchar('\n');
1172      }
1173      lastrearr = (i == spp);
1174      if (lastrearr) {
1175        if (progress) {
1176          printf("\nDoing global rearrangements\n");
1177          printf("  !");
1178          for (j = 1; j <= (nonodes); j++)
1179            putchar('-');
1180          printf("!\n");
1181        }
1182        bestlike = bestyet;
1183        if (jumb == 1) {
1184          bstlike2 = bestlike;
1185          nextree = 1;
1186        }
1187        do {
1188          if (progress)
1189            printf("   ");
1190          gotlike = bestlike;
1191          for (j = 0; j < (nonodes); j++) {
1192            bestyet = -32000.0;
1193            item = treenode[j];
1194            if (item != root) {
1195              re_move(&item, &nufork);
1196              there = root;
1197              addpreorder(root, item, nufork);
1198              add(there, item, nufork);
1199            }
1200            if (progress)
1201              putchar('.');
1202          }
1203          if (progress)
1204            putchar('\n');
1205        } while (bestlike > gotlike);
1206      }
1207    }
1208    if (progress)
1209      putchar('\n');
1210    for (i = spp - 1; i >= 1; i--)
1211      re_move(&treenode[i], &dummy);
1212    if (jumb == njumble) {
1213      if (treeprint) {
1214        putc('\n', outfile);
1215        if (nextree == 2)
1216          fprintf(outfile, "One most parsimonious tree found:\n");
1217        else
1218          fprintf(outfile, "%6ld trees in all found\n", nextree - 1);
1219      }
1220      if (nextree > maxtrees + 1) {
1221        if (treeprint)
1222          fprintf(outfile, "here are the first%4ld of them\n", (long)maxtrees);
1223        nextree = maxtrees + 1;
1224      }
1225      if (treeprint)
1226        putc('\n', outfile);
1227      for (i = 0; i <= (nextree - 2); i++) {
1228        root = treenode[0];
1229        add(treenode[0], treenode[1], treenode[spp]);
1230        for (j = 3; j <= (spp); j++)
1231            add(treenode[bestrees[i][j - 1] - 1], treenode[j - 1],
1232            treenode[spp + j - 2]);
1233        if (noroot)
1234          reroot(treenode[outgrno - 1]);
1235        didreroot = (outgropt && noroot);
1236        evaluate(root);
1237        printree();
1238        describe();
1239        for (j = 1; j < (spp); j++)
1240          re_move(&treenode[j], &dummy);
1241      }
1242    }
1243  } else {
1244    fscanf(infile, "%ld%*[^\n]", &numtrees);
1245    getc(infile);
1246    if (treeprint) {
1247      fprintf(outfile, "User-defined tree");
1248      if (numtrees > 1)
1249        putc('s', outfile);
1250      fprintf(outfile, ":\n\n");
1251    }
1252    which = 1;
1253    while (which <= numtrees ) {
1254      treeread();
1255      didreroot = (outgropt && noroot);
1256      if (noroot)
1257        reroot(treenode[outgrno - 1]);
1258      evaluate(root);
1259      printree();
1260      describe();
1261      which++;
1262    }
1263    fprintf(outfile, "\n\n");
1264    if (numtrees > 1 && chars > 1 ) {
1265      if (numtrees > maxuser) {
1266        printf("TOO MANY USER-DEFINED TREES");
1267        printf("  test only performed in the first%4ld of them\n",
1268               (long)maxuser);
1269        num = maxuser;
1270      } else
1271        num = numtrees;
1272      fprintf(outfile, "Tree    Steps   Diff Steps   Its S.D.");
1273      fprintf(outfile, "   Significantly worse?\n\n");
1274      for (which = 1; which <= num; which++) {
1275        fprintf(outfile, "%4ld%10.1f", which, nsteps[which - 1]);
1276        if (which == minwhich)
1277          fprintf(outfile, "  <------- best\n");
1278        else {
1279          sumw = 0;
1280          sum = 0.0;
1281          sum2 = 0.0;
1282          for (j = 0; j < (chars); j++) {
1283            if (weight[j] > 0) {
1284              sumw += weight[j];
1285              sum += fsteps[which - 1][j] - fsteps[minwhich - 1][j];
1286              TEMP = fsteps[which - 1][j] - fsteps[minwhich - 1][j];
1287              sum2 += TEMP * TEMP;
1288            }
1289          }
1290          sd = sqrt(sumw / (sumw - 1.0) * (sum2 - sum * sum / sumw));
1291          fprintf(outfile, "%8.1f%15.5f", nsteps[which - 1] - minsteps, sd);
1292          if (sum > 1.95996 * sd)
1293            fprintf(outfile, "           Yes\n");
1294          else
1295            fprintf(outfile, "           No\n");
1296        }
1297      }
1298      fprintf(outfile, "\n\n");
1299    }
1300  }
1301  if (jumb == njumble) {
1302    if (progress) {
1303      printf("\nOutput written to output file\n\n");
1304      if (trout)
1305        printf("Trees also written onto tree file\n");
1306      putchar('\n');
1307    }
1308  }
1309free(place);
1310free(steps);
1311free(zeroanc);
1312free(oneanc);
1313free(fulzeroanc);
1314free(empzeroanc);
1315}  /* maketree */
1316
Note: See TracBrowser for help on using the repository browser.