bme.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:16k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: bme.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 18:09:50  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.2
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: bme.cpp,v 1000.1 2004/06/01 18:09:50 gouriano Exp $
  10. * ===========================================================================
  11. *
  12. *                            PUBLIC DOMAIN NOTICE
  13. *               National Center for Biotechnology Information
  14. *
  15. *  This software/database is a "United States Government Work" under the
  16. *  terms of the United States Copyright Act.  It was written as part of
  17. *  the author's official duties as a United States Government employee and
  18. *  thus cannot be copyrighted.  This software/database is freely available
  19. *  to the public for use. The National Library of Medicine and the U.S.
  20. *  Government have not placed any restriction on its use or reproduction.
  21. *
  22. *  Although all reasonable efforts have been taken to ensure the accuracy
  23. *  and reliability of the software and data, the NLM and the U.S.
  24. *  Government do not and cannot warrant the performance or results that
  25. *  may be obtained by using this software or data. The NLM and the U.S.
  26. *  Government disclaim all warranties, express or implied, including
  27. *  warranties of performance, merchantability or fitness for any particular
  28. *  purpose.
  29. *
  30. *  Please cite the author in any work or product based on this material.
  31. *
  32. * ===========================================================================
  33. *
  34. * Author:  Richard Desper
  35. *
  36. * File Description:  bme.cpp
  37. *
  38. *    A part of the Miminum Evolution algorithm
  39. *
  40. */
  41. #include <ncbi_pch.hpp>
  42. #include <stdio.h>
  43. #include <stdlib.h>
  44. #include <math.h>
  45. #include "graph.h"
  46. #include "fastme.h"
  47. BEGIN_NCBI_SCOPE
  48. BEGIN_SCOPE(fastme)
  49. meEdge *siblingEdge(meEdge *e);
  50. boolean leaf(meNode *v);
  51. meEdge *depthFirstTraverse(meTree *T, meEdge *e);
  52. meEdge *topFirstTraverse(meTree *T, meEdge *e);
  53. void BalWFext(meEdge *e, double **A) /*works except when e is the one edge
  54.   inserted to new vertex v by firstInsert*/
  55. {
  56.   meEdge *f, *g;
  57.   if ((leaf(e->head)) && (leaf(e->tail)))
  58.     e->distance = A[e->head->index][e->head->index];
  59.   else if (leaf(e->head))
  60.     {
  61.       f = e->tail->parentEdge;
  62.       g = siblingEdge(e);
  63.       e->distance = 0.5*(A[e->head->index][g->head->index]
  64.  + A[e->head->index][f->head->index]
  65.  - A[g->head->index][f->head->index]);
  66.     }
  67.   else
  68.     {
  69.       f = e->head->leftEdge;
  70.       g = e->head->rightEdge;
  71.       e->distance = 0.5*(A[g->head->index][e->head->index]
  72.  + A[f->head->index][e->head->index]
  73.  - A[f->head->index][g->head->index]);
  74.     }
  75. }
  76. void BalWFint(meEdge *e, double **A)
  77. {
  78.   int up, down, left, right;
  79.   up = e->tail->index;
  80.   down = (siblingEdge(e))->head->index;
  81.   left = e->head->leftEdge->head->index;
  82.   right = e->head->rightEdge->head->index;
  83.   e->distance = 0.25*(A[up][left] + A[up][right] + A[left][down] + A[right][down]) - 0.5*(A[down][up] + A[left][right]);
  84.   
  85. void assignBMEWeights(meTree *T, double **A)
  86. {
  87.   meEdge *e;
  88.   e = depthFirstTraverse(T,NULL);
  89.   while (NULL != e) {
  90.     if ((leaf(e->head)) || (leaf(e->tail)))
  91.       BalWFext(e,A);
  92.     else
  93.       BalWFint(e,A);
  94.     e = depthFirstTraverse(T,e);
  95.   }
  96. }      
  97. void BMEcalcDownAverage(meTree *T, meNode *v, meEdge *e, double **D, double **A)
  98. {
  99.   meEdge  *left, *right;
  100.   if (leaf(e->head))
  101.     A[e->head->index][v->index] = D[v->index2][e->head->index2]; 
  102.   else
  103.     {
  104.       left = e->head->leftEdge;
  105.       right = e->head->rightEdge;
  106.       A[e->head->index][v->index] = 0.5 * A[left->head->index][v->index] 
  107. + 0.5 * A[right->head->index][v->index];
  108.     }
  109. }
  110. void BMEcalcUpAverage(meTree *T, meNode *v, meEdge *e, double **D, double **A)
  111. {
  112.   meEdge *up,*down;
  113.   if (T->root == e->tail)
  114.     A[v->index][e->head->index] = D[v->index2][e->tail->index2];
  115.   /*for now, use convention
  116.     v->index first => looking up
  117.     v->index second => looking down */
  118.   else
  119.     {
  120.       up = e->tail->parentEdge;
  121.       down = siblingEdge(e);
  122.       A[v->index][e->head->index] = 0.5 * A[v->index][up->head->index]
  123. +0.5  * A[down->head->index][v->index];
  124.     }
  125. }
  126. void BMEcalcNewvAverages(meTree *T, meNode *v, double **D, double **A)
  127. {
  128.   /*loop over edges*/
  129.   /*depth-first search*/
  130.   meEdge *e;
  131.   e = NULL;
  132.   e = depthFirstTraverse(T,e);  /*the downward averages need to be
  133.   calculated from bottom to top */
  134.   while(NULL != e)
  135.     {
  136.       BMEcalcDownAverage(T,v,e,D,A);
  137.       e = depthFirstTraverse(T,e);
  138.     }
  139.   
  140.   e = topFirstTraverse(T,e);   /*the upward averages need to be calculated 
  141.  from top to bottom */
  142.   while(NULL != e)
  143.     {
  144.       BMEcalcUpAverage(T,v,e,D,A);
  145.       e = topFirstTraverse(T,e);
  146.     }
  147. }
  148. /*update Pair updates A[nearEdge][farEdge] and makes recursive call to subtree
  149.   beyond farEdge*/
  150. /*root is head or tail of meEdge being split, depending on direction toward
  151.   v*/
  152. void updatePair(double **A, meEdge *nearEdge, meEdge *farEdge, meNode *v,
  153. meNode *root, double dcoeff, int direction)
  154. {
  155.   meEdge *sib;
  156.   switch(direction) /*the various cases refer to where the new vertex has
  157.       been inserted, in relation to the meEdge nearEdge*/
  158.     {
  159.     case UP: /*this case is called when v has been inserted above 
  160.        or skew to farEdge*/
  161.       /*do recursive calls first!*/
  162.       if (NULL != farEdge->head->leftEdge)
  163. updatePair(A,nearEdge,farEdge->head->leftEdge,v,root,dcoeff,UP);
  164.       if (NULL != farEdge->head->rightEdge)
  165. updatePair(A,nearEdge,farEdge->head->rightEdge,v,root,dcoeff,UP);
  166.       A[farEdge->head->index][nearEdge->head->index] =
  167. A[nearEdge->head->index][farEdge->head->index]
  168. = A[farEdge->head->index][nearEdge->head->index]
  169. + dcoeff*A[farEdge->head->index][v->index]
  170. - dcoeff*A[farEdge->head->index][root->index];
  171.       break; 
  172.     case DOWN: /*called when v has been inserted below farEdge*/
  173.       if (NULL != farEdge->tail->parentEdge)
  174. updatePair(A,nearEdge,farEdge->tail->parentEdge,v,root,dcoeff,DOWN);
  175.       sib = siblingEdge(farEdge);
  176.       if (NULL != sib)
  177. updatePair(A,nearEdge,sib,v,root,dcoeff,UP);
  178.       A[farEdge->head->index][nearEdge->head->index] =
  179. A[nearEdge->head->index][farEdge->head->index]
  180. = A[farEdge->head->index][nearEdge->head->index]
  181. + dcoeff*A[v->index][farEdge->head->index]
  182. - dcoeff*A[farEdge->head->index][root->index];   
  183.     }
  184. }
  185. void updateSubTree(double **A, meEdge *nearEdge, meNode *v, meNode *root,
  186.    meNode *newNode, double dcoeff, int direction)
  187. {
  188.   meEdge *sib;
  189.   switch(direction)
  190.     {
  191.     case UP: /*newNode is above the meEdge nearEdge*/
  192.       A[v->index][nearEdge->head->index] = A[nearEdge->head->index][v->index];
  193.       A[newNode->index][nearEdge->head->index] = 
  194. A[nearEdge->head->index][newNode->index] =
  195. A[nearEdge->head->index][root->index];
  196.       if (NULL != nearEdge->head->leftEdge)
  197. updateSubTree(A, nearEdge->head->leftEdge, v, root, newNode, 0.5*dcoeff, UP);
  198.       if (NULL != nearEdge->head->rightEdge)
  199. updateSubTree(A, nearEdge->head->rightEdge, v, root, newNode, 0.5*dcoeff, UP);
  200.       updatePair(A, nearEdge, nearEdge, v, root, dcoeff, UP);
  201.       break;
  202.     case DOWN: /*newNode is below the meEdge nearEdge*/
  203.       A[nearEdge->head->index][v->index] = A[v->index][nearEdge->head->index];
  204.       A[newNode->index][nearEdge->head->index] = 
  205. A[nearEdge->head->index][newNode->index] =
  206. 0.5*(A[nearEdge->head->index][root->index] 
  207.      + A[v->index][nearEdge->head->index]);
  208.       sib = siblingEdge(nearEdge);
  209.       if (NULL != sib)
  210. updateSubTree(A, sib, v, root, newNode, 0.5*dcoeff, SKEW);
  211.       if (NULL != nearEdge->tail->parentEdge)
  212. updateSubTree(A, nearEdge->tail->parentEdge, v, root, newNode, 0.5*dcoeff, DOWN);
  213.       updatePair(A, nearEdge, nearEdge, v, root, dcoeff, DOWN);
  214.       break;
  215.     case SKEW: /*newNode is neither above nor below nearEdge*/
  216.       A[v->index][nearEdge->head->index] = A[nearEdge->head->index][v->index];
  217.       A[newNode->index][nearEdge->head->index] = 
  218. A[nearEdge->head->index][newNode->index] =
  219. 0.5*(A[nearEdge->head->index][root->index] + 
  220.      A[nearEdge->head->index][v->index]);
  221.       if (NULL != nearEdge->head->leftEdge)
  222. updateSubTree(A, nearEdge->head->leftEdge, v, root, newNode, 0.5*dcoeff,SKEW);
  223.       if (NULL != nearEdge->head->rightEdge)
  224. updateSubTree(A, nearEdge->head->rightEdge, v, root, newNode, 0.5*dcoeff,SKEW);
  225.       updatePair(A, nearEdge, nearEdge, v, root, dcoeff, UP);
  226.     }
  227. }
  228. /*we update all the averages for nodes (u1,u2), where the insertion point of 
  229.   v is in "direction" from both u1 and u2 */
  230. /*The general idea is to proceed in a direction from those edges already corrected
  231.  */
  232. /*r is the root of the meTree relative to the inserted node*/
  233. void BMEupdateAveragesMatrix(double **A, meEdge *e, meNode *v,meNode *newNode)
  234. {
  235.   meEdge *sib, *par, *left, *right;
  236.   /*first, update the v,newNode entries*/
  237.   A[newNode->index][newNode->index] = 0.5*(A[e->head->index][e->head->index]
  238.    + A[v->index][e->head->index]);
  239.   A[v->index][newNode->index] = A[newNode->index][v->index] = 
  240.     A[v->index][e->head->index];
  241.   A[v->index][v->index] = 
  242.     0.5*(A[e->head->index][v->index] + A[v->index][e->head->index]);
  243.   left = e->head->leftEdge;
  244.   right = e->head->rightEdge;
  245.   if (NULL != left)
  246.     updateSubTree(A,left,v,e->head,newNode,0.25,UP); /*updates left and below*/
  247.   if (NULL != right)
  248.     updateSubTree(A,right,v,e->head,newNode,0.25,UP); /*updates right and below*/
  249.   sib = siblingEdge(e);
  250.   if (NULL != sib)
  251.     updateSubTree(A,sib,v,e->head,newNode,0.25,SKEW); /*updates sib and below*/
  252.   par = e->tail->parentEdge;
  253.   if (NULL != par)
  254.     updateSubTree(A,par,v,e->head,newNode,0.25,DOWN); /*updates par and above*/
  255.   /*must change values A[e->head][*] last, as they are used to update
  256.     the rest of the matrix*/
  257.   A[newNode->index][e->head->index] = A[e->head->index][newNode->index]
  258.     = A[e->head->index][e->head->index];
  259.   A[v->index][e->head->index] = A[e->head->index][v->index];
  260.   updatePair(A,e,e,v,e->head,0.5,UP); /*updates e->head fields only*/
  261. }      
  262. /*A is meTree below sibling, B is meTree below edge, C is meTree above edge*/
  263. double wf3(double D_AB, double D_AC, double D_kB, double D_kC)
  264. {
  265.   return(D_AC + D_kB - D_AB - D_kC);
  266. }
  267. void BMEtestEdge(meEdge *e, meNode *v, double **A)
  268. {
  269.   meEdge *up, *down;
  270.   down = siblingEdge(e);
  271.   up = e->tail->parentEdge;
  272.   e->totalweight = wf3(A[e->head->index][down->head->index],
  273.       A[down->head->index][e->tail->index],
  274.       A[e->head->index][v->index],
  275.       A[v->index][e->tail->index])
  276.     + up->totalweight;
  277. }
  278. void BMEsplitEdge(meTree *T, meNode *v, meEdge *e, double **A)
  279. {
  280.   meEdge *newPendantEdge;
  281.   meEdge *newInternalEdge;
  282.   meNode *newNode;
  283.   char nodeLabel[NODE_LABEL_LENGTH];
  284.   char edgeLabel1[EDGE_LABEL_LENGTH];
  285.   char edgeLabel2[EDGE_LABEL_LENGTH];
  286.   sprintf(nodeLabel,"I%d",T->size+1);
  287.   sprintf(edgeLabel1,"E%d",T->size);
  288.   sprintf(edgeLabel2,"E%d",T->size+1);
  289.   
  290.   /*make the new meNode and edges*/
  291.   newNode = makeNewNode(nodeLabel,T->size+1);
  292.   newPendantEdge = makeEdge(edgeLabel1,newNode,v,0.0);
  293.   newInternalEdge = makeEdge(edgeLabel2,newNode,e->head,0.0);
  294.   /*update the matrix of average distances*/
  295.   BMEupdateAveragesMatrix(A,e,v,newNode);
  296.   /*put them in the correct topology*/
  297.   newNode->parentEdge = e;
  298.   e->head->parentEdge = newInternalEdge;
  299.   v->parentEdge = newPendantEdge;
  300.   e->head = newNode;
  301.   T->size = T->size + 2;    
  302.   if (e->tail->leftEdge == e) 
  303.     /*actually this is totally arbitrary and probably unnecessary*/
  304.     {
  305.       newNode->leftEdge = newInternalEdge;
  306.       newNode->rightEdge = newPendantEdge;
  307.     }
  308.   else
  309.     {
  310.       newNode->leftEdge = newInternalEdge;
  311.       newNode->rightEdge = newPendantEdge;
  312.     }
  313. }
  314. meTree *BMEaddSpecies(meTree *T,meNode *v, double **D, double **A) 
  315.      /*the key function of the program addSpeices inserts
  316.        the meNode v to the meTree T.  It uses testEdge to see what the relative
  317.        weight would be if v split a particular edge.  Once insertion point
  318.        is found, v is added to T, and A is updated.  Edge weights
  319.        are not assigned until entire meTree is build*/
  320. {
  321.   meTree *T_e;
  322.   meEdge *e; /*loop variable*/
  323.   meEdge *e_min; /*points to best meEdge seen thus far*/
  324.   double w_min = 0.0;   /*used to keep track of meTree weights*/
  325.   
  326.   /*initialize variables as necessary*/
  327.   
  328.   /*CASE 1: T is empty, v is the first node*/
  329.   if (NULL == T)  /*create a meTree with v as only vertex, no edges*/
  330.     {
  331.       T_e = newTree();
  332.       T_e->root = v;  
  333.       /*note that we are rooting T arbitrarily at a leaf.  
  334. T->root is not the phylogenetic root*/
  335.       v->index = 0;
  336.       T_e->size = 1;
  337.       return(T_e);      
  338.     }
  339.   /*CASE 2: T is a single-vertex tree*/
  340.   if (1 == T->size)
  341. {
  342.   v->index = 1;
  343.   e = makeEdge("",T->root,v,0.0);
  344.   sprintf(e->label,"E1");
  345.   A[v->index][v->index] = D[v->index2][T->root->index2];
  346.   T->root->leftEdge = v->parentEdge = e;
  347.   T->size = 2;
  348.   return(T); 
  349. }
  350.   /*CASE 3: T has at least two nodes and an edge.  Insert new node
  351.     by breaking one of the edges*/
  352.   
  353.   v->index = T->size;
  354.   BMEcalcNewvAverages(T,v,D,A);
  355.   /*calcNewvAverages will update A for the row and column 
  356.     include the meNode v.  Will do so using pre-existing averages in T and
  357.     information from A,D*/
  358.   e_min = T->root->leftEdge;
  359.   e = e_min->head->leftEdge;
  360.   while (NULL != e)
  361.     {
  362.       BMEtestEdge(e,v,A); 
  363.       /*testEdge tests weight of meTree if loop variable 
  364. e is the meEdge split, places this value in the e->totalweight field */
  365.       if (e->totalweight < w_min)
  366. {
  367.   e_min = e;
  368.   w_min = e->totalweight;
  369. }
  370.       e = topFirstTraverse(T,e);
  371.     }
  372.   /*e_min now points at the meEdge we want to split*/
  373.   if (verbose)
  374.     
  375.     printf("Inserting %s between %s and %s on %sn",v->label,e_min->tail->label,
  376.    e_min->head->label,e_min->label);
  377.   BMEsplitEdge(T,v,e_min,A);
  378.   return(T);
  379. }
  380. /*calcUpAverages will ensure that A[e->head->index][f->head->index] is
  381.   filled for any f >= g.  Works recursively*/
  382. void calcUpAverages(double **D, double **A, meEdge *e, meEdge *g)
  383. {
  384.   meNode *u,*v;
  385.   meEdge *s;
  386.   if (!(leaf(g->tail)))
  387.     {
  388.       calcUpAverages(D,A,e,g->tail->parentEdge);
  389.       s = siblingEdge(g);
  390.       u = g->tail;
  391.       v = s->head;
  392.       A[e->head->index][g->head->index] = A[g->head->index][e->head->index]
  393. = 0.5*(A[e->head->index][u->index] + A[e->head->index][v->index]);
  394.     }
  395. }
  396. void makeBMEAveragesTable(meTree *T, double **D, double **A)
  397. {
  398.   meEdge *e, *f, *exclude;
  399.   meNode *u,*v;
  400.   /*first, let's deal with the averages involving the root of T*/
  401.   e = T->root->leftEdge;
  402.   f = depthFirstTraverse(T,NULL);
  403.   while (NULL != f) {
  404.     if (leaf(f->head))
  405.       A[e->head->index][f->head->index] = A[f->head->index][e->head->index]
  406. = D[e->tail->index2][f->head->index2];
  407.     else
  408.       {
  409. u = f->head->leftEdge->head;
  410. v = f->head->rightEdge->head;
  411. A[e->head->index][f->head->index] = A[f->head->index][e->head->index]
  412.   = 0.5*(A[e->head->index][u->index] + A[e->head->index][v->index]);
  413.       }
  414.     f = depthFirstTraverse(T,f);
  415.   }
  416.  e = depthFirstTraverse(T,NULL);
  417.   while (T->root->leftEdge != e) {
  418.     f = exclude = e;
  419.     while (T->root->leftEdge != f) {
  420.       if (f == exclude)
  421. exclude = exclude->tail->parentEdge;
  422.       else if (leaf(e->head))
  423. {
  424.   if (leaf(f->head))
  425.     A[e->head->index][f->head->index] = 
  426.       A[f->head->index][e->head->index]
  427.       = D[e->head->index2][f->head->index2];
  428.   else
  429.     {
  430.       u = f->head->leftEdge->head; /*since f is chosen using a
  431.      depth-first search, other values
  432.      have been calculated*/
  433.       v = f->head->rightEdge->head;
  434.       A[e->head->index][f->head->index] 
  435. = A[f->head->index][e->head->index] 
  436. = 0.5*(A[e->head->index][u->index] + A[e->head->index][v->index]);
  437.     }
  438. }
  439.       else
  440. {
  441.   u = e->head->leftEdge->head;
  442.   v = e->head->rightEdge->head;
  443.   A[e->head->index][f->head->index] = A[f->head->index][e->head->index] = 0.5*(A[f->head->index][u->index] + A[f->head->index][v->index]);
  444. }
  445.       f = depthFirstTraverse(T,f);
  446.     }    
  447.     e = depthFirstTraverse(T,e);
  448.   }
  449.   e = depthFirstTraverse(T,NULL);
  450.   while (T->root->leftEdge != e)
  451.     {
  452.       calcUpAverages(D,A,e,e); /*calculates averages for 
  453.  A[e->head->index][g->head->index] for
  454.  any meEdge g in path from e to root of tree*/ 
  455.       e = depthFirstTraverse(T,e);
  456.     }
  457. } /*makeAveragesMatrix*/
  458. END_SCOPE(fastme)
  459. END_NCBI_SCOPE
  460. /*
  461.  * ===========================================================================
  462.  * $Log: bme.cpp,v $
  463.  * Revision 1000.1  2004/06/01 18:09:50  gouriano
  464.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.2
  465.  *
  466.  * Revision 1.2  2004/05/21 21:41:03  gorelenk
  467.  * Added PCH ncbi_pch.hpp
  468.  *
  469.  * Revision 1.1  2004/02/10 15:16:00  jcherry
  470.  * Initial version
  471.  *
  472.  * ===========================================================================
  473.  */