source: trunk/GDE/PHYLIP/dist.c

Last change on this file was 2175, checked in by westram, 21 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: 10.8 KB
Line 
1#include "phylip.h"
2#include "dist.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
9void alloctree(pointptr *treenode, long nonodes)
10{
11  /* allocate treenode dynamically */
12  /* used in fitch, kitsch & neighbor */
13  long i, j;
14  node *p, *q;
15
16  *treenode = (pointptr)Malloc(nonodes*sizeof(node *));
17  for (i = 0; i < spp; i++)
18    (*treenode)[i] = (node *)Malloc(sizeof(node));
19  for (i = spp; i < nonodes; i++) {
20    q = NULL;
21    for (j = 1; j <= 3; j++) {
22      p = (node *)Malloc(sizeof(node));
23      p->next = q;
24      q = p;
25    }
26    p->next->next->next = p;
27    (*treenode)[i] = p;
28  }
29} /* alloctree */
30
31
32void allocd(long nonodes, pointptr treenode)
33{
34  /* used in fitch & kitsch */
35  long i, j;
36  node *p;
37
38  for (i = 0; i < (spp); i++) {
39    treenode[i]->d = (vector)Malloc(nonodes*sizeof(double));
40  }
41  for (i = spp; i < nonodes; i++) {
42    p = treenode[i];
43    for (j = 1; j <= 3; j++) {
44      p->d = (vector)Malloc(nonodes*sizeof(double));
45      p = p->next;
46    }
47  }
48}
49
50
51void allocw(long nonodes, pointptr treenode)
52{
53  /* used in fitch & kitsch */
54  long i, j;
55  node *p;
56
57  for (i = 0; i < (spp); i++) {
58      treenode[i]->w = (vector)Malloc(nonodes*sizeof(double));
59  }
60  for (i = spp; i < nonodes; i++) {
61    p = treenode[i];
62    for (j = 1; j <= 3; j++) {
63      p->w = (vector)Malloc(nonodes*sizeof(double));
64      p = p->next;
65    }
66  }
67}
68
69
70void setuptree(tree *a, long nonodes)
71{
72  /* initialize a tree */
73  /* used in fitch, kitsch, & neighbor */
74  long i=0;
75  node *p;
76
77  for (i = 1; i <= nonodes; i++) {
78    a->nodep[i - 1]->back = NULL;
79    a->nodep[i - 1]->tip = (i <= spp);
80    a->nodep[i - 1]->iter = true;
81    a->nodep[i - 1]->index = i;
82    a->nodep[i - 1]->t = 0.0;
83    a->nodep[i - 1]->sametime = false;
84    a->nodep[i - 1]->v = 0.0;
85    if (i > spp) {
86      p = a->nodep[i-1]->next;
87      while (p != a->nodep[i-1]) {
88        p->back = NULL;
89        p->tip = false;
90        p->iter = true;
91        p->index = i;
92        p->t = 0.0;
93        p->sametime = false;
94        p = p->next;
95      }
96    }
97  }
98  a->likelihood = -1.0;
99  a->start = a->nodep[0];
100  a->root = NULL;
101}  /* setuptree */
102
103
104void inputdata(boolean replicates, boolean printdata, boolean lower,
105                        boolean upper, vector *x, intvector *reps)
106{
107  /* read in distance matrix */
108  /* used in fitch & neighbor */
109  long i=0, j=0, k=0, columns=0;
110  boolean skipit=false, skipother=false;
111
112  if (replicates)
113    columns = 4;
114  else
115    columns = 6;
116  if (printdata) {
117    fprintf(outfile, "\nName                       Distances");
118    if (replicates)
119      fprintf(outfile, " (replicates)");
120    fprintf(outfile, "\n----                       ---------");
121    if (replicates)
122      fprintf(outfile, "-------------");
123    fprintf(outfile, "\n\n");
124  }
125  for (i = 0; i < spp; i++) {
126    x[i][i] = 0.0;
127    scan_eoln(infile);
128    initname(i);
129    for (j = 0; j < spp; j++) {
130      skipit = ((lower && j + 1 >= i + 1) || (upper && j + 1 <= i + 1));
131      skipother = ((lower && i + 1 >= j + 1) || (upper && i + 1 <= j + 1));
132      if (!skipit) {
133        if (eoln(infile))
134          scan_eoln(infile);
135        fscanf(infile, "%lf", &x[i][j]);
136        if (replicates) {
137          if (eoln(infile))
138            scan_eoln(infile);
139          fscanf(infile, "%ld", &reps[i][j]);
140        } else
141          reps[i][j] = 1;
142      }
143      if (!skipit && skipother) {
144          x[j][i] = x[i][j];
145          reps[j][i] = reps[i][j];
146      }
147    }
148  }
149  scan_eoln(infile);
150  if (!printdata)
151    return;
152  for (i = 0; i < spp; i++) {
153    for (j = 0; j < nmlngth; j++)
154      putc(nayme[i][j], outfile);
155    putc(' ', outfile);
156    for (j = 1; j <= spp; j++) {
157      fprintf(outfile, "%10.5f", x[i][j - 1]);
158      if (replicates)
159        fprintf(outfile, " (%3ld)", reps[i][j - 1]);
160      if (j % columns == 0 && j < spp) {
161        putc('\n', outfile);
162        for (k = 1; k <= nmlngth + 1; k++)
163          putc(' ', outfile);
164      }
165    }
166    putc('\n', outfile);
167  }
168  putc('\n', outfile);
169}  /* inputdata */
170
171
172void coordinates(node *p, double lengthsum, long *tipy, double *tipmax,
173                        node *start, boolean njoin)
174{
175  /* establishes coordinates of nodes */
176  node *q, *first, *last;
177
178  if (p->tip) {
179    p->xcoord = (long)(over * lengthsum + 0.5);
180    p->ycoord = *tipy;
181    p->ymin = *tipy;
182    p->ymax = *tipy;
183    (*tipy) += down;
184    if (lengthsum > *tipmax)
185      *tipmax = lengthsum;
186    return;
187  }
188  q = p->next;
189   do {
190     if (q->back)
191       coordinates(q->back, lengthsum + q->v, tipy,tipmax, start, njoin);
192    q = q->next;
193  } while ((p == start || p != q) && (p != start || p->next != q));
194  first = p->next->back;
195  q = p;
196  while (q->next != p && q->next->back)  /* is this right ? */
197    q = q->next;
198  last = q->back;
199  p->xcoord = (long)(over * lengthsum + 0.5);
200  if (p == start) {
201    if (njoin)
202      p->ycoord = p->next->next->back->ycoord;
203    else
204      p->ycoord = (p->next->back->ycoord + p->next->next->back->ycoord) / 2;
205  } else
206    p->ycoord = (first->ycoord + last->ycoord) / 2;
207  p->ymin = first->ymin;
208  p->ymax = last->ymax;
209}  /* coordinates */
210
211
212void drawline(long i, double scale, node *start, boolean rooted)
213{
214  /* draws one row of the tree diagram by moving up tree */
215  node *p, *q;
216  long n=0, j=0;
217  boolean extra=false, trif=false;
218  node *r, *first =NULL, *last =NULL;
219  boolean done=false;
220
221  p = start;
222  q = start;
223  extra = false;
224  trif = false;
225  if (i == (long)p->ycoord && p == start) {  /* display the root */
226    if (rooted) {
227      if (p->index - spp >= 10)
228        fprintf(outfile, "-");
229      else
230        fprintf(outfile, "--");
231    }
232    else {
233      if (p->index - spp >= 10)
234        fprintf(outfile, " ");
235      else
236        fprintf(outfile, "  ");
237    }
238    if (p->index - spp >= 10)
239      fprintf(outfile, "%2ld", p->index - spp);
240    else
241      fprintf(outfile, "%ld", p->index - spp);
242    extra = true;
243    trif = true;
244  } else
245    fprintf(outfile, "  ");
246  do {
247    if (!p->tip) { /* internal nodes */
248      r = p->next;
249      done = false; /* r->back here is going to the same node. */
250      do {
251        if (!r->back) {
252          r = r->next;
253          continue;
254        }
255        if (i >= r->back->ymin && i <= r->back->ymax) {
256          q = r->back;
257          break;
258        }
259        r = r->next;
260      } while (!((p != start && r == p) || (p == start && r == p->next)));
261      first = p->next->back;
262      r = p;
263      while (r->next != p) 
264        r = r->next;
265      last = r->back;
266      if (!rooted && (p == start))
267        last = p->back;
268    } /* end internal node case... */
269    /* draw the line: */
270    done = (p->tip || p == q);
271    n = (long)(scale * (q->xcoord - p->xcoord) + 0.5);
272    if (!q->tip) {
273      if ((n < 3) && (q->index - spp >= 10))
274        n = 3;
275      if ((n < 2) && (q->index - spp < 10))
276        n = 2;
277    }
278    if (extra) {
279      n--;
280      extra = false;
281    }
282    if ((long)q->ycoord == i && !done) {
283      if (p->ycoord != q->ycoord)
284        putc('+', outfile);
285      if (trif) {
286        n++;
287        trif = false;
288      } 
289      if (!q->tip) {
290        for (j = 1; j <= n - 2; j++)
291          putc('-', outfile);
292        if (q->index - spp >= 10)
293          fprintf(outfile, "%2ld", q->index - spp);
294        else
295          fprintf(outfile, "-%ld", q->index - spp);
296        extra = true;
297      } else {
298        for (j = 1; j < n; j++)
299          putc('-', outfile);
300      }
301    } else if (!p->tip) {
302      if ((long)last->ycoord > i && (long)first->ycoord < i
303           && i != (long)p->ycoord) {
304        putc('!', outfile);
305        for (j = 1; j < n; j++)
306          putc(' ', outfile);
307      } else {
308        for (j = 1; j <= n; j++)
309          putc(' ', outfile);
310        trif = false;
311      }
312    }
313    if (q != p)
314      p = q;
315  } while (!done);
316  if ((long)p->ycoord == i && p->tip) {
317    for (j = 0; j < nmlngth; j++)
318      putc(nayme[p->index - 1][j], outfile);
319  }
320  putc('\n', outfile);
321}  /* drawline */
322
323
324void printree(node *start, boolean treeprint,
325                        boolean        njoin, boolean rooted)
326{
327  /* prints out diagram of the tree */
328  /* used in fitch & neighbor */
329  long i;
330  long tipy;
331  double scale,tipmax;
332
333  if (!treeprint)
334    return;
335  putc('\n', outfile);
336  tipy = 1;
337  tipmax = 0.0;
338  coordinates(start, 0.0, &tipy, &tipmax, start, njoin);
339  scale = 1.0 / (long)(tipmax + 1.000);
340  for (i = 1; i <= (tipy - down); i++)
341    drawline(i, scale, start, rooted);
342  putc('\n', outfile);
343}  /* printree */
344
345
346void treeoutr(node *p, long *col, tree *curtree)
347{
348  /* write out file with representation of final tree.
349   * Rooted case. Used in kitsch and neighbor. */
350  long i, n, w;
351  Char c;
352  double x;
353
354  if (p->tip) {
355    n = 0;
356    for (i = 1; i <= nmlngth; i++) {
357      if (nayme[p->index - 1][i - 1] != ' ')
358        n = i;
359    }
360    for (i = 0; i < n; i++) {
361      c = nayme[p->index - 1][i];
362      if (c == ' ')
363        c = '_';
364      putc(c, outtree);
365    }
366    (*col) += n;
367  } else {
368    putc('(', outtree);
369    (*col)++;
370    treeoutr(p->next->back,col,curtree);
371    putc(',', outtree);
372    (*col)++;
373    if ((*col) > 55) {
374      putc('\n', outtree);
375      (*col) = 0;
376    }
377    treeoutr(p->next->next->back,col,curtree);
378    putc(')', outtree);
379    (*col)++;
380  }
381  x = p->v;
382  if (x > 0.0)
383    w = (long)(0.43429448222 * log(x));
384  else if (x == 0.0)
385    w = 0;
386  else
387    w = (long)(0.43429448222 * log(-x)) + 1;
388  if (w < 0)
389    w = 0;
390  if (p == curtree->root)
391    fprintf(outtree, ";\n");
392  else {
393    fprintf(outtree, ":%*.5f", (int)(w + 7), x);
394    (*col) += w + 8;
395  }
396}  /* treeoutr */
397
398
399void treeout(node *p, long *col, double m, boolean njoin, node *start)
400{
401  /* write out file with representation of final tree */
402  /* used in fitch & neighbor */
403  long i=0, n=0, w=0;
404  Char c;
405  double x=0.0;
406
407  if (p->tip) {
408    n = 0;
409    for (i = 1; i <= nmlngth; i++) {
410      if (nayme[p->index - 1][i - 1] != ' ')
411        n = i;
412    }
413    for (i = 0; i < n; i++) {
414      c = nayme[p->index - 1][i];
415      if (c == ' ')
416        c = '_';
417      putc(c, outtree);
418    }
419    *col += n;
420  } else {
421    putc('(', outtree);
422    (*col)++;
423    treeout(p->next->back, col, m, njoin, start);
424    putc(',', outtree);
425    (*col)++;
426    if (*col > 55) {
427      putc('\n', outtree);
428      *col = 0;
429    }
430    treeout(p->next->next->back, col, m, njoin, start);
431    if (p == start && njoin) {
432      putc(',', outtree);
433      treeout(p->back, col, m, njoin, start);
434    }
435    putc(')', outtree);
436    (*col)++;
437  }
438  x = p->v;
439  if (x > 0.0)
440    w = (long)(m * log(x));
441  else if (x == 0.0)
442    w = 0;
443  else
444    w = (long)(m * log(-x)) + 1;
445  if (w < 0)
446    w = 0;
447  if (p == start)
448    fprintf(outtree, ";\n");
449  else {
450    fprintf(outtree, ":%*.5f", (int) w + 7, x);
451    *col += w + 8;
452  }
453}  /* treeout */
454
Note: See TracBrowser for help on using the repository browser.