source: trunk/GDE/PHYLIP/contrast.c

Last change on this file was 19480, checked in by westram, 15 months ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 26.7 KB
Line 
1
2/* version 3.6. (c) Copyright 1993-2002 by the University of Washington.
3   Written by Joseph Felsenstein, Akiko Fuseki, Sean Lamont, and Andrew Keeffe.
4   Permission is granted to copy and use this program provided no fee is
5   charged for it and provided that this copyright notice is not removed. */
6
7#include "phylip.h"
8#include "cont.h"
9
10
11
12#ifndef OLDC
13/* function prototypes */
14void   getoptions(void);
15void   getdata(void);
16void   allocrest(void);
17void   doinit(void);
18void   contwithin(void);
19void   contbetween(node *, node *);
20void   nuview(node *);
21void   makecontrasts(node *);
22void   writecontrasts(void);
23
24void   regressions(void);
25double logdet(double **);
26void   invert(double **);
27void   initcovars(boolean);
28double normdiff(boolean);
29void   matcopy(double **, double **);
30void   newcovars(boolean);
31void   printcovariances(boolean);
32void   emiterate(boolean);
33void   initcontrastnode(node **, node **, node *, long, long, long *,
34             long *, initops, pointarray, pointarray, Char *, Char *, FILE *);
35
36void   maketree(void);
37/* function prototypes */
38#endif
39
40
41Char infilename[FNMLNGTH], outfilename[FNMLNGTH], intreename[FNMLNGTH];
42long nonodes, chars, numtrees;
43long *sample, contnum;
44phenotype3 **x, **cntrast, *ssqcont;
45double **vara, **vare, **oldvara, **oldvare,
46       **Bax, **Bex, **temp1, **temp2, **temp3;
47double logL, logLvara, logLnovara;
48boolean nophylo, printdata, progress, reg, mulsets,
49  varywithin, writecont, bifurcating;
50long contno;
51node *grbg;
52
53/* Local variables for maketree, propagated globally for c version: */
54tree curtree;
55
56/* Variables declared just to make treeread happy */
57boolean haslengths, goteof, first;
58double trweight;
59
60
61void getoptions()
62{
63  /* interactively set options */
64  long loopcount, loopcount2;
65  Char ch;
66  boolean done, done1;
67
68  mulsets = false;
69  nophylo = true;
70  printdata = false;
71  progress = true;
72  varywithin = false;
73  writecont = false;
74  loopcount = 0;
75  do {
76    cleerhome();
77    printf("\nContinuous character comparative analysis, version %s\n\n",
78             VERSION);
79    printf("Settings for this run:\n");
80    printf("  W        within-population variation in data?");
81    if (varywithin)
82      printf("  Yes, multiple individuals\n");
83    else {
84      printf("  No, species values are means\n");
85      printf("  R     Print out correlations and regressions?  %s\n",
86             (reg ? "Yes" : "No"));
87    }
88    printf("  A      LRT test of no phylogenetic component?");
89    if (nophylo)
90      printf("  Yes, with and without VarA\n");
91    else
92      printf("  No, just assume it is there\n");
93    if (!varywithin)
94      printf("  C                        Print out contrasts?  %s\n",
95               (writecont? "Yes" : "No"));
96    printf("  M                     Analyze multiple trees?");
97    if (mulsets)
98      printf("  Yes, %2ld trees\n", numtrees);
99    else
100      printf("  No\n");
101    printf("  0         Terminal type (IBM PC, ANSI, none)?  %s\n",
102           ibmpc ? "IBM PC"  :
103           ansi  ? "ANSI"    : "(none)");
104    printf("  1          Print out the data at start of run  %s\n",
105           (printdata ? "Yes" : "No"));
106    printf("  2        Print indications of progress of run  %s\n",
107           (progress ? "Yes" : "No"));
108    printf("\n  Y to accept these or type the letter for one to change\n");
109#ifdef WIN32
110    phyFillScreenColor();
111#endif
112    scanf("%c%*[^\n]", &ch);
113    getchar();
114    if (ch == '\n')
115      ch = ' ';
116    uppercase(&ch);
117    done = (ch == 'Y');
118    if (!done) {
119      if (strchr("RAMWC120", ch) != NULL) {
120        switch (ch) {
121
122        case 'R':
123          reg = !reg;
124          break;
125
126        case 'A':
127          nophylo = !nophylo;
128          break;
129
130        case 'M':
131          mulsets = !mulsets;
132          if (mulsets) {
133            loopcount2 = 0;
134            do {
135              printf("How many trees?\n");
136#ifdef WIN32
137              phyFillScreenColor();
138#endif
139              scanf("%ld%*[^\n]", &numtrees);
140              getchar();
141              done1 = (numtrees >= 1);
142              if (!done1)
143                printf("BAD TREES NUMBER:  it must be greater than 1\n");
144              countup(&loopcount2, 10);
145            } while (done1 != true);
146          }
147          break;
148
149        case 'C':
150          writecont = !writecont;
151          break;
152
153        case 'W':
154          varywithin = !varywithin;
155          break;
156
157        case '0':
158          initterminal(&ibmpc, &ansi);
159          break;
160
161        case '1':
162          printdata = !printdata;
163          break;
164
165        case '2':
166          progress = !progress;
167          break;
168        }
169      } else
170        printf("Not a possible option!\n");
171    }
172    countup(&loopcount, 100);
173  } while (!done);
174}  /* getoptions */
175
176
177void getdata()
178{
179  /* read species data */
180  long i, j, k, l;
181
182  if (printdata) {
183    fprintf(outfile,
184       "\nContinuous character contrasts analysis, version %s\n\n",VERSION);
185    fprintf(outfile, "%4ld Populations, %4ld Characters\n\n", spp, chars);
186    fprintf(outfile, "Name");
187    fprintf(outfile, "                       Phenotypes\n");
188    fprintf(outfile, "----");
189    fprintf(outfile, "                       ----------\n\n");
190  }
191  x = (phenotype3 **)Malloc((long)spp*sizeof(phenotype3 *));
192  cntrast = (phenotype3 **)Malloc((long)spp*sizeof(phenotype3 *));
193  ssqcont = (phenotype3 *)Malloc((long)spp*sizeof(phenotype3 *));
194  contnum = spp-1;
195  for (i = 0; i < spp; i++) {
196    scan_eoln(infile);
197    initname(i);
198    if (varywithin) {
199      fscanf(infile, "%ld", &sample[i]);
200      contnum += sample[i]-1;
201      scan_eoln(infile);
202    }
203    else sample[i] = 1;
204    if (printdata)
205      for(j = 0; j < nmlngth; j++)
206        putc(nayme[i][j], outfile);
207    x[i] = (phenotype3 *)Malloc((long)sample[i]*sizeof(phenotype3));
208    cntrast[i] = (phenotype3 *)Malloc((long)(sample[i]*sizeof(phenotype3)));
209    ssqcont[i] = (double *)Malloc((long)(sample[i]*sizeof(double)));
210    for (k = 0; k <= sample[i]-1; k++) {
211      x[i][k] = (phenotype3)Malloc((long)chars*sizeof(double));
212      cntrast[i][k] = (phenotype3)Malloc((long)chars*sizeof(double));
213      for (j = 1; j <= chars; j++) {
214        if (eoln(infile)) 
215          scan_eoln(infile);
216        fscanf(infile, "%lf", &x[i][k][j - 1]);
217        if (printdata) {
218          fprintf(outfile, "%10.5f", x[i][k][j - 1]);
219          if (j % 6 == 0) {
220            putc('\n', outfile);
221            for (l = 1; l <= nmlngth; l++)
222              putc(' ', outfile);
223          }
224        }
225      }
226    }
227    if (printdata)
228      putc('\n', outfile);
229  }
230  scan_eoln(infile);
231  if (printdata)
232    putc('\n', outfile);
233}  /* getdata */
234
235
236void allocrest()
237{
238  long i;
239
240  /* otherwise if individual variation, these are allocated in getdata  */
241  sample = (long *)Malloc((long)spp*sizeof(long));
242  nayme = (naym *)Malloc((long)spp*sizeof(naym));
243  vara = (double **)Malloc((long)chars*sizeof(double *));
244  oldvara = (double **)Malloc((long)chars*sizeof(double *));
245  vare = (double **)Malloc((long)chars*sizeof(double *));
246  oldvare = (double **)Malloc((long)chars*sizeof(double *));
247  Bax = (double **)Malloc((long)chars*sizeof(double *));
248  Bex = (double **)Malloc((long)chars*sizeof(double *));
249  temp1 = (double **)Malloc((long)chars*sizeof(double *));
250  temp2 = (double **)Malloc((long)chars*sizeof(double *));
251  temp3 = (double **)Malloc((long)chars*sizeof(double *));
252  for (i = 0; i < chars; i++) {
253     vara[i] = (double *)Malloc((long)chars*sizeof(double));
254     oldvara[i] = (double *)Malloc((long)chars*sizeof(double));
255     vare[i] = (double *)Malloc((long)chars*sizeof(double));
256     oldvare[i] = (double *)Malloc((long)chars*sizeof(double));
257     Bax[i] = (double *)Malloc((long)chars*sizeof(double));
258     Bex[i] = (double *)Malloc((long)chars*sizeof(double));
259     temp1[i] = (double *)Malloc((long)chars*sizeof(double));
260     temp2[i] = (double *)Malloc((long)chars*sizeof(double));
261     temp3[i] = (double *)Malloc((long)chars*sizeof(double));
262  }
263}  /* allocrest */
264
265
266void doinit()
267{
268  /* initializes variables */
269
270  inputnumbers(&spp, &chars, &nonodes, 1);
271  getoptions();
272  allocrest();
273}  /* doinit */
274
275
276void contwithin()
277{
278  /* compute the within-species contrasts, if any */
279  long i, j, k;
280  double *sumphen;
281
282  sumphen = (double *)Malloc((long)chars*sizeof(double));
283  for (i = 0; i <= spp-1 ; i++) {
284    for (j = 0; j < chars; j++)
285      sumphen[j] = 0.0;
286    for (k = 0; k <= (sample[i]-1); k++) {
287      for (j = 0; j < chars; j++) {
288        if (k > 0)
289          cntrast[i][k][j]
290              = (sumphen[j] - k*x[i][k][j])/sqrt((double)(k*(k+1)));
291        sumphen[j] += x[i][k][j];
292        if (k == (sample[i]-1))
293          curtree.nodep[i]->view[j] = sumphen[j]/sample[i];
294        x[i][0][j] = sumphen[j]/sample[i];
295      }
296      if (k == 0)
297        curtree.nodep[i]->ssq = 1.0/sample[i]; /* sum of squares for sp. i */
298      else
299        ssqcont[i][k] = 1.0;   /* if a within contrast */
300    }
301  }
302  contno = 1;
303}  /* contwithin */
304
305
306void contbetween(node *p, node *q)
307{
308  /* compute one contrast */
309  long i;
310  double v1, v2;
311
312  for (i = 0; i < chars; i++)
313    cntrast[contno - 1][0][i] = (p->view[i] - q->view[i])/sqrt(p->ssq+q->ssq);
314  v1 = q->v + q->deltav;
315  if (p->back != q)
316    v2 = p->v + p->deltav;
317  else v2 = p->deltav;
318  ssqcont[contno - 1][0] = (v1 + v2)/(p->ssq + q->ssq);
319     /* this is really the variance of the contrast */
320  contno++;
321}  /* contbetween */
322
323
324void nuview(node *p)
325{
326  /* renew information about subtrees */
327  long j;
328  node *q, *r;
329  double v1, v2, vtot, f1, f2;
330
331  q = p->next->back;
332  r = p->next->next->back;
333  v1 = q->v + q->deltav;
334  v2 = r->v + r->deltav;
335  vtot = v1 + v2;
336  if (vtot > 0.0)
337    f1 = v2 / vtot;
338  else
339    f1 = 0.5;
340  f2 = 1.0 - f1;
341  for (j = 0; j < chars; j++)
342    p->view[j] = f1 * q->view[j] + f2 * r->view[j];
343  p->deltav = v1 * f1;
344  p->ssq = f1*f1*q->ssq + f2*f2*r->ssq;
345}  /* nuview */
346
347
348void makecontrasts(node *p)
349{
350  /* compute the contrasts, recursively */
351  if (p->tip)
352    return;
353  makecontrasts(p->next->back);
354  makecontrasts(p->next->next->back);
355  nuview(p);
356  contbetween(p->next->back, p->next->next->back);
357}  /* makecontrasts */
358
359
360void writecontrasts()
361{
362  /* write out the contrasts */
363  long i, j;
364
365  if (printdata || reg) {
366    fprintf(outfile, "\nContrasts (columns are different characters)\n");
367    fprintf(outfile, "--------- -------- --- --------- -----------\n\n");
368  }
369  for (i = 0; i <= contno - 2; i++) {
370    for (j = 0; j < chars; j++)
371      fprintf(outfile, "%10.5f", cntrast[i][0][j]);
372    putc('\n', outfile);
373  }
374}  /* writecontrasts */
375
376
377void regressions()
378{
379  /* compute regressions and correlations among contrasts */
380  long i, j, k;
381  double **sumprod;
382
383  sumprod = (double **)Malloc((long)chars*sizeof(double *));
384  for (i = 0; i < chars; i++) {
385    sumprod[i] = (double *)Malloc((long)chars*sizeof(double));
386    for (j = 0; j < chars; j++)
387      sumprod[i][j] = 0.0;
388  }
389    for (i = 0; i <= contno - 2; i++) {
390    for (j = 0; j < chars; j++) {
391      for (k = 0; k < chars; k++)
392        sumprod[j][k] += cntrast[i][0][j] * cntrast[i][0][k];
393    }
394  }
395  fprintf(outfile, "\nCovariance matrix\n");
396  fprintf(outfile, "---------- ------\n\n");
397  for (i = 0; i < chars; i++) {
398    for (j = 0; j < chars; j++)
399      sumprod[i][j] /= contno - 1;
400  }
401  for (i = 0; i < chars; i++) {
402    for (j = 0; j < chars; j++)
403      fprintf(outfile, "%10.4f", sumprod[i][j]);
404    putc('\n', outfile);
405  }
406  fprintf(outfile, "\nRegressions (columns on rows)\n");
407  fprintf(outfile, "----------- -------- -- -----\n\n");
408  for (i = 0; i < chars; i++) {
409    for (j = 0; j < chars; j++)
410      fprintf(outfile, "%10.4f", sumprod[i][j] / sumprod[i][i]);
411    putc('\n', outfile);
412  }
413  fprintf(outfile, "\nCorrelations\n");
414  fprintf(outfile, "------------\n\n");
415  for (i = 0; i < chars; i++) {
416    for (j = 0; j < chars; j++)
417      fprintf(outfile, "%10.4f",
418              sumprod[i][j] / sqrt(sumprod[i][i] * sumprod[j][j]));
419    putc('\n', outfile);
420  }
421  for (i = 0; i < chars; i++)
422    free(sumprod[i]);
423  free(sumprod);
424}  /* regressions */
425
426
427double logdet(double **a)
428{
429  /* Gauss-Jordan log determinant calculation.
430     in place, overwriting previous contents of a.  On exit,
431      matrix a contains the inverse. Works only for positive definite A */
432  long i, j, k;
433  double temp, sum;
434
435  sum = 0.0;
436  for (i = 0; i < chars; i++) {
437    if (a[i][i] == 0.0) {  /* debug make fabs() < 1.0E-37 instead? */
438       printf("ERROR: tried to invert singular matrix.\n");
439       exxit(-1);
440    }
441    sum += log(a[i][i]);
442    temp = 1.0 / a[i][i];
443    a[i][i] = 1.0;
444    for (j = 0; j < chars; j++)
445      a[i][j] *= temp;
446    for (j = 0; j < chars; j++) {
447      if (j != i) {
448        temp = a[j][i];
449        a[j][i] = 0.0;
450        for (k = 0; k < chars; k++)
451          a[j][k] -= temp * a[i][k];
452      }
453    }
454  }
455  return(sum);
456}  /* lodget */
457
458
459void invert(double **a)
460{
461  /* Gauss-Jordan reduction -- invert chars x chars matrix a
462     in place, overwriting previous contents of a.  On exit,
463      matrix a contains the inverse.*/
464  long i, j, k;
465  double temp;
466
467  for (i = 0; i < chars; i++) {
468    if (a[i][i] == 0.0) {  /* debug make fabs() < 1.0E-37 instead? */
469       printf("ERROR: tried to invert singular matrix.\n");
470       exxit(-1);
471    }
472    temp = 1.0 / a[i][i];
473    a[i][i] = 1.0;
474    for (j = 0; j < chars; j++)
475      a[i][j] *= temp;
476    for (j = 0; j < chars; j++) {
477      if (j != i) {
478        temp = a[j][i];
479        a[j][i] = 0.0;
480        for (k = 0; k < chars; k++)
481          a[j][k] -= temp * a[i][k];
482      }
483    }
484  }
485}  /*invert*/
486
487
488void initcovars(boolean novara)
489{
490/* Initialize covariance estimates */
491   long i, j, k, l, contswithin;
492
493   /* zero the matrices */
494   for (i = 0; i < chars; i++)
495     for (j = 0; j < chars; j++) {
496       vara[i][j] = 0.0;
497       vare[i][j] = 0.0;
498   }
499   /* estimate VE from within contrasts -- unbiasedly */
500   contswithin = 0;
501   for (i = 0; i < spp; i++) {
502     for (j = 1; j < sample[i]; j++) {
503       contswithin++;
504       for (k = 0; k < chars; k++)
505         for (l = 0; l < chars; l++)
506           vare[k][l] += cntrast[i][j][k]*cntrast[i][j][l];
507     }
508   }
509   /* estimate VA from between contrasts -- biasedly: does not take out VE */
510   if (!novara) {   /* leave VarA = 0 if no A component assumed present */
511     for (i = 0; i < spp-1; i++) {
512       for (j = 0; j < chars; j++)
513         for (k = 0; k < chars; k++)
514           if (ssqcont[i][0] <= 0.0)
515             vara[j][k] += cntrast[i][0][j]*cntrast[i][0][k];
516           else
517             vara[j][k] += cntrast[i][0][j]*cntrast[i][0][k]
518                           / ((long)(spp-1)*ssqcont[i][0]);
519     }
520   }
521   for (k = 0; k < chars; k++)
522     for (l = 0; l < chars; l++)
523       if (contswithin > 0)
524         vare[k][l] /= contswithin;
525       else {
526         if (!novara) {
527           vara[k][l] = 0.5 * vara[k][l];
528           vare[k][l] = vara[k][l];
529         }
530       }
531}  /* initcovars */
532
533
534double normdiff(boolean novara)
535{
536/* Get relative norm of difference between old, new covariances */
537   double s;
538   long i, j;
539
540   s = 0.0;
541   for (i = 0; i < chars; i++)
542     for (j = 0; j < chars; j++) {
543        if (!novara) {
544          if (fabs(oldvara[i][j]) <= 0.00000001)
545            s += vara[i][j];
546          else
547            s += fabs(vara[i][j]/oldvara[i][j]-1.0);
548        }
549        if (fabs(oldvare[i][j]) <= 0.00000001)
550          s += vare[i][j];
551        else
552          s += fabs(vare[i][j]/oldvare[i][j]-1.0);
553     }
554   return s/((double)(chars*chars));
555}  /* normdiff */
556
557
558void matcopy(double **a, double **b)
559{
560/* Copy matrices chars x chars: a to b */
561   long i;
562   
563   for (i = 0; i < chars; i++) {
564      memcpy(b[i], a[i], chars*sizeof(double));
565   }
566}  /* matcopy */
567
568
569void newcovars(boolean novara)
570{
571/* one EM update of covariances, compute old likelihood too */
572  long i, j, k, l, m;
573  double sum, sum2, sum3, sqssq;
574
575  if (!novara)
576    matcopy(vara, oldvara); 
577  matcopy(vare, oldvare); 
578  sum2 = 0.0;         /* log likelihood of old parameters accumulates here */
579  for (i = 0; i < chars; i++)                    /* zero out vara and vare */
580    for (j = 0; j < chars; j++) {
581      if (!novara)
582        vara[i][j] = 0.0;
583      vare[i][j] = 0.0;
584    }
585  for (i = 0; i < spp-1; i++) {            /* accumulate over contrasts ... */
586    if (i <= spp-2) {       /* E(aa'|x) and E(ee'|x) for "between" contrasts */
587      sqssq = sqrt(ssqcont[i][0]);
588      for (k = 0; k < chars; k++)       /* compute (dA+E) for this contrast */
589        for (l = 0; l < chars; l++)
590          if (!novara)
591            temp1[k][l] = ssqcont[i][0] * oldvara[k][l] + oldvare[k][l]; 
592          else
593            temp1[k][l] = oldvare[k][l]; 
594      matcopy(temp1, temp2);
595      invert(temp2);                               /* compute (dA+E)^(-1)  */
596      /* sum of - x (dA+E)^(-1) x'/2 for old A, E */
597      for (k = 0; k < chars; k++)
598        for (l = 0; l < chars; l++)
599          sum2 -= cntrast[i][0][k]*temp2[k][l]*cntrast[i][0][l]/2.0;
600      matcopy(temp1, temp3);
601      sum2 -= 0.5 * logdet(temp3);             /* log determinant term too */
602      if (!novara) {
603        for (k = 0; k < chars; k++)
604          for (l = 0; l < chars; l++) {
605            sum = 0.0;
606            for (j = 0; j < chars; j++)
607              sum += temp2[k][j] * sqssq * oldvara[j][l];
608            Bax[k][l] = sum;           /*  Bax = (dA+E)^(-1) * sqrt(d) * A */
609          }
610      }
611      for (k = 0; k < chars; k++)
612        for (l = 0; l < chars; l++) {
613          sum = 0.0;
614          for (j = 0; j < chars; j++)
615            sum += temp2[k][j] * oldvare[j][l];
616          Bex[k][l] = sum;                       /*  Bex = (dA+E)^(-1) * E */
617        }
618      if (!novara) {
619        for (k = 0; k < chars; k++)
620          for (l = 0; l < chars; l++) {
621             sum = 0.0;
622             for (m = 0; m < chars; m++)
623               sum += Bax[m][k] * (cntrast[i][0][m]*cntrast[i][0][l]
624                                     -temp1[m][l]);
625             temp2[k][l] = sum;                  /*  Bax'*(xx'-(dA+E)) ... */
626          }
627        for (k = 0; k < chars; k++)
628          for (l = 0; l < chars; l++) {
629             sum = 0.0;
630             for (m = 0; m < chars; m++)
631               sum += temp2[k][m] * Bax[m][l];
632             vara[k][l] += sum;                          /*   ... * Bax  */
633          }
634      }
635      for (k = 0; k < chars; k++)
636        for (l = 0; l < chars; l++) {
637           sum = 0.0;
638           for (m = 0; m < chars; m++)
639             sum += Bex[m][k] * (cntrast[i][0][m]*cntrast[i][0][l]
640                                   -temp1[m][l]);
641           temp2[k][l] = sum;                   /*  Bex'*(xx'-(dA+E)) ... */
642        }
643      for (k = 0; k < chars; k++)
644        for (l = 0; l < chars; l++) {
645           sum = 0.0;
646           for (m = 0; m < chars; m++)
647             sum += temp2[k][m] * Bex[m][l];
648           vare[k][l] += sum;                            /*   ... * Bex  */
649        }
650    }
651  }
652  matcopy(oldvare, temp2);
653  invert(temp2);                          /* get E^(-1) */
654  matcopy(oldvare, temp3);
655  sum3 = 0.5 * logdet(temp3);             /* get 1/2 log det(E) */
656  for (i = 0; i < spp; i++) {
657    if (sample[i] > 1) {
658      for (j = 1; j < sample[i]; j++) {   /* E(aa'|x) (invisibly) and
659                                             E(ee'|x) for within contrasts */
660        for (k = 0; k < chars; k++)
661          for (l = 0; l < chars; l++) {
662            vare[k][l] += cntrast[i][j][k] * cntrast[i][j][l] - oldvare[k][l];
663            sum2 -= cntrast[i][j][k] * temp2[k][l] * cntrast[i][j][l] / 2.0;
664                                  /* accumulate - x*E^(-1)*x'/2 for old E */
665          }
666        sum2 -= sum3;                          /* log determinant term too */
667      }
668    }
669  }
670  for (i = 0; i < chars; i++)        /* complete EM by dividing by denom ... */
671    for (j = 0; j < chars; j++) {    /* ... and adding old VA, VE */
672      if (!novara) {
673        vara[i][j] /= (double)contnum;
674        vara[i][j] += oldvara[i][j];
675      }
676      vare[i][j] /= (double)contnum;
677      vare[i][j] += oldvare[i][j];
678    }
679  logL = sum2;                       /* log likelihood for old values */
680}  /* newcovars */
681
682
683void printcovariances(boolean novara)
684{
685/* print out ML covariances and regressions in the error-covariance case */
686   long i, j;
687
688   fprintf(outfile, "\n\n");
689   if (novara)
690     fprintf(outfile, "Estimates when VarA is not in the model\n\n");
691   else
692     fprintf(outfile, "Estimates when VarA is in the model\n\n");
693   if (!novara) {
694     fprintf(outfile, "Estimate of VarA\n");
695     fprintf(outfile, "-------- -- ----\n");
696     fprintf(outfile, "\n");
697     for (i = 0; i < chars; i++) {
698       for (j = 0; j < chars; j++)
699         fprintf(outfile, " %12.6f ", vara[i][j]);
700       fprintf(outfile, "\n");
701     }
702     fprintf(outfile, "\n");
703   }
704   fprintf(outfile, "Estimate of VarE\n");
705   fprintf(outfile, "-------- -- ----\n");
706   fprintf(outfile, "\n");
707   for (i = 0; i < chars; i++) {
708     for (j = 0; j < chars; j++)
709       fprintf(outfile, " %12.6f ", vare[i][j]);
710     fprintf(outfile, "\n");
711   }
712   fprintf(outfile, "\n");
713   if (!novara) {
714     fprintf(outfile, "VarA Regressions (columns on rows)\n");
715     fprintf(outfile, "---- ----------- -------- -- -----\n\n");
716     for (i = 0; i < chars; i++) {
717       for (j = 0; j < chars; j++)
718         fprintf(outfile, "%10.4f", vara[i][j] / vara[i][i]);
719       putc('\n', outfile);
720     }
721     fprintf(outfile, "\n");
722     fprintf(outfile, "VarA Correlations\n");
723     fprintf(outfile, "---- ------------\n\n");
724     for (i = 0; i < chars; i++) {
725       for (j = 0; j < chars; j++)
726         fprintf(outfile, "%10.4f",
727                 vara[i][j] / sqrt(vara[i][i] * vara[j][j]));
728       putc('\n', outfile);
729     }
730     fprintf(outfile, "\n");
731   }
732   fprintf(outfile, "VarE Regressions (columns on rows)\n");
733   fprintf(outfile, "---- ----------- -------- -- -----\n\n");
734   for (i = 0; i < chars; i++) {
735     for (j = 0; j < chars; j++)
736       fprintf(outfile, "%10.4f", vare[i][j] / vare[i][i]);
737     putc('\n', outfile);
738   }
739   fprintf(outfile, "\n");
740   fprintf(outfile, "\nVarE Correlations\n");
741   fprintf(outfile, "---- ------------\n\n");
742   for (i = 0; i < chars; i++) {
743     for (j = 0; j < chars; j++)
744       fprintf(outfile, "%10.4f",
745               vare[i][j] / sqrt(vare[i][i] * vare[j][j]));
746     putc('\n', outfile);
747   }
748   fprintf(outfile, "\n\n");
749} /* printcovariances */
750
751
752void emiterate(boolean novara)
753{
754/* EM iteration of error and phylogenetic covariances */
755   /* How to handle missing values? */
756   long its;
757   double relnorm;
758
759   initcovars(novara);
760   its = 1;
761   do {
762     newcovars(novara);
763     relnorm = normdiff(novara);
764     if (its % 100 == 0)
765      printf("Iteration no. %ld:  ln L = %f, Norm = %f\n", its, logL, relnorm);
766     its++;
767   } while ((relnorm > 0.00001) && (its < 10000));
768   if (its == 10000) {
769     printf("\nWARNING: Iterations did not converge.");
770     printf("  Results may be unreliable.\n");
771   }
772} /* emiterate */
773
774
775void initcontrastnode(node **p, node **local_grbg, node *UNUSED_q, long UNUSED_len,
776                        long nodei, long *UNUSED_ntips, long *parens, initops whichinit,
777                        pointarray UNUSED_treenode, pointarray nodep, Char *str,
778                        Char *ch, FILE *fp_intree)
779{
780    (void)UNUSED_q;
781    (void)UNUSED_len;
782    (void)UNUSED_ntips;
783    (void)UNUSED_treenode;
784
785  /* initializes a node */
786  boolean minusread;
787  double valyew, divisor;
788
789  switch (whichinit) {
790  case bottom:
791    gnu(local_grbg, p);
792    (*p)->index = nodei;
793    (*p)->tip = false;
794    nodep[(*p)->index - 1] = (*p);
795    (*p)->view = (phenotype3)Malloc((long)chars*sizeof(double));
796    break;
797  case nonbottom:
798    gnu(local_grbg, p);
799    (*p)->index = nodei;
800    (*p)->view = (phenotype3)Malloc((long)chars*sizeof(double));
801    break;
802  case tip:
803    match_names_to_data (str, nodep, p, spp);
804    (*p)->view = (phenotype3)Malloc((long)chars*sizeof(double));
805    (*p)->deltav = 0.0;
806    break;
807  case length:
808    processlength(&valyew, &divisor, ch, &minusread, fp_intree, parens);
809    (*p)->v = valyew / divisor;
810    (*p)->iter = false;
811    if ((*p)->back != NULL) {
812      (*p)->back->v = (*p)->v;
813      (*p)->back->iter = false;
814    }
815    break;
816  default:        /* cases of hslength,iter,hsnolength,treewt,unittrwt*/
817    break;        /* not handled                                            */
818  }
819} /* initcontrastnode */
820
821
822void maketree()
823{
824  /* set up the tree and use it */
825  long which, nextnode;
826  node *q, *r;
827
828  alloctree(&curtree.nodep, nonodes);
829  setuptree(&curtree, nonodes);
830  which = 1;
831  while (which <= numtrees) {
832    if ((printdata || reg) && numtrees > 1) {
833      fprintf(outfile, "Tree number%4ld\n", which);
834      fprintf(outfile, "==== ====== ====\n\n");
835    }
836    nextnode = 0;
837    treeread (intree, &curtree.start, curtree.nodep, &goteof, &first,
838            curtree.nodep, &nextnode, &haslengths, &grbg, initcontrastnode);
839    q = curtree.start;
840    r = curtree.start;
841    while (!(q->next == curtree.start))
842      q = q->next;
843    q->next = curtree.start->next;
844    curtree.start = q;
845    chuck(&grbg, r);
846    curtree.nodep[spp] = q;
847    bifurcating = (curtree.start->next->next == curtree.start);
848    contwithin();
849    makecontrasts(curtree.start);
850    if (!bifurcating) {
851      makecontrasts(curtree.start->back);
852      contbetween(curtree.start, curtree.start->back);
853    }
854    if (!varywithin) {
855      if (writecont)
856        writecontrasts();
857      if (reg)
858        regressions();
859      putc('\n', outfile);
860      }
861    else {
862      emiterate(false);
863      printcovariances(false);
864      if (nophylo) {
865        logLvara = logL;
866        emiterate(nophylo);
867        printcovariances(nophylo);
868        logLnovara = logL;
869        fprintf(outfile, "\n\n\n    Likelihood Ratio Test");
870        fprintf(outfile,  " of no VarA component\n");
871        fprintf(outfile, "    ---------- ----- ----");
872        fprintf(outfile,  " -- -- ---- ---------\n\n");
873        fprintf(outfile, "      Log likelihood with varA     = %13.5f,",
874                          logLvara);
875        fprintf(outfile, "  %ld parameters\n\n", chars*(chars+1));
876        fprintf(outfile, "      Log likelihood without varA  = %13.5f,",
877                          logLnovara);
878        fprintf(outfile, "  %ld parameters\n\n", chars*(chars+1)/2);
879        fprintf(outfile, "                     difference    = %13.5f\n\n",
880                          logLvara-logLnovara);
881        fprintf(outfile, "      Chi-square value = %13.5f, ",
882                  2.0*(logLvara-logLnovara));
883        fprintf(outfile, "  %ld  degrees of freedom\n\n", chars*(chars+1)/2);
884      }
885    }
886    which++;
887  }
888  if (progress)
889    printf("\nOutput written to file \"%s\"\n\n", outfilename);
890}  /* maketree */
891
892
893int main(int argc, Char *argv[])
894{  /* main program */
895#ifdef MAC
896  argc = 1;                /* macsetup("Contrast","Contrast");                */
897  argv[0] = "Contrast";
898#endif
899  init(argc, argv);
900  openfile(&infile,INFILE,"input data","r",argv[0],infilename);
901  openfile(&intree,INTREE,"input tree", "r",argv[0],intreename);
902  openfile(&outfile,OUTFILE,"output", "w",argv[0],outfilename);
903  ibmpc = IBMCRT;
904  ansi = ANSICRT;
905  reg = true;
906  numtrees = 1;
907  doinit();
908  getdata();
909  maketree();
910  FClose(infile);
911  FClose(outfile);
912  FClose(intree);
913  printf("Done.\n\n");
914#ifdef WIN32
915  phyRestoreConsoleAttributes();
916#endif
917  return 0; 
918}
Note: See TracBrowser for help on using the repository browser.