4 /* version 3.6. (c) Copyright 1993-2004 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. */
9 void alloctree(pointptr *treenode, long nonodes)
11 /* allocate treenode dynamically */
12 /* used in fitch, kitsch & neighbor */
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++) {
21 for (j = 1; j <= 3; j++) {
22 p = (node *)Malloc(sizeof(node));
26 p->next->next->next = p;
32 void freetree(pointptr *treenode, long nonodes)
37 for (i = 0; i < spp; i++)
39 for (i = spp; i < nonodes; i++) {
41 for (j = 1; j <= 3; j++) {
51 void allocd(long nonodes, pointptr treenode)
53 /* used in fitch & kitsch */
57 for (i = 0; i < (spp); i++) {
58 treenode[i]->d = (vector)Malloc(nonodes*sizeof(double));
60 for (i = spp; i < nonodes; i++) {
62 for (j = 1; j <= 3; j++) {
63 p->d = (vector)Malloc(nonodes*sizeof(double));
70 void freed(long nonodes, pointptr treenode)
76 for (i = 0; i < (spp); i++) {
79 for (i = spp; i < nonodes; i++) {
81 for (j = 1; j <= 3; j++) {
89 void allocw(long nonodes, pointptr treenode)
91 /* used in fitch & kitsch */
95 for (i = 0; i < (spp); i++) {
96 treenode[i]->w = (vector)Malloc(nonodes*sizeof(double));
98 for (i = spp; i < nonodes; i++) {
100 for (j = 1; j <= 3; j++) {
101 p->w = (vector)Malloc(nonodes*sizeof(double));
108 void freew(long nonodes, pointptr treenode)
114 for (i = 0; i < (spp); i++) {
115 free(treenode[i]->w);
117 for (i = spp; i < nonodes; i++) {
119 for (j = 1; j <= 3; j++) {
127 void setuptree(tree *a, long nonodes)
129 /* initialize a tree */
130 /* used in fitch, kitsch, & neighbor */
134 for (i = 1; i <= nonodes; i++) {
135 a->nodep[i - 1]->back = NULL;
136 a->nodep[i - 1]->tip = (i <= spp);
137 a->nodep[i - 1]->iter = true;
138 a->nodep[i - 1]->index = i;
139 a->nodep[i - 1]->t = 0.0;
140 a->nodep[i - 1]->sametime = false;
141 a->nodep[i - 1]->v = 0.0;
143 p = a->nodep[i-1]->next;
144 while (p != a->nodep[i-1]) {
155 a->likelihood = -1.0;
156 a->start = a->nodep[0];
161 void inputdata(boolean replicates, boolean printdata, boolean lower,
162 boolean upper, vector *x, intvector *reps)
164 /* read in distance matrix */
165 /* used in fitch & neighbor */
166 long i=0, j=0, k=0, columns=0;
167 boolean skipit=false, skipother=false;
174 fprintf(outfile, "\nName Distances");
176 fprintf(outfile, " (replicates)");
177 fprintf(outfile, "\n---- ---------");
179 fprintf(outfile, "-------------");
180 fprintf(outfile, "\n\n");
182 for (i = 0; i < spp; i++) {
186 for (j = 0; j < spp; j++) {
187 skipit = ((lower && j + 1 >= i + 1) || (upper && j + 1 <= i + 1));
188 skipother = ((lower && i + 1 >= j + 1) || (upper && i + 1 <= j + 1));
192 if (fscanf(infile, "%lf", &x[i][j]) != 1) {
193 printf("The infile is of the wrong type\n");
199 fscanf(infile, "%ld", &reps[i][j]);
203 if (!skipit && skipother) {
205 reps[j][i] = reps[i][j];
207 if ((i == j) && (fabs(x[i][j]) > 0.000000001)) {
208 printf("\nERROR: diagonal element of row %ld of distance matrix ", i+1);
209 printf("is not zero.\n");
210 printf(" Is it a distance matrix?\n\n");
213 if ((j < i) && (fabs(x[i][j]-x[j][i]) > 0.000000001)) {
214 printf("ERROR: distance matrix is not symmetric:\n");
215 printf(" (%ld,%ld) element and (%ld,%ld) element are unequal.\n",
217 printf(" They are %10.6f and %10.6f, respectively.\n",
219 printf(" Is it a distance matrix?\n\n");
227 for (i = 0; i < spp; i++) {
228 for (j = 0; j < nmlngth; j++)
229 putc(nayme[i][j], outfile);
231 for (j = 1; j <= spp; j++) {
232 fprintf(outfile, "%10.5f", x[i][j - 1]);
234 fprintf(outfile, " (%3ld)", reps[i][j - 1]);
235 if (j % columns == 0 && j < spp) {
237 for (k = 1; k <= nmlngth + 1; k++)
247 void coordinates(node *p, double lengthsum, long *tipy, double *tipmax,
248 node *start, boolean njoin)
250 /* establishes coordinates of nodes */
251 node *q, *first, *last;
254 p->xcoord = (long)(over * lengthsum + 0.5);
259 if (lengthsum > *tipmax)
266 coordinates(q->back, lengthsum + q->v, tipy,tipmax, start, njoin);
268 } while ((p == start || p != q) && (p != start || p->next != q));
269 first = p->next->back;
271 while (q->next != p && q->next->back) /* is this right ? */
274 p->xcoord = (long)(over * lengthsum + 0.5);
275 if (p == start && p->back)
276 p->ycoord = p->next->next->back->ycoord;
278 p->ycoord = (first->ycoord + last->ycoord) / 2;
279 p->ymin = first->ymin;
280 p->ymax = last->ymax;
284 void drawline(long i, double scale, node *start, boolean rooted)
286 /* draws one row of the tree diagram by moving up tree */
289 boolean extra=false, trif=false;
290 node *r, *first =NULL, *last =NULL;
297 if (i == (long)p->ycoord && p == start) { /* display the root */
299 if (p->index - spp >= 10)
300 fprintf(outfile, "-");
302 fprintf(outfile, "--");
305 if (p->index - spp >= 10)
306 fprintf(outfile, " ");
308 fprintf(outfile, " ");
310 if (p->index - spp >= 10)
311 fprintf(outfile, "%2ld", p->index - spp);
313 fprintf(outfile, "%ld", p->index - spp);
317 fprintf(outfile, " ");
319 if (!p->tip) { /* internal nodes */
321 /* r->back here is going to the same node. */
327 if (i >= r->back->ymin && i <= r->back->ymax) {
332 } while (!((p != start && r == p) || (p == start && r == p->next)));
333 first = p->next->back;
338 if (!rooted && (p == start))
340 } /* end internal node case... */
342 done = (p->tip || p == q);
343 n = (long)(scale * (q->xcoord - p->xcoord) + 0.5);
345 if ((n < 3) && (q->index - spp >= 10))
347 if ((n < 2) && (q->index - spp < 10))
354 if ((long)q->ycoord == i && !done) {
355 if (p->ycoord != q->ycoord)
362 for (j = 1; j <= n - 2; j++)
364 if (q->index - spp >= 10)
365 fprintf(outfile, "%2ld", q->index - spp);
367 fprintf(outfile, "-%ld", q->index - spp);
370 for (j = 1; j < n; j++)
373 } else if (!p->tip) {
374 if ((long)last->ycoord > i && (long)first->ycoord < i
375 && i != (long)p->ycoord) {
377 for (j = 1; j < n; j++)
380 for (j = 1; j <= n; j++)
388 if ((long)p->ycoord == i && p->tip) {
389 for (j = 0; j < nmlngth; j++)
390 putc(nayme[p->index - 1][j], outfile);
396 void printree(node *start, boolean treeprint,
397 boolean njoin, boolean rooted)
399 /* prints out diagram of the tree */
400 /* used in fitch & neighbor */
410 coordinates(start, 0.0, &tipy, &tipmax, start, njoin);
411 scale = 1.0 / (long)(tipmax + 1.000);
412 for (i = 1; i <= (tipy - down); i++)
413 drawline(i, scale, start, rooted);
418 void treeoutr(node *p, long *col, tree *curtree)
420 /* write out file with representation of final tree.
421 * Rooted case. Used in kitsch and neighbor. */
428 for (i = 1; i <= nmlngth; i++) {
429 if (nayme[p->index - 1][i - 1] != ' ')
432 for (i = 0; i < n; i++) {
433 c = nayme[p->index - 1][i];
442 treeoutr(p->next->back,col,curtree);
449 treeoutr(p->next->next->back,col,curtree);
455 w = (long)(0.43429448222 * log(x));
459 w = (long)(0.43429448222 * log(-x)) + 1;
462 if (p == curtree->root)
463 fprintf(outtree, ";\n");
465 fprintf(outtree, ":%*.5f", (int)(w + 7), x);
471 void treeout(node *p, long *col, double m, boolean njoin, node *start)
473 /* write out file with representation of final tree */
474 /* used in fitch & neighbor */
481 for (i = 1; i <= nmlngth; i++) {
482 if (nayme[p->index - 1][i - 1] != ' ')
485 for (i = 0; i < n; i++) {
486 c = nayme[p->index - 1][i];
495 treeout(p->next->back, col, m, njoin, start);
502 treeout(p->next->next->back, col, m, njoin, start);
503 if (p == start && njoin) {
505 treeout(p->back, col, m, njoin, start);
512 w = (long)(m * log(x));
516 w = (long)(m * log(-x)) + 1;
520 fprintf(outtree, ";\n");
522 fprintf(outtree, ":%*.5f", (int) w + 7, x);