/* \input cnoweb Program: weighbor \hfill\break File: calcb.c \hfill\break Author: N. D. Socci \hfill\break Created: 6-Feb-97 \hfill\break \title{calcb.c} \job{Weighbor} Calculate the $b_{i;j}$ matrix. */ /*__* *__* *__* WEIGHBOR 1.2 [21-Jun-01] *__* *__* Copyright (c) 1997-2001 *__* Los Alamos National Laboratories *__* The Rockefeller University *__* *__* This file is part of the WEIGHBOR program that can be used free of *__* charge in academic research and teaching. Any commercial use of *__* this software requires prior permission and possibly a license. For *__* commercial use contact: W. Bruno at billb@t10.lanl.gov Los Alamos *__* National Laboratories makes no representations about the *__* suitability of this software for any purpose. It is provided *__* "as is" without express or implied warranty *__* *__* For those using this program for research please use the following *__* citation for this program: *__* *__* Bruno, W. J., Socci, N. D. and Halpern, A. L., ``Weighted *__* Neighbor Joining: A Fast Approximation to Maximum-Likelihood *__* Phylogeny Reconstruction,'' Molecular Biology and Evolution, *__* 17(1): 189-197, (2000). *__* *__* *__*/ #include #include #include "tree.h" #include "matrix.h" #include "weighbor.h" #include static char version[] __attribute__ ((unused)) = "$Id: calcb.c,v 1.7 2001/07/04 01:38:53 nds Exp $"; /* \section{calc_b} Calculate the $b_{i;j}$ matrix eq 0.7 and also calculate and return $\Delta b_{ij}$ (eq 0.8), $s_{ij}$ (eq 0.9), and the new terms; $\Delta^2b_{ij}$ (eq 0.14), and $\overline{\sigma^2_{ij}}$ (eq 0.15) */ void calc_b(int N, MatrixT b, MatrixT deltaB, MatrixT delta2B, MatrixT s) { int i, j, k; if(printLevel>3) fprintf(outfile, "Previous pair (%d,%d)-->%d\n", ta, tb, tc); for(i=0;i0.0); } } } /* #ifndef HASH1 */ else { /* We have already calculated $s_{ij}$ for this $(i,j)$ pair. So now just update by subtracting out the previously joined pair (\|ta|,\|tb|) and adding in the new taxon \|tc|. */ double weighta=1.0/(sigma2_3(i,ta,j) +sigma2_3(j,ta,i)+EPSILON); double weightb=1.0/(sigma2_3(i,tb,j) +sigma2_3(j,tb,i)+EPSILON); double weightc=1.0/(sigma2_3(i,tc,j) +sigma2_3(j,tc,i)+EPSILON); s[i][j] = S(i,j) - weighta - weightb + weightc; deltaB[i][j] = DelB(i,j) - weighta*(D(i,ta)-D(j,ta)) - weightb*(D(i,tb)-D(j,tb)) + weightc*(D(i,tc)-D(j,tc)); delta2B[i][j] = Del2B(i,j) - weighta*(D(i,ta)-D(j,ta))*(D(i,ta)-D(j,ta)) - weightb*(D(i,tb)-D(j,tb))*(D(i,tb)-D(j,tb)) + weightc*(D(i,tc)-D(j,tc))*(D(i,tc)-D(j,tc)); } /* #endif */ /* assert(s[i][j]>0) assert( s[i][j]*delta2B[i][j] > -1) */ if(s[i][j] <= 0 || delta2B[i][j] <= -1) { fprintf(stderr, "%s::%d\n", __FILE__, __LINE__); fprintf(stderr, "Round off error in the calculation\n"); fprintf(stderr, "of s_ij and/or delta^2B_ij. Can\n"); fprintf(stderr, "not use the N^3 version of\n"); fprintf(stderr, "weighbor for this tree\n"); exit(1); } } for(i=0;i2) { fprintf(outfile,"Delta b_{ij}=\n"); for(i=0;i= fabs(deltaB[i][j]) ) b[i][j] = (deltaB[i][j] + D(i,j))/2.0; else if( D(i,j) < -deltaB[i][j] ) b[i][j] = 0.0; else b[i][j] = D(i,j); } } /* \section{\|recalc_b|} Redo the calculation of $b_{i;j}$ (eq 0.7) $\Delta b_{ij}$ (eq 0.8), $s_{ij}$ (eq 0.9), $\Delta^2b_{ij}$ (eq 0.14) using the new $\sigma^{2'}_{ij;k}$ and the old values of $\Delta b_{ij}$. */ void recalc_b(int N, MatrixT b, MatrixT deltaB, MatrixT delta2B, MatrixT s) { int i, j, k; MatrixT old_deltaB = matrix(N); /* Tmp matrix to hold old values of $\delta b_{ij}$ */ setMM(N, deltaB, old_deltaB); for(i=0;i0.0); } } deltaB[i][j] /= s[i][j]; delta2B[i][j] /= s[i][j]; } } if(printLevel>2) { fprintf(outfile,"Delta b_{ij}=\n"); for(i=0;i= fabs(deltaB[i][j]) ) b[i][j] = (deltaB[i][j] + D(i,j))/2.0; else if( D(i,j) < -deltaB[i][j] ) b[i][j] = 0.0; else b[i][j] = D(i,j); } freeMatrix(old_deltaB); } /* \endc */