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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: gme.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 18:09:56  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.2
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: gme.cpp,v 1000.1 2004/06/01 18:09:56 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:  gme.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. /*from NNI.c*/
  54. void fillTableUp(meEdge *e, meEdge *f, double **A, double **D, meTree *T);
  55. /*from graph.c*/
  56. void updateSizes(meEdge *e, int direction);
  57. /*OLSint and OLSext use the average distance array to calculate weights
  58.   instead of using the meEdge average weight fields*/
  59. void OLSext(meEdge *e, double **A)
  60. {
  61.   meEdge *f, *g;
  62.   if(leaf(e->head))
  63.     {
  64.       f = siblingEdge(e);
  65.       e->distance = 0.5*(A[e->head->index][e->tail->index] 
  66.  + A[e->head->index][f->head->index]
  67.  - A[f->head->index][e->tail->index]);
  68.     }
  69.   else
  70.     {
  71.       f = e->head->leftEdge;
  72.       g = e->head->rightEdge;
  73.       e->distance = 0.5*(A[e->head->index][f->head->index]
  74.  + A[e->head->index][g->head->index]
  75.  - A[f->head->index][g->head->index]);
  76.     }
  77. }
  78. double wf(double lambda, double D_LR, double D_LU, double D_LD, 
  79.    double D_RU, double D_RD, double D_DU)
  80. {
  81.   double weight;
  82.   weight = 0.5*(lambda*(D_LU  + D_RD) + (1 -lambda)*(D_LD + D_RU)
  83. - (D_LR + D_DU));  
  84.   return(weight);
  85. }
  86. void OLSint(meEdge *e, double **A)
  87. {
  88.   double lambda;
  89.   meEdge *left, *right, *sib;
  90.   left = e->head->leftEdge;
  91.   right = e->head->rightEdge;
  92.   sib = siblingEdge(e);
  93.   lambda = ((double) sib->bottomsize*left->bottomsize + 
  94.     right->bottomsize*e->tail->parentEdge->topsize) /
  95.     (e->bottomsize*e->topsize);
  96.   e->distance = wf(lambda,A[left->head->index][right->head->index],
  97.    A[left->head->index][e->tail->index],
  98.    A[left->head->index][sib->head->index],
  99.    A[right->head->index][e->tail->index],
  100.    A[right->head->index][sib->head->index],
  101.    A[sib->head->index][e->tail->index]);
  102. }
  103. void assignOLSWeights(meTree *T, double **A)
  104. {
  105.   meEdge *e;
  106.   e = depthFirstTraverse(T,NULL);
  107.   while (NULL != e) {
  108.     if ((leaf(e->head)) || (leaf(e->tail)))
  109.       OLSext(e,A);
  110.     else
  111.       OLSint(e,A);
  112.     e = depthFirstTraverse(T,e);
  113.   }
  114. }      
  115. /*makes table of average distances from scratch*/
  116. void makeOLSAveragesTable(meTree *T, double **D, double **A)
  117. {
  118.   meEdge *e, *f, *g, *h;
  119.   meEdge *exclude;
  120.   e = f = NULL;
  121.   e = depthFirstTraverse(T,e);
  122.   while (NULL != e)
  123.     {
  124.       f = e;
  125.       exclude = e->tail->parentEdge;
  126.       /*we want to calculate A[e->head][f->head] for all edges
  127. except those edges which are ancestral to e.  For those
  128. edges, we will calculate A[e->head][f->head] to have a
  129. different meaning, later*/
  130.       if(leaf(e->head))
  131. while (NULL != f)
  132.   {
  133.     if (exclude != f)    
  134.       {
  135. if (leaf(f->head))
  136.   A[e->head->index][f->head->index] = A[f->head->index][e->head->index] = D[e->head->index2][f->head->index2];
  137. else
  138.   {
  139.     g = f->head->leftEdge;
  140.     h = f->head->rightEdge;
  141.     A[e->head->index][f->head->index] = A[f->head->index][e->head->index] = (g->bottomsize*A[e->head->index][g->head->index] + h->bottomsize*A[e->head->index][h->head->index])/f->bottomsize; 
  142.   }
  143.       }
  144.     else /*exclude == f*/
  145.       exclude = exclude->tail->parentEdge; 
  146.     f = depthFirstTraverse(T,f);
  147.   }
  148.       else 
  149. /*e->head is not a leaf, so we go recursively to values calculated for
  150.   the nodes below e*/
  151. while(NULL !=f )
  152.   {
  153.     if (exclude != f)       
  154.       {
  155. g = e->head->leftEdge;
  156. h = e->head->rightEdge;
  157. A[e->head->index][f->head->index] = A[f->head->index][e->head->index] = (g->bottomsize*A[f->head->index][g->head->index] + h->bottomsize*A[f->head->index][h->head->index])/e->bottomsize;
  158.       }
  159.     else
  160.       exclude = exclude->tail->parentEdge;
  161.     f = depthFirstTraverse(T,f);
  162.   }
  163.   /*now we move to fill up the rest of the table: we want
  164.     A[e->head->index][f->head->index] for those cases where e is an
  165.     ancestor of f, or vice versa.  We'll do this by choosing e via a
  166.     depth first-search, and the recursing for f up the path to the
  167.     root*/
  168.       f = e->tail->parentEdge;
  169.       if (NULL != f)
  170. fillTableUp(e,f,A,D,T);    
  171.       e = depthFirstTraverse(T,e);
  172.     } 
  173.   /*we are indexing this table by vertex indices, but really the
  174.     underlying object is the meEdge set.  Thus, the array is one element
  175.     too big in each direction, but we'll ignore the entries involving the root,
  176.     and instead refer to each meEdge by the head of that edge.  The head of
  177.     the root points to the meEdge ancestral to the rest of the tree, so
  178.     we'll keep track of up distances by pointing to that head*/
  179.   /*10/13/2001: collapsed three depth-first searces into 1*/
  180. }
  181. void GMEcalcDownAverage(meNode *v, meEdge *e, double **D, double **A)
  182. {
  183.   meEdge *left, *right;
  184.   if (leaf(e->head))
  185.     A[e->head->index][v->index] = D[v->index2][e->head->index2]; 
  186.   else
  187.     {
  188.       left = e->head->leftEdge;
  189.       right = e->head->rightEdge;
  190.       A[e->head->index][v->index] = 
  191. ( left->bottomsize * A[left->head->index][v->index] + 
  192.   right->bottomsize * A[right->head->index][v->index]) 
  193. / e->bottomsize;
  194.     }
  195. }
  196. void GMEcalcUpAverage(meNode *v, meEdge *e, double **D, double **A)
  197. {
  198.   meEdge *up, *down;
  199.   if (NULL == e->tail->parentEdge)
  200.     A[v->index][e->head->index] =  D[v->index2][e->tail->index2];
  201.   else
  202.     {
  203.       up = e->tail->parentEdge;
  204.       down = siblingEdge(e);
  205.       A[v->index][e->head->index] = 
  206. (up->topsize * A[v->index][up->head->index] + 
  207.  down->bottomsize * A[down->head->index][v->index])
  208. / e->topsize;
  209.       }
  210. }
  211. /*this function calculates average distance D_Xv for each X which is
  212.   a meSet of leaves of an induced submeTree of T*/
  213. void GMEcalcNewvAverages(meTree *T, meNode *v, double **D, double **A)
  214. {
  215.   /*loop over edges*/
  216.   /*depth-first search*/
  217.   meEdge *e;
  218.   e = NULL;
  219.   e = depthFirstTraverse(T,e);  /*the downward averages need to be
  220.   calculated from bottom to top */
  221.   while(NULL != e)
  222.     {
  223.       GMEcalcDownAverage(v,e,D,A);
  224.       e = depthFirstTraverse(T,e);
  225.     }
  226.   
  227.   e = topFirstTraverse(T,e);   /*the upward averages need to be calculated 
  228.  from top to bottom */
  229.   while(NULL != e)
  230.     {
  231.       GMEcalcUpAverage(v,e,D,A);
  232.       e = topFirstTraverse(T,e);
  233.     }
  234. }
  235. double wf4(double lambda, double lambda2, double D_AB, double D_AC, 
  236.    double D_BC, double D_Av, double D_Bv, double D_Cv)
  237. {
  238.   return(((1 - lambda) * (D_AC + D_Bv) + (lambda2 - 1)*(D_AB + D_Cv)
  239.  + (lambda - lambda2)*(D_BC + D_Av)));
  240. }
  241. /*testEdge cacluates what the OLS weight would be if v were inserted into
  242.   T along e.  Compare against known values for inserting along 
  243.   f = e->parentEdge */
  244. /*edges are tested by a top-first, left-first scheme. we presume
  245.   all distances are fixed to the correct weight for 
  246.   e->parentEdge, if e is a left-oriented edge*/
  247. void testEdge(meEdge *e, meNode *v, double **A)
  248. {
  249.   double lambda, lambda2;
  250.   meEdge *par, *sib;
  251.   sib = siblingEdge(e);
  252.   par = e->tail->parentEdge;
  253.   /*C is meSet above e->tail, B is meSet below e, and A is meSet below sib*/
  254.   /*following the nomenclature of Desper & Gascuel*/
  255.   lambda =  (((double) (sib->bottomsize + e->bottomsize*par->topsize))
  256.      / ((1 + par->topsize)*(par->bottomsize)));
  257.   lambda2 = (((double) (sib->bottomsize + e->bottomsize*par->topsize))
  258.      / ((1 + e->bottomsize)*(e->topsize)));
  259.   e->totalweight = par->totalweight 
  260.     + wf4(lambda,lambda2,A[e->head->index][sib->head->index],
  261.   A[sib->head->index][e->tail->index],
  262.   A[e->head->index][e->tail->index],
  263.   A[sib->head->index][v->index],A[e->head->index][v->index],
  264.   A[v->index][e->tail->index]);  
  265. }
  266. void printDoubleTable(double **A, int d)
  267. {
  268.   int i,j;
  269.   for(i=0;i<d;i++)
  270.     {
  271.       for(j=0;j<d;j++)
  272. printf("%lf ", A[i][j]);
  273.       printf("n");
  274.     }
  275. }
  276. void GMEsplitEdge(meTree *T, meNode *v, meEdge *e, double **A);
  277. meTree *GMEaddSpecies(meTree *T,meNode *v, double **D, double **A) 
  278.      /*the key function of the program addSpeices inserts
  279.        the meNode v to the meTree T.  It uses testEdge to see what the
  280.        weight would be if v split a particular edge.  Weights are assigned by
  281.        OLS formula*/
  282. {
  283.   meTree *T_e;
  284.   meEdge *e; /*loop variable*/
  285.   meEdge *e_min; /*points to best meEdge seen thus far*/
  286.   double w_min = 0.0;   /*used to keep track of meTree weights*/
  287.   if (verbose)
  288.     printf("Adding %s.n",v->label);
  289.  
  290.   /*initialize variables as necessary*/
  291.   /*CASE 1: T is empty, v is the first node*/
  292.   if (NULL == T)  /*create a meTree with v as only vertex, no edges*/
  293.     {
  294.       T_e = newTree();
  295.       T_e->root = v;  
  296.       /*note that we are rooting T arbitrarily at a leaf.  
  297. T->root is not the phylogenetic root*/
  298.       v->index = 0;
  299.       T_e->size = 1;
  300.       return(T_e);      
  301.     }
  302.   /*CASE 2: T is a single-vertex tree*/
  303.   if (1 == T->size)
  304. {
  305.   v->index = 1;
  306.   e = makeEdge("",T->root,v,0.0);
  307.   sprintf(e->label,"E1");
  308.   e->topsize = 1;
  309.   e->bottomsize = 1;
  310.   A[v->index][v->index] = D[v->index2][T->root->index2];
  311.   T->root->leftEdge = v->parentEdge = e;
  312.   T->size = 2;
  313.   return(T); 
  314. }
  315.   /*CASE 3: T has at least two nodes and an edge.  Insert new node
  316.     by breaking one of the edges*/
  317.   
  318.   v->index = T->size;
  319.   /*if (!(T->size % 100))
  320.     printf("T->size is %dn",T->size);*/
  321.   GMEcalcNewvAverages(T,v,D,A);
  322.   /*calcNewvAverges will assign values to all the meEdge averages of T which
  323.     include the meNode v.  Will do so using pre-existing averages in T and
  324.     information from A,D*/
  325.   e_min = T->root->leftEdge;  
  326.   e = e_min->head->leftEdge;  
  327.   while (NULL != e)
  328.     {
  329.       testEdge(e,v,A); 
  330.       /*testEdge tests weight of meTree if loop variable 
  331. e is the meEdge split, places this weight in e->totalweight field */
  332.       if (e->totalweight < w_min)
  333. {
  334.   e_min = e;
  335.   w_min = e->totalweight;
  336. }
  337.       e = topFirstTraverse(T,e);
  338.     }
  339.   /*e_min now points at the meEdge we want to split*/
  340.   GMEsplitEdge(T,v,e_min,A);
  341.   return(T);
  342. }
  343. void updateSubTreeAverages(double **A, meEdge *e, meNode *v, int direction);
  344. /*the ME version of updateAveragesMatrix does not update the entire matrix
  345.   A, but updates A[v->index][w->index] whenever this represents an average
  346.   of 1-distant or 2-distant subtrees*/
  347. void GMEupdateAveragesMatrix(double **A, meEdge *e, meNode *v, meNode *newNode)
  348. {
  349.   meEdge *sib, *par, *left, *right;
  350.   sib = siblingEdge(e);
  351.   left = e->head->leftEdge;
  352.   right = e->head->rightEdge;
  353.   par = e->tail->parentEdge;
  354.   /*we need to update the matrix A so all 1-distant, 2-distant, and
  355.     3-distant averages are correct*/
  356.   
  357.   /*first, initialize the newNode entries*/
  358.   /*1-distant*/
  359.   A[newNode->index][newNode->index] = 
  360.     (e->bottomsize*A[e->head->index][e->head->index]
  361.      + A[v->index][e->head->index])
  362.     / (e->bottomsize + 1);
  363.   /*1-distant for v*/
  364.   A[v->index][v->index] = 
  365.     (e->bottomsize*A[e->head->index][v->index] 
  366.      + e->topsize*A[v->index][e->head->index])
  367.     / (e->bottomsize + e->topsize);
  368.   /*2-distant for v,newNode*/
  369.   A[v->index][newNode->index] = A[newNode->index][v->index] = 
  370.     A[v->index][e->head->index];
  371.   
  372.   /*second 2-distant for newNode*/
  373.   A[newNode->index][e->tail->index] = A[e->tail->index][newNode->index]
  374.     = (e->bottomsize*A[e->head->index][e->tail->index]
  375.        + A[v->index][e->tail->index])/(e->bottomsize + 1);
  376.   /*third 2-distant for newNode*/
  377.   A[newNode->index][e->head->index] = A[e->head->index][newNode->index]
  378.     = A[e->head->index][e->head->index];
  379.    
  380.   if (NULL != sib)
  381.     {
  382.       /*fourth and last 2-distant for newNode*/
  383.       A[newNode->index][sib->head->index] =
  384. A[sib->head->index][newNode->index] = 
  385. (e->bottomsize*A[sib->head->index][e->head->index]
  386.  + A[sib->head->index][v->index]) / (e->bottomsize + 1);
  387.       updateSubTreeAverages(A,sib,v,SKEW); /*updates sib and below*/
  388.     }
  389.   if (NULL != par)
  390.     {
  391.       if (e->tail->leftEdge == e)
  392. updateSubTreeAverages(A,par,v,LEFT); /*updates par and above*/
  393.       else
  394. updateSubTreeAverages(A,par,v,RIGHT);
  395.     }
  396.   if (NULL != left)
  397.     updateSubTreeAverages(A,left,v,UP); /*updates left and below*/
  398.   if (NULL != right)
  399.     updateSubTreeAverages(A,right,v,UP); /*updates right and below*/  
  400.   /*1-dist for e->head*/
  401.   A[e->head->index][e->head->index] = 
  402.     (e->topsize*A[e->head->index][e->head->index]
  403.      + A[e->head->index][v->index]) / (e->topsize+1);
  404.   /*2-dist for e->head (v,newNode,left,right)
  405.     taken care of elsewhere*/
  406.   /*3-dist with e->head either taken care of elsewhere (below)
  407.     or unchanged (sib,e->tail)*/
  408.   
  409.   /*symmetrize the matrix (at least for distant-2 subtrees) */
  410.   A[v->index][e->head->index] = A[e->head->index][v->index];
  411.   /*and distant-3 subtrees*/
  412.   A[e->tail->index][v->index] = A[v->index][e->tail->index];
  413.   if (NULL != left)
  414.     A[v->index][left->head->index] = A[left->head->index][v->index];
  415.   if (NULL != right)
  416.     A[v->index][right->head->index] = A[right->head->index][v->index];
  417.   if (NULL != sib)
  418.     A[v->index][sib->head->index] = A[sib->head->index][v->index];
  419. }      
  420.   
  421. void GMEsplitEdge(meTree *T, meNode *v, meEdge *e, double **A)
  422. {
  423.   char nodelabel[NODE_LABEL_LENGTH];
  424.   char edgelabel[EDGE_LABEL_LENGTH];
  425.   meEdge *newPendantEdge;
  426.   meEdge *newInternalEdge;
  427.   meNode *newNode;
  428.     
  429.   sprintf(nodelabel,"I%d",T->size+1); 
  430.   newNode = makeNewNode(nodelabel,T->size + 1);  
  431.   
  432.   sprintf(edgelabel,"E%d",T->size); 
  433.   newPendantEdge = makeEdge(edgelabel,newNode,v,0.0);   
  434.   
  435.   sprintf(edgelabel,"E%d",T->size+1); 
  436.   newInternalEdge = makeEdge(edgelabel,newNode,e->head,0.0);   
  437.   
  438.   if (verbose)
  439.     printf("Inserting meNode %s on meEdge %s between nodes %s and %s.n",
  440.    v->label,e->label,e->tail->label,e->head->label); 
  441.   /*update the matrix of average distances*/
  442.   /*also updates the bottomsize, topsize fields*/
  443.   
  444.   GMEupdateAveragesMatrix(A,e,v,newNode);
  445.   newNode->parentEdge = e;
  446.   e->head->parentEdge = newInternalEdge;
  447.   v->parentEdge = newPendantEdge;
  448.   e->head = newNode;
  449.   
  450.   T->size = T->size + 2;
  451.   if (e->tail->leftEdge == e) 
  452.     {
  453.       newNode->leftEdge = newInternalEdge;
  454.       newNode->rightEdge = newPendantEdge;
  455.     }
  456.   else
  457.     {
  458.       newNode->leftEdge = newInternalEdge;
  459.       newNode->rightEdge = newPendantEdge;
  460.     }
  461.   
  462.   /*assign proper topsize, bottomsize values to the two new Edges*/
  463.   
  464.   newPendantEdge->bottomsize = 1; 
  465.   newPendantEdge->topsize = e->bottomsize + e->topsize;
  466.   
  467.   newInternalEdge->bottomsize = e->bottomsize;
  468.   newInternalEdge->topsize = e->topsize;  /*off by one, but we adjust
  469.     that below*/
  470.   
  471.   /*and increment these fields for all other edges*/
  472.   updateSizes(newInternalEdge,UP);
  473.   updateSizes(e,DOWN);
  474. }
  475. void updateSubTreeAverages(double **A, meEdge *e, meNode *v, int direction)
  476.      /*the monster function of this program*/
  477. {
  478.   meEdge *sib, *left, *right, *par;
  479.   left = e->head->leftEdge;
  480.   right = e->head->rightEdge;
  481.   sib = siblingEdge(e);
  482.   par = e->tail->parentEdge;
  483.   switch(direction)
  484.     {
  485.       /*want to preserve correctness of 
  486. all 1-distant, 2-distant, and 3-distant averages*/
  487.       /*1-distant updated at meEdge splitting the two trees*/
  488.       /*2-distant updated:
  489. (left->head,right->head) and (head,tail) updated at
  490. a given edge.  Note, NOT updating (head,sib->head)!
  491. (That would lead to multiple updating).*/
  492.       /*3-distant updated: at meEdge in center of quartet*/
  493.     case UP: /*point of insertion is above e*/
  494.       /*1-distant average of nodes below e to 
  495.        nodes above e*/
  496.       A[e->head->index][e->head->index] = 
  497. (e->topsize*A[e->head->index][e->head->index] + 
  498.  A[e->head->index][v->index])/(e->topsize + 1);      
  499.       /*2-distant average of nodes below e to 
  500. nodes above parent of e*/
  501.       A[e->head->index][par->head->index] = 
  502. A[par->head->index][e->head->index] = 
  503. (par->topsize*A[par->head->index][e->head->index]
  504.  + A[e->head->index][v->index]) / (par->topsize + 1);
  505.       /*must do both 3-distant averages involving par*/
  506.       if (NULL != left)
  507. {
  508.   updateSubTreeAverages(A, left, v, UP); /*and recursive call*/
  509.   /*3-distant average*/
  510.   A[par->head->index][left->head->index]
  511.     = A[left->head->index][par->head->index]
  512.     = (par->topsize*A[par->head->index][left->head->index]
  513.        + A[left->head->index][v->index]) / (par->topsize + 1);
  514. }
  515.       if (NULL != right)
  516. {
  517.   updateSubTreeAverages(A, right, v, UP);
  518.   A[par->head->index][right->head->index]
  519.     = A[right->head->index][par->head->index]
  520.     = (par->topsize*A[par->head->index][right->head->index]
  521.        + A[right->head->index][v->index]) / (par->topsize + 1);
  522. }
  523.       break;
  524.     case SKEW: /*point of insertion is skew to e*/
  525.       /*1-distant average of nodes below e to 
  526. nodes above e*/
  527.       A[e->head->index][e->head->index] = 
  528. (e->topsize*A[e->head->index][e->head->index] + 
  529.  A[e->head->index][v->index])/(e->topsize + 1);      
  530.       /*no 2-distant averages to update in this case*/
  531.       /*updating 3-distant averages involving sib*/
  532.       if (NULL != left)
  533. {
  534.   updateSubTreeAverages(A, left, v, UP);
  535.   A[sib->head->index][left->head->index]
  536.     = A[left->head->index][sib->head->index]
  537.     = (sib->bottomsize*A[sib->head->index][left->head->index]
  538.        + A[left->head->index][v->index]) / (sib->bottomsize + 1);
  539. }
  540.       if (NULL != right)
  541. {
  542.   updateSubTreeAverages(A, right, v, UP);
  543.   A[sib->head->index][right->head->index]
  544.     = A[right->head->index][sib->head->index]
  545.     = (sib->bottomsize*A[par->head->index][right->head->index]
  546.        + A[right->head->index][v->index]) / (sib->bottomsize + 1);
  547. }
  548.       break;
  549.     case LEFT: /*point of insertion is below the meEdge left*/
  550.       /*1-distant average*/
  551.       A[e->head->index][e->head->index] = 
  552. (e->bottomsize*A[e->head->index][e->head->index] + 
  553.  A[v->index][e->head->index])/(e->bottomsize + 1);        
  554.       /*2-distant averages*/
  555.       A[e->head->index][e->tail->index] = 
  556. A[e->tail->index][e->head->index] = 
  557. (e->bottomsize*A[e->head->index][e->tail->index] + 
  558.  A[v->index][e->tail->index])/(e->bottomsize + 1);  
  559.       A[left->head->index][right->head->index] = 
  560. A[right->head->index][left->head->index] = 
  561. (left->bottomsize*A[right->head->index][left->head->index]
  562.  + A[right->head->index][v->index]) / (left->bottomsize+1);
  563.       /*3-distant avereages involving left*/
  564.       if (NULL != sib)
  565. {
  566.   updateSubTreeAverages(A, sib, v, SKEW);
  567.   A[left->head->index][sib->head->index]
  568.     = A[sib->head->index][left->head->index]
  569.     = (left->bottomsize*A[left->head->index][sib->head->index]
  570.        + A[sib->head->index][v->index]) / (left->bottomsize + 1);
  571. }
  572.       if (NULL != par)
  573. {
  574.   if (e->tail->leftEdge == e)
  575.     updateSubTreeAverages(A, par, v, LEFT);
  576.   else
  577.     updateSubTreeAverages(A, par, v, RIGHT);
  578.   A[left->head->index][par->head->index]
  579.     = A[par->head->index][left->head->index]
  580.     = (left->bottomsize*A[left->head->index][par->head->index]
  581.        + A[v->index][par->head->index]) / (left->bottomsize + 1);
  582. }
  583.       break;    
  584.     case RIGHT: /*point of insertion is below the meEdge right*/
  585.       /*1-distant average*/
  586.       A[e->head->index][e->head->index] = 
  587. (e->bottomsize*A[e->head->index][e->head->index] + 
  588.  A[v->index][e->head->index])/(e->bottomsize + 1);        
  589.       /*2-distant averages*/
  590.       A[e->head->index][e->tail->index] = 
  591. A[e->tail->index][e->head->index] = 
  592. (e->bottomsize*A[e->head->index][e->tail->index] + 
  593.  A[v->index][e->tail->index])/(e->bottomsize + 1);  
  594.       A[left->head->index][right->head->index] = 
  595. A[right->head->index][left->head->index] = 
  596. (right->bottomsize*A[right->head->index][left->head->index]
  597.  + A[left->head->index][v->index]) / (right->bottomsize+1);
  598.       /*3-distant avereages involving right*/
  599.       if (NULL != sib)
  600. {
  601.   updateSubTreeAverages(A, sib, v, SKEW);
  602.   A[right->head->index][sib->head->index]
  603.     = A[sib->head->index][right->head->index]
  604.     = (right->bottomsize*A[right->head->index][sib->head->index]
  605.        + A[sib->head->index][v->index]) / (right->bottomsize + 1);
  606. }
  607.       if (NULL != par)
  608. {
  609.   if (e->tail->leftEdge == e)
  610.     updateSubTreeAverages(A, par, v, LEFT);
  611.   else
  612.     updateSubTreeAverages(A, par, v, RIGHT);
  613.   A[right->head->index][par->head->index]
  614.     = A[par->head->index][right->head->index]
  615.     = (right->bottomsize*A[right->head->index][par->head->index]
  616.        + A[v->index][par->head->index]) / (right->bottomsize + 1);
  617. }
  618.       break;
  619.     }
  620. }
  621. void assignBottomsize(meEdge *e)
  622. {
  623.   if (leaf(e->head))
  624.     e->bottomsize = 1;
  625.   else
  626.     {
  627.       assignBottomsize(e->head->leftEdge);
  628.       assignBottomsize(e->head->rightEdge);
  629.       e->bottomsize = e->head->leftEdge->bottomsize
  630. + e->head->rightEdge->bottomsize;
  631.     }
  632. }
  633. void assignTopsize(meEdge *e, int numLeaves)
  634. {
  635.   if (NULL != e)
  636.     {
  637.       e->topsize = numLeaves - e->bottomsize;
  638.       assignTopsize(e->head->leftEdge,numLeaves);
  639.       assignTopsize(e->head->rightEdge,numLeaves);
  640.     }
  641. }
  642. void assignAllSizeFields(meTree *T)
  643. {
  644.   assignBottomsize(T->root->leftEdge);
  645.   assignTopsize(T->root->leftEdge,T->size/2 + 1);
  646. }
  647. END_SCOPE(fastme)
  648. END_NCBI_SCOPE
  649. /*
  650.  * ===========================================================================
  651.  * $Log: gme.cpp,v $
  652.  * Revision 1000.1  2004/06/01 18:09:56  gouriano
  653.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.2
  654.  *
  655.  * Revision 1.2  2004/05/21 21:41:03  gorelenk
  656.  * Added PCH ncbi_pch.hpp
  657.  *
  658.  * Revision 1.1  2004/02/10 15:16:02  jcherry
  659.  * Initial version
  660.  *
  661.  * ===========================================================================
  662.  */