bpp-phyl  2.1.0
Bpp/Phyl/Likelihood/RHomogeneousTreeLikelihood.cpp
Go to the documentation of this file.
00001 //
00002 // File: RHomogeneousTreeLikelihood.cpp
00003 // Created by: Julien Dutheil
00004 // Created on: Fri Oct 17 18:14:51 2003
00005 //
00006 
00007 /*
00008    Copyright or © or Copr. Bio++ Development Team, (November 16, 2004)
00009 
00010    This software is a computer program whose purpose is to provide classes
00011    for phylogenetic data analysis.
00012 
00013    This software is governed by the CeCILL  license under French law and
00014    abiding by the rules of distribution of free software.  You can  use,
00015    modify and/ or redistribute the software under the terms of the CeCILL
00016    license as circulated by CEA, CNRS and INRIA at the following URL
00017    "http://www.cecill.info".
00018 
00019    As a counterpart to the access to the source code and  rights to copy,
00020    modify and redistribute granted by the license, users are provided only
00021    with a limited warranty  and the software's author,  the holder of the
00022    economic rights,  and the successive licensors  have only  limited
00023    liability.
00024 
00025    In this respect, the user's attention is drawn to the risks associated
00026    with loading,  using,  modifying and/or developing or reproducing the
00027    software by the user in light of its specific status of free software,
00028    that may mean  that it is complicated to manipulate,  and  that  also
00029    therefore means  that it is reserved for developers  and  experienced
00030    professionals having in-depth computer knowledge. Users are therefore
00031    encouraged to load and test the software's suitability as regards their
00032    requirements in conditions enabling the security of their systems and/or
00033    data to be ensured and,  more generally, to use and operate it in the
00034    same conditions as regards security.
00035 
00036    The fact that you are presently reading this means that you have had
00037    knowledge of the CeCILL license and that you accept its terms.
00038  */
00039 
00040 #include "RHomogeneousTreeLikelihood.h"
00041 #include "../PatternTools.h"
00042 
00043 #include <Bpp/Text/TextTools.h>
00044 #include <Bpp/App/ApplicationTools.h>
00045 
00046 using namespace bpp;
00047 
00048 // From the STL:
00049 #include <iostream>
00050 
00051 using namespace std;
00052 
00053 /******************************************************************************/
00054 
00055 RHomogeneousTreeLikelihood::RHomogeneousTreeLikelihood(
00056   const Tree& tree,
00057   SubstitutionModel* model,
00058   DiscreteDistribution* rDist,
00059   bool checkRooted,
00060   bool verbose,
00061   bool usePatterns)
00062 throw (Exception) :
00063   AbstractHomogeneousTreeLikelihood(tree, model, rDist, checkRooted, verbose),
00064   likelihoodData_(0),
00065   minusLogLik_(-1.)
00066 {
00067   init_(usePatterns);
00068 }
00069 
00070 /******************************************************************************/
00071 
00072 RHomogeneousTreeLikelihood::RHomogeneousTreeLikelihood(
00073   const Tree& tree,
00074   const SiteContainer& data,
00075   SubstitutionModel* model,
00076   DiscreteDistribution* rDist,
00077   bool checkRooted,
00078   bool verbose,
00079   bool usePatterns)
00080 throw (Exception) :
00081   AbstractHomogeneousTreeLikelihood(tree, model, rDist, checkRooted, verbose),
00082   likelihoodData_(0),
00083   minusLogLik_(-1.)
00084 {
00085   init_(usePatterns);
00086   setData(data);
00087 }
00088 
00089 /******************************************************************************/
00090 
00091 void RHomogeneousTreeLikelihood::init_(bool usePatterns) throw (Exception)
00092 {
00093   likelihoodData_ = new DRASRTreeLikelihoodData(
00094     tree_,
00095     rateDistribution_->getNumberOfCategories(),
00096     usePatterns);
00097 }
00098 
00099 /******************************************************************************/
00100 
00101 RHomogeneousTreeLikelihood::RHomogeneousTreeLikelihood(
00102   const RHomogeneousTreeLikelihood& lik) :
00103   AbstractHomogeneousTreeLikelihood(lik),
00104   likelihoodData_(0),
00105   minusLogLik_(lik.minusLogLik_)
00106 {
00107   likelihoodData_ = dynamic_cast<DRASRTreeLikelihoodData*>(lik.likelihoodData_->clone());
00108   likelihoodData_->setTree(tree_);
00109 }
00110 
00111 /******************************************************************************/
00112 
00113 RHomogeneousTreeLikelihood& RHomogeneousTreeLikelihood::operator=(
00114   const RHomogeneousTreeLikelihood& lik)
00115 {
00116   AbstractHomogeneousTreeLikelihood::operator=(lik);
00117   if (likelihoodData_) delete likelihoodData_;
00118   likelihoodData_ = dynamic_cast<DRASRTreeLikelihoodData*>(lik.likelihoodData_->clone());
00119   likelihoodData_->setTree(tree_);
00120   minusLogLik_ = lik.minusLogLik_;
00121   return *this;
00122 }
00123 
00124 /******************************************************************************/
00125 
00126 RHomogeneousTreeLikelihood::~RHomogeneousTreeLikelihood()
00127 {
00128   delete likelihoodData_;
00129 }
00130 
00131 /******************************************************************************/
00132 
00133 void RHomogeneousTreeLikelihood::setData(const SiteContainer& sites) throw (Exception)
00134 {
00135   if (data_) delete data_;
00136   data_ = PatternTools::getSequenceSubset(sites, *tree_->getRootNode());
00137   if (verbose_) ApplicationTools::displayTask("Initializing data structure");
00138   likelihoodData_->initLikelihoods(*data_, *model_);
00139   if (verbose_) ApplicationTools::displayTaskDone();
00140 
00141   nbSites_ = likelihoodData_->getNumberOfSites();
00142   nbDistinctSites_ = likelihoodData_->getNumberOfDistinctSites();
00143   nbStates_ = likelihoodData_->getNumberOfStates();
00144 
00145   if (verbose_) ApplicationTools::displayResult("Number of distinct sites",
00146                                                 TextTools::toString(nbDistinctSites_));
00147   initialized_ = false;
00148 }
00149 
00150 /******************************************************************************/
00151 
00152 double RHomogeneousTreeLikelihood::getLikelihood() const
00153 {
00154   double l = 1.;
00155   for (size_t i = 0; i < nbSites_; i++)
00156   {
00157     l *= getLikelihoodForASite(i);
00158   }
00159   return l;
00160 }
00161 
00162 /******************************************************************************/
00163 
00164 double RHomogeneousTreeLikelihood::getLogLikelihood() const
00165 {
00166   double ll = 0;
00167   vector<double> la(nbSites_);
00168   for (size_t i = 0; i < nbSites_; i++)
00169   {
00170     la[i] = getLogLikelihoodForASite(i);
00171   }
00172   sort(la.begin(), la.end());
00173   for (size_t i = nbSites_; i > 0; i--)
00174   {
00175     ll += la[i - 1];
00176   }
00177   return ll;
00178 }
00179 
00180 /******************************************************************************/
00181 
00182 double RHomogeneousTreeLikelihood::getLikelihoodForASite(size_t site) const
00183 {
00184   double l = 0;
00185   for (size_t i = 0; i < nbClasses_; i++)
00186   {
00187     l += getLikelihoodForASiteForARateClass(site, i) * rateDistribution_->getProbability(i);
00188   }
00189   return l;
00190 }
00191 
00192 /******************************************************************************/
00193 
00194 double RHomogeneousTreeLikelihood::getLogLikelihoodForASite(size_t site) const
00195 {
00196   double l = 0;
00197   for (size_t i = 0; i < nbClasses_; i++)
00198   {
00199     double li = getLikelihoodForASiteForARateClass(site, i) * rateDistribution_->getProbability(i);
00200     if (li > 0) l+= li; //Corrects for numerical instabilities leading to slightly negative likelihoods
00201   }
00202   return log(l);
00203 }
00204 
00205 /******************************************************************************/
00206 
00207 double RHomogeneousTreeLikelihood::getLikelihoodForASiteForARateClass(size_t site, size_t rateClass) const
00208 {
00209   double l = 0;
00210   Vdouble* la = &likelihoodData_->getLikelihoodArray(tree_->getRootNode()->getId())[likelihoodData_->getRootArrayPosition(site)][rateClass];
00211   for (size_t i = 0; i < nbStates_; i++)
00212   {
00213     //cout << (*la)[i] << "\t" << rootFreqs_[i] << endl;
00214     double li = (*la)[i] * rootFreqs_[i];
00215     if (li > 0) l+= li; //Corrects for numerical instabilities leading to slightly negative likelihoods
00216   }
00217   return l;
00218 }
00219 
00220 /******************************************************************************/
00221 
00222 double RHomogeneousTreeLikelihood::getLogLikelihoodForASiteForARateClass(size_t site, size_t rateClass) const
00223 {
00224   double l = 0;
00225   Vdouble* la = &likelihoodData_->getLikelihoodArray(tree_->getRootNode()->getId())[likelihoodData_->getRootArrayPosition(site)][rateClass];
00226   for (size_t i = 0; i < nbStates_; i++)
00227   {
00228     l += (*la)[i] * rootFreqs_[i];
00229   }
00230   //if(l <= 0.) cerr << "WARNING!!! Negative likelihood." << endl;
00231   return log(l);
00232 }
00233 
00234 /******************************************************************************/
00235 
00236 double RHomogeneousTreeLikelihood::getLikelihoodForASiteForARateClassForAState(size_t site, size_t rateClass, int state) const
00237 {
00238   return likelihoodData_->getLikelihoodArray(tree_->getRootNode()->getId())[likelihoodData_->getRootArrayPosition(site)][rateClass][state];
00239 }
00240 
00241 /******************************************************************************/
00242 
00243 double RHomogeneousTreeLikelihood::getLogLikelihoodForASiteForARateClassForAState(size_t site, size_t rateClass, int state) const
00244 {
00245   return log(likelihoodData_->getLikelihoodArray(tree_->getRootNode()->getId())[likelihoodData_->getRootArrayPosition(site)][rateClass][state]);
00246 }
00247 
00248 /******************************************************************************/
00249 
00250 void RHomogeneousTreeLikelihood::setParameters(const ParameterList& parameters)
00251 throw (ParameterNotFoundException, ConstraintException)
00252 {
00253   setParametersValues(parameters);
00254 }
00255 
00256 /******************************************************************************/
00257 
00258 void RHomogeneousTreeLikelihood::fireParameterChanged(const ParameterList& params)
00259 {
00260   applyParameters();
00261 
00262   if (rateDistribution_->getParameters().getCommonParametersWith(params).size() > 0
00263       || model_->getParameters().getCommonParametersWith(params).size() > 0)
00264   {
00265     //Rate parameter changed, need to recompute all probs:
00266     computeAllTransitionProbabilities();
00267   }
00268   else if (params.size() > 0)
00269   {
00270     //We may save some computations:
00271     for (size_t i = 0; i < params.size(); i++)
00272     {
00273       string s = params[i].getName();
00274       if (s.substr(0, 5) == "BrLen")
00275       {
00276         //Branch length parameter:
00277         computeTransitionProbabilitiesForNode(nodes_[TextTools::to<size_t>(s.substr(5))]);
00278       }
00279     }
00280     rootFreqs_ = model_->getFrequencies();
00281   }
00282 
00283   computeTreeLikelihood();
00284 
00285   minusLogLik_ = -getLogLikelihood();
00286 }
00287 
00288 /******************************************************************************/
00289 
00290 double RHomogeneousTreeLikelihood::getValue() const
00291 throw (Exception)
00292 {
00293   if (!isInitialized()) throw Exception("RHomogeneousTreeLikelihood::getValue(). Instance is not initialized.");
00294   return minusLogLik_;
00295 }
00296 
00297 /******************************************************************************
00298 *                           First Order Derivatives                          *
00299 ******************************************************************************/
00300 
00301 double RHomogeneousTreeLikelihood::getDLikelihoodForASiteForARateClass(
00302   size_t site,
00303   size_t rateClass) const
00304 {
00305   double dl = 0;
00306   Vdouble* dla = &likelihoodData_->getDLikelihoodArray(tree_->getRootNode()->getId())[likelihoodData_->getRootArrayPosition(site)][rateClass];
00307   for (size_t i = 0; i < nbStates_; i++)
00308   {
00309     dl += (*dla)[i] * rootFreqs_[i];
00310   }
00311   return dl;
00312 }
00313 
00314 /******************************************************************************/
00315 
00316 double RHomogeneousTreeLikelihood::getDLikelihoodForASite(size_t site) const
00317 {
00318   // Derivative of the sum is the sum of derivatives:
00319   double dl = 0;
00320   for (size_t i = 0; i < nbClasses_; i++)
00321   {
00322     dl += getDLikelihoodForASiteForARateClass(site, i) * rateDistribution_->getProbability(i);
00323   }
00324   return dl;
00325 }
00326 
00327 /******************************************************************************/
00328 
00329 double RHomogeneousTreeLikelihood::getDLogLikelihoodForASite(size_t site) const
00330 {
00331   // d(f(g(x)))/dx = dg(x)/dx . df(g(x))/dg :
00332   return getDLikelihoodForASite(site) / getLikelihoodForASite(site);
00333 }
00334 
00335 /******************************************************************************/
00336 
00337 double RHomogeneousTreeLikelihood::getDLogLikelihood() const
00338 {
00339   // Derivative of the sum is the sum of derivatives:
00340   double dl = 0;
00341   for (size_t i = 0; i < nbSites_; i++)
00342   {
00343     dl += getDLogLikelihoodForASite(i);
00344   }
00345   return dl;
00346 }
00347 
00348 /******************************************************************************/
00349 
00350 double RHomogeneousTreeLikelihood::getFirstOrderDerivative(const string& variable) const
00351 throw (Exception)
00352 {
00353   if (!hasParameter(variable))
00354     throw ParameterNotFoundException("RHomogeneousTreeLikelihood::getFirstOrderDerivative().", variable);
00355   if (getRateDistributionParameters().hasParameter(variable))
00356   {
00357     throw Exception("Derivatives respective to rate distribution parameter are not implemented.");
00358   }
00359   if (getSubstitutionModelParameters().hasParameter(variable))
00360   {
00361     throw Exception("Derivatives respective to substitution model parameters are not implemented.");
00362   }
00363 
00364   const_cast<RHomogeneousTreeLikelihood*>(this)->computeTreeDLikelihood(variable);
00365   return -getDLogLikelihood();
00366 }
00367 
00368 /******************************************************************************/
00369 
00370 void RHomogeneousTreeLikelihood::computeTreeDLikelihood(const string& variable)
00371 {
00372   // Get the node with the branch whose length must be derivated:
00373   size_t brI = TextTools::to<size_t>(variable.substr(5));
00374   const Node* branch = nodes_[brI];
00375   const Node* father = branch->getFather();
00376   VVVdouble* _dLikelihoods_father = &likelihoodData_->getDLikelihoodArray(father->getId());
00377 
00378   // Compute dLikelihoods array for the father node.
00379   // Fist initialize to 1:
00380   size_t nbSites  = _dLikelihoods_father->size();
00381   for (size_t i = 0; i < nbSites; i++)
00382   {
00383     VVdouble* _dLikelihoods_father_i = &(*_dLikelihoods_father)[i];
00384     for (size_t c = 0; c < nbClasses_; c++)
00385     {
00386       Vdouble* _dLikelihoods_father_i_c = &(*_dLikelihoods_father_i)[c];
00387       for (size_t s = 0; s < nbStates_; s++)
00388       {
00389         (*_dLikelihoods_father_i_c)[s] = 1.;
00390       }
00391     }
00392   }
00393 
00394   size_t nbNodes = father->getNumberOfSons();
00395   for (size_t l = 0; l < nbNodes; l++)
00396   {
00397     const Node* son = father->getSon(l);
00398 
00399     vector<size_t> * _patternLinks_father_son = &likelihoodData_->getArrayPositions(father->getId(), son->getId());
00400     VVVdouble* _likelihoods_son = &likelihoodData_->getLikelihoodArray(son->getId());
00401 
00402     if (son == branch)
00403     {
00404       VVVdouble* dpxy__son = &dpxy_[son->getId()];
00405       for (size_t i = 0; i < nbSites; i++)
00406       {
00407         VVdouble* _likelihoods_son_i = &(*_likelihoods_son)[(*_patternLinks_father_son)[i]];
00408         VVdouble* _dLikelihoods_father_i = &(*_dLikelihoods_father)[i];
00409         for (size_t c = 0; c < nbClasses_; c++)
00410         {
00411           Vdouble* _likelihoods_son_i_c = &(*_likelihoods_son_i)[c];
00412           Vdouble* _dLikelihoods_father_i_c = &(*_dLikelihoods_father_i)[c];
00413           VVdouble* dpxy__son_c = &(*dpxy__son)[c];
00414           for (size_t x = 0; x < nbStates_; x++)
00415           {
00416             double dl = 0;
00417             Vdouble* dpxy__son_c_x = &(*dpxy__son_c)[x];
00418             for (size_t y = 0; y < nbStates_; y++)
00419             {
00420               dl += (*dpxy__son_c_x)[y] * (*_likelihoods_son_i_c)[y];
00421             }
00422             (*_dLikelihoods_father_i_c)[x] *= dl;
00423           }
00424         }
00425       }
00426     }
00427     else
00428     {
00429       VVVdouble* pxy__son = &pxy_[son->getId()];
00430       for (size_t i = 0; i < nbSites; i++)
00431       {
00432         VVdouble* _likelihoods_son_i = &(*_likelihoods_son)[(*_patternLinks_father_son)[i]];
00433         VVdouble* _dLikelihoods_father_i = &(*_dLikelihoods_father)[i];
00434         for (size_t c = 0; c < nbClasses_; c++)
00435         {
00436           Vdouble* _likelihoods_son_i_c = &(*_likelihoods_son_i)[c];
00437           Vdouble* _dLikelihoods_father_i_c = &(*_dLikelihoods_father_i)[c];
00438           VVdouble* pxy__son_c = &(*pxy__son)[c];
00439           for (size_t x = 0; x < nbStates_; x++)
00440           {
00441             double dl = 0;
00442             Vdouble* pxy__son_c_x = &(*pxy__son_c)[x];
00443             for (size_t y = 0; y < nbStates_; y++)
00444             {
00445               dl += (*pxy__son_c_x)[y] * (*_likelihoods_son_i_c)[y];
00446             }
00447             (*_dLikelihoods_father_i_c)[x] *= dl;
00448           }
00449         }
00450       }
00451     }
00452   }
00453 
00454   // Now we go down the tree toward the root node:
00455   computeDownSubtreeDLikelihood(father);
00456 }
00457 
00458 /******************************************************************************/
00459 
00460 void RHomogeneousTreeLikelihood::computeDownSubtreeDLikelihood(const Node* node)
00461 {
00462   const Node* father = node->getFather();
00463   // We assume that the _dLikelihoods array has been filled for the current node 'node'.
00464   // We will evaluate the array for the father node.
00465   if (father == NULL) return; // We reached the root!
00466 
00467   // Compute dLikelihoods array for the father node.
00468   // Fist initialize to 1:
00469   VVVdouble* _dLikelihoods_father = &likelihoodData_->getDLikelihoodArray(father->getId());
00470   size_t nbSites  = _dLikelihoods_father->size();
00471   for (size_t i = 0; i < nbSites; i++)
00472   {
00473     VVdouble* _dLikelihoods_father_i = &(*_dLikelihoods_father)[i];
00474     for (size_t c = 0; c < nbClasses_; c++)
00475     {
00476       Vdouble* _dLikelihoods_father_i_c = &(*_dLikelihoods_father_i)[c];
00477       for (size_t s = 0; s < nbStates_; s++)
00478       {
00479         (*_dLikelihoods_father_i_c)[s] = 1.;
00480       }
00481     }
00482   }
00483 
00484   size_t nbNodes = father->getNumberOfSons();
00485   for (size_t l = 0; l < nbNodes; l++)
00486   {
00487     const Node* son = father->getSon(l);
00488 
00489     VVVdouble* pxy__son = &pxy_[son->getId()];
00490     vector<size_t> * _patternLinks_father_son = &likelihoodData_->getArrayPositions(father->getId(), son->getId());
00491 
00492     if (son == node)
00493     {
00494       VVVdouble* _dLikelihoods_son = &likelihoodData_->getDLikelihoodArray(son->getId());
00495       for (size_t i = 0; i < nbSites; i++)
00496       {
00497         VVdouble* _dLikelihoods_son_i = &(*_dLikelihoods_son)[(*_patternLinks_father_son)[i]];
00498         VVdouble* _dLikelihoods_father_i = &(*_dLikelihoods_father)[i];
00499         for (size_t c = 0; c < nbClasses_; c++)
00500         {
00501           Vdouble* _dLikelihoods_son_i_c = &(*_dLikelihoods_son_i)[c];
00502           Vdouble* _dLikelihoods_father_i_c = &(*_dLikelihoods_father_i)[c];
00503           VVdouble* pxy__son_c = &(*pxy__son)[c];
00504           for (size_t x = 0; x < nbStates_; x++)
00505           {
00506             double dl = 0;
00507             Vdouble* pxy__son_c_x = &(*pxy__son_c)[x];
00508             for (size_t y = 0; y < nbStates_; y++)
00509             {
00510               dl += (*pxy__son_c_x)[y] * (*_dLikelihoods_son_i_c)[y];
00511             }
00512             (*_dLikelihoods_father_i_c)[x] *= dl;
00513           }
00514         }
00515       }
00516     }
00517     else
00518     {
00519       VVVdouble* _likelihoods_son = &likelihoodData_->getLikelihoodArray(son->getId());
00520       for (size_t i = 0; i < nbSites; i++)
00521       {
00522         VVdouble* _likelihoods_son_i = &(*_likelihoods_son)[(*_patternLinks_father_son)[i]];
00523         VVdouble* _dLikelihoods_father_i = &(*_dLikelihoods_father)[i];
00524         for (size_t c = 0; c < nbClasses_; c++)
00525         {
00526           Vdouble* _likelihoods_son_i_c = &(*_likelihoods_son_i)[c];
00527           Vdouble* _dLikelihoods_father_i_c = &(*_dLikelihoods_father_i)[c];
00528           VVdouble* pxy__son_c = &(*pxy__son)[c];
00529           for (size_t x = 0; x < nbStates_; x++)
00530           {
00531             double dl = 0;
00532             Vdouble* pxy__son_c_x = &(*pxy__son_c)[x];
00533             for (size_t y = 0; y < nbStates_; y++)
00534             {
00535               dl += (*pxy__son_c_x)[y] * (*_likelihoods_son_i_c)[y];
00536             }
00537             (*_dLikelihoods_father_i_c)[x] *= dl;
00538           }
00539         }
00540       }
00541     }
00542   }
00543 
00544   //Next step: move toward grand father...
00545   computeDownSubtreeDLikelihood(father);
00546 }
00547 
00548 /******************************************************************************
00549 *                           Second Order Derivatives                         *
00550 ******************************************************************************/
00551 
00552 double RHomogeneousTreeLikelihood::getD2LikelihoodForASiteForARateClass(
00553   size_t site,
00554   size_t rateClass) const
00555 {
00556   double d2l = 0;
00557   Vdouble* d2la = &likelihoodData_->getD2LikelihoodArray(tree_->getRootNode()->getId())[likelihoodData_->getRootArrayPosition(site)][rateClass];
00558   for (size_t i = 0; i < nbStates_; i++)
00559   {
00560     d2l += (*d2la)[i] * rootFreqs_[i];
00561   }
00562   return d2l;
00563 }
00564 
00565 /******************************************************************************/
00566 
00567 double RHomogeneousTreeLikelihood::getD2LikelihoodForASite(size_t site) const
00568 {
00569   // Derivative of the sum is the sum of derivatives:
00570   double d2l = 0;
00571   for (size_t i = 0; i < nbClasses_; i++)
00572   {
00573     d2l += getD2LikelihoodForASiteForARateClass(site, i) * rateDistribution_->getProbability(i);
00574   }
00575   return d2l;
00576 }
00577 
00578 /******************************************************************************/
00579 
00580 double RHomogeneousTreeLikelihood::getD2LogLikelihoodForASite(size_t site) const
00581 {
00582   return getD2LikelihoodForASite(site) / getLikelihoodForASite(site)
00583          - pow( getDLikelihoodForASite(site) / getLikelihoodForASite(site), 2);
00584 }
00585 
00586 /******************************************************************************/
00587 
00588 double RHomogeneousTreeLikelihood::getD2LogLikelihood() const
00589 {
00590   // Derivative of the sum is the sum of derivatives:
00591   double dl = 0;
00592   for (size_t i = 0; i < nbSites_; i++)
00593   {
00594     dl += getD2LogLikelihoodForASite(i);
00595   }
00596   return dl;
00597 }
00598 
00599 /******************************************************************************/
00600 
00601 double RHomogeneousTreeLikelihood::getSecondOrderDerivative(const string& variable) const
00602 throw (Exception)
00603 {
00604   if (!hasParameter(variable))
00605     throw ParameterNotFoundException("RHomogeneousTreeLikelihood::getSecondOrderDerivative().", variable);
00606   if (getRateDistributionParameters().hasParameter(variable))
00607   {
00608     throw Exception("Derivatives respective to rate distribution parameter are not implemented.");
00609   }
00610   if (getSubstitutionModelParameters().hasParameter(variable))
00611   {
00612     throw Exception("Derivatives respective to substitution model parameters are not implemented.");
00613   }
00614 
00615   const_cast<RHomogeneousTreeLikelihood*>(this)->computeTreeD2Likelihood(variable);
00616   return -getD2LogLikelihood();
00617 }
00618 
00619 /******************************************************************************/
00620 
00621 void RHomogeneousTreeLikelihood::computeTreeD2Likelihood(const string& variable)
00622 {
00623   // Get the node with the branch whose length must be derivated:
00624   size_t brI = TextTools::to<size_t>(variable.substr(5));
00625   const Node* branch = nodes_[brI];
00626   const Node* father = branch->getFather();
00627 
00628   // Compute dLikelihoods array for the father node.
00629   // Fist initialize to 1:
00630   VVVdouble* _d2Likelihoods_father = &likelihoodData_->getD2LikelihoodArray(father->getId());
00631   size_t nbSites  = _d2Likelihoods_father->size();
00632   for (size_t i = 0; i < nbSites; i++)
00633   {
00634     VVdouble* _d2Likelihoods_father_i = &(*_d2Likelihoods_father)[i];
00635     for (size_t c = 0; c < nbClasses_; c++)
00636     {
00637       Vdouble* _d2Likelihoods_father_i_c = &(*_d2Likelihoods_father_i)[c];
00638       for (size_t s = 0; s < nbStates_; s++)
00639       {
00640         (*_d2Likelihoods_father_i_c)[s] = 1.;
00641       }
00642     }
00643   }
00644 
00645   size_t nbNodes = father->getNumberOfSons();
00646   for (size_t l = 0; l < nbNodes; l++)
00647   {
00648     const Node* son = father->getSon(l);
00649 
00650     vector<size_t> * _patternLinks_father_son = &likelihoodData_->getArrayPositions(father->getId(), son->getId());
00651     VVVdouble* _likelihoods_son = &likelihoodData_->getLikelihoodArray(son->getId());
00652 
00653     if (son == branch)
00654     {
00655       VVVdouble* d2pxy__son = &d2pxy_[son->getId()];
00656       for (size_t i = 0; i < nbSites; i++)
00657       {
00658         VVdouble* _likelihoods_son_i = &(*_likelihoods_son)[(*_patternLinks_father_son)[i]];
00659         VVdouble* _d2Likelihoods_father_i = &(*_d2Likelihoods_father)[i];
00660         for (size_t c = 0; c < nbClasses_; c++)
00661         {
00662           Vdouble* _likelihoods_son_i_c = &(*_likelihoods_son_i)[c];
00663           Vdouble* _d2Likelihoods_father_i_c = &(*_d2Likelihoods_father_i)[c];
00664           VVdouble* d2pxy__son_c = &(*d2pxy__son)[c];
00665           for (size_t x = 0; x < nbStates_; x++)
00666           {
00667             double d2l = 0;
00668             Vdouble* d2pxy__son_c_x = &(*d2pxy__son_c)[x];
00669             for (size_t y = 0; y < nbStates_; y++)
00670             {
00671               d2l += (*d2pxy__son_c_x)[y] * (*_likelihoods_son_i_c)[y];
00672             }
00673             (*_d2Likelihoods_father_i_c)[x] *= d2l;
00674           }
00675         }
00676       }
00677     }
00678     else
00679     {
00680       VVVdouble* pxy__son = &pxy_[son->getId()];
00681       for (size_t i = 0; i < nbSites; i++)
00682       {
00683         VVdouble* _likelihoods_son_i = &(*_likelihoods_son)[(*_patternLinks_father_son)[i]];
00684         VVdouble* _d2Likelihoods_father_i = &(*_d2Likelihoods_father)[i];
00685         for (size_t c = 0; c < nbClasses_; c++)
00686         {
00687           Vdouble* _likelihoods_son_i_c = &(*_likelihoods_son_i)[c];
00688           Vdouble* _d2Likelihoods_father_i_c = &(*_d2Likelihoods_father_i)[c];
00689           VVdouble* pxy__son_c = &(*pxy__son)[c];
00690           for (size_t x = 0; x < nbStates_; x++)
00691           {
00692             double d2l = 0;
00693             Vdouble* pxy__son_c_x = &(*pxy__son_c)[x];
00694             for (size_t y = 0; y < nbStates_; y++)
00695             {
00696               d2l += (*pxy__son_c_x)[y] * (*_likelihoods_son_i_c)[y];
00697             }
00698             (*_d2Likelihoods_father_i_c)[x] *= d2l;
00699           }
00700         }
00701       }
00702     }
00703   }
00704 
00705   // Now we go down the tree toward the root node:
00706   computeDownSubtreeD2Likelihood(father);
00707 }
00708 
00709 /******************************************************************************/
00710 
00711 void RHomogeneousTreeLikelihood::computeDownSubtreeD2Likelihood(const Node* node)
00712 {
00713   const Node* father = node->getFather();
00714   // We assume that the _dLikelihoods array has been filled for the current node 'node'.
00715   // We will evaluate the array for the father node.
00716   if (father == NULL) return; // We reached the root!
00717 
00718   // Compute dLikelihoods array for the father node.
00719   // Fist initialize to 1:
00720   VVVdouble* _d2Likelihoods_father = &likelihoodData_->getD2LikelihoodArray(father->getId());
00721   size_t nbSites  = _d2Likelihoods_father->size();
00722   for (size_t i = 0; i < nbSites; i++)
00723   {
00724     VVdouble* _d2Likelihoods_father_i = &(*_d2Likelihoods_father)[i];
00725     for (size_t c = 0; c < nbClasses_; c++)
00726     {
00727       Vdouble* _d2Likelihoods_father_i_c = &(*_d2Likelihoods_father_i)[c];
00728       for (size_t s = 0; s < nbStates_; s++)
00729       {
00730         (*_d2Likelihoods_father_i_c)[s] = 1.;
00731       }
00732     }
00733   }
00734 
00735   size_t nbNodes = father->getNumberOfSons();
00736   for (size_t l = 0; l < nbNodes; l++)
00737   {
00738     const Node* son = father->getSon(l);
00739 
00740     VVVdouble* pxy__son = &pxy_[son->getId()];
00741     vector<size_t> * _patternLinks_father_son = &likelihoodData_->getArrayPositions(father->getId(), son->getId());
00742 
00743     if (son == node)
00744     {
00745       VVVdouble* _d2Likelihoods_son = &likelihoodData_->getD2LikelihoodArray(son->getId());
00746       for (size_t i = 0; i < nbSites; i++)
00747       {
00748         VVdouble* _d2Likelihoods_son_i = &(*_d2Likelihoods_son)[(*_patternLinks_father_son)[i]];
00749         VVdouble* _d2Likelihoods_father_i = &(*_d2Likelihoods_father)[i];
00750         for (size_t c = 0; c < nbClasses_; c++)
00751         {
00752           Vdouble* _d2Likelihoods_son_i_c = &(*_d2Likelihoods_son_i)[c];
00753           Vdouble* _d2Likelihoods_father_i_c = &(*_d2Likelihoods_father_i)[c];
00754           VVdouble* pxy__son_c = &(*pxy__son)[c];
00755           for (size_t x = 0; x < nbStates_; x++)
00756           {
00757             double d2l = 0;
00758             Vdouble* pxy__son_c_x = &(*pxy__son_c)[x];
00759             for (size_t y = 0; y < nbStates_; y++)
00760             {
00761               d2l += (*pxy__son_c_x)[y] * (*_d2Likelihoods_son_i_c)[y];
00762             }
00763             (*_d2Likelihoods_father_i_c)[x] *= d2l;
00764           }
00765         }
00766       }
00767     }
00768     else
00769     {
00770       VVVdouble* _likelihoods_son = &likelihoodData_->getLikelihoodArray(son->getId());
00771       for (size_t i = 0; i < nbSites; i++)
00772       {
00773         VVdouble* _likelihoods_son_i = &(*_likelihoods_son)[(*_patternLinks_father_son)[i]];
00774         VVdouble* _d2Likelihoods_father_i = &(*_d2Likelihoods_father)[i];
00775         for (size_t c = 0; c < nbClasses_; c++)
00776         {
00777           Vdouble* _likelihoods_son_i_c = &(*_likelihoods_son_i)[c];
00778           Vdouble* _d2Likelihoods_father_i_c = &(*_d2Likelihoods_father_i)[c];
00779           VVdouble* pxy__son_c = &(*pxy__son)[c];
00780           for (size_t x = 0; x < nbStates_; x++)
00781           {
00782             double dl = 0;
00783             Vdouble* pxy__son_c_x = &(*pxy__son_c)[x];
00784             for (size_t y = 0; y < nbStates_; y++)
00785             {
00786               dl += (*pxy__son_c_x)[y] * (*_likelihoods_son_i_c)[y];
00787             }
00788             (*_d2Likelihoods_father_i_c)[x] *= dl;
00789           }
00790         }
00791       }
00792     }
00793   }
00794 
00795   //Next step: move toward grand father...
00796   computeDownSubtreeD2Likelihood(father);
00797 }
00798 
00799 /******************************************************************************/
00800 
00801 void RHomogeneousTreeLikelihood::computeTreeLikelihood()
00802 {
00803   computeSubtreeLikelihood(tree_->getRootNode());
00804 }
00805 
00806 /******************************************************************************/
00807 
00808 void RHomogeneousTreeLikelihood::computeSubtreeLikelihood(const Node* node)
00809 {
00810   if (node->isLeaf()) return;
00811 
00812   size_t nbSites = likelihoodData_->getLikelihoodArray(node->getId()).size();
00813   size_t nbNodes = node->getNumberOfSons();
00814 
00815   // Must reset the likelihood array first (i.e. set all of them to 1):
00816   VVVdouble* _likelihoods_node = &likelihoodData_->getLikelihoodArray(node->getId());
00817   for (size_t i = 0; i < nbSites; i++)
00818   {
00819     //For each site in the sequence,
00820     VVdouble* _likelihoods_node_i = &(*_likelihoods_node)[i];
00821     for (size_t c = 0; c < nbClasses_; c++)
00822     {
00823       //For each rate classe,
00824       Vdouble* _likelihoods_node_i_c = &(*_likelihoods_node_i)[c];
00825       for (size_t x = 0; x < nbStates_; x++)
00826       {
00827         //For each initial state,
00828         (*_likelihoods_node_i_c)[x] = 1.;
00829       }
00830     }
00831   }
00832 
00833   for (size_t l = 0; l < nbNodes; l++)
00834   {
00835     //For each son node,
00836 
00837     const Node* son = node->getSon(l);
00838 
00839     computeSubtreeLikelihood(son); //Recursive method:
00840 
00841     VVVdouble* pxy__son = &pxy_[son->getId()];
00842     vector<size_t> * _patternLinks_node_son = &likelihoodData_->getArrayPositions(node->getId(), son->getId());
00843     VVVdouble* _likelihoods_son = &likelihoodData_->getLikelihoodArray(son->getId());
00844 
00845     for (size_t i = 0; i < nbSites; i++)
00846     {
00847       //For each site in the sequence,
00848       VVdouble* _likelihoods_son_i = &(*_likelihoods_son)[(*_patternLinks_node_son)[i]];
00849       VVdouble* _likelihoods_node_i = &(*_likelihoods_node)[i];
00850       for (size_t c = 0; c < nbClasses_; c++)
00851       {
00852         //For each rate classe,
00853         Vdouble* _likelihoods_son_i_c = &(*_likelihoods_son_i)[c];
00854         Vdouble* _likelihoods_node_i_c = &(*_likelihoods_node_i)[c];
00855         VVdouble* pxy__son_c = &(*pxy__son)[c];
00856         for (size_t x = 0; x < nbStates_; x++)
00857         {
00858           //For each initial state,
00859           Vdouble* pxy__son_c_x = &(*pxy__son_c)[x];
00860           double likelihood = 0;
00861           for (size_t y = 0; y < nbStates_; y++)
00862           {
00863             likelihood += (*pxy__son_c_x)[y] * (*_likelihoods_son_i_c)[y];
00864           }
00865           (*_likelihoods_node_i_c)[x] *= likelihood;
00866         }
00867       }
00868     }
00869   }
00870 }
00871 
00872 /******************************************************************************/
00873 
00874 void RHomogeneousTreeLikelihood::displayLikelihood(const Node* node)
00875 {
00876   cout << "Likelihoods at node " << node->getName() << ": " << endl;
00877   displayLikelihoodArray(likelihoodData_->getLikelihoodArray(node->getId()));
00878   cout << "                                         ***" << endl;
00879 }
00880 
00881 /*******************************************************************************/
00882 
 All Classes Namespaces Files Functions Variables Typedefs Friends