source: branches/profile/GDE/PHYLIP/discrete.c

Last change on this file was 2175, checked in by westram, 20 years ago

upgrade to PHYLIP 3.6

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 78.9 KB
Line 
1#include "phylip.h"
2#include "discrete.h"
3
4/* version 3.6. (c) Copyright 1993-2000 by the University of Washington.
5   Written by Joseph Felsenstein, Akiko Fuseki, Sean Lamont, and Andrew Keeffe.
6   Permission is granted to copy and use this program provided no fee is
7   charged for it and provided that this copyright notice is not removed. */
8
9long nonodes, endsite, outgrno, nextree, which;
10boolean interleaved, printdata, outgropt, treeprint, dotdiff;
11steptr weight, category, alias, location, ally;
12sequence y, convtab;
13
14
15void inputdata(long chars)
16{
17  /* input the names and sequences for each species */
18  /* used by pars */
19  long i, j, k, l;
20  long basesread=0, basesnew=0, nsymbol=0, convsymboli=0;
21  Char charstate;
22  boolean allread, done, found;
23
24  if (printdata)
25    headings(chars, "Sequences", "---------");
26  basesread = 0;
27  allread = false;
28  while (!(allread)) {
29    allread = true;
30    if (eoln(infile))
31      scan_eoln(infile);
32    i = 1;
33    while (i <= spp) {
34      if ((interleaved && basesread == 0) || !interleaved)
35        initname(i - 1);
36      j = (interleaved) ? basesread : 0;
37      done = false;
38      while (!done && !eoff(infile)) {
39        if (interleaved)
40          done = true;
41        while (j < chars && !(eoln(infile) || eoff(infile))) {
42          charstate = gettc(infile);
43          if (charstate == '\n')
44            charstate = ' ';
45          if (charstate == ' ')
46            continue;
47          if ((strchr("!\"#$%&'()*+,-./0123456789:;<=>?@\
48                       ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`\
49                       abcdefghijklmnopqrstuvwxyz{|}~",charstate)) == NULL){
50            printf(
51                  "\n\nERROR: Bad base: %c at position %ld of species %ld\n\n",
52                   charstate, j+1, i);
53            exxit(-1);
54          }
55          j++;
56          y[i - 1][j - 1] = charstate;
57        }
58        if (interleaved)
59          continue;
60        if (j < chars) 
61          scan_eoln(infile);
62        else if (j == chars)
63          done = true;
64      }
65      if (interleaved && i == 1)
66        basesnew = j;
67
68      scan_eoln(infile);
69     
70      if ((interleaved && j != basesnew) ||
71          (!interleaved && j != chars)) {
72        printf("\n\nERROR: Sequences out of alignment at position %ld\n\n", j);
73        exxit(-1);
74      }
75      i++;
76    }
77    if (interleaved) {
78      basesread = basesnew;
79      allread = (basesread == chars);
80    } else
81      allread = (i > spp);
82  }
83  if (printdata) {
84    for (i = 1; i <= ((chars - 1) / 60 + 1); i++) {
85      for (j = 1; j <= spp; j++) {
86        for (k = 0; k < nmlngth; k++)
87          putc(nayme[j - 1][k], outfile);
88        fprintf(outfile, "   ");
89        l = i * 60;
90        if (l > chars)
91          l = chars;
92        for (k = (i - 1) * 60 + 1; k <= l; k++) {
93          if (dotdiff && (j > 1 && y[j - 1][k - 1] == y[0][k - 1]))
94            charstate = '.';
95          else
96            charstate = y[j - 1][k - 1];
97          putc(charstate, outfile);
98          if (k % 10 == 0 && k % 60 != 0)
99            putc(' ', outfile);
100        }
101        putc('\n', outfile);
102      }
103      putc('\n', outfile);
104    }
105    putc('\n', outfile);
106  }
107  for (i = 1; i <= chars; i++) {
108    nsymbol = 0;
109    for (j = 1; j <= spp; j++) {
110      if ((nsymbol == 0) && (y[j - 1][i - 1] != '?')) {
111        nsymbol = 1;
112        convsymboli = 1;
113        convtab[0][i-1] = y[j-1][i-1];
114      } else if (y[j - 1][i - 1] != '?'){
115        found = false;
116        for (k = 1; k <= nsymbol; k++) {
117          if (convtab[k - 1][i - 1] == y[j - 1][i - 1]) {
118            found = true;
119            convsymboli = k;
120          }
121        }
122        if (!found) {
123          nsymbol++;
124          convtab[nsymbol-1][i - 1] = y[j - 1][i - 1];
125          convsymboli = nsymbol;
126        } 
127      }
128      if (nsymbol <= 8) {
129        if (y[j - 1][i - 1] != '?')
130          y[j - 1][i - 1] = (Char)('0' + (convsymboli - 1));
131      } else {
132        printf(
133          "\n\nERROR: More than maximum of 8 symbols in column %ld\n\n", i);
134        exxit(-1);
135      }
136    }
137  }
138}  /* inputdata */
139
140
141void alloctree(pointarray *treenode, long nonodes, boolean usertree)
142{
143  /* allocate treenode dynamically */
144  /* used in pars */
145  long i, j;
146  node *p, *q;
147
148  *treenode = (pointarray)Malloc(nonodes*sizeof(node *));
149  for (i = 0; i < spp; i++) {
150    (*treenode)[i] = (node *)Malloc(sizeof(node));
151    (*treenode)[i]->tip = true;
152    (*treenode)[i]->index = i+1;
153    (*treenode)[i]->iter = true;
154    (*treenode)[i]->branchnum = i+1;
155    (*treenode)[i]->initialized = true;
156  }
157  if (!usertree)
158    for (i = spp; i < nonodes; i++) {
159      q = NULL;
160      for (j = 1; j <= 3; j++) {
161        p = (node *)Malloc(sizeof(node));
162        p->tip = false;
163        p->index = i+1;
164        p->iter = true;
165        p->branchnum = i+1;
166        p->initialized = false;
167        p->next = q;
168        q = p;
169      }
170      p->next->next->next = p;
171      (*treenode)[i] = p;
172    }
173} /* alloctree */
174
175
176void setuptree(pointarray treenode, long nonodes, boolean usertree)
177{
178  /* initialize treenodes */
179  long i;
180  node *p;
181
182  for (i = 1; i <= nonodes; i++) {
183    if (i <= spp || !usertree) {
184      treenode[i-1]->back = NULL;
185      treenode[i-1]->tip = (i <= spp);
186      treenode[i-1]->index = i;
187      treenode[i-1]->numdesc = 0;
188      treenode[i-1]->iter = true;
189      treenode[i-1]->initialized = true;
190    }
191  }
192  if (!usertree) {
193    for (i = spp + 1; i <= nonodes; i++) {
194      p = treenode[i-1]->next;
195      while (p != treenode[i-1]) {
196        p->back = NULL;
197        p->tip = false;
198        p->index = i;
199        p->numdesc = 0;
200        p->iter = true;
201        p->initialized = false;
202        p = p->next;
203      }
204    }
205  }
206} /* setuptree */
207
208
209void alloctip(node *p, long *zeros, unsigned char *zeros2)
210{ /* allocate a tip node */
211  /* used by pars */
212
213  p->numsteps = (steptr)Malloc(endsite*sizeof(long));
214  p->oldnumsteps = (steptr)Malloc(endsite*sizeof(long));
215  p->discbase = (discbaseptr)Malloc(endsite*sizeof(unsigned char));
216  p->olddiscbase = (discbaseptr)Malloc(endsite*sizeof(unsigned char));
217  memcpy(p->discbase, zeros2, endsite*sizeof(unsigned char));
218  memcpy(p->numsteps, zeros, endsite*sizeof(long));
219  memcpy(p->olddiscbase, zeros2, endsite*sizeof(unsigned char));
220  memcpy(p->oldnumsteps, zeros, endsite*sizeof(long));
221}  /* alloctip */
222
223
224void sitesort(long chars, steptr weight)
225{
226  /* Shell sort keeping sites, weights in same order */
227  /* used in pars */
228  long gap, i, j, jj, jg, k, itemp;
229  boolean flip, tied;
230
231  gap = chars / 2;
232  while (gap > 0) {
233    for (i = gap + 1; i <= chars; i++) {
234      j = i - gap;
235      flip = true;
236      while (j > 0 && flip) {
237        jj = alias[j - 1];
238        jg = alias[j + gap - 1];
239        tied = true;
240        k = 1;
241        while (k <= spp && tied) {
242          flip = (y[k - 1][jj - 1] > y[k - 1][jg - 1]);
243          tied = (tied && y[k - 1][jj - 1] == y[k - 1][jg - 1]);
244          k++;
245        }
246        if (!flip)
247          break;
248        itemp = alias[j - 1];
249        alias[j - 1] = alias[j + gap - 1];
250        alias[j + gap - 1] = itemp;
251        itemp = weight[j - 1];
252        weight[j - 1] = weight[j + gap - 1];
253        weight[j + gap - 1] = itemp;
254        j -= gap;
255      }
256    }
257    gap /= 2;
258  }
259}  /* sitesort */
260
261
262void sitecombine(long chars)
263{
264  /* combine sites that have identical patterns */
265  /* used in pars */
266  long i, j, k;
267  boolean tied;
268
269  i = 1;
270  while (i < chars) {
271    j = i + 1;
272    tied = true;
273    while (j <= chars && tied) {
274      k = 1;
275      while (k <= spp && tied) {
276        tied = (tied &&
277            y[k - 1][alias[i - 1] - 1] == y[k - 1][alias[j - 1] - 1]);
278        k++;
279      }
280      if (tied) {
281        weight[i - 1] += weight[j - 1];
282        weight[j - 1] = 0;
283        ally[alias[j - 1] - 1] = alias[i - 1];
284      }
285      j++;
286    }
287    i = j - 1;
288  }
289}  /* sitecombine */
290
291
292void sitescrunch(long chars)
293{
294  /* move so one representative of each pattern of
295     sites comes first */
296  /* used in pars */
297  long i, j, itemp;
298  boolean done, found;
299
300  done = false;
301  i = 1;
302  j = 2;
303  while (!done) {
304    if (ally[alias[i - 1] - 1] != alias[i - 1]) {
305      if (j <= i)
306        j = i + 1;
307      if (j <= chars) {
308        found = false;
309        do {
310          found = (ally[alias[j - 1] - 1] == alias[j - 1]);
311          j++;
312        } while (!(found || j > chars));
313        if (found) {
314          j--;
315          itemp = alias[i - 1];
316          alias[i - 1] = alias[j - 1];
317          alias[j - 1] = itemp;
318          itemp = weight[i - 1];
319          weight[i - 1] = weight[j - 1];
320          weight[j - 1] = itemp;
321        } else
322          done = true;
323      } else
324        done = true;
325    }
326    i++;
327    done = (done || i >= chars);
328  }
329}  /* sitescrunch */
330
331
332void makevalues(pointarray treenode, long *zeros, unsigned char *zeros2,
333                        boolean usertree)
334{
335  /* set up fractional likelihoods at tips */
336  /* used by pars */
337  long i, j;
338  unsigned char ns=0;
339  node *p;
340
341  setuptree(treenode, nonodes, usertree);
342  for (i = 0; i < spp; i++)
343    alloctip(treenode[i], zeros, zeros2);
344  if (!usertree) {
345    for (i = spp; i < nonodes; i++) {
346      p = treenode[i];
347      do {
348        allocdiscnontip(p, zeros, zeros2, endsite);
349        p = p->next;
350      } while (p != treenode[i]);
351    }
352  }
353  for (j = 0; j < endsite; j++) {
354    for (i = 0; i < spp; i++) {
355      switch (y[i][alias[j] - 1]) {
356
357      case '0':
358        ns = 1 << zero;
359        break;
360
361      case '1':
362        ns = 1 << one;
363        break;
364
365      case '2':
366        ns = 1 << two;
367        break;
368
369      case '3':
370        ns = 1 << three;
371        break;
372
373      case '4':
374        ns = 1 << four;
375        break;
376
377      case '5':
378        ns = 1 << five;
379        break;
380
381      case '6':
382        ns = 1 << six;
383        break;
384
385      case '7':
386        ns = 1 << seven;
387        break;
388
389      case '?':
390        ns = (1 << zero) | (1 << one) | (1 << two) | (1 << three) |
391               (1 << four) | (1 << five) | (1 << six) | (1 << seven);
392        break;
393      }
394      treenode[i]->discbase[j] = ns;
395      treenode[i]->numsteps[j] = 0;
396    }
397  }
398}  /* makevalues */
399
400
401void fillin(node *p, node *left, node *rt)
402{
403  /* sets up for each node in the tree the base sequence
404     at that point and counts the changes.  */
405  long i, j, k, n;
406  node *q;
407
408  if (!left) {
409    memcpy(p->discbase, rt->discbase, endsite*sizeof(unsigned char));
410    memcpy(p->numsteps, rt->numsteps, endsite*sizeof(long));
411    q = rt;
412  } else if (!rt) {
413    memcpy(p->discbase, left->discbase, endsite*sizeof(unsigned char));
414    memcpy(p->numsteps, left->numsteps, endsite*sizeof(long));
415    q = left;
416  } else {
417    for (i = 0; i < endsite; i++) {
418      p->discbase[i] = left->discbase[i] & rt->discbase[i];
419      p->numsteps[i] = left->numsteps[i] + rt->numsteps[i];
420      if (p->discbase[i] == 0) {
421        p->discbase[i] = left->discbase[i] | rt->discbase[i];
422        p->numsteps[i] += weight[i];
423      }
424    }
425    q = rt;
426  }
427  if (left && rt) n = 2;
428  else n = 1;
429  for (i = 0; i < endsite; i++)
430    for (j = (long)zero; j <= (long)seven; j++)
431      p->discnumnuc[i][j] = 0;
432  for (k = 1; k <= n; k++) {
433    if (k == 2) q = left;
434    for (i = 0; i < endsite; i++) {
435      for (j = (long)zero; j <= (long)seven; j++) {
436        if (q->discbase[i] & (1 << j))
437          p->discnumnuc[i][j]++;
438      }
439    }
440  }
441}  /* fillin */
442
443
444long getlargest(long *discnumnuc)
445{
446  /* find the largest in array numnuc */
447  long i, largest;
448
449  largest = 0;
450  for (i = (long)zero; i <= (long)seven; i++)
451    if (discnumnuc[i] > largest)
452      largest = discnumnuc[i];
453  return largest;
454} /* getlargest */
455
456
457void multifillin(node *p, node *q, long dnumdesc)
458{
459  /* sets up for each node in the tree the base sequence
460     at that point and counts the changes according to the
461     changes in q's base */
462  long i, j, largest, descsteps;
463  unsigned char b;
464
465  memcpy(p->olddiscbase, p->discbase, endsite*sizeof(unsigned char));
466  memcpy(p->oldnumsteps, p->numsteps, endsite*sizeof(long));
467  for (i = 0; i < endsite; i++) {
468    descsteps = 0;
469    for (j = (long)zero; j <= (long)seven; j++) {
470      b = 1 << j;
471      if ((descsteps == 0) && (p->discbase[i] & b)) 
472        descsteps = p->numsteps[i] 
473                      - (p->numdesc - dnumdesc - p->discnumnuc[i][j])
474                        * weight[i];
475    }
476    if (dnumdesc == -1)
477      descsteps -= q->oldnumsteps[i];
478    else if (dnumdesc == 0)
479      descsteps += (q->numsteps[i] - q->oldnumsteps[i]);
480    else
481      descsteps += q->numsteps[i];
482    if (q->olddiscbase[i] != q->discbase[i]) {
483      for (j = (long)zero; j <= (long)seven; j++) {
484        b = 1 << j;
485        if ((q->olddiscbase[i] & b) && !(q->discbase[i] & b))
486          p->discnumnuc[i][j]--;
487        else if (!(q->olddiscbase[i] & b) && (q->discbase[i] & b))
488          p->discnumnuc[i][j]++;
489      }
490    }
491    largest = getlargest(p->discnumnuc[i]);
492    if (q->olddiscbase[i] != q->discbase[i]) {
493      p->discbase[i] = 0;
494      for (j = (long)zero; j <= (long)seven; j++) {
495        if (p->discnumnuc[i][j] == largest)
496            p->discbase[i] |= (1 << j);
497      }
498    }
499    p->numsteps[i] = (p->numdesc - largest) * weight[i] + descsteps;
500  }
501} /* multifillin */
502
503
504void sumnsteps(node *p, node *left, node *rt, long a, long b)
505{
506  /* sets up for each node in the tree the base sequence
507     at that point and counts the changes. */
508  long i;
509  unsigned char ns, rs, ls;
510
511  if (!left) {
512    memcpy(p->numsteps, rt->numsteps, endsite*sizeof(long));
513    memcpy(p->discbase, rt->discbase, endsite*sizeof(unsigned char));
514  } else if (!rt) {
515    memcpy(p->numsteps, left->numsteps, endsite*sizeof(long));
516    memcpy(p->discbase, left->discbase, endsite*sizeof(unsigned char));
517  } else 
518    for (i = a; i < b; i++) {
519      ls = left->discbase[i];
520      rs = rt->discbase[i];
521      ns = ls & rs;
522      p->numsteps[i] = left->numsteps[i] + rt->numsteps[i];
523      if (ns == 0) {
524        ns = ls | rs;
525        p->numsteps[i] += weight[i];
526      }
527      p->discbase[i] = ns;
528    }
529}  /* sumnsteps */
530
531
532void sumnsteps2(node *p, node *left, node *rt, long a, long b, long *threshwt)
533{
534  /* counts the changes at each node.  */
535  long i, steps;
536  unsigned char ns, rs, ls;
537  long term;
538
539  if (a == 0) p->sumsteps = 0.0;
540  if (!left)
541    memcpy(p->numsteps, rt->numsteps, endsite*sizeof(long));
542  else if (!rt)
543    memcpy(p->numsteps, left->numsteps, endsite*sizeof(long));
544  else 
545    for (i = a; i < b; i++) {
546      ls = left->discbase[i];
547      rs = rt->discbase[i];
548      ns = ls & rs;
549      p->numsteps[i] = left->numsteps[i] + rt->numsteps[i];
550      if (ns == 0)
551        p->numsteps[i] += weight[i];
552    }
553  for (i = a; i < b; i++) {
554    steps = p->numsteps[i];
555    if ((long)steps <= threshwt[i])
556      term = steps;
557    else
558      term = threshwt[i];
559    p->sumsteps += (double)term;
560  }
561}  /* sumnsteps2 */
562
563
564void multisumnsteps(node *p, node *q, long a, long b, long *threshwt)
565{
566  /* sets up for each node in the tree the base sequence
567     at that point and counts the changes according to the
568     changes in q's base */
569  long i, j, steps, largest, descsteps;
570  long term;
571
572  if (a == 0) p->sumsteps = 0.0;
573  for (i = a; i < b; i++) {
574    largest = getlargest(p->discnumnuc[i]);
575    descsteps = 0;
576    for (j = (long)zero; j <= (long)seven; j++) {
577      if ((descsteps == 0) && (p->discbase[i] & (1 << j))) 
578        descsteps = p->numsteps[i] -
579                        (p->numdesc - 1 - p->discnumnuc[i][j]) * weight[i];
580    }
581    descsteps += q->numsteps[i];
582    largest = 0;
583    for (j = (long)zero; j <= (long)seven; j++) {
584      if (q->discbase[i] & (1 << j))
585        p->discnumnuc[i][j]++;
586      if (p->discnumnuc[i][j] > largest)
587        largest = p->discnumnuc[i][j];
588    }
589    steps = ((p->numdesc - largest) * weight[i] + descsteps);
590    if ((long)steps <= threshwt[i])
591      term = steps;
592    else
593      term = threshwt[i];
594    p->sumsteps += (double)term;
595  }
596} /* multisumnsteps */
597
598
599void multisumnsteps2(node *p)
600{
601  /* counts the changes at each multi-way node. Sums up
602     steps of all descendants */
603  long i, j, largest;
604  node *q;
605  discbaseptr b;
606
607  for (i = 0; i < endsite; i++) {
608    p->numsteps[i] = 0;
609    q = p->next;
610    while (q != p) {
611      if (q->back) {
612        p->numsteps[i] += q->back->numsteps[i];
613        b = q->back->discbase;
614        for (j = (long)zero; j <= (long)seven; j++)
615          if (b[i] & (1 << j))
616            p->discnumnuc[i][j]++;
617      }
618      q = q->next;
619    }
620    largest = getlargest(p->discnumnuc[i]);
621    p->numsteps[i] += ((p->numdesc - largest) * weight[i]);
622    p->discbase[i] = 0;
623    for (j = (long)zero; j <= (long)seven; j++) {
624      if (p->discnumnuc[i][j] == largest)
625       p->discbase[i] |= (1 << j);
626    }
627  }
628}  /* multisumnsteps2 */
629
630
631boolean alltips(node *forknode, node *p)
632{
633  /* returns true if all descendants of forknode except p are tips;
634     false otherwise.  */
635  node *q, *r;
636  boolean tips;
637
638  tips = true;
639  r = forknode;
640  q = forknode->next;
641  do {
642    if (q->back && q->back != p && !q->back->tip)
643      tips = false;
644    q = q->next;
645  } while (tips && q != r);
646  return tips;
647} /* alltips */
648
649
650void gdispose(node *p, node **grbg, pointarray treenode)
651{
652  /* go through tree throwing away nodes */
653  node *q, *r;
654
655  p->back = NULL;
656  if (p->tip)
657    return;
658  treenode[p->index - 1] = NULL;
659  q = p->next;
660  while (q != p) {
661    gdispose(q->back, grbg, treenode);
662    q->back = NULL;
663    r = q;
664    q = q->next;
665    chucktreenode(grbg, r);
666  }
667  chucktreenode(grbg, q);
668}  /* gdispose */
669
670
671void preorder(node *p, node *r, node *root, node *removing, node *adding,
672                        node *changing, long dnumdesc)
673{
674  /* recompute number of steps in preorder taking both ancestoral and
675     descendent steps into account. removing points to a node being
676     removed, if any */
677  node *q, *p1, *p2;
678
679  if (p && !p->tip && p != adding) {
680    q = p;
681    do {
682      if (p->back != r) {
683        if (p->numdesc > 2) {
684          if (changing)
685            multifillin (p, r, dnumdesc);
686          else
687            multifillin (p, r, 0);
688        } else {
689          p1 = p->next;
690          if (!removing)
691            while (!p1->back)
692              p1 = p1->next;
693          else
694            while (!p1->back || p1->back == removing)
695              p1 = p1->next;
696          p2 = p1->next;
697          if (!removing)
698            while (!p2->back)
699              p2 = p2->next;
700          else
701            while (!p2->back || p2->back == removing)
702              p2 = p2->next;
703          p1 = p1->back;
704          p2 = p2->back;
705          if (p->back == p1) p1 = NULL;
706          else if (p->back == p2) p2 = NULL;
707          memcpy(p->olddiscbase, p->discbase, endsite*sizeof(unsigned char));
708          memcpy(p->oldnumsteps, p->numsteps, endsite*sizeof(long));
709          fillin(p, p1, p2);
710        }
711      }
712      p = p->next;
713    } while (p != q);
714    q = p;
715    do {
716      preorder(p->next->back, p->next, root, removing, adding, NULL, 0);
717      p = p->next;
718    } while (p->next != q);
719  }
720} /* preorder */
721
722
723void updatenumdesc(node *p, node *root, long n)
724{
725  /* set p's numdesc to n.  If p is the root, numdesc of p's
726  descendants are set to n-1. */
727  node *q;
728
729  q = p;
730  if (p == root && n > 0) {
731    p->numdesc = n;
732    n--;
733    q = q->next;
734  }
735  do {
736    q->numdesc = n;
737    q = q->next;
738  } while (q != p);
739}
740
741
742void add(node *below, node *newtip, node *newfork, node **root, boolean recompute,
743                        pointarray treenode, node **grbg, long *zeros, unsigned char *zeros2)
744{
745  /* inserts the nodes newfork and its left descendant, newtip,
746     to the tree.  below becomes newfork's right descendant.
747     if newfork is NULL, newtip is added as below's sibling */
748  /* used in pars */
749  node *p;
750
751  if (below != treenode[below->index - 1])
752    below = treenode[below->index - 1];
753  if (newfork) {
754    if (below->back != NULL)
755      below->back->back = newfork;
756    newfork->back = below->back;
757    below->back = newfork->next->next;
758    newfork->next->next->back = below;
759    newfork->next->back = newtip;
760    newtip->back = newfork->next;
761    if (*root == below)
762      *root = newfork;
763    updatenumdesc(newfork, *root, 2);
764  } else {
765    gnudisctreenode(grbg, &p, below->index, endsite, zeros, zeros2);
766    p->back = newtip;
767    newtip->back = p;
768    p->next = below->next;
769    below->next = p;
770    updatenumdesc(below, *root, below->numdesc + 1);
771  }
772  if (!newtip->tip)
773    updatenumdesc(newtip, *root, newtip->numdesc);
774  (*root)->back = NULL;
775  if (!recompute)
776    return;
777  if (!newfork) {
778    memcpy(newtip->back->discbase, below->discbase, endsite*sizeof(unsigned char));
779    memcpy(newtip->back->numsteps, below->numsteps, endsite*sizeof(long));
780    memcpy(newtip->back->discnumnuc, below->discnumnuc, endsite*sizeof(discnucarray));
781    if (below != *root) {
782      memcpy(below->back->olddiscbase, zeros2, endsite*sizeof(unsigned char));
783      memcpy(below->back->oldnumsteps, zeros, endsite*sizeof(long));
784      multifillin(newtip->back, below->back, 1);
785    }
786    if (!newtip->tip) {
787      memcpy(newtip->back->olddiscbase, zeros2, endsite*sizeof(unsigned char));
788      memcpy(newtip->back->oldnumsteps, zeros, endsite*sizeof(long));
789      preorder(newtip, newtip->back, *root, NULL, NULL, below, 1);
790    }
791    memcpy(newtip->olddiscbase, zeros2, endsite*sizeof(unsigned char));
792    memcpy(newtip->oldnumsteps, zeros, endsite*sizeof(long));
793    preorder(below, newtip, *root, NULL, newtip, below, 1);
794    if (below != *root)
795      preorder(below->back, below, *root, NULL, NULL, NULL, 0);
796  } else {
797    fillin(newtip->back, newtip->back->next->back,
798             newtip->back->next->next->back);
799    if (!newtip->tip) {
800      memcpy(newtip->back->olddiscbase, zeros2, endsite*sizeof(unsigned char));
801      memcpy(newtip->back->oldnumsteps, zeros, endsite*sizeof(long));
802      preorder(newtip, newtip->back, *root, NULL, NULL, newfork, 1);
803    }
804    if (newfork != *root) {
805      memcpy(below->back->discbase, newfork->back->discbase, endsite*sizeof(unsigned char));
806      memcpy(below->back->numsteps, newfork->back->numsteps, endsite*sizeof(long));
807      preorder(newfork, newtip, *root, NULL, newtip, NULL, 0);
808    } else {
809      fillin(below->back, newtip, NULL);
810      fillin(newfork, newtip, below);
811      memcpy(below->back->olddiscbase, zeros2, endsite*sizeof(unsigned char));
812      memcpy(below->back->oldnumsteps, zeros, endsite*sizeof(long));
813      preorder(below, below->back, *root, NULL, NULL, newfork, 1);
814    }
815    if (newfork != *root) {
816      memcpy(newfork->olddiscbase, below->discbase, endsite*sizeof(unsigned char));
817      memcpy(newfork->oldnumsteps, below->numsteps, endsite*sizeof(long));
818      preorder(newfork->back, newfork, *root, NULL, NULL, NULL, 0);
819    }
820  }
821}  /* add */
822
823
824void findbelow(node **below, node *item, node *fork)
825{
826  /* decide which of fork's binary children is below */
827
828  if (fork->next->back == item)
829    *below = fork->next->next->back;
830  else
831    *below = fork->next->back;
832} /* findbelow */
833
834
835void re_move(node *item, node **fork, node **root, boolean recompute,
836                        pointarray treenode, node **grbg, long *zeros, unsigned char *zeros2)
837{
838  /* removes nodes item and its ancestor, fork, from the tree.
839     the new descendant of fork's ancestor is made to be
840     fork's second descendant (other than item).  Also
841     returns pointers to the deleted nodes, item and fork.
842     If item belongs to a node with more than 2 descendants,
843     fork will not be deleted */
844  /* used in pars */
845  node *p, *q, *other, *otherback = NULL;
846
847  if (item->back == NULL) {
848    *fork = NULL;
849    return;
850  }
851  *fork = treenode[item->back->index - 1];
852  if ((*fork)->numdesc == 2) {
853    updatenumdesc(*fork, *root, 0);
854    findbelow(&other, item, *fork);
855    otherback = other->back;
856    if (*root == *fork) {
857      if (other->tip)
858        *root = NULL;
859      else {
860        *root = other;
861        updatenumdesc(other, *root, other->numdesc);
862      }
863    }
864    p = item->back->next->back;
865    q = item->back->next->next->back;
866    if (p != NULL)
867      p->back = q;
868    if (q != NULL)
869      q->back = p;
870    (*fork)->back = NULL;
871    p = (*fork)->next;
872    while (p != *fork) {
873      p->back = NULL;
874      p = p->next;
875    }
876  } else {
877    updatenumdesc(*fork, *root, (*fork)->numdesc - 1);
878    p = *fork;
879    while (p->next != item->back)
880      p = p->next;
881    p->next = item->back->next;
882  }
883  if (!item->tip) {
884    updatenumdesc(item, item, item->numdesc);
885    if (recompute) {
886      memcpy(item->back->olddiscbase, item->back->discbase,
887               endsite*sizeof(unsigned char));
888      memcpy(item->back->oldnumsteps, item->back->numsteps, endsite*sizeof(long));
889      memcpy(item->back->discbase, zeros2, endsite*sizeof(unsigned char));
890      memcpy(item->back->numsteps, zeros, endsite*sizeof(long));
891      preorder(item, item->back, *root, item->back, NULL, item, -1);
892    }
893  }
894  if ((*fork)->numdesc >= 2)
895    chucktreenode(grbg, item->back);
896  item->back = NULL;
897  if (!recompute)
898    return;
899  if ((*fork)->numdesc == 0) {
900    memcpy(otherback->olddiscbase, otherback->discbase,
901             endsite*sizeof(unsigned char)); 
902    memcpy(otherback->oldnumsteps, otherback->numsteps, endsite*sizeof(long));
903    if (other == *root) {
904      memcpy(otherback->discbase, zeros2, endsite*sizeof(unsigned char));
905      memcpy(otherback->numsteps, zeros, endsite*sizeof(long));
906    } else {
907      memcpy(otherback->discbase, other->back->discbase,
908               endsite*sizeof(unsigned char));
909      memcpy(otherback->numsteps, other->back->numsteps, endsite*sizeof(long));
910    }
911    p = other->back;
912    other->back = otherback;
913    if (other == *root)
914      preorder(other, otherback, *root, otherback, NULL, other, -1);
915    else
916      preorder(other, otherback, *root, NULL, NULL, NULL, 0);
917    other->back = p;
918    if (other != *root) {
919      memcpy(other->olddiscbase,(*fork)->discbase, endsite*sizeof(unsigned char));
920      memcpy(other->oldnumsteps,(*fork)->numsteps, endsite*sizeof(long));
921      preorder(other->back, other, *root, NULL, NULL, NULL, 0);
922    }
923  } else {
924    memcpy(item->olddiscbase, item->discbase, endsite*sizeof(unsigned char));
925    memcpy(item->oldnumsteps, item->numsteps, endsite*sizeof(long));
926    memcpy(item->discbase, zeros2, endsite*sizeof(unsigned char));
927    memcpy(item->numsteps, zeros, endsite*sizeof(long));
928    preorder(*fork, item, *root, NULL, NULL, *fork, -1);
929    if (*fork != *root)
930      preorder((*fork)->back, *fork, *root, NULL, NULL, NULL, 0);
931    memcpy(item->discbase, item->olddiscbase, endsite*sizeof(unsigned char));
932    memcpy(item->numsteps, item->oldnumsteps, endsite*sizeof(long));
933  }
934}  /* re_move */
935
936
937void postorder(node *p)
938{
939  /* traverses an n-ary tree, suming up steps at a node's descendants */
940  /* used in pars */
941  node *q;
942
943  if (p->tip)
944    return;
945  q = p->next;
946  while (q != p) {
947    postorder(q->back);
948    q = q->next;
949  }
950  zerodiscnumnuc(p, endsite);
951  if (p->numdesc > 2)
952    multisumnsteps2(p);
953  else
954    fillin(p, p->next->back, p->next->next->back);
955}  /* postorder */
956
957
958void getnufork(node **nufork, node **grbg, pointarray treenode, long *zeros,
959                        unsigned char *zeros2)
960{
961  /* find a fork not used currently */
962  long i;
963
964  i = spp;
965  while (treenode[i] && treenode[i]->numdesc > 0) i++;
966  if (!treenode[i])
967    gnudisctreenode(grbg, &treenode[i], i, endsite, zeros, zeros2);
968  *nufork = treenode[i];
969} /* getnufork */
970
971
972void reroot(node *outgroup, node *root)
973{
974  /* reorients tree, putting outgroup in desired position. used if
975     the root is binary. */
976  /* used in pars */
977  node *p, *q;
978
979  if (outgroup->back->index == root->index)
980    return;
981  p = root->next;
982  q = root->next->next;
983  p->back->back = q->back;
984  q->back->back = p->back;
985  p->back = outgroup;
986  q->back = outgroup->back;
987  outgroup->back->back = q;
988  outgroup->back = p;
989}  /* reroot */
990
991
992void reroot2(node *outgroup, node *root)
993{
994  /* reorients tree, putting outgroup in desired position. */
995  /* used in pars */
996  node *p;
997
998  p = outgroup->back->next;
999  while (p->next != outgroup->back)
1000    p = p->next;
1001  root->next = outgroup->back;
1002  p->next = root;
1003}  /* reroot2 */
1004
1005
1006void reroot3(node *outgroup,node *root,node *root2,node *lastdesc,node **grbg)
1007{
1008  /* reorients tree, putting back outgroup in original position. */
1009  /* used in pars */
1010  node *p;
1011
1012  p = root->next;
1013  while (p->next != root)
1014    p = p->next;
1015  chucktreenode(grbg, root);
1016  p->next = outgroup->back;
1017  root2->next = lastdesc->next;
1018  lastdesc->next = root2;
1019}  /* reroot3 */
1020
1021
1022void savetraverse(node *p)
1023{
1024  /* sets BOOLEANs that indicate which way is down */
1025  node *q;
1026
1027  p->bottom = true;
1028  if (p->tip)
1029    return;
1030  q = p->next;
1031  while (q != p) {
1032    q->bottom = false;
1033    savetraverse(q->back);
1034    q = q->next;
1035  }
1036}  /* savetraverse */
1037
1038
1039void newindex(long i, node *p)
1040{
1041  /* assigns index i to node p */
1042
1043  while (p->index != i) {
1044    p->index = i;
1045    p = p->next;
1046  }
1047} /* newindex */
1048
1049
1050void flipindexes(long nextnode, pointarray treenode)
1051{
1052  /* flips index of nodes between nextnode and last node.  */
1053  long last;
1054  node *temp;
1055
1056  last = nonodes;
1057  while (treenode[last - 1]->numdesc == 0)
1058    last--;
1059  if (last > nextnode) {
1060    temp = treenode[nextnode - 1];
1061    treenode[nextnode - 1] = treenode[last - 1];
1062    treenode[last - 1] = temp;
1063    newindex(nextnode, treenode[nextnode - 1]);
1064    newindex(last, treenode[last - 1]);
1065  }
1066} /* flipindexes */ 
1067
1068
1069boolean parentinmulti(node *anode)
1070{
1071  /* sees if anode's parent has more than 2 children */
1072  node *p;
1073
1074  while (!anode->bottom) anode = anode->next;
1075  p = anode->back;
1076  while (!p->bottom)
1077    p = p->next;
1078  return (p->numdesc > 2);
1079} /* parentinmulti */
1080
1081
1082long sibsvisited(node *anode, long *place)
1083{
1084  /* computes the number of nodes which are visited earlier than anode among
1085  its siblings */
1086  node *p;
1087  long nvisited;
1088
1089  while (!anode->bottom) anode = anode->next;
1090  p = anode->back->next;
1091  nvisited = 0;
1092  do {
1093    if (!p->bottom && place[p->back->index - 1] != 0)
1094      nvisited++;
1095    p = p->next;
1096  } while (p != anode->back);
1097  return nvisited;
1098}  /* sibsvisited */
1099
1100
1101long smallest(node *anode, long *place)
1102{
1103  /* finds the smallest index of sibling of anode */
1104  node *p;
1105  long min;
1106
1107  while (!anode->bottom) anode = anode->next;
1108  p = anode->back->next;
1109  if (p->bottom) p = p->next;
1110  min = nonodes;
1111  do {
1112    if (p->back && place[p->back->index - 1] != 0) {
1113      if (p->back->index <= spp) {
1114        if (p->back->index < min)
1115          min = p->back->index;
1116      } else {
1117        if (place[p->back->index - 1] < min)
1118          min = place[p->back->index - 1];
1119      }
1120    }
1121    p = p->next;
1122    if (p->bottom) p = p->next;
1123  } while (p != anode->back);
1124  return min;
1125}  /* smallest */
1126
1127
1128void bintomulti(node **root, node **binroot, node **grbg, long *zeros,
1129                        unsigned char *zeros2)
1130{  /* attaches root's left child to its right child and makes
1131      the right child new root */
1132  node *left, *right, *newnode, *temp;
1133
1134  right = (*root)->next->next->back;
1135  left = (*root)->next->back;
1136  if (right->tip) {
1137    (*root)->next = right->back;
1138    (*root)->next->next = left->back;
1139    temp = left;
1140    left = right;
1141    right = temp;
1142    right->back->next = *root;
1143  }
1144  gnudisctreenode(grbg, &newnode, right->index, endsite, zeros, zeros2);
1145  newnode->next = right->next;
1146  newnode->back = left;
1147  left->back = newnode;
1148  right->next = newnode;
1149  (*root)->next->back = (*root)->next->next->back = NULL;
1150  *binroot = *root;
1151  (*binroot)->numdesc = 0;
1152  *root = right;
1153  (*root)->numdesc++;
1154  (*root)->back = NULL;
1155} /* bintomulti */
1156
1157
1158void backtobinary(node **root, node *binroot, node **grbg)
1159{ /* restores binary root */
1160  node *p;
1161
1162  binroot->next->back = (*root)->next->back;
1163  (*root)->next->back->back = binroot->next;
1164  p = (*root)->next;
1165  (*root)->next = p->next;
1166  binroot->next->next->back = *root;
1167  (*root)->back = binroot->next->next;
1168  chucktreenode(grbg, p);
1169  (*root)->numdesc--;
1170  *root = binroot;
1171  (*root)->numdesc = 2;
1172} /* backtobinary */
1173
1174
1175boolean outgrin(node *root, node *outgrnode)
1176{ /* checks if outgroup node is a child of root */
1177  node *p;
1178
1179  p = root->next;
1180  while (p != root) {
1181    if (p->back == outgrnode)
1182      return true;
1183    p = p->next;
1184  }
1185  return false;
1186} /* outgrin */
1187
1188
1189void flipnodes(node *nodea, node *nodeb)
1190{ /* flip nodes */
1191  node *backa, *backb;
1192
1193  backa = nodea->back;
1194  backb = nodeb->back;
1195  backa->back = nodeb;
1196  backb->back = nodea;
1197  nodea->back = backb;
1198  nodeb->back = backa;
1199} /* flipnodes */
1200
1201
1202void moveleft(node *root, node *outgrnode, node **flipback)
1203{ /* makes outgroup node to leftmost child of root */
1204  node *p;
1205  boolean done;
1206
1207  p = root->next;
1208  done = false;
1209  while (p != root && !done) {
1210    if (p->back == outgrnode) {
1211      *flipback = p;
1212      flipnodes(root->next->back, p->back);
1213      done = true;
1214    }
1215    p = p->next;
1216  }
1217} /* moveleft */
1218
1219
1220void savetree(node *root, long *place, pointarray treenode,
1221                        node **grbg, long *zeros, unsigned char *zeros2)
1222{  /* record in place where each species has to be
1223     added to reconstruct this tree */
1224  /* used by pars */
1225  long i, j, nextnode, nvisited;
1226  node *p, *q, *r = NULL, *rute, *root2, *lastdesc, 
1227                *outgrnode, *binroot, *flipback;
1228  boolean done, newfork, newnode;
1229
1230  rute = root->next->back;
1231  binroot = NULL;
1232  lastdesc = NULL;
1233  root2 = NULL;
1234  flipback = NULL;
1235  outgrnode = treenode[outgrno - 1];
1236  if (root->numdesc == 2)
1237    bintomulti(&root, &binroot, grbg, zeros, zeros2);
1238  if (outgrin(root, outgrnode)) {
1239    if (outgrnode != root->next->back)
1240      moveleft(root, outgrnode, &flipback);
1241  } else {
1242    root2 = root;
1243    lastdesc = root->next;
1244    while (lastdesc->next != root)
1245      lastdesc = lastdesc->next;
1246    lastdesc->next = root->next;
1247    gnudisctreenode(grbg, &root, outgrnode->back->index, endsite, zeros, zeros2);
1248    root->numdesc = root2->numdesc;
1249    reroot2(outgrnode, root);
1250  }
1251  savetraverse(root);
1252  nextnode = spp + 1;
1253  for (i = nextnode; i <= nonodes; i++)
1254    if (treenode[i - 1]->numdesc == 0)
1255      flipindexes(i, treenode);
1256  for (i = 0; i < nonodes; i++)
1257    place[i] = 0;
1258  place[root->index - 1] = 1;
1259  for (i = 1; i <= spp; i++) {
1260    p = treenode[i - 1];
1261    while (place[p->index - 1] == 0) {
1262      place[p->index - 1] = i;
1263      while (!p->bottom)
1264        p = p->next;
1265      r = p;
1266      p = p->back;
1267    }
1268    if (i > 1) {
1269      q = treenode[i - 1]; 
1270      newfork = true;
1271      newnode = true;
1272      nvisited = sibsvisited(q, place);
1273      if (nvisited == 0) {
1274        if (parentinmulti(r)) {
1275          nvisited = sibsvisited(r, place);
1276          if (nvisited == 0)
1277            place[i - 1] = place[p->index - 1];
1278          else if (nvisited == 1)
1279            place[i - 1] = smallest(r, place);
1280          else {
1281            place[i - 1] = -smallest(r, place);
1282            newfork = false;
1283          }
1284        } else
1285          place[i - 1] = place[p->index - 1];
1286      } else if (nvisited == 1) {
1287        place[i - 1] = place[p->index - 1];
1288      } else {
1289        place[i - 1] = -smallest(q, place);
1290        newfork = false;
1291      }
1292      if (newfork) {
1293        j = place[p->index - 1];
1294        done = false;
1295        while (!done) {
1296          place[p->index - 1] = nextnode;
1297          while (!p->bottom)
1298            p = p->next;
1299          p = p->back;
1300          done = (p == NULL);
1301          if (!done)
1302            done = (place[p->index - 1] != j);
1303          if (done) {
1304            nextnode++;
1305          }
1306        }
1307      }
1308    }
1309  }
1310  if (flipback)
1311    flipnodes(outgrnode, flipback->back);
1312  else {
1313    if (root2) {
1314      reroot3(outgrnode, root, root2, lastdesc, grbg);
1315      root = root2;
1316    }
1317  }
1318  if (binroot)
1319    backtobinary(&root, binroot, grbg);
1320}  /* savetree */ 
1321
1322
1323void addnsave(node *p, node *item, node *nufork, node **root, node **grbg,
1324                        boolean multf, pointarray treenode, long *place, long *zeros,
1325                        unsigned char *zeros2)
1326{  /* adds item to tree and save it.  Then removes item. */
1327  node *dummy;
1328
1329  if (!multf)
1330    add(p, item, nufork, root, false, treenode, grbg, zeros, zeros2);
1331  else
1332    add(p, item, NULL, root, false, treenode, grbg, zeros, zeros2);
1333  savetree(*root, place, treenode, grbg, zeros, zeros2);
1334  if (!multf)
1335    re_move(item, &nufork, root, false, treenode, grbg, zeros, zeros2);
1336  else
1337    re_move(item, &dummy, root, false, treenode, grbg, zeros, zeros2);
1338} /* addnsave */
1339
1340
1341void addbestever(long *pos, long *nextree, long maxtrees, boolean collapse,
1342                        long *place, bestelm *bestrees)
1343{ /* adds first best tree */
1344
1345  *pos = 1;
1346  *nextree = 1;
1347  initbestrees(bestrees, maxtrees, true);
1348  initbestrees(bestrees, maxtrees, false);
1349  addtree(*pos, nextree, collapse, place, bestrees);
1350} /* addbestever */
1351
1352
1353void addtiedtree(long pos, long *nextree, long maxtrees, boolean collapse,
1354                        long *place, bestelm *bestrees)
1355{ /* add tied tree */
1356
1357  if (*nextree <= maxtrees)
1358    addtree(pos, nextree, collapse, place, bestrees);
1359} /* addtiedtree */
1360
1361
1362void clearcollapse(pointarray treenode)
1363{
1364  /* clears collapse status at a node */
1365  long i;
1366  node *p;
1367
1368  for (i = 0; i < nonodes; i++) {
1369    treenode[i]->collapse = undefined;
1370    if (!treenode[i]->tip) {
1371      p = treenode[i]->next;
1372      while (p != treenode[i]) {
1373        p->collapse = undefined;
1374        p = p->next;
1375      }
1376    }
1377  }
1378} /* clearcollapse */
1379
1380
1381void clearbottom(pointarray treenode)
1382{
1383  /* clears boolean bottom at a node */
1384  long i;
1385  node *p;
1386
1387  for (i = 0; i < nonodes; i++) {
1388    treenode[i]->bottom = false;
1389    if (!treenode[i]->tip) {
1390      p = treenode[i]->next;
1391      while (p != treenode[i]) {
1392        p->bottom = false;
1393        p = p->next;
1394      }
1395    }
1396  }
1397} /* clearbottom */
1398
1399
1400void collabranch(node *collapfrom, node *tempfrom, node *tempto)
1401{ /* collapse branch from collapfrom */
1402  long i, j, largest, descsteps;
1403  boolean done;
1404  unsigned char b;
1405
1406  for (i = 0; i < endsite; i++) {
1407    largest = getlargest(collapfrom->discnumnuc[i]);
1408    descsteps = 0;
1409    for (j = (long)zero; j <= (long)seven; j++) {
1410      b = 1 << j;
1411      if ((descsteps == 0) && (collapfrom->discbase[i] & b)) 
1412        descsteps = tempfrom->oldnumsteps[i] 
1413                     - (collapfrom->numdesc - collapfrom->discnumnuc[i][j])
1414                       * weight[i];
1415    }
1416    largest = getlargest(tempto->discnumnuc[i]);
1417    done = false;
1418    for (j = (long)zero; j <= (long)seven; j++) {
1419      b = 1 << j;
1420      if (!done && (tempto->discbase[i] & b)) {
1421        descsteps += (tempto->numsteps[i] 
1422                      - (tempto->numdesc - collapfrom->numdesc
1423                        - tempto->discnumnuc[i][j]) * weight[i]);
1424        done = true;
1425      }
1426    }
1427    for (j = (long)zero; j <= (long)seven; j++)
1428      tempto->discnumnuc[i][j] += collapfrom->discnumnuc[i][j];
1429    largest = getlargest(tempto->discnumnuc[i]);
1430    tempto->discbase[i] = 0;
1431    for (j = (long)zero; j <= (long)seven; j++) {
1432      if (tempto->discnumnuc[i][j] == largest)
1433        tempto->discbase[i] |= (1 << j);
1434    }
1435    tempto->numsteps[i] = (tempto->numdesc - largest) * weight[i] + descsteps;
1436  }
1437} /* collabranch */
1438
1439
1440boolean allcommonbases(node *a, node *b, boolean *allsame)
1441{  /* see if bases are common at all sites for nodes a and b */   
1442  long i;
1443  boolean allcommon;
1444
1445  allcommon = true;
1446  *allsame = true;
1447  for (i = 0; i < endsite; i++) {
1448    if ((a->discbase[i] & b->discbase[i]) == 0)
1449      allcommon = false;
1450    else if (a->discbase[i] != b->discbase[i])
1451      *allsame = false;
1452  }
1453  return allcommon;
1454} /* allcommonbases */
1455
1456
1457void findbottom(node *p, node **bottom)
1458{ /* find a node with field bottom set at node p */
1459  node *q;
1460
1461  if (p->bottom)
1462    *bottom = p;
1463  else {
1464    q = p->next;
1465    while(!q->bottom && q != p)
1466      q = q->next;
1467    *bottom = q;
1468  }
1469} /* findbottom */
1470
1471
1472boolean moresteps(node *a, node *b)
1473{  /* see if numsteps of node a exceeds those of node b */   
1474  long i;
1475
1476  for (i = 0; i < endsite; i++)
1477    if (a->numsteps[i] > b->numsteps[i])
1478      return true;
1479  return false;
1480} /* moresteps */
1481
1482
1483boolean passdown(node *desc, node *parent, node *start, node *below, node *item,
1484                        node *added, node *total, node *tempdsc, node *tempprt,
1485                        boolean multf)
1486{ /* track down to node start to see if an ancestor branch can be collapsed */
1487  node *temp;
1488  boolean done, allsame;
1489
1490  done = (parent == start);
1491  while (!done) {
1492    desc = parent;
1493    findbottom(parent->back, &parent);
1494    if (multf && start == below && parent == below)
1495      parent = added;
1496    memcpy(tempdsc->discbase, tempprt->discbase, endsite*sizeof(unsigned char));
1497    memcpy(tempdsc->numsteps, tempprt->numsteps, endsite*sizeof(long));
1498    memcpy(tempdsc->olddiscbase, desc->discbase, endsite*sizeof(unsigned char));
1499    memcpy(tempdsc->oldnumsteps, desc->numsteps, endsite*sizeof(long));
1500    memcpy(tempprt->discbase, parent->discbase, endsite*sizeof(unsigned char));
1501    memcpy(tempprt->numsteps, parent->numsteps, endsite*sizeof(long));
1502    memcpy(tempprt->discnumnuc, parent->discnumnuc, endsite*sizeof(discnucarray));
1503    tempprt->numdesc = parent->numdesc;
1504    multifillin(tempprt, tempdsc, 0);
1505    if (!allcommonbases(tempprt, parent, &allsame))
1506      return false;
1507    else if (moresteps(tempprt, parent))
1508      return false;
1509    else if (allsame)
1510      return true;
1511    if (parent == added)
1512      parent = below;
1513    done = (parent == start);
1514    if (done && ((start == item) || (!multf && start == below))) {
1515      memcpy(tempdsc->discbase, tempprt->discbase, endsite*sizeof(unsigned char));
1516      memcpy(tempdsc->numsteps, tempprt->numsteps, endsite*sizeof(long));
1517      memcpy(tempdsc->olddiscbase, start->discbase, endsite*sizeof(unsigned char));
1518      memcpy(tempdsc->oldnumsteps, start->numsteps, endsite*sizeof(long));
1519      multifillin(added, tempdsc, 0);
1520      tempprt = added;
1521    }
1522  } 
1523  temp = tempdsc;
1524  if (start == below || start == item)
1525    fillin(temp, tempprt, below->back);
1526  else
1527    fillin(temp, tempprt, added);
1528  return !moresteps(temp, total);
1529} /* passdown */
1530
1531
1532boolean trycollapdesc(node *desc, node *parent, node *start, node *below,
1533                        node *item, node *added, node *total, node *tempdsc, node *tempprt,
1534                        boolean multf,long *zeros, unsigned char *zeros2)
1535{ /* see if branch between nodes desc and parent can be collapsed */
1536  boolean allsame;
1537
1538  if (desc->numdesc == 1)
1539    return true;
1540  if (multf && start == below && parent == below)
1541    parent = added;
1542  memcpy(tempdsc->discbase, zeros2, endsite*sizeof(unsigned char));
1543  memcpy(tempdsc->numsteps, zeros, endsite*sizeof(long));
1544  memcpy(tempdsc->olddiscbase, desc->discbase, endsite*sizeof(unsigned char));
1545  memcpy(tempdsc->oldnumsteps, desc->numsteps, endsite*sizeof(long));
1546  memcpy(tempprt->discbase, parent->discbase, endsite*sizeof(unsigned char));
1547  memcpy(tempprt->numsteps, parent->numsteps, endsite*sizeof(long));
1548  memcpy(tempprt->discnumnuc, parent->discnumnuc, endsite*sizeof(discnucarray));
1549  tempprt->numdesc = parent->numdesc - 1;
1550  multifillin(tempprt, tempdsc, -1);
1551  tempprt->numdesc += desc->numdesc;
1552  collabranch(desc, tempdsc, tempprt);
1553  if (!allcommonbases(tempprt, parent, &allsame) || 
1554        moresteps(tempprt, parent)) {
1555    if (parent != added) {
1556      desc->collapse = nocollap;
1557      parent->collapse = nocollap;
1558    }
1559    return false;
1560  } else if (allsame) {
1561    if (parent != added) {
1562      desc->collapse = tocollap;
1563      parent->collapse = tocollap;
1564    }
1565    return true;
1566  }
1567  if (parent == added)
1568    parent = below;
1569  if ((start == item && parent == item) ||
1570        (!multf && start == below && parent == below)) {
1571    memcpy(tempdsc->discbase, tempprt->discbase, endsite*sizeof(unsigned char));
1572    memcpy(tempdsc->numsteps, tempprt->numsteps, endsite*sizeof(long));
1573    memcpy(tempdsc->olddiscbase, start->discbase, endsite*sizeof(unsigned char));
1574    memcpy(tempdsc->oldnumsteps, start->numsteps, endsite*sizeof(long));
1575    memcpy(tempprt->discbase, added->discbase, endsite*sizeof(unsigned char));
1576    memcpy(tempprt->numsteps, added->numsteps, endsite*sizeof(long));
1577    memcpy(tempprt->discnumnuc, added->discnumnuc, endsite*sizeof(discnucarray));
1578    tempprt->numdesc = added->numdesc;
1579    multifillin(tempprt, tempdsc, 0);
1580    if (!allcommonbases(tempprt, added, &allsame))
1581      return false;
1582    else if (moresteps(tempprt, added))
1583      return false;
1584    else if (allsame)
1585      return true;
1586  }
1587  return passdown(desc, parent, start, below, item, added, total, tempdsc,
1588                    tempprt, multf);
1589} /* trycollapdesc */
1590
1591
1592void setbottom(node *p)
1593{ /* set field bottom at node p */
1594  node *q;
1595
1596  p->bottom = true;
1597  q = p->next;
1598  do {
1599    q->bottom = false;
1600    q = q->next;
1601  } while (q != p);
1602} /* setbottom */
1603
1604
1605boolean zeroinsubtree(node *subtree, node *start, node *below, node *item,
1606                        node *added, node *total, node *tempdsc, node *tempprt,
1607                        boolean multf, node* root, long *zeros, 
1608                        unsigned char *zeros2)
1609{ /* sees if subtree contains a zero length branch */
1610  node *p;
1611
1612  if (!subtree->tip) {
1613    setbottom(subtree);
1614    p = subtree->next;
1615    do {
1616      if (p->back && !p->back->tip && 
1617         !((p->back->collapse == nocollap) && (subtree->collapse == nocollap))
1618           && (subtree->numdesc != 1)) {
1619        if ((p->back->collapse == tocollap) && (subtree->collapse == tocollap)
1620             && multf && (subtree != below))
1621          return true;
1622        /* when root->numdesc == 2
1623         * there is no mandatory step at the root,
1624         * instead of checking at the root we check around it
1625         * we only need to check p because the first if
1626         * statement already gets rid of it for the subtree */
1627        else if ((p->back->index != root->index || root->numdesc > 2) &&
1628            trycollapdesc(p->back, subtree, start, below, item, added, total, 
1629                tempdsc, tempprt, multf, zeros, zeros2))
1630          return true;
1631        else if ((p->back->index == root->index && root->numdesc == 2) &&
1632            !(root->next->back->tip) && !(root->next->next->back->tip) &&
1633            trycollapdesc(root->next->back, root->next->next->back, start,
1634                below, item, added, total, tempdsc, tempprt, multf, zeros,
1635                zeros2))
1636          return true;
1637      }
1638      p = p->next;
1639    } while (p != subtree);
1640    p = subtree->next;
1641    do {
1642      if (p->back && !p->back->tip) {
1643        if (zeroinsubtree(p->back, start, below, item, added, total, 
1644                            tempdsc, tempprt, multf, root, zeros, zeros2))
1645          return true;
1646      }
1647      p = p->next;
1648    } while (p != subtree);
1649  }
1650  return false;
1651} /* zeroinsubtree */
1652
1653
1654boolean collapsible(node *item, node *below, node *temp, node *temp1, 
1655                node *tempdsc, node *tempprt, node *added, node *total, 
1656                boolean multf, node *root, long *zeros, unsigned char *zeros2, 
1657                pointarray treenode)
1658{
1659  /* sees if any branch can be collapsed */
1660  node *belowbk;
1661  boolean allsame;
1662
1663  if (multf) {
1664    memcpy(tempdsc->discbase, item->discbase, endsite*sizeof(unsigned char));
1665    memcpy(tempdsc->numsteps, item->numsteps, endsite*sizeof(long));
1666    memcpy(tempdsc->olddiscbase, zeros2, endsite*sizeof(unsigned char));
1667    memcpy(tempdsc->oldnumsteps, zeros, endsite*sizeof(long));
1668    memcpy(added->discbase, below->discbase, endsite*sizeof(unsigned char));
1669    memcpy(added->numsteps, below->numsteps, endsite*sizeof(long));
1670    memcpy(added->discnumnuc, below->discnumnuc, endsite*sizeof(discnucarray));
1671    added->numdesc = below->numdesc + 1;
1672    multifillin(added, tempdsc, 1);
1673  } else {
1674    fillin(added, item, below);
1675    added->numdesc = 2;
1676  }
1677  fillin(total, added, below->back);
1678  clearbottom(treenode);
1679  if (below->back) {
1680    if (zeroinsubtree(below->back, below->back, below, item, added, total,
1681                        tempdsc, tempprt, multf, root, zeros, zeros2))
1682      return true;
1683  }
1684  if (multf) {
1685    if (zeroinsubtree(below, below, below, item, added, total,
1686                       tempdsc, tempprt, multf, root, zeros, zeros2))
1687      return true;
1688  } else if (!below->tip) {
1689    if (zeroinsubtree(below, below, below, item, added, total,
1690                        tempdsc, tempprt, multf, root, zeros, zeros2))
1691      return true;
1692  }
1693  if (!item->tip) {
1694    if (zeroinsubtree(item, item, below, item, added, total,
1695                        tempdsc, tempprt, multf, root, zeros, zeros2))
1696      return true;
1697  }
1698  if (multf && below->back && !below->back->tip) {
1699    memcpy(tempdsc->discbase, zeros2, endsite*sizeof(unsigned char));
1700    memcpy(tempdsc->numsteps, zeros, endsite*sizeof(long));
1701    memcpy(tempdsc->olddiscbase, added->discbase, endsite*sizeof(unsigned char));
1702    memcpy(tempdsc->oldnumsteps, added->numsteps, endsite*sizeof(long));
1703    if (below->back == treenode[below->back->index - 1])
1704      belowbk = below->back->next;
1705    else
1706      belowbk = treenode[below->back->index - 1];
1707    memcpy(tempprt->discbase, belowbk->discbase, endsite*sizeof(unsigned char));
1708    memcpy(tempprt->numsteps, belowbk->numsteps, endsite*sizeof(long));
1709    memcpy(tempprt->discnumnuc, belowbk->discnumnuc, endsite*sizeof(discnucarray));
1710    tempprt->numdesc = belowbk->numdesc - 1;
1711    multifillin(tempprt, tempdsc, -1);
1712    tempprt->numdesc += added->numdesc;
1713    collabranch(added, tempdsc, tempprt);
1714    if (!allcommonbases(tempprt, belowbk, &allsame))
1715      return false;
1716    else if (allsame && !moresteps(tempprt, belowbk))
1717      return true;
1718    else if (belowbk->back) {
1719      fillin(temp, tempprt, belowbk->back);
1720      fillin(temp1, belowbk, belowbk->back);
1721      return !moresteps(temp, temp1);
1722    }
1723  }
1724  return false;
1725} /* collapsible */
1726
1727
1728void replaceback(node **oldback, node *item, node *forknode, node **grbg,
1729                        long *zeros, unsigned char *zeros2)
1730{ /* replaces back node of item with another */
1731  node *p;
1732
1733  p = forknode;
1734  while (p->next->back != item)
1735    p = p->next;
1736  *oldback = p->next;
1737  gnudisctreenode(grbg, &p->next, forknode->index, endsite, zeros, zeros2);
1738  p->next->next = (*oldback)->next;
1739  p->next->back = (*oldback)->back;
1740  p->next->back->back = p->next;
1741  (*oldback)->next = (*oldback)->back = NULL;
1742} /* replaceback */
1743
1744
1745void putback(node *oldback, node *item, node *forknode, node **grbg)
1746{ /* restores node to back of item */
1747  node *p, *q;
1748
1749  p = forknode;
1750  while (p->next != item->back)
1751    p = p->next;
1752  q = p->next;
1753  oldback->next = p->next->next;
1754  p->next = oldback;
1755  oldback->back = item;
1756  item->back = oldback;
1757  oldback->index = forknode->index;
1758  chucktreenode(grbg, q);
1759} /* putback */
1760
1761
1762void savelocrearr(node *item, node *forknode, node *below, node *tmp, node *tmp1,
1763                        node *tmp2, node *tmp3, node *tmprm, node *tmpadd, node **root,
1764                        long maxtrees, long *nextree, boolean multf, boolean bestever,
1765                        boolean *saved, long *place, bestelm *bestrees, pointarray treenode,
1766                        node **grbg, long *zeros, unsigned char *zeros2)
1767{ /* saves tied or better trees during local rearrangements by removing
1768     item from forknode and adding to below */
1769  node *other, *otherback=NULL, *oldfork, *nufork, *oldback;
1770  long pos;
1771  boolean found, collapse;
1772
1773  if (forknode->numdesc == 2) {
1774    findbelow(&other, item, forknode);
1775    otherback = other->back;
1776    oldback = NULL;
1777  } else {
1778    other = NULL;
1779    replaceback(&oldback, item, forknode, grbg, zeros, zeros2);
1780  }
1781  re_move(item, &oldfork, root, false, treenode, grbg, zeros, zeros2);
1782  if (!multf)
1783    getnufork(&nufork, grbg, treenode, zeros, zeros2);
1784  else
1785    nufork = NULL;
1786  addnsave(below, item, nufork, root, grbg, multf, treenode, place,
1787             zeros, zeros2);
1788  pos = 0;
1789  findtree(&found, &pos, *nextree, place, bestrees);
1790  if (other) {
1791    add(other, item, oldfork, root, false, treenode, grbg, zeros, zeros2);
1792    if (otherback->back != other)
1793      flipnodes(item, other);
1794  } else
1795    add(forknode, item, NULL, root, false, treenode, grbg, zeros, zeros2);
1796  *saved = false;
1797  if (found) {
1798    if (oldback)
1799      putback(oldback, item, forknode, grbg);
1800  } else {
1801    if (oldback)
1802      chucktreenode(grbg, oldback);
1803    re_move(item, &oldfork, root, true, treenode, grbg, zeros, zeros2);
1804    collapse = collapsible(item, below, tmp, tmp1, tmp2, tmp3, tmprm,
1805                     tmpadd, multf, *root, zeros, zeros2, treenode);
1806    if (!collapse) {
1807      if (bestever)
1808        addbestever(&pos, nextree, maxtrees, collapse, place, bestrees);
1809      else
1810        addtiedtree(pos, nextree, maxtrees, collapse, place, bestrees);
1811    }
1812    if (other)
1813      add(other, item, oldfork, root, true, treenode, grbg, zeros, zeros2);
1814    else
1815      add(forknode, item, NULL, root, true, treenode, grbg, zeros, zeros2);
1816    *saved = !collapse;
1817  }
1818} /* savelocrearr */
1819
1820
1821void clearvisited(pointarray treenode)
1822{
1823  /* clears boolean visited at a node */
1824  long i;
1825  node *p;
1826
1827  for (i = 0; i < nonodes; i++) {
1828    treenode[i]->visited = false;
1829    if (!treenode[i]->tip) {
1830      p = treenode[i]->next;
1831      while (p != treenode[i]) {
1832        p->visited = false;
1833        p = p->next;
1834      }
1835    }
1836  }
1837} /* clearvisited */
1838
1839
1840void hyprint(long b1,long b2,struct LOC_hyptrav *htrav,pointarray treenode)
1841{
1842  /* print out states in sites b1 through b2 at node */
1843  long i, j, k;
1844  boolean dot, found;
1845
1846  if (htrav->bottom) {
1847    if (!outgropt)
1848      fprintf(outfile, "       ");
1849    else
1850      fprintf(outfile, "root   ");
1851  } else
1852    fprintf(outfile, "%4ld   ", htrav->r->back->index - spp);
1853  if (htrav->r->tip) {
1854    for (i = 0; i < nmlngth; i++)
1855      putc(nayme[htrav->r->index - 1][i], outfile);
1856  } else
1857    fprintf(outfile, "%4ld      ", htrav->r->index - spp);
1858  if (htrav->bottom)
1859    fprintf(outfile, "          ");
1860  else if (htrav->nonzero)
1861    fprintf(outfile, "   yes    ");
1862  else if (htrav->maybe)
1863    fprintf(outfile, "  maybe   ");
1864  else
1865    fprintf(outfile, "   no     ");
1866  for (i = b1; i <= b2; i++) {
1867    j = location[ally[i - 1] - 1];
1868    htrav->tempset = htrav->r->discbase[j - 1];
1869    htrav->anc = htrav->hypset[j - 1];
1870    if (!htrav->bottom)
1871      htrav->anc = treenode[htrav->r->back->index - 1]->discbase[j - 1];
1872    dot = dotdiff && (htrav->tempset == htrav->anc && !htrav->bottom);
1873    if (dot)
1874      putc('.', outfile); 
1875    else {
1876      found = false;
1877      k = (long)zero;
1878      do {
1879        if (htrav->tempset == (1 << k)) {
1880          putc(convtab[k][i - 1], outfile);
1881          found = true;
1882        }
1883        k++;
1884      } while (!found && k <= (long)seven);
1885      if (!found) 
1886        putc('?', outfile);
1887    }
1888    if (i % 10 == 0)
1889      putc(' ', outfile);
1890  }
1891  putc('\n', outfile);
1892}  /* hyprint */
1893
1894
1895void gnubase(gbases **p, gbases **garbage, long endsite)
1896{
1897  /* this and the following are do-it-yourself garbage collectors.
1898     Make a new node or pull one off the garbage list */
1899  if (*garbage != NULL) {
1900    *p = *garbage;
1901    *garbage = (*garbage)->next;
1902  } else {
1903    *p = (gbases *)Malloc(sizeof(gbases));
1904    (*p)->discbase = (discbaseptr)Malloc(endsite*sizeof(unsigned char));
1905  }
1906  (*p)->next = NULL;
1907}  /* gnubase */
1908
1909
1910void chuckbase(gbases *p, gbases **garbage)
1911{
1912  /* collect garbage on p -- put it on front of garbage list */
1913  p->next = *garbage;
1914  *garbage = p;
1915}  /* chuckbase */
1916
1917
1918void hyptrav(node *r_, discbaseptr hypset_, long b1, long b2, boolean bottom_,
1919                        pointarray treenode, gbases **garbage)
1920{
1921  /*  compute, print out states at one interior node */
1922  struct LOC_hyptrav Vars;
1923  long i, j, k;
1924  long largest;
1925  gbases *ancset;
1926  discnucarray *tempnuc;
1927  node *p, *q;
1928
1929  Vars.bottom = bottom_;
1930  Vars.r = r_;
1931  Vars.hypset = hypset_;
1932  gnubase(&ancset, garbage, endsite);
1933  tempnuc = (discnucarray *)Malloc(endsite*sizeof(discnucarray));
1934  Vars.maybe = false;
1935  Vars.nonzero = false;
1936  if (!Vars.r->tip)
1937    zerodiscnumnuc(Vars.r, endsite);
1938  for (i = b1 - 1; i < b2; i++) {
1939    j = location[ally[i] - 1];
1940    Vars.anc = Vars.hypset[j - 1];
1941    if (!Vars.r->tip) {
1942      p = Vars.r->next;
1943      for (k = (long)zero; k <= (long)seven; k++)
1944        if (Vars.anc & (1 << k))
1945          Vars.r->discnumnuc[j - 1][k]++;
1946      do {
1947        for (k = (long)zero; k <= (long)seven; k++)
1948          if (p->back->discbase[j - 1] & (1 << k))
1949            Vars.r->discnumnuc[j - 1][k]++;
1950        p = p->next;
1951      } while (p != Vars.r);
1952      largest = getlargest(Vars.r->discnumnuc[j - 1]);
1953      Vars.tempset = 0;
1954      for (k = (long)zero; k <= (long)seven; k++) {
1955        if (Vars.r->discnumnuc[j - 1][k] == largest)
1956          Vars.tempset |= (1 << k);
1957      }
1958      Vars.r->discbase[j - 1] = Vars.tempset;
1959    }
1960    if (!Vars.bottom)
1961      Vars.anc = treenode[Vars.r->back->index - 1]->discbase[j - 1];
1962    Vars.nonzero = (Vars.nonzero || (Vars.r->discbase[j - 1] & Vars.anc) == 0);
1963    Vars.maybe = (Vars.maybe || Vars.r->discbase[j - 1] != Vars.anc);
1964  }
1965  hyprint(b1, b2, &Vars, treenode);
1966  Vars.bottom = false;
1967  if (!Vars.r->tip) {
1968    memcpy(tempnuc, Vars.r->discnumnuc, endsite*sizeof(discnucarray));
1969    q = Vars.r->next;
1970    do {
1971      memcpy(Vars.r->discnumnuc, tempnuc, endsite*sizeof(discnucarray));
1972      for (i = b1 - 1; i < b2; i++) {
1973        j = location[ally[i] - 1];
1974        for (k = (long)zero; k <= (long)seven; k++)
1975          if (q->back->discbase[j - 1] & (1 << k))
1976            Vars.r->discnumnuc[j - 1][k]--;
1977        largest = getlargest(Vars.r->discnumnuc[j - 1]);
1978        ancset->discbase[j - 1] = 0;
1979        for (k = (long)zero; k <= (long)seven; k++)
1980          if (Vars.r->discnumnuc[j - 1][k] == largest)
1981            ancset->discbase[j - 1] |= (1 << k);
1982        if (!Vars.bottom)
1983          Vars.anc = ancset->discbase[j - 1];
1984      }
1985      hyptrav(q->back, ancset->discbase, b1, b2, Vars.bottom,
1986                treenode, garbage);
1987      q = q->next;
1988    } while (q != Vars.r);
1989  }
1990  chuckbase(ancset, garbage);
1991}  /* hyptrav */
1992
1993
1994void hypstates(long chars, node *root, pointarray treenode, gbases **garbage)
1995{
1996  /* fill in and describe states at interior nodes */
1997  /* used in pars */
1998  long i, n;
1999  discbaseptr nothing;
2000
2001  fprintf(outfile, "\nFrom    To     Any Steps?    State at upper node\n");
2002  fprintf(outfile, "                            ");
2003  if (dotdiff)
2004    fprintf(outfile, " ( . means same as in the node below it on tree)\n");
2005  nothing = (discbaseptr)Malloc(endsite*sizeof(unsigned char));
2006  for (i = 0; i < endsite; i++)
2007    nothing[i] = 0;
2008  for (i = 1; i <= ((chars - 1) / 40 + 1); i++) {
2009    putc('\n', outfile);
2010    n = i * 40;
2011    if (n > chars)
2012      n = chars;
2013    hyptrav(root, nothing, i * 40 - 39, n, true, treenode, garbage);
2014  }
2015  free(nothing);
2016}  /* hypstates */
2017
2018
2019void initbranchlen(node *p)
2020{
2021  node *q;
2022
2023  p->v = 0.0;
2024  if (p->back)
2025    p->back->v = 0.0;
2026  if (p->tip)
2027    return;
2028  q = p->next;
2029  while (q != p) {
2030    initbranchlen(q->back);
2031    q = q->next;
2032  }
2033  q = p->next;
2034  while (q != p) {
2035    q->v = 0.0;
2036    q = q->next;
2037  }
2038} /* initbranchlen */
2039
2040
2041void initmin(node *p, long sitei, boolean internal)
2042{
2043  long i;
2044
2045  if (internal) {
2046    for (i = (long)zero; i <= (long)seven; i++) {
2047      p->disccumlengths[i] = 0;
2048      p->discnumreconst[i] = 1;
2049    }
2050  } else {
2051    for (i = (long)zero; i <= (long)seven; i++) {
2052      if (p->discbase[sitei - 1] & (1 << i)) {
2053        p->disccumlengths[i] = 0;
2054        p->discnumreconst[i] = 1;
2055      } else {
2056        p->disccumlengths[i] = -1;
2057        p->discnumreconst[i] = 0;
2058      }
2059    }
2060  }
2061} /* initmin */
2062
2063
2064void initbase(node *p, long sitei)
2065{
2066  /* traverse tree to initialize base at internal nodes */
2067  node *q;
2068  long i, largest;
2069
2070  if (p->tip)
2071    return;
2072  q = p->next;
2073  while (q != p) {
2074    if (q->back) {
2075      memcpy(q->discnumnuc, p->discnumnuc, endsite*sizeof(discnucarray));
2076      for (i = (long)zero; i <= (long)seven; i++) {
2077        if (q->back->discbase[sitei - 1] & (1 << i))
2078          q->discnumnuc[sitei - 1][i]--;
2079      }
2080      if (p->back) {
2081        for (i = (long)zero; i <= (long)seven; i++) {
2082          if (p->back->discbase[sitei - 1] & (1 << i))
2083            q->discnumnuc[sitei - 1][i]++;
2084        }
2085      }
2086      largest = getlargest(q->discnumnuc[sitei - 1]);
2087      q->discbase[sitei - 1] = 0;
2088      for (i = (long)zero; i <= (long)seven; i++) {
2089        if (q->discnumnuc[sitei - 1][i] == largest)
2090          q->discbase[sitei - 1] |= (1 << i);
2091      }
2092    }
2093    q = q->next;
2094  }
2095  q = p->next;
2096  while (q != p) {
2097    initbase(q->back, sitei);
2098    q = q->next;
2099  }
2100} /* initbase */
2101
2102
2103void inittreetrav(node *p, long sitei)
2104{
2105  /* traverse tree to clear boolean initialized and set up base */
2106  node *q;
2107
2108  if (p->tip) {
2109    initmin(p, sitei, false);
2110    p->initialized = true;
2111    return;
2112  }
2113  q = p->next;
2114  while (q != p) {
2115    inittreetrav(q->back, sitei);
2116    q = q->next;
2117  }
2118  initmin(p, sitei, true);
2119  p->initialized = false;
2120  q = p->next;
2121  while (q != p) {
2122    initmin(q, sitei, true);
2123    q->initialized = false;
2124    q = q->next;
2125  }
2126} /* inittreetrav */
2127
2128
2129void compmin(node *p, node *desc)
2130{
2131  /* computes minimum lengths up to p */
2132  long i, j, minn, cost, desclen, descrecon=0, maxx;
2133
2134  maxx = 10 * spp;
2135  for (i = (long)zero; i <= (long)seven; i++) {
2136    minn = maxx;
2137    for (j = (long)zero; j <= (long)seven; j++) {
2138      if (i == j) 
2139        cost = 0;
2140      else
2141        cost = 1;
2142      if (desc->disccumlengths[j] == -1) {
2143        desclen = maxx;
2144      } else {
2145        desclen = desc->disccumlengths[j];
2146      }
2147      if (minn > cost + desclen) {
2148        minn = cost + desclen;
2149        descrecon = 0;
2150      }
2151      if (minn == cost + desclen) {
2152        descrecon += desc->discnumreconst[j];
2153      }
2154    }
2155    p->disccumlengths[i] += minn;
2156    p->discnumreconst[i] *= descrecon;
2157  }
2158  p->initialized = true;
2159} /* compmin */
2160
2161
2162void minpostorder(node *p, pointarray treenode)
2163{
2164  /* traverses an n-ary tree, computing minimum steps at each node */
2165  node *q;
2166
2167  if (p->tip) {
2168    return;
2169  }
2170  q = p->next;
2171  while (q != p) {
2172    if (q->back)
2173      minpostorder(q->back, treenode);
2174    q = q->next;
2175  }
2176  if (!p->initialized) {
2177    q = p->next;
2178    while (q != p) {
2179      if (q->back)
2180        compmin(p, q->back);
2181      q = q->next;
2182    }
2183  }
2184}  /* minpostorder */
2185
2186
2187void branchlength(node *subtr1, node *subtr2, double *brlen, 
2188                               pointarray treenode)
2189{
2190  /* computes a branch length between two subtrees for a given site */
2191  long i, j, minn, cost, nom, denom;
2192  node *temp;
2193
2194  if (subtr1->tip) {
2195    temp = subtr1;
2196    subtr1 = subtr2;
2197    subtr2 = temp;
2198  }
2199  if (subtr1->index == outgrno) {
2200    temp = subtr1;
2201    subtr1 = subtr2;
2202    subtr2 = temp;
2203  }
2204  minpostorder(subtr1, treenode);
2205  minpostorder(subtr2, treenode);
2206  minn = 10 * spp;
2207  nom = 0;
2208  denom = 0;
2209  for (i = (long)zero; i <= (long)seven; i++) {
2210    for (j = (long)zero; j <= (long)seven; j++) {
2211      if (i == j)
2212        cost = 0;
2213      else
2214        cost = 1;
2215      if (subtr1->disccumlengths[i] != -1 && (subtr2->disccumlengths[j] != -1)) {
2216        if (subtr1->disccumlengths[i] + cost + subtr2->disccumlengths[j] < minn) {
2217          minn = subtr1->disccumlengths[i] + cost + subtr2->disccumlengths[j];
2218          nom = 0;
2219          denom = 0;
2220        }
2221        if (subtr1->disccumlengths[i] + cost + subtr2->disccumlengths[j] == minn) {
2222          nom += subtr1->discnumreconst[i] * subtr2->discnumreconst[j] * cost;
2223          denom += subtr1->discnumreconst[i] * subtr2->discnumreconst[j];
2224        }
2225      }
2226    }
2227  }
2228  *brlen = (double)nom/(double)denom;
2229} /* branchlength */ 
2230
2231
2232void printbranchlengths(node *p)
2233{
2234  node *q;
2235  long i;
2236
2237  if (p->tip)
2238    return;
2239  q = p->next;
2240  do {
2241    fprintf(outfile, "%6ld      ",q->index - spp);
2242    if (q->back->tip) {
2243      for (i = 0; i < nmlngth; i++)
2244        putc(nayme[q->back->index - 1][i], outfile);
2245    } else
2246      fprintf(outfile, "%6ld    ", q->back->index - spp);
2247    fprintf(outfile, "     %.2f\n",q->v);
2248    if (q->back)
2249      printbranchlengths(q->back);
2250    q = q->next;
2251  } while (q != p);
2252} /* printbranchlengths */
2253
2254
2255void branchlentrav(node *p, node *root, long sitei, long chars,
2256                        double *brlen, pointarray treenode)
2257  {
2258  /*  traverses the tree computing tree length at each branch */
2259  node *q;
2260
2261  if (p->tip)
2262    return;
2263  if (p->index == outgrno)
2264    p = p->back;
2265  q = p->next;
2266  do {
2267    if (q->back) {
2268      branchlength(q, q->back, brlen, treenode);
2269      q->v += ((weight[sitei - 1] / 10.0) * (*brlen));
2270      q->back->v += ((weight[sitei - 1] / 10.0) * (*brlen));
2271      if (!q->back->tip)
2272        branchlentrav(q->back, root, sitei, chars, brlen, treenode);
2273    }
2274    q = q->next;
2275  } while (q != p);
2276}  /* branchlentrav */
2277
2278
2279void treelength(node *root, long chars, pointarray treenode)
2280  {
2281  /*  calls branchlentrav at each site */
2282  long sitei;
2283  double trlen;
2284
2285  initbranchlen(root);
2286  for (sitei = 1; sitei <= endsite; sitei++) {
2287    trlen = 0.0;
2288    initbase(root, sitei);
2289    inittreetrav(root, sitei);
2290    branchlentrav(root, root, sitei, chars, &trlen, treenode);
2291  }
2292} /* treelength */
2293
2294
2295void coordinates(node *p, long *tipy, double f, long *fartemp)
2296{
2297  /* establishes coordinates of nodes for display without lengths */
2298  node *q, *first, *last, *mid1 = NULL, *mid2 = NULL;
2299  long numbranches, numb2;
2300
2301  if (p->tip) {
2302    p->xcoord = 0;
2303    p->ycoord = *tipy;
2304    p->ymin = *tipy;
2305    p->ymax = *tipy;
2306    (*tipy) += down;
2307    return;
2308  }
2309  numbranches = 0;
2310  q = p->next;
2311  do {
2312    coordinates(q->back, tipy, f, fartemp);
2313    numbranches += 1;
2314    q = q->next;
2315  } while (p != q);
2316  first = p->next->back;
2317  q = p->next;
2318  while (q->next != p) 
2319    q = q->next;
2320  last = q->back;
2321  numb2 = 1;
2322  q = p->next;
2323  while (q != p) {
2324    if (numb2 == (numbranches + 1)/2)
2325      mid1 = q->back;
2326    if (numb2 == (numbranches/2 + 1))
2327      mid2 = q->back;
2328    numb2 += 1;
2329    q = q->next;
2330  }
2331  p->xcoord = (long)((double)(last->ymax - first->ymin) * f);
2332  p->ycoord = (long)((mid1->ycoord + mid2->ycoord) / 2);
2333  p->ymin = first->ymin;
2334  p->ymax = last->ymax;
2335  if (p->xcoord > *fartemp)
2336    *fartemp = p->xcoord;
2337}  /* coordinates */
2338
2339
2340void drawline(long i, double scale, node *root)
2341{
2342  /* draws one row of the tree diagram by moving up tree */
2343  node *p, *q, *r, *first = NULL, *last = NULL;
2344  long n, j;
2345  boolean extra, done, noplus;
2346
2347  p = root;
2348  q = root;
2349  extra = false;
2350  noplus = false;
2351  if (i == (long)p->ycoord && p == root) {
2352    if (p->index - spp >= 10)
2353      fprintf(outfile, " %2ld", p->index - spp);
2354    else
2355      fprintf(outfile, "  %ld", p->index - spp);
2356    extra = true;
2357    noplus = true;
2358  } else
2359    fprintf(outfile, "  ");
2360  do {
2361    if (!p->tip) {
2362      r = p->next;
2363      done = false;
2364      do {
2365        if (i >= r->back->ymin && i <= r->back->ymax) {
2366          q = r->back;
2367          done = true;
2368        }
2369        r = r->next;
2370      } while (!(done || r == p));
2371      first = p->next->back;
2372      r = p->next;
2373      while (r->next != p)
2374        r = r->next;
2375      last = r->back;
2376    }
2377    done = (p == q);
2378    n = (long)(scale * (p->xcoord - q->xcoord) + 0.5);
2379    if (n < 3 && !q->tip)
2380      n = 3;
2381    if (extra) {
2382      n--;
2383      extra = false;
2384    }
2385    if ((long)q->ycoord == i && !done) {
2386      if (noplus) {
2387        putc('-', outfile);
2388        noplus = false;
2389      }
2390      else
2391        putc('+', outfile);
2392      if (!q->tip) {
2393        for (j = 1; j <= n - 2; j++)
2394          putc('-', outfile);
2395        if (q->index - spp >= 10)
2396          fprintf(outfile, "%2ld", q->index - spp);
2397        else
2398          fprintf(outfile, "-%ld", q->index - spp);
2399        extra = true;
2400        noplus = true;
2401      } else {
2402        for (j = 1; j < n; j++)
2403          putc('-', outfile);
2404      }
2405    } else if (!p->tip) {
2406      if ((long)last->ycoord > i && (long)first->ycoord < i
2407            && i != (long)p->ycoord) {
2408        putc('!', outfile);
2409        for (j = 1; j < n; j++)
2410          putc(' ', outfile);
2411      } else {
2412        for (j = 1; j <= n; j++)
2413          putc(' ', outfile);
2414      }
2415      noplus = false;
2416    } else {
2417      for (j = 1; j <= n; j++)
2418        putc(' ', outfile);
2419      noplus = false;
2420    }
2421    if (p != q)
2422      p = q;
2423  } while (!done);
2424  if ((long)p->ycoord == i && p->tip) {
2425    for (j = 0; j < nmlngth; j++)
2426      putc(nayme[p->index - 1][j], outfile);
2427  }
2428  putc('\n', outfile);
2429}  /* drawline */
2430
2431
2432void printree(node *root, double f)
2433{
2434  /* prints out diagram of the tree */
2435  /* used in pars */
2436  long i, tipy, dummy;
2437  double scale;
2438
2439  putc('\n', outfile);
2440  if (!treeprint)
2441    return;
2442  putc('\n', outfile);
2443  tipy = 1;
2444  dummy = 0;
2445  coordinates(root, &tipy, f, &dummy);
2446  scale = 1.5;
2447  putc('\n', outfile);
2448  for (i = 1; i <= (tipy - down); i++)
2449    drawline(i, scale, root);
2450  fprintf(outfile, "\n  remember:");
2451  if (outgropt)
2452    fprintf(outfile, " (although rooted by outgroup)");
2453  fprintf(outfile, " this is an unrooted tree!\n\n");
2454}  /* printree */
2455
2456
2457void writesteps(long chars, boolean weights, steptr oldweight, node *root)
2458{
2459  /* used in pars */
2460  long i, j, k, l;
2461
2462  putc('\n', outfile);
2463  if (weights)
2464    fprintf(outfile, "weighted ");
2465  fprintf(outfile, "steps in each site:\n");
2466  fprintf(outfile, "      ");
2467  for (i = 0; i <= 9; i++)
2468    fprintf(outfile, "%4ld", i);
2469  fprintf(outfile, "\n     *------------------------------------");
2470  fprintf(outfile, "-----\n");
2471  for (i = 0; i <= (chars / 10); i++) {
2472    fprintf(outfile, "%5ld", i * 10);
2473    putc('|', outfile);
2474    for (j = 0; j <= 9; j++) {
2475      k = i * 10 + j;
2476      if (k == 0 || k > chars)
2477        fprintf(outfile, "    ");
2478      else {
2479        l = location[ally[k - 1] - 1];
2480        if (oldweight[k - 1] > 0)
2481          fprintf(outfile, "%4ld",
2482                  oldweight[k - 1] *
2483                  (root->numsteps[l - 1] / weight[l - 1]));
2484        else
2485          fprintf(outfile, "   0");
2486      }
2487    }
2488    putc('\n', outfile);
2489  }
2490} /* writesteps */
2491
2492
2493void treeout(node *p, long nextree, long *col, node *root)
2494{
2495  /* write out file with representation of final tree */
2496  /* used in pars */
2497  node *q;
2498  long i, n;
2499  Char c;
2500
2501  if (p->tip) {
2502    n = 0;
2503    for (i = 1; i <= nmlngth; i++) {
2504      if (nayme[p->index - 1][i - 1] != ' ')
2505        n = i;
2506    }
2507    for (i = 0; i < n; i++) {
2508      c = nayme[p->index - 1][i];
2509      if (c == ' ')
2510        c = '_';
2511      putc(c, outtree);
2512    }
2513    *col += n;
2514  } else {
2515    putc('(', outtree);
2516    (*col)++;
2517    q = p->next;
2518    while (q != p) {
2519      treeout(q->back, nextree, col, root);
2520      q = q->next;
2521      if (q == p)
2522        break;
2523      putc(',', outtree);
2524      (*col)++;
2525      if (*col > 60) {
2526        putc('\n', outtree);
2527        *col = 0;
2528      }
2529    }
2530    putc(')', outtree);
2531    (*col)++;
2532  }
2533  if (p != root)
2534    return;
2535  if (nextree > 2)
2536    fprintf(outtree, "[%6.4f];\n", 1.0 / (nextree - 1));
2537  else
2538    fprintf(outtree, ";\n");
2539}  /* treeout */
2540
2541
2542void treeout3(node *p, long nextree, long *col, node *root)
2543{
2544  /* write out file with representation of final tree */
2545  /* used in dnapars -- writes branch lengths */
2546  node *q;
2547  long i, n, w;
2548  double x;
2549  Char c;
2550
2551  if (p->tip) {
2552    n = 0;
2553    for (i = 1; i <= nmlngth; i++) {
2554      if (nayme[p->index - 1][i - 1] != ' ')
2555        n = i;
2556    }
2557    for (i = 0; i < n; i++) {
2558      c = nayme[p->index - 1][i];
2559      if (c == ' ')
2560        c = '_';
2561      putc(c, outtree);
2562    }
2563    *col += n;
2564  } else {
2565    putc('(', outtree);
2566    (*col)++;
2567    q = p->next;
2568    while (q != p) {
2569      treeout3(q->back, nextree, col, root);
2570      q = q->next;
2571      if (q == p)
2572        break;
2573      putc(',', outtree);
2574      (*col)++;
2575      if (*col > 60) {
2576        putc('\n', outtree);
2577        *col = 0;
2578      }
2579    }
2580    putc(')', outtree);
2581    (*col)++;
2582  }
2583  x = p->v;
2584  if (x > 0.0)
2585    w = (long)(0.43429448222 * log(x));
2586  else if (x == 0.0)
2587    w = 0;
2588  else
2589    w = (long)(0.43429448222 * log(-x)) + 1;
2590  if (w < 0)
2591    w = 0;
2592  if (p != root) {
2593    fprintf(outtree, ":%*.2f", (int)(w + 4), x);
2594    col += w + 8;
2595  }
2596  if (p != root)
2597    return;
2598  if (nextree > 2)
2599    fprintf(outtree, "[%6.4f];\n", 1.0 / (nextree - 1));
2600  else
2601    fprintf(outtree, ";\n");
2602}  /* treeout3 */
2603
2604
2605void drawline3(long i, double scale, node *start)
2606{
2607  /* draws one row of the tree diagram by moving up tree */
2608  /* used in pars */
2609  node *p, *q;
2610  long n, j;
2611  boolean extra;
2612  node *r, *first = NULL, *last = NULL;
2613  boolean done;
2614
2615  p = start;
2616  q = start;
2617  extra = false;
2618  if (i == (long)p->ycoord) {
2619    if (p->index - spp >= 10)
2620      fprintf(outfile, " %2ld", p->index - spp);
2621    else
2622      fprintf(outfile, "  %ld", p->index - spp);
2623    extra = true;
2624  } else
2625    fprintf(outfile, "  ");
2626  do {
2627    if (!p->tip) {
2628      r = p->next;
2629      done = false;
2630      do {
2631        if (i >= r->back->ymin && i <= r->back->ymax) {
2632          q = r->back;
2633          done = true;
2634        }
2635        r = r->next;
2636      } while (!(done || (r == p))); 
2637      first = p->next->back;
2638      r = p;
2639      while (r->next != p)
2640        r = r->next;
2641      last = r->back;
2642    }
2643    done = (p->tip || p == q);
2644    n = (long)(scale * (q->xcoord - p->xcoord) + 0.5);
2645    if (n < 3 && !q->tip)
2646      n = 3;
2647    if (extra) {
2648      n--;
2649      extra = false;
2650    }
2651    if ((long)q->ycoord == i && !done) {
2652      if ((long)p->ycoord != (long)q->ycoord)
2653        putc('+', outfile);
2654      else
2655        putc('-', outfile);
2656      if (!q->tip) {
2657        for (j = 1; j <= n - 2; j++)
2658          putc('-', outfile);
2659        if (q->index - spp >= 10)
2660          fprintf(outfile, "%2ld", q->index - spp);
2661        else
2662          fprintf(outfile, "-%ld", q->index - spp);
2663        extra = true;
2664      } else {
2665        for (j = 1; j < n; j++)
2666          putc('-', outfile);
2667      }
2668    } else if (!p->tip) {
2669      if ((long)last->ycoord > i && (long)first->ycoord < i &&
2670          (i != (long)p->ycoord || p == start)) {
2671        putc('|', outfile);
2672        for (j = 1; j < n; j++)
2673          putc(' ', outfile);
2674      } else {
2675        for (j = 1; j <= n; j++)
2676          putc(' ', outfile);
2677      }
2678    } else {
2679      for (j = 1; j <= n; j++)
2680        putc(' ', outfile);
2681    }
2682    if (q != p)
2683      p = q;
2684  } while (!done);
2685  if ((long)p->ycoord == i && p->tip) {
2686    for (j = 0; j < nmlngth; j++)
2687      putc(nayme[p->index-1][j], outfile);
2688  }
2689  putc('\n', outfile);
2690}  /* drawline3 */
2691
2692
2693void standev(long chars, long numtrees, long minwhich, double minsteps,
2694                        double *nsteps, long **fsteps, longer seed)
2695{  /* compute and write standard deviation of user trees */
2696   /* used in pars */
2697  long i, j, k;
2698  double wt, sumw, sum, sum2, sd;
2699  double temp;
2700  double **covar, *P, *f;
2701
2702#define SAMPLES 1000
2703#define MAXSHIMOTREES 1000
2704/* ????? if numtrees too big for Shimo, truncate */
2705  if (numtrees == 2) {
2706    fprintf(outfile, "Kishino-Hasegawa-Templeton test\n\n");
2707    fprintf(outfile, "Tree    Steps   Diff Steps   Its S.D.");
2708    fprintf(outfile, "   Significantly worse?\n\n");
2709    which = 1;
2710    while (which <= numtrees) {
2711      fprintf(outfile, "%3ld%10.1f", which, nsteps[which - 1] / 10);
2712      if (minwhich == which)
2713        fprintf(outfile, "  <------ best\n");
2714      else {
2715        sumw = 0.0;
2716        sum = 0.0;
2717        sum2 = 0.0;
2718        for (i = 0; i < chars; i++) {
2719          if (weight[i] > 0) {
2720            wt = weight[i] / 10.0;
2721            sumw += wt;
2722            temp = (fsteps[which - 1][i] - fsteps[minwhich - 1][i]) / 10.0;
2723            sum += temp;
2724            sum2 += temp * temp / wt;
2725          }
2726        }
2727        temp = sum / sumw;
2728        sd = sqrt(sumw / (sumw - 1.0) * (sum2 - temp * temp));
2729        fprintf(outfile, "%10.1f%12.4f",
2730                (nsteps[which - 1] - minsteps) / 10, sd);
2731        if (sum > 1.95996 * sd)
2732          fprintf(outfile, "           Yes\n");
2733        else
2734          fprintf(outfile, "           No\n");
2735      }
2736      which++;
2737    }
2738    fprintf(outfile, "\n\n");
2739  } else {           /* Shimodaira-Hasegawa test using normal approximation */
2740    fprintf(outfile, "Shimodaira-Hasegawa test\n\n");
2741    covar = (double **)Malloc(numtrees*sizeof(double *)); 
2742    for (i = 0; i < numtrees; i++)
2743      covar[i] = (double *)Malloc(numtrees*sizeof(double)); 
2744    sumw = 0.0;
2745    for (i = 0; i < chars; i++)
2746      sumw += weight[i];
2747    for (i = 0; i < numtrees; i++) {        /* compute covariances of trees */
2748      sum = nsteps[i]/(10.0*sumw);
2749      for (j = 0; j <=i; j++) {
2750        sum2 = nsteps[j]/(10.0*sumw);
2751        temp = 0.0;
2752        for (k = 0; k < chars; k++) {
2753          wt = weight[k]/10.0;
2754          if (weight[k] > 0) {
2755            temp = temp + wt*(fsteps[i][k]/(10.0*wt)-sum)
2756                            *(fsteps[j][k]/(10.0*wt)-sum2);
2757          }
2758        }
2759        covar[i][j] = temp;
2760        if (i != j)
2761          covar[j][i] = temp;
2762      }
2763    }
2764    for (i = 0; i < numtrees; i++) { /* in-place Cholesky decomposition
2765                                        of trees x trees covariance matrix */
2766      sum = 0.0;
2767      for (j = 0; j <= i-1; j++)
2768        sum = sum + covar[i][j] * covar[i][j];
2769      if (covar[i][i]-sum <= 0.0)
2770        temp = 0.0;
2771      else
2772        temp = sqrt(covar[i][i] - sum);
2773      covar[i][i] = temp;
2774      for (j = i+1; j < numtrees; j++) {
2775        sum = 0.0;
2776        for (k = 0; k < i; k++)
2777          sum = sum + covar[i][k] * covar[j][k];
2778        if (fabs(temp) < 1.0E-23)
2779          covar[j][i] = 0.0;
2780        else
2781          covar[j][i] = (covar[j][i] - sum)/temp;
2782      }
2783    }
2784    f = (double *)Malloc(numtrees*sizeof(double)); /* vector of P's of trees */
2785    P = (double *)Malloc(numtrees*sizeof(double)); /* vector of P's of trees */
2786    for (i = 0; i < numtrees; i++)
2787      P[i] = 0.0;
2788    sum2 = nsteps[0]/10.0;               /* sum2 will be smallest # of steps */
2789    for (i = 1; i < numtrees; i++)
2790      if (sum2 > nsteps[i]/10.0)
2791        sum2 = nsteps[i]/10.0;
2792    for (i = 1; i < SAMPLES; i++) {           /* loop over resampled trees */
2793      for (j = 0; j < numtrees; j++) {        /* draw vectors */
2794        sum = 0.0;
2795        for (k = 0; k <= j; k++)
2796          sum += normrand(seed)*covar[j][k];
2797        f[j] = sum;
2798      }
2799      sum = f[1];
2800      for (j = 1; j < numtrees; j++)          /* get min of vector */
2801        if (f[j] < sum)
2802          sum = f[j];
2803      for (j = 0; j < numtrees; j++)          /* accumulate P's */
2804        if (nsteps[j]/10.0-sum2 < f[j] - sum)
2805          P[j] += 1.0/SAMPLES;
2806    }
2807    fprintf(outfile, "Tree    Steps   Diff Steps   P value");
2808    fprintf(outfile, "   Significantly worse?\n\n");
2809    for (i = 0; i < numtrees; i++) {
2810      fprintf(outfile, "%3ld%10.1f", i+1, nsteps[i]/10);
2811      if ((minwhich-1) == i)
2812        fprintf(outfile, "  <------ best\n");
2813      else {
2814        fprintf(outfile, "  %9.1f %10.3f", nsteps[i]/10.0-sum2, P[i]);
2815        if (P[i] < 0.05)
2816          fprintf(outfile, "           Yes\n");
2817        else
2818          fprintf(outfile, "           No\n");
2819      }
2820    }
2821  fprintf(outfile, "\n");
2822  free(P);             /* free the variables we Malloc'ed */
2823  free(f);
2824  for (i = 0; i < numtrees; i++)
2825    free(covar[i]);
2826  free(covar);
2827  }
2828}  /* standev */
2829
2830
2831void freetip(node *anode)
2832{
2833  /* used in pars */
2834
2835  free(anode->numsteps);
2836  free(anode->oldnumsteps);
2837  free(anode->discbase);
2838  free(anode->olddiscbase);
2839}  /* freetip */
2840
2841
2842void freenontip(node *anode)
2843{
2844  /* used in pars */
2845  free(anode->numsteps);
2846  free(anode->oldnumsteps);
2847  free(anode->discbase);
2848  free(anode->olddiscbase);
2849  free(anode->discnumnuc);
2850}  /* freenontip */
2851
2852
2853void freenodes(long nonodes, pointarray treenode)
2854{
2855  /* used in pars */
2856  long i;
2857  node *p;
2858
2859  for (i = 0; i < spp; i++)
2860    freetip(treenode[i]);
2861  for (i = spp; i < nonodes; i++) {
2862    if (treenode[i] != NULL) {
2863      p = treenode[i]->next;
2864      do {
2865        freenontip(p);
2866        p = p->next;
2867      } while (p != treenode[i]);
2868      freenontip(p);
2869    }
2870  }
2871}  /* freenodes */
2872
2873
2874void freenode(node **anode)
2875{
2876  /* used in pars */
2877
2878  freenontip(*anode);
2879  free(*anode);
2880}  /* freenode */
2881
2882
2883void freetree(long nonodes, pointarray treenode)
2884{
2885  /* used in pars */
2886  long i;
2887  node *p, *q;
2888
2889  for (i = 0; i < spp; i++)
2890    free(treenode[i]);
2891  for (i = spp; i < nonodes; i++) {
2892    if (treenode[i] != NULL) {
2893      p = treenode[i]->next;
2894      do {
2895        q = p->next;
2896        free(p);
2897        p = q;
2898      } while (p != treenode[i]);
2899      free(p);
2900    }
2901  }
2902  free(treenode);
2903}  /* freetree */
2904
2905
2906void freegarbage(gbases **garbage)
2907{
2908  /* used in pars */
2909  gbases *p;
2910
2911  while (*garbage) {
2912    p = *garbage;
2913    *garbage = (*garbage)->next;
2914    free(p->discbase);
2915    free(p);
2916  }
2917}  /* freegarbage */
2918
2919
2920void freegrbg(node **grbg)
2921{
2922  /* used in pars */
2923  node *p;
2924
2925  while (*grbg) {
2926    p = *grbg;
2927    *grbg = (*grbg)->next;
2928    freenontip(p);
2929    free(p);
2930  }
2931} /*freegrbg */
Note: See TracBrowser for help on using the repository browser.