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