source: branches/port5/GDE/RAxML/topologies.c

Last change on this file was 5262, checked in by westram, 17 years ago
  • update to RAxML 7.0.3
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 17.1 KB
Line 
1
2/*  RAxML-VI-HPC (version 2.2) a program for sequential and parallel estimation of phylogenetic trees
3 *  Copyright August 2006 by Alexandros Stamatakis
4 *
5 *  Partially derived from
6 *  fastDNAml, a program for estimation of phylogenetic trees from sequences by Gary J. Olsen
7 * 
8 *  and
9 *
10 *  Programs of the PHYLIP package by Joe Felsenstein.
11 *
12 *  This program is free software; you may redistribute it and/or modify its
13 *  under the terms of the GNU General Public License as published by the Free
14 *  Software Foundation; either version 2 of the License, or (at your option)
15 *  any later version.
16 *
17 *  This program is distributed in the hope that it will be useful, but
18 *  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 *  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20 *  for more details.
21 *
22 *
23 *  For any other enquiries send an Email to Alexandros Stamatakis
24 *  Alexandros.Stamatakis@epfl.ch
25 *
26 *  When publishing work that is based on the results from RAxML-VI-HPC please cite:
27 *
28 *  Alexandros Stamatakis:"RAxML-VI-HPC: maximum likelihood-based phylogenetic analyses with thousands of taxa and mixed models".
29 *  Bioinformatics 2006; doi: 10.1093/bioinformatics/btl446
30 */
31
32#ifndef WIN32
33#include <sys/times.h>
34#include <sys/types.h>
35#include <sys/time.h>
36#include <unistd.h>
37#endif
38
39#include <math.h>
40#include <time.h>
41#include <stdlib.h>
42#include <stdio.h>
43#include <ctype.h>
44#include <string.h>
45
46#include "axml.h"
47
48
49topolRELL *initTopolRELL(tree *tr)
50{
51  topolRELL *tpl;
52 
53  tpl = (topolRELL *)malloc(sizeof(topolRELL));
54
55  tpl->connect = (connectRELL *)malloc((2 * tr->mxtips - 3) * sizeof(connectRELL));
56  tpl->likelihood = unlikely;
57  return tpl;                                 
58}
59
60
61
62static void saveTopolRELLRec(nodeptr p, topolRELL *tpl, int *i, int numsp, int numBranches)
63{
64  int k;
65  if(isTip(p->number, numsp))
66    return;
67  else
68    {
69      nodeptr q = p->next;     
70      while(q != p)
71        {         
72          tpl->connect[*i].p = q;
73          tpl->connect[*i].q = q->back;       
74          for(k = 0; k < numBranches; k++)
75            tpl->connect[*i].z[k] = q->z[k];
76          *i = *i + 1;
77         
78          saveTopolRELLRec(q->back, tpl, i, numsp, numBranches);
79          q = q->next;
80        }
81    }
82}
83
84void saveTopolRELL(tree *tr, topolRELL *tpl)
85{
86  nodeptr p = tr->start;
87  int k, i = 0;
88     
89  tpl->likelihood = tr->likelihood;
90  tpl->start      = 1;
91     
92  tpl->connect[i].p = p;
93  tpl->connect[i].q = p->back;
94 
95  for(k = 0; k < tr->numBranches; k++)
96    tpl->connect[i].z[k] = p->z[k];
97  i++;
98     
99  saveTopolRELLRec(p->back, tpl, &i, tr->rdta->numsp, tr->numBranches);     
100}
101
102
103void restoreTopolRELL(tree *tr, topolRELL *tpl)
104{
105  int i;
106  nodeptr p, p0;
107
108  for (i = 1; i <= 2*(tr->mxtips) - 2; i++) {
109    p0 = p = tr->nodep[i];
110    do {
111      p->back = (nodeptr) NULL;
112      p = p->next;
113    } while (p != p0);
114  }
115
116  for (i = 0; i < 2 * tr->mxtips - 3; i++)       
117    hookup(tpl->connect[i].p, tpl->connect[i].q, tpl->connect[i].z,  tr->numBranches);   
118 
119
120  tr->likelihood = tpl->likelihood;
121  tr->start      = tr->nodep[tpl->start];
122}
123
124static void restoreTopolRELL_Light(tree *tr, topolRELL *tpl)
125{
126  int i;
127  nodeptr p, p0;
128
129  for (i = 1; i <= 2*(tr->mxtips) - 2; i++) {
130    p0 = p = tr->nodep[i];
131    do {
132      p->back = (nodeptr) NULL;
133      p = p->next;
134    } while (p != p0);
135  }
136
137  for (i = 0; i < 2 * tr->mxtips - 3; i++) 
138    {
139      tpl->connect[i].p->back = tpl->connect[i].q;
140      tpl->connect[i].q->back = tpl->connect[i].p;
141    }
142
143  tr->start      = tr->nodep[tpl->start];
144}
145
146
147void initTL(topolRELL_LIST *rl, tree *tr, int n)
148{
149  int i;
150
151  rl->max = n;
152  rl->members = n;
153  rl->t = (topolRELL **)malloc(sizeof(topolRELL *) * n);
154
155  for(i = 0; i < n; i++)
156    {
157      rl->t[i] = (topolRELL *)malloc(sizeof(topolRELL));
158      rl->t[i]->connect = (connectRELL *)malloc((2 * tr->mxtips - 3) * sizeof(connectRELL));
159      rl->t[i]->likelihood = unlikely;
160    }
161}
162
163
164void freeTL(topolRELL_LIST *rl)
165{
166  int i;
167  for(i = 0; i < rl->max; i++)   
168    {
169      free(rl->t[i]->connect);
170      free(rl->t[i]);
171    }
172  free(rl->t);
173}
174
175
176void restoreTL(topolRELL_LIST *rl, tree *tr, int n)
177{
178  assert(n >= 0 && n < rl->max);   
179
180  restoreTopolRELL(tr, rl->t[n]); 
181}
182
183void restoreTL_Light(topolRELL_LIST *rl, tree *tr, int n)
184{
185  assert(n >= 0 && n < rl->max);
186 
187  restoreTopolRELL_Light(tr, rl->t[n]); 
188}
189
190
191
192void resetTL(topolRELL_LIST *rl)
193{
194  int i;
195
196  for(i = 0; i < rl->max; i++)
197    rl->t[i]->likelihood = unlikely;     
198}
199
200
201/*void saveTL(topolRELL_LIST *rl, tree *tr)
202{
203  if(rl->members < rl->max)
204    {
205      saveTopolRELL(tr, rl->t[rl->members]);
206      rl->members++;     
207    }
208  else
209    {
210      int i, found = 0;
211      for(i = 0; i < rl->max && !found; i++)
212        {
213          if(tr->likelihood > rl->t[i]->likelihood)
214            {
215              saveTopolRELL(tr, rl->t[i]);
216              found = 1;
217            }
218        }     
219    }
220    }*/
221
222void saveTL(topolRELL_LIST *rl, tree *tr, int index)
223{
224 
225  assert(index >= 0 && index < rl->max);   
226   
227  if(tr->likelihood > rl->t[index]->likelihood)   
228    saveTopolRELL(tr, rl->t[index]);     
229}
230
231
232void  *tipValPtr (nodeptr p)
233{ 
234  return  (void *) & p->number;
235}
236
237
238int  cmpTipVal (void *v1, void *v2)
239  { /* cmpTipVal */
240    int  i1, i2;
241
242    i1 = *((int *) v1);
243    i2 = *((int *) v2);
244    return  (i1 < i2) ? -1 : ((i1 == i2) ? 0 : 1);
245  } /* cmpTipVal */
246
247
248
249
250
251/*  These are the only routines that need to UNDERSTAND topologies */
252
253topol  *setupTopol (int maxtips)
254  { /* setupTopol */
255    topol   *tpl;
256
257    if (! (tpl = (topol *) malloc(sizeof(topol))) || 
258        ! (tpl->links = (connptr) malloc((2*maxtips-3) * sizeof(connect))))
259      {
260        printf("ERROR: Unable to get topology memory");
261        tpl = (topol *) NULL;
262      }
263    else 
264      {
265        tpl->likelihood  = unlikely;
266        tpl->start       = (node *) NULL;
267        tpl->nextlink    = 0;
268        tpl->ntips       = 0;
269        tpl->nextnode    = 0;   
270        tpl->scrNum      = 0;     /* position in sorted list of scores */
271        tpl->tplNum      = 0;     /* position in sorted list of trees */
272        tpl->prelabeled  = TRUE;
273        tpl->smoothed    = FALSE; /* branch optimization converged? */
274      }
275
276    return  tpl;
277  } /* setupTopol */
278
279
280void  freeTopol (topol *tpl)
281  { /* freeTopol */
282    free(tpl->links);
283    free(tpl);
284  } /* freeTopol */
285
286
287static int saveSubtree (nodeptr p, topol *tpl, int numsp, int numBranches) 
288{
289  connptr  r, r0;
290  nodeptr  q, s;
291  int      t, t0, t1, k;
292
293  r0 = tpl->links;
294  r = r0 + (tpl->nextlink)++;
295  r->p = p;
296  r->q = q = p->back;
297
298  for(k = 0; k < numBranches; k++)
299    r->z[k] = p->z[k];
300
301  r->descend = 0;                     /* No children (yet) */
302
303  if (/*q->tip*/ isTip(q->number, numsp)) 
304    {
305      r->valptr = tipValPtr(q);         /* Assign value */
306    }
307  else 
308    {                              /* Internal node, look at children */
309      s = q->next;                      /* First child */
310      do 
311        {
312          t = saveSubtree(s, tpl, numsp, numBranches);        /* Generate child's subtree */
313
314          t0 = 0;                         /* Merge child into list */
315          t1 = r->descend;
316          while (t1 && (cmpTipVal(r0[t1].valptr, r0[t].valptr) < 0)) {
317            t0 = t1;
318            t1 = r0[t1].sibling;
319          }
320          if (t0) r0[t0].sibling = t;  else  r->descend = t;
321          r0[t].sibling = t1;
322
323          s = s->next;                    /* Next child */
324        } while (s != q);
325
326      r->valptr = r0[r->descend].valptr;   /* Inherit first child's value */
327      }                                 /* End of internal node processing */
328
329  return  (r - r0);
330}
331
332
333static nodeptr minSubtreeTip (nodeptr  p0, int numsp)
334{ 
335  nodeptr  minTip, p, testTip;
336
337  if (/*p0->tip*/ isTip(p0->number, numsp)) 
338    return p0;
339
340  p = p0->next;
341
342  minTip = minSubtreeTip(p->back, numsp);
343
344  while ((p = p->next) != p0) 
345    {
346      testTip = minSubtreeTip(p->back, numsp);
347      if (cmpTipVal(tipValPtr(testTip), tipValPtr(minTip)) < 0)
348        minTip = testTip;
349    }
350  return minTip;
351} 
352
353
354static nodeptr  minTreeTip (nodeptr  p, int numsp)
355{
356  nodeptr  minp, minpb;
357
358  minp  = minSubtreeTip(p, numsp);
359  minpb = minSubtreeTip(p->back, numsp);
360  return (cmpTipVal(tipValPtr(minp), tipValPtr(minpb)) < 0 ? minp : minpb);
361}
362
363
364void saveTree (tree *tr, topol *tpl)
365    /*  Save a tree topology in a standard order so that first branches
366     *  from a node contain lower value tips than do second branches from
367     *  the node.  The root tip should have the lowest value of all.
368     */
369  { /* saveTree */
370    connptr  r; 
371
372    tpl->nextlink = 0;                             /* Reset link pointer */
373    r = tpl->links + saveSubtree(minTreeTip(tr->start, tr->rdta->numsp), tpl, tr->rdta->numsp, tr->numBranches);  /* Save tree */
374    r->sibling = 0;
375
376    tpl->likelihood = tr->likelihood;
377    tpl->start      = tr->start;
378    tpl->ntips      = tr->ntips;
379    tpl->nextnode   = tr->nextnode; 
380    tpl->prelabeled = tr->prelabeled;
381    tpl->smoothed   = tr->smoothed;   
382   
383  } /* saveTree */
384
385
386
387
388
389
390
391
392boolean restoreTree (topol *tpl, tree *tr)
393{ 
394  connptr  r;
395  nodeptr  p, p0;   
396  int  i;
397
398  for (i = 1; i <= 2*(tr->mxtips) - 2; i++) 
399    { 
400      /* Uses p = p->next at tip */
401      p0 = p = tr->nodep[i];
402      do 
403        {
404          p->back = (nodeptr) NULL;
405          p = p->next;
406        } 
407      while (p != p0);
408    }
409
410  /*  Copy connections from topology */
411
412  for (r = tpl->links, i = 0; i < tpl->nextlink; r++, i++)     
413    hookup(r->p, r->q, r->z, tr->numBranches);     
414
415  tr->likelihood = tpl->likelihood;
416  tr->start      = tpl->start;
417  tr->ntips      = tpl->ntips;
418 
419  tr->nextnode   = tpl->nextnode;   
420  tr->prelabeled = tpl->prelabeled;
421  tr->smoothed   = tpl->smoothed; 
422
423
424  onlyInitrav(tr, tr->start);
425  return TRUE;
426}
427
428
429boolean restoreTopology (topol *tpl, tree *tr)
430  { 
431    connptr  r;   
432    int  i;   
433
434    for (r = tpl->links, i = 0; i < tpl->nextlink; r++, i++) 
435      {
436        hookup(r->p, r->q, r->z, tr->numBranches);
437      }
438
439    tr->likelihood = tpl->likelihood;
440    tr->start      = tpl->start;
441    tr->ntips      = tpl->ntips;
442   
443    tr->nextnode   = tpl->nextnode;
444    tr->prelabeled = tpl->prelabeled;
445    tr->smoothed   = tpl->smoothed;
446   
447
448    onlyInitrav(tr, tr->start);
449    return TRUE; 
450  } /* restoreTree */
451
452
453int initBestTree (bestlist *bt, int newkeep, int numsp)
454  { /* initBestTree */
455    int  i;
456
457
458    bt->nkeep = 0;
459
460    if (bt->ninit <= 0) {
461      if (! (bt->start = setupTopol(numsp)))  return  0;
462      bt->ninit = -1;
463      bt->nvalid = 0;
464      bt->numtrees = 0;
465      bt->best = unlikely;
466      bt->improved = FALSE;
467      bt->byScore = (topol **) malloc((newkeep+1) * sizeof(topol *));
468      bt->byTopol = (topol **) malloc((newkeep+1) * sizeof(topol *));
469      if (! bt->byScore || ! bt->byTopol) {
470        printf( "initBestTree: malloc failure\n");
471        return 0;
472        }
473      }
474    else if (ABS(newkeep) > bt->ninit) {
475      if (newkeep <  0) newkeep = -(bt->ninit);
476      else newkeep = bt->ninit;
477      }
478
479    if (newkeep < 1) {    /*  Use negative newkeep to clear list  */
480      newkeep = -newkeep;
481      if (newkeep < 1) newkeep = 1;
482      bt->nvalid = 0;
483      bt->best = unlikely;
484      }
485
486    if (bt->nvalid >= newkeep) {
487      bt->nvalid = newkeep;
488      bt->worst = bt->byScore[newkeep]->likelihood;
489      }
490    else 
491      {
492        bt->worst = unlikely;
493      }
494
495    for (i = bt->ninit + 1; i <= newkeep; i++) 
496      {   
497        if (! (bt->byScore[i] = setupTopol(numsp)))  break;
498        bt->byTopol[i] = bt->byScore[i];
499        bt->ninit = i;
500      }
501
502    return  (bt->nkeep = MIN(newkeep, bt->ninit));
503  } /* initBestTree */
504
505
506
507void resetBestTree (bestlist *bt)
508  { /* resetBestTree */
509    bt->best     = unlikely;
510    bt->worst    = unlikely;
511    bt->nvalid   = 0;
512    bt->improved = FALSE;
513  } /* resetBestTree */
514
515
516boolean  freeBestTree(bestlist *bt)
517  { /* freeBestTree */
518    while (bt->ninit >= 0)  freeTopol(bt->byScore[(bt->ninit)--]);
519   
520    /* VALGRIND */
521
522    free(bt->byScore);
523    free(bt->byTopol);
524
525    /* VALGRIND END */
526
527    freeTopol(bt->start);
528    return TRUE;
529  } /* freeBestTree */
530
531
532/*  Compare two trees, assuming that each is in standard order.  Return
533 *  -1 if first preceeds second, 0 if they are identical, or +1 if first
534 *  follows second in standard order.  Lower number tips preceed higher
535 *  number tips.  A tip preceeds a corresponding internal node.  Internal
536 *  nodes are ranked by their lowest number tip.
537 */
538
539int  cmpSubtopol (connptr p10, connptr p1, connptr p20, connptr p2)
540  { /* cmpSubtopol */
541    connptr  p1d, p2d;
542    int  cmp;
543
544    if (! p1->descend && ! p2->descend)          /* Two tips */
545      return cmpTipVal(p1->valptr, p2->valptr);
546
547    if (! p1->descend) return -1;                /* p1 = tip, p2 = node */
548    if (! p2->descend) return  1;                /* p2 = tip, p1 = node */
549
550    p1d = p10 + p1->descend;
551    p2d = p20 + p2->descend;
552    while (1) {                                  /* Two nodes */
553      if ((cmp = cmpSubtopol(p10, p1d, p20, p2d)))  return cmp; /* Subtrees */
554      if (! p1d->sibling && ! p2d->sibling)  return  0; /* Lists done */
555      if (! p1d->sibling) return -1;             /* One done, other not */
556      if (! p2d->sibling) return  1;             /* One done, other not */
557      p1d = p10 + p1d->sibling;                  /* Neither done */
558      p2d = p20 + p2d->sibling;
559      }
560  } /* cmpSubtopol */
561
562
563
564int  cmpTopol (void *tpl1, void *tpl2)
565  { /* cmpTopol */
566    connptr  r1, r2;
567    int      cmp;
568
569    r1 = ((topol *) tpl1)->links;
570    r2 = ((topol *) tpl2)->links;
571    cmp = cmpTipVal(tipValPtr(r1->p), tipValPtr(r2->p));
572    if (cmp) return cmp;
573    return  cmpSubtopol(r1, r1, r2, r2);
574  } /* cmpTopol */
575
576
577
578int  cmpTplScore (void *tpl1, void *tpl2)
579  { /* cmpTplScore */
580    double  l1, l2;
581
582    l1 = ((topol *) tpl1)->likelihood;
583    l2 = ((topol *) tpl2)->likelihood;
584    return  (l1 > l2) ? -1 : ((l1 == l2) ? 0 : 1);
585  } /* cmpTplScore */
586
587
588
589/*  Find an item in a sorted list of n items.  If the item is in the list,
590 *  return its index.  If it is not in the list, return the negative of the
591 *  position into which it should be inserted.
592 */
593
594int  findInList (void *item, void *list[], int n, int (* cmpFunc)(void *, void *))
595  { /* findInList */
596    int  mid, hi, lo, cmp = 0;
597
598    if (n < 1) return  -1;                    /*  No match; first index  */
599
600    lo = 1;
601    mid = 0;
602    hi = n;
603    while (lo < hi) {
604      mid = (lo + hi) >> 1;
605      cmp = (* cmpFunc)(item, list[mid-1]);
606      if (cmp) {
607        if (cmp < 0) hi = mid;
608        else lo = mid + 1;
609        }
610      else  return  mid;                        /*  Exact match  */
611      }
612
613    if (lo != mid) {
614       cmp = (* cmpFunc)(item, list[lo-1]);
615       if (cmp == 0) return lo;
616       }
617    if (cmp > 0) lo++;                         /*  Result of step = 0 test  */
618    return  -lo;
619  } /* findInList */
620
621
622
623int  findTreeInList (bestlist *bt, tree *tr)
624  { /* findTreeInList */
625    topol  *tpl;
626
627    tpl = bt->byScore[0];
628    saveTree(tr, tpl);
629    return  findInList((void *) tpl, (void **) (& (bt->byTopol[1])),
630                       bt->nvalid, cmpTopol);
631  } /* findTreeInList */
632
633
634int  saveBestTree (bestlist *bt, tree *tr)
635  { /* saveBestTree */
636   
637    topol  *tpl, *reuse;
638    int  tplNum, scrNum, reuseScrNum, reuseTplNum, i, oldValid, newValid;
639
640    tplNum = findTreeInList(bt, tr);
641    tpl = bt->byScore[0];
642    oldValid = newValid = bt->nvalid;
643
644    if (tplNum > 0) {                      /* Topology is in list  */
645      reuse = bt->byTopol[tplNum];         /* Matching topol  */
646      reuseScrNum = reuse->scrNum;
647      reuseTplNum = reuse->tplNum;
648      }
649                                           /* Good enough to keep? */
650    else if (tr->likelihood < bt->worst)  return 0;
651
652    else {                                 /* Topology is not in list */
653      tplNum = -tplNum;                    /* Add to list (not replace) */
654      if (newValid < bt->nkeep) bt->nvalid = ++newValid;
655      reuseScrNum = newValid;              /* Take worst tree */
656      reuse = bt->byScore[reuseScrNum];
657      reuseTplNum = (newValid > oldValid) ? newValid : reuse->tplNum;
658      if (tr->likelihood > bt->start->likelihood) bt->improved = TRUE;
659      }
660
661    scrNum = findInList((void *) tpl, (void **) (& (bt->byScore[1])),
662                         oldValid, cmpTplScore);
663    scrNum = ABS(scrNum);
664
665    if (scrNum < reuseScrNum)
666      for (i = reuseScrNum; i > scrNum; i--)
667        (bt->byScore[i] = bt->byScore[i-1])->scrNum = i;
668
669    else if (scrNum > reuseScrNum) {
670      scrNum--;
671      for (i = reuseScrNum; i < scrNum; i++)
672        (bt->byScore[i] = bt->byScore[i+1])->scrNum = i;
673      }
674
675    if (tplNum < reuseTplNum)
676      for (i = reuseTplNum; i > tplNum; i--)
677        (bt->byTopol[i] = bt->byTopol[i-1])->tplNum = i;
678
679    else if (tplNum > reuseTplNum) {
680      tplNum--;
681      for (i = reuseTplNum; i < tplNum; i++)
682        (bt->byTopol[i] = bt->byTopol[i+1])->tplNum = i;
683      }
684
685   
686
687    tpl->scrNum = scrNum;
688    tpl->tplNum = tplNum;
689    bt->byTopol[tplNum] = bt->byScore[scrNum] = tpl;
690    bt->byScore[0] = reuse;
691
692    if (scrNum == 1)  bt->best = tr->likelihood;
693    if (newValid == bt->nkeep) bt->worst = bt->byScore[newValid]->likelihood;
694
695    return  scrNum;
696  } /* saveBestTree */
697
698
699
700
701
702
703
704
705int  recallBestTree (bestlist *bt, int rank, tree *tr)
706{ 
707  if (rank < 1)  rank = 1;
708  if (rank > bt->nvalid)  rank = bt->nvalid;
709  if (rank > 0)  if (! restoreTree(bt->byScore[rank], tr)) return FALSE;
710  return  rank;
711}
712
713
714
715/*=======================================================================*/
716/*                       End of best tree routines                       */
717/*=======================================================================*/
Note: See TracBrowser for help on using the repository browser.