bpp-phyl  2.1.0
Bpp/Phyl/Likelihood/RNonHomogeneousTreeLikelihood.cpp
Go to the documentation of this file.
00001 //
00002 // File: RNonHomogeneousTreeLikelihood.cpp
00003 // Created by: Julien Dutheil
00004 // Created on: Tue Oct 09 16:07 2007
00005 // From file: RHomogeneousTreeLikelihood.cpp
00006 //
00007 
00008 /*
00009    Copyright or © or Copr. CNRS, (November 16, 2004)
00010 
00011    This software is a computer program whose purpose is to provide classes
00012    for phylogenetic data analysis.
00013 
00014    This software is governed by the CeCILL  license under French law and
00015    abiding by the rules of distribution of free software.  You can  use,
00016    modify and/ or redistribute the software under the terms of the CeCILL
00017    license as circulated by CEA, CNRS and INRIA at the following URL
00018    "http://www.cecill.info".
00019 
00020    As a counterpart to the access to the source code and  rights to copy,
00021    modify and redistribute granted by the license, users are provided only
00022    with a limited warranty  and the software's author,  the holder of the
00023    economic rights,  and the successive licensors  have only  limited
00024    liability.
00025 
00026    In this respect, the user's attention is drawn to the risks associated
00027    with loading,  using,  modifying and/or developing or reproducing the
00028    software by the user in light of its specific status of free software,
00029    that may mean  that it is complicated to manipulate,  and  that  also
00030    therefore means  that it is reserved for developers  and  experienced
00031    professionals having in-depth computer knowledge. Users are therefore
00032    encouraged to load and test the software's suitability as regards their
00033    requirements in conditions enabling the security of their systems and/or
00034    data to be ensured and,  more generally, to use and operate it in the
00035    same conditions as regards security.
00036 
00037    The fact that you are presently reading this means that you have had
00038    knowledge of the CeCILL license and that you accept its terms.
00039  */
00040 
00041 #include "RNonHomogeneousTreeLikelihood.h"
00042 #include "../PatternTools.h"
00043 
00044 #include <Bpp/Text/TextTools.h>
00045 #include <Bpp/App/ApplicationTools.h>
00046 
00047 using namespace bpp;
00048 
00049 // From the STL:
00050 #include <iostream>
00051 
00052 using namespace std;
00053 
00054 /******************************************************************************/
00055 
00056 RNonHomogeneousTreeLikelihood::RNonHomogeneousTreeLikelihood(
00057   const Tree& tree,
00058   SubstitutionModelSet* modelSet,
00059   DiscreteDistribution* rDist,
00060   bool verbose,
00061   bool usePatterns,
00062   bool reparametrizeRoot)
00063 throw (Exception) :
00064   AbstractNonHomogeneousTreeLikelihood(tree, modelSet, rDist, verbose, reparametrizeRoot),
00065   likelihoodData_(0),
00066   minusLogLik_(-1.)
00067 {
00068   if (!modelSet->isFullySetUpFor(tree))
00069     throw Exception("RNonHomogeneousTreeLikelihood(constructor). Model set is not fully specified.");
00070   init_(usePatterns);
00071 }
00072 
00073 /******************************************************************************/
00074 
00075 RNonHomogeneousTreeLikelihood::RNonHomogeneousTreeLikelihood(
00076   const Tree& tree,
00077   const SiteContainer& data,
00078   SubstitutionModelSet* modelSet,
00079   DiscreteDistribution* rDist,
00080   bool verbose,
00081   bool usePatterns,
00082   bool reparametrizeRoot)
00083 throw (Exception) :
00084   AbstractNonHomogeneousTreeLikelihood(tree, modelSet, rDist, verbose, reparametrizeRoot),
00085   likelihoodData_(0),
00086   minusLogLik_(-1.)
00087 {
00088   if (!modelSet->isFullySetUpFor(tree))
00089     throw Exception("RNonHomogeneousTreeLikelihood(constructor). Model set is not fully specified.");
00090   init_(usePatterns);
00091   setData(data);
00092 }
00093 
00094 /******************************************************************************/
00095 
00096 void RNonHomogeneousTreeLikelihood::init_(bool usePatterns) throw (Exception)
00097 {
00098   likelihoodData_ = new DRASRTreeLikelihoodData(
00099     tree_,
00100     rateDistribution_->getNumberOfCategories(),
00101     usePatterns);
00102 }
00103 
00104 /******************************************************************************/
00105 
00106 RNonHomogeneousTreeLikelihood::RNonHomogeneousTreeLikelihood(
00107   const RNonHomogeneousTreeLikelihood& lik) :
00108   AbstractNonHomogeneousTreeLikelihood(lik),
00109   likelihoodData_(0),
00110   minusLogLik_(lik.minusLogLik_)
00111 {
00112   likelihoodData_ = dynamic_cast<DRASRTreeLikelihoodData*>(lik.likelihoodData_->clone());
00113   likelihoodData_->setTree(tree_);
00114 }
00115 
00116 /******************************************************************************/
00117 
00118 RNonHomogeneousTreeLikelihood& RNonHomogeneousTreeLikelihood::operator=(
00119   const RNonHomogeneousTreeLikelihood& lik)
00120 {
00121   AbstractNonHomogeneousTreeLikelihood::operator=(lik);
00122   if (likelihoodData_) delete likelihoodData_;
00123   likelihoodData_ = dynamic_cast<DRASRTreeLikelihoodData*>(lik.likelihoodData_->clone());
00124   likelihoodData_->setTree(tree_);
00125   minusLogLik_ = lik.minusLogLik_;
00126   return *this;
00127 }
00128 
00129 /******************************************************************************/
00130 
00131 RNonHomogeneousTreeLikelihood::~RNonHomogeneousTreeLikelihood()
00132 {
00133   delete likelihoodData_;
00134 }
00135 
00136 /******************************************************************************/
00137 
00138 void RNonHomogeneousTreeLikelihood::setData(const SiteContainer& sites) throw (Exception)
00139 {
00140   if (data_) delete data_;
00141   data_ = PatternTools::getSequenceSubset(sites, *tree_->getRootNode());
00142   if (verbose_) ApplicationTools::displayTask("Initializing data structure");
00143   likelihoodData_->initLikelihoods(*data_, *modelSet_->getModel(0)); //We assume here that all models have the same number of states, and that they have the same 'init' method,
00144                                                                      //Which is a reasonable assumption as long as they share the same alphabet.
00145   if (verbose_) ApplicationTools::displayTaskDone();
00146 
00147   nbSites_         = likelihoodData_->getNumberOfSites();
00148   nbDistinctSites_ = likelihoodData_->getNumberOfDistinctSites();
00149   nbStates_        = likelihoodData_->getNumberOfStates();
00150 
00151   if (verbose_) ApplicationTools::displayResult("Number of distinct sites",
00152                                                 TextTools::toString(nbDistinctSites_));
00153   initialized_ = false;
00154 }
00155 
00156 /******************************************************************************/
00157 
00158 double RNonHomogeneousTreeLikelihood::getLikelihood() const
00159 {
00160   double l = 1.;
00161   for (size_t i = 0; i < nbSites_; i++)
00162   {
00163     l *= getLikelihoodForASite(i);
00164   }
00165   return l;
00166 }
00167 
00168 /******************************************************************************/
00169 
00170 double RNonHomogeneousTreeLikelihood::getLogLikelihood() const
00171 {
00172   double ll = 0;
00173   vector<double> la(nbSites_);
00174   for (size_t i = 0; i < nbSites_; i++)
00175   {
00176     la[i] = getLogLikelihoodForASite(i);
00177   }
00178   sort(la.begin(), la.end());
00179   for (size_t i = nbSites_; i > 0; i--)
00180   {
00181     ll += la[i - 1];
00182   }
00183   return ll;
00184 }
00185 
00186 /******************************************************************************/
00187 
00188 double RNonHomogeneousTreeLikelihood::getLikelihoodForASite(size_t site) const
00189 {
00190   double l = 0;
00191   for (size_t i = 0; i < nbClasses_; i++)
00192   {
00193     l += getLikelihoodForASiteForARateClass(site, i) * rateDistribution_->getProbability(i);
00194   }
00195   return l;
00196 }
00197 
00198 /******************************************************************************/
00199 
00200 double RNonHomogeneousTreeLikelihood::getLogLikelihoodForASite(size_t site) const
00201 {
00202   double l = 0;
00203   for (size_t i = 0; i < nbClasses_; i++)
00204   {
00205     l += getLikelihoodForASiteForARateClass(site, i) * rateDistribution_->getProbability(i);
00206   }
00207   //if(l <= 0.) cerr << "WARNING!!! Negative likelihood." << endl;
00208   if (l < 0) l = 0; //May happen because of numerical errors.
00209   return log(l);
00210 }
00211 
00212 /******************************************************************************/
00213 
00214 double RNonHomogeneousTreeLikelihood::getLikelihoodForASiteForARateClass(size_t site, size_t rateClass) const
00215 {
00216   double l = 0;
00217   Vdouble* la = &likelihoodData_->getLikelihoodArray(tree_->getRootNode()->getId())[likelihoodData_->getRootArrayPosition(site)][rateClass];
00218   for (size_t i = 0; i < nbStates_; i++)
00219   {
00220     l += (*la)[i] * rootFreqs_[i];
00221   }
00222   return l;
00223 }
00224 
00225 /******************************************************************************/
00226 
00227 double RNonHomogeneousTreeLikelihood::getLogLikelihoodForASiteForARateClass(size_t site, size_t rateClass) const
00228 {
00229   double l = 0;
00230   Vdouble* la = &likelihoodData_->getLikelihoodArray(tree_->getRootNode()->getId())[likelihoodData_->getRootArrayPosition(site)][rateClass];
00231   for (size_t i = 0; i < nbStates_; i++)
00232   {
00233     l += (*la)[i] * rootFreqs_[i];
00234   }
00235   return log(l);
00236 }
00237 
00238 /******************************************************************************/
00239 
00240 double RNonHomogeneousTreeLikelihood::getLikelihoodForASiteForARateClassForAState(size_t site, size_t rateClass, int state) const
00241 {
00242   return likelihoodData_->getLikelihoodArray(tree_->getRootNode()->getId())[likelihoodData_->getRootArrayPosition(site)][rateClass][state];
00243 }
00244 
00245 /******************************************************************************/
00246 
00247 double RNonHomogeneousTreeLikelihood::getLogLikelihoodForASiteForARateClassForAState(size_t site, size_t rateClass, int state) const
00248 {
00249   return log(likelihoodData_->getLikelihoodArray(tree_->getRootNode()->getId())[likelihoodData_->getRootArrayPosition(site)][rateClass][state]);
00250 }
00251 
00252 /******************************************************************************/
00253 
00254 void RNonHomogeneousTreeLikelihood::setParameters(const ParameterList& parameters)
00255 throw (ParameterNotFoundException, ConstraintException)
00256 {
00257   setParametersValues(parameters);
00258 }
00259 
00260 /******************************************************************************/
00261 
00262 void RNonHomogeneousTreeLikelihood::fireParameterChanged(const ParameterList& params)
00263 {
00264   applyParameters();
00265 
00266   if (params.getCommonParametersWith(rateDistribution_->getIndependentParameters()).size() > 0)
00267   {
00268     computeAllTransitionProbabilities();
00269   }
00270   else
00271   {
00272     vector<int> ids;
00273     vector<string> tmp = params.getCommonParametersWith(modelSet_->getNodeParameters()).getParameterNames();
00274     for (size_t i = 0; i < tmp.size(); i++)
00275     {
00276       vector<int> tmpv = modelSet_->getNodesWithParameter(tmp[i]);
00277       ids = VectorTools::vectorUnion(ids, tmpv);
00278     }
00279     tmp = params.getCommonParametersWith(brLenParameters_).getParameterNames();
00280     vector<const Node*> nodes;
00281     for (size_t i = 0; i < ids.size(); i++)
00282     {
00283       nodes.push_back(idToNode_[ids[i]]);
00284     }
00285     vector<const Node*> tmpv;
00286     bool test = false;
00287     for (size_t i = 0; i < tmp.size(); i++)
00288     {
00289       if (tmp[i] == "BrLenRoot" || tmp[i] == "RootPosition")
00290       {
00291         if (!test)
00292         {
00293           tmpv.push_back(tree_->getRootNode()->getSon(0));
00294           tmpv.push_back(tree_->getRootNode()->getSon(1));
00295           test = true; //Add only once.
00296         }
00297       }
00298       else
00299         tmpv.push_back(nodes_[TextTools::to < size_t > (tmp[i].substr(5))]);
00300     }
00301     nodes = VectorTools::vectorUnion(nodes, tmpv);
00302 
00303     for (size_t i = 0; i < nodes.size(); i++)
00304     {
00305       computeTransitionProbabilitiesForNode(nodes[i]);
00306     }
00307     rootFreqs_ = modelSet_->getRootFrequencies();
00308   }
00309   computeTreeLikelihood();
00310 
00311   minusLogLik_ = -getLogLikelihood();
00312 }
00313 
00314 /******************************************************************************/
00315 
00316 double RNonHomogeneousTreeLikelihood::getValue() const
00317 throw (Exception)
00318 {
00319   if (!isInitialized()) throw Exception("RNonHomogeneousTreeLikelihood::getValue(). Instance is not initialized.");
00320   return minusLogLik_;
00321 }
00322 
00323 /******************************************************************************
00324 *                           First Order Derivatives                          *
00325 ******************************************************************************/
00326 
00327 double RNonHomogeneousTreeLikelihood::getDLikelihoodForASiteForARateClass(
00328   size_t site,
00329   size_t rateClass) const
00330 {
00331   double dl = 0;
00332   Vdouble* dla = &likelihoodData_->getDLikelihoodArray(tree_->getRootNode()->getId())[likelihoodData_->getRootArrayPosition(site)][rateClass];
00333   for (size_t i = 0; i < nbStates_; i++)
00334   {
00335     dl += (*dla)[i] * rootFreqs_[i];
00336   }
00337   return dl;
00338 }
00339 
00340 /******************************************************************************/
00341 
00342 double RNonHomogeneousTreeLikelihood::getDLikelihoodForASite(size_t site) const
00343 {
00344   // Derivative of the sum is the sum of derivatives:
00345   double dl = 0;
00346   for (size_t i = 0; i < nbClasses_; i++)
00347   {
00348     dl += getDLikelihoodForASiteForARateClass(site, i) * rateDistribution_->getProbability(i);
00349   }
00350   return dl;
00351 }
00352 
00353 /******************************************************************************/
00354 
00355 double RNonHomogeneousTreeLikelihood::getDLogLikelihoodForASite(size_t site) const
00356 {
00357   // d(f(g(x)))/dx = dg(x)/dx . df(g(x))/dg :
00358   return getDLikelihoodForASite(site) / getLikelihoodForASite(site);
00359 }
00360 
00361 /******************************************************************************/
00362 
00363 double RNonHomogeneousTreeLikelihood::getDLogLikelihood() const
00364 {
00365   // Derivative of the sum is the sum of derivatives:
00366   double dl = 0;
00367   for (size_t i = 0; i < nbSites_; i++)
00368   {
00369     dl += getDLogLikelihoodForASite(i);
00370   }
00371   return dl;
00372 }
00373 
00374 /******************************************************************************/
00375 
00376 double RNonHomogeneousTreeLikelihood::getFirstOrderDerivative(const string& variable) const
00377 throw (Exception)
00378 {
00379   if (!hasParameter(variable))
00380     throw ParameterNotFoundException("RNonHomogeneousTreeLikelihood::getFirstOrderDerivative().", variable);
00381   if (getRateDistributionParameters().hasParameter(variable))
00382   {
00383     throw Exception("Derivatives respective to rate distribution parameter are not implemented.");
00384   }
00385   if (getSubstitutionModelParameters().hasParameter(variable))
00386   {
00387     throw Exception("Derivatives respective to substitution model parameters are not implemented.");
00388   }
00389 
00390   const_cast<RNonHomogeneousTreeLikelihood*>(this)->computeTreeDLikelihood(variable);
00391   return -getDLogLikelihood();
00392 }
00393 
00394 /******************************************************************************/
00395 
00396 void RNonHomogeneousTreeLikelihood::computeTreeDLikelihood(const string& variable)
00397 {
00398   if (variable == "BrLenRoot")
00399   {
00400     const Node* father = tree_->getRootNode();
00401 
00402     // Compute dLikelihoods array for the father node.
00403     // Fist initialize to 1:
00404     VVVdouble* _dLikelihoods_father = &likelihoodData_->getDLikelihoodArray(father->getId());
00405     size_t nbSites  = _dLikelihoods_father->size();
00406     for (size_t i = 0; i < nbSites; i++)
00407     {
00408       VVdouble* _dLikelihoods_father_i = &(*_dLikelihoods_father)[i];
00409       for (size_t c = 0; c < nbClasses_; c++)
00410       {
00411         Vdouble* _dLikelihoods_father_i_c = &(*_dLikelihoods_father_i)[c];
00412         for (size_t s = 0; s < nbStates_; s++)
00413         {
00414           (*_dLikelihoods_father_i_c)[s] = 1.;
00415         }
00416       }
00417     }
00418 
00419     size_t nbNodes = father->getNumberOfSons();
00420     for (size_t l = 0; l < nbNodes; l++)
00421     {
00422       const Node* son = father->getSon(l);
00423 
00424       if (son->getId() == root1_)
00425       {
00426         const Node* root1 = father->getSon(0);
00427         const Node* root2 = father->getSon(1);
00428         vector<size_t> * _patternLinks_fatherroot1_ = &likelihoodData_->getArrayPositions(father->getId(), root1->getId());
00429         vector<size_t> * _patternLinks_fatherroot2_ = &likelihoodData_->getArrayPositions(father->getId(), root2->getId());
00430         VVVdouble* _likelihoodsroot1_ = &likelihoodData_->getLikelihoodArray(root1->getId());
00431         VVVdouble* _likelihoodsroot2_ = &likelihoodData_->getLikelihoodArray(root2->getId());
00432         double pos = getParameterValue("RootPosition");
00433 
00434         VVVdouble* dpxy_root1_  = &dpxy_[root1_];
00435         VVVdouble* dpxy_root2_  = &dpxy_[root2_];
00436         VVVdouble* pxy_root1_   = &pxy_[root1_];
00437         VVVdouble* pxy_root2_   = &pxy_[root2_];
00438         for (size_t i = 0; i < nbSites; i++)
00439         {
00440           VVdouble* _likelihoodsroot1__i = &(*_likelihoodsroot1_)[(*_patternLinks_fatherroot1_)[i]];
00441           VVdouble* _likelihoodsroot2__i = &(*_likelihoodsroot2_)[(*_patternLinks_fatherroot2_)[i]];
00442           VVdouble* _dLikelihoods_father_i = &(*_dLikelihoods_father)[i];
00443           for (size_t c = 0; c < nbClasses_; c++)
00444           {
00445             Vdouble* _likelihoodsroot1__i_c = &(*_likelihoodsroot1__i)[c];
00446             Vdouble* _likelihoodsroot2__i_c = &(*_likelihoodsroot2__i)[c];
00447             Vdouble* _dLikelihoods_father_i_c = &(*_dLikelihoods_father_i)[c];
00448             VVdouble* dpxy_root1__c  = &(*dpxy_root1_)[c];
00449             VVdouble* dpxy_root2__c  = &(*dpxy_root2_)[c];
00450             VVdouble* pxy_root1__c   = &(*pxy_root1_)[c];
00451             VVdouble* pxy_root2__c   = &(*pxy_root2_)[c];
00452             for (size_t x = 0; x < nbStates_; x++)
00453             {
00454               Vdouble* dpxy_root1__c_x  = &(*dpxy_root1__c)[x];
00455               Vdouble* dpxy_root2__c_x  = &(*dpxy_root2__c)[x];
00456               Vdouble* pxy_root1__c_x   = &(*pxy_root1__c)[x];
00457               Vdouble* pxy_root2__c_x   = &(*pxy_root2__c)[x];
00458               double dl1 = 0, dl2 = 0, l1 = 0, l2 = 0;
00459               for (size_t y = 0; y < nbStates_; y++)
00460               {
00461                 dl1  += (*dpxy_root1__c_x)[y]  * (*_likelihoodsroot1__i_c)[y];
00462                 dl2  += (*dpxy_root2__c_x)[y]  * (*_likelihoodsroot2__i_c)[y];
00463                 l1   += (*pxy_root1__c_x)[y]   * (*_likelihoodsroot1__i_c)[y];
00464                 l2   += (*pxy_root2__c_x)[y]   * (*_likelihoodsroot2__i_c)[y];
00465               }
00466               double dl = pos * dl1 * l2 + (1. - pos) * dl2 * l1;
00467               (*_dLikelihoods_father_i_c)[x] *= dl;
00468             }
00469           }
00470         }
00471       }
00472       else if (son->getId() == root2_)
00473       {
00474         //Do nothing, this was accounted when dealing with root1_
00475       }
00476       else
00477       {
00478         //Account for a putative multifurcation:
00479         vector<size_t> * _patternLinks_father_son = &likelihoodData_->getArrayPositions(father->getId(), son->getId());
00480         VVVdouble* _likelihoods_son = &likelihoodData_->getLikelihoodArray(son->getId());
00481 
00482         VVVdouble* pxy__son = &pxy_[son->getId()];
00483         for (size_t i = 0; i < nbSites; i++)
00484         {
00485           VVdouble* _likelihoods_son_i = &(*_likelihoods_son)[(*_patternLinks_father_son)[i]];
00486           VVdouble* _dLikelihoods_father_i = &(*_dLikelihoods_father)[i];
00487           for (size_t c = 0; c < nbClasses_; c++)
00488           {
00489             Vdouble* _likelihoods_son_i_c = &(*_likelihoods_son_i)[c];
00490             Vdouble* _dLikelihoods_father_i_c = &(*_dLikelihoods_father_i)[c];
00491             VVdouble* pxy__son_c = &(*pxy__son)[c];
00492             for (size_t x = 0; x < nbStates_; x++)
00493             {
00494               double dl = 0;
00495               Vdouble* pxy__son_c_x = &(*pxy__son_c)[x];
00496               for (size_t y = 0; y < nbStates_; y++)
00497               {
00498                 dl += (*pxy__son_c_x)[y] * (*_likelihoods_son_i_c)[y];
00499               }
00500               (*_dLikelihoods_father_i_c)[x] *= dl;
00501             }
00502           }
00503         }
00504       }
00505     }
00506     return;
00507   }
00508   else if (variable == "RootPosition")
00509   {
00510     const Node* father = tree_->getRootNode();
00511 
00512     // Compute dLikelihoods array for the father node.
00513     // Fist initialize to 1:
00514     VVVdouble* _dLikelihoods_father = &likelihoodData_->getDLikelihoodArray(father->getId());
00515     size_t nbSites  = _dLikelihoods_father->size();
00516     for (size_t i = 0; i < nbSites; i++)
00517     {
00518       VVdouble* _dLikelihoods_father_i = &(*_dLikelihoods_father)[i];
00519       for (size_t c = 0; c < nbClasses_; c++)
00520       {
00521         Vdouble* _dLikelihoods_father_i_c = &(*_dLikelihoods_father_i)[c];
00522         for (size_t s = 0; s < nbStates_; s++)
00523         {
00524           (*_dLikelihoods_father_i_c)[s] = 1.;
00525         }
00526       }
00527     }
00528 
00529     size_t nbNodes = father->getNumberOfSons();
00530     for (size_t l = 0; l < nbNodes; l++)
00531     {
00532       const Node* son = father->getSon(l);
00533 
00534       if (son->getId() == root1_)
00535       {
00536         const Node* root1 = father->getSon(0);
00537         const Node* root2 = father->getSon(1);
00538         vector<size_t> * _patternLinks_fatherroot1_ = &likelihoodData_->getArrayPositions(father->getId(), root1->getId());
00539         vector<size_t> * _patternLinks_fatherroot2_ = &likelihoodData_->getArrayPositions(father->getId(), root2->getId());
00540         VVVdouble* _likelihoodsroot1_ = &likelihoodData_->getLikelihoodArray(root1->getId());
00541         VVVdouble* _likelihoodsroot2_ = &likelihoodData_->getLikelihoodArray(root2->getId());
00542         double len = getParameterValue("BrLenRoot");
00543 
00544         VVVdouble* dpxy_root1_  = &dpxy_[root1_];
00545         VVVdouble* dpxy_root2_  = &dpxy_[root2_];
00546         VVVdouble* pxy_root1_   = &pxy_[root1_];
00547         VVVdouble* pxy_root2_   = &pxy_[root2_];
00548         for (size_t i = 0; i < nbSites; i++)
00549         {
00550           VVdouble* _likelihoodsroot1__i = &(*_likelihoodsroot1_)[(*_patternLinks_fatherroot1_)[i]];
00551           VVdouble* _likelihoodsroot2__i = &(*_likelihoodsroot2_)[(*_patternLinks_fatherroot2_)[i]];
00552           VVdouble* _dLikelihoods_father_i = &(*_dLikelihoods_father)[i];
00553           for (size_t c = 0; c < nbClasses_; c++)
00554           {
00555             Vdouble* _likelihoodsroot1__i_c = &(*_likelihoodsroot1__i)[c];
00556             Vdouble* _likelihoodsroot2__i_c = &(*_likelihoodsroot2__i)[c];
00557             Vdouble* _dLikelihoods_father_i_c = &(*_dLikelihoods_father_i)[c];
00558             VVdouble* dpxy_root1__c  = &(*dpxy_root1_)[c];
00559             VVdouble* dpxy_root2__c  = &(*dpxy_root2_)[c];
00560             VVdouble* pxy_root1__c   = &(*pxy_root1_)[c];
00561             VVdouble* pxy_root2__c   = &(*pxy_root2_)[c];
00562             for (size_t x = 0; x < nbStates_; x++)
00563             {
00564               Vdouble* dpxy_root1__c_x  = &(*dpxy_root1__c)[x];
00565               Vdouble* dpxy_root2__c_x  = &(*dpxy_root2__c)[x];
00566               Vdouble* pxy_root1__c_x   = &(*pxy_root1__c)[x];
00567               Vdouble* pxy_root2__c_x   = &(*pxy_root2__c)[x];
00568               double dl1 = 0, dl2 = 0, l1 = 0, l2 = 0;
00569               for (size_t y = 0; y < nbStates_; y++)
00570               {
00571                 dl1  += (*dpxy_root1__c_x)[y]  * (*_likelihoodsroot1__i_c)[y];
00572                 dl2  += (*dpxy_root2__c_x)[y]  * (*_likelihoodsroot2__i_c)[y];
00573                 l1   += (*pxy_root1__c_x)[y]   * (*_likelihoodsroot1__i_c)[y];
00574                 l2   += (*pxy_root2__c_x)[y]   * (*_likelihoodsroot2__i_c)[y];
00575               }
00576               double dl = len * (dl1 * l2 - dl2 * l1);
00577               (*_dLikelihoods_father_i_c)[x] *= dl;
00578             }
00579           }
00580         }
00581       }
00582       else if (son->getId() == root2_)
00583       {
00584         //Do nothing, this was accounted when dealing with root1_
00585       }
00586       else
00587       {
00588         //Account for a putative multifurcation:
00589         vector<size_t> * _patternLinks_father_son = &likelihoodData_->getArrayPositions(father->getId(), son->getId());
00590         VVVdouble* _likelihoods_son = &likelihoodData_->getLikelihoodArray(son->getId());
00591 
00592         VVVdouble* pxy__son = &pxy_[son->getId()];
00593         for (size_t i = 0; i < nbSites; i++)
00594         {
00595           VVdouble* _likelihoods_son_i = &(*_likelihoods_son)[(*_patternLinks_father_son)[i]];
00596           VVdouble* _dLikelihoods_father_i = &(*_dLikelihoods_father)[i];
00597           for (size_t c = 0; c < nbClasses_; c++)
00598           {
00599             Vdouble* _likelihoods_son_i_c = &(*_likelihoods_son_i)[c];
00600             Vdouble* _dLikelihoods_father_i_c = &(*_dLikelihoods_father_i)[c];
00601             VVdouble* pxy__son_c = &(*pxy__son)[c];
00602             for (size_t x = 0; x < nbStates_; x++)
00603             {
00604               double dl = 0;
00605               Vdouble* pxy__son_c_x = &(*pxy__son_c)[x];
00606               for (size_t y = 0; y < nbStates_; y++)
00607               {
00608                 dl += (*pxy__son_c_x)[y] * (*_likelihoods_son_i_c)[y];
00609               }
00610               (*_dLikelihoods_father_i_c)[x] *= dl;
00611             }
00612           }
00613         }
00614       }
00615     }
00616     return;
00617   }
00618 
00619   // Get the node with the branch whose length must be derivated:
00620   size_t brI = TextTools::to<size_t>(variable.substr(5));
00621   const Node* branch = nodes_[brI];
00622   const Node* father = branch->getFather();
00623   VVVdouble* _dLikelihoods_father = &likelihoodData_->getDLikelihoodArray(father->getId());
00624 
00625   // Compute dLikelihoods array for the father node.
00626   // Fist initialize to 1:
00627   size_t nbSites  = _dLikelihoods_father->size();
00628   for (size_t i = 0; i < nbSites; i++)
00629   {
00630     VVdouble* _dLikelihoods_father_i = &(*_dLikelihoods_father)[i];
00631     for (size_t c = 0; c < nbClasses_; c++)
00632     {
00633       Vdouble* _dLikelihoods_father_i_c = &(*_dLikelihoods_father_i)[c];
00634       for (size_t s = 0; s < nbStates_; s++)
00635       {
00636         (*_dLikelihoods_father_i_c)[s] = 1.;
00637       }
00638     }
00639   }
00640 
00641   size_t nbNodes = father->getNumberOfSons();
00642   for (size_t l = 0; l < nbNodes; l++)
00643   {
00644     const Node* son = father->getSon(l);
00645 
00646     vector<size_t> * _patternLinks_father_son = &likelihoodData_->getArrayPositions(father->getId(), son->getId());
00647     VVVdouble* _likelihoods_son = &likelihoodData_->getLikelihoodArray(son->getId());
00648 
00649     if (son == branch)
00650     {
00651       VVVdouble* dpxy__son = &dpxy_[son->getId()];
00652       for (size_t i = 0; i < nbSites; i++)
00653       {
00654         VVdouble* _likelihoods_son_i = &(*_likelihoods_son)[(*_patternLinks_father_son)[i]];
00655         VVdouble* _dLikelihoods_father_i = &(*_dLikelihoods_father)[i];
00656         for (size_t c = 0; c < nbClasses_; c++)
00657         {
00658           Vdouble* _likelihoods_son_i_c = &(*_likelihoods_son_i)[c];
00659           Vdouble* _dLikelihoods_father_i_c = &(*_dLikelihoods_father_i)[c];
00660           VVdouble* dpxy__son_c = &(*dpxy__son)[c];
00661           for (size_t x = 0; x < nbStates_; x++)
00662           {
00663             double dl = 0;
00664             Vdouble* dpxy__son_c_x = &(*dpxy__son_c)[x];
00665             for (size_t y = 0; y < nbStates_; y++)
00666             {
00667               dl += (*dpxy__son_c_x)[y] * (*_likelihoods_son_i_c)[y];
00668             }
00669             (*_dLikelihoods_father_i_c)[x] *= dl;
00670           }
00671         }
00672       }
00673     }
00674     else
00675     {
00676       VVVdouble* pxy__son = &pxy_[son->getId()];
00677       for (size_t i = 0; i < nbSites; i++)
00678       {
00679         VVdouble* _likelihoods_son_i = &(*_likelihoods_son)[(*_patternLinks_father_son)[i]];
00680         VVdouble* _dLikelihoods_father_i = &(*_dLikelihoods_father)[i];
00681         for (size_t c = 0; c < nbClasses_; c++)
00682         {
00683           Vdouble* _likelihoods_son_i_c = &(*_likelihoods_son_i)[c];
00684           Vdouble* _dLikelihoods_father_i_c = &(*_dLikelihoods_father_i)[c];
00685           VVdouble* pxy__son_c = &(*pxy__son)[c];
00686           for (size_t x = 0; x < nbStates_; x++)
00687           {
00688             double dl = 0;
00689             Vdouble* pxy__son_c_x = &(*pxy__son_c)[x];
00690             for (size_t y = 0; y < nbStates_; y++)
00691             {
00692               dl += (*pxy__son_c_x)[y] * (*_likelihoods_son_i_c)[y];
00693             }
00694             (*_dLikelihoods_father_i_c)[x] *= dl;
00695           }
00696         }
00697       }
00698     }
00699   }
00700 
00701   // Now we go down the tree toward the root node:
00702   computeDownSubtreeDLikelihood(father);
00703 }
00704 
00705 /******************************************************************************/
00706 
00707 void RNonHomogeneousTreeLikelihood::computeDownSubtreeDLikelihood(const Node* node)
00708 {
00709   const Node* father = node->getFather();
00710   // We assume that the _dLikelihoods array has been filled for the current node 'node'.
00711   // We will evaluate the array for the father node.
00712   if (father == 0) return; // We reached the root!
00713 
00714   // Compute dLikelihoods array for the father node.
00715   // Fist initialize to 1:
00716   VVVdouble* _dLikelihoods_father = &likelihoodData_->getDLikelihoodArray(father->getId());
00717   size_t nbSites  = _dLikelihoods_father->size();
00718   for (size_t i = 0; i < nbSites; i++)
00719   {
00720     VVdouble* _dLikelihoods_father_i = &(*_dLikelihoods_father)[i];
00721     for (size_t c = 0; c < nbClasses_; c++)
00722     {
00723       Vdouble* _dLikelihoods_father_i_c = &(*_dLikelihoods_father_i)[c];
00724       for (size_t s = 0; s < nbStates_; s++)
00725       {
00726         (*_dLikelihoods_father_i_c)[s] = 1.;
00727       }
00728     }
00729   }
00730 
00731   size_t nbNodes = father->getNumberOfSons();
00732   for (size_t l = 0; l < nbNodes; l++)
00733   {
00734     const Node* son = father->getSon(l);
00735 
00736     VVVdouble* pxy__son = &pxy_[son->getId()];
00737     vector<size_t> * _patternLinks_father_son = &likelihoodData_->getArrayPositions(father->getId(), son->getId());
00738 
00739     if (son == node)
00740     {
00741       VVVdouble* _dLikelihoods_son = &likelihoodData_->getDLikelihoodArray(son->getId());
00742       for (size_t i = 0; i < nbSites; i++)
00743       {
00744         VVdouble* _dLikelihoods_son_i = &(*_dLikelihoods_son)[(*_patternLinks_father_son)[i]];
00745         VVdouble* _dLikelihoods_father_i = &(*_dLikelihoods_father)[i];
00746         for (size_t c = 0; c < nbClasses_; c++)
00747         {
00748           Vdouble* _dLikelihoods_son_i_c = &(*_dLikelihoods_son_i)[c];
00749           Vdouble* _dLikelihoods_father_i_c = &(*_dLikelihoods_father_i)[c];
00750           VVdouble* pxy__son_c = &(*pxy__son)[c];
00751           for (size_t x = 0; x < nbStates_; x++)
00752           {
00753             double dl = 0;
00754             Vdouble* pxy__son_c_x = &(*pxy__son_c)[x];
00755             for (size_t y = 0; y < nbStates_; y++)
00756             {
00757               dl += (*pxy__son_c_x)[y] * (*_dLikelihoods_son_i_c)[y];
00758             }
00759             (*_dLikelihoods_father_i_c)[x] *= dl;
00760           }
00761         }
00762       }
00763     }
00764     else
00765     {
00766       VVVdouble* _likelihoods_son = &likelihoodData_->getLikelihoodArray(son->getId());
00767       for (size_t i = 0; i < nbSites; i++)
00768       {
00769         VVdouble* _likelihoods_son_i = &(*_likelihoods_son)[(*_patternLinks_father_son)[i]];
00770         VVdouble* _dLikelihoods_father_i = &(*_dLikelihoods_father)[i];
00771         for (size_t c = 0; c < nbClasses_; c++)
00772         {
00773           Vdouble* _likelihoods_son_i_c = &(*_likelihoods_son_i)[c];
00774           Vdouble* _dLikelihoods_father_i_c = &(*_dLikelihoods_father_i)[c];
00775           VVdouble* pxy__son_c = &(*pxy__son)[c];
00776           for (size_t x = 0; x < nbStates_; x++)
00777           {
00778             double dl = 0;
00779             Vdouble* pxy__son_c_x = &(*pxy__son_c)[x];
00780             for (size_t y = 0; y < nbStates_; y++)
00781             {
00782               dl += (*pxy__son_c_x)[y] * (*_likelihoods_son_i_c)[y];
00783             }
00784             (*_dLikelihoods_father_i_c)[x] *= dl;
00785           }
00786         }
00787       }
00788     }
00789   }
00790 
00791   //Next step: move toward grand father...
00792   computeDownSubtreeDLikelihood(father);
00793 }
00794 
00795 /******************************************************************************
00796 *                           Second Order Derivatives                         *
00797 ******************************************************************************/
00798 
00799 double RNonHomogeneousTreeLikelihood::getD2LikelihoodForASiteForARateClass(
00800   size_t site,
00801   size_t rateClass) const
00802 {
00803   double d2l = 0;
00804   Vdouble* d2la = &likelihoodData_->getD2LikelihoodArray(tree_->getRootNode()->getId())[likelihoodData_->getRootArrayPosition(site)][rateClass];
00805   for (size_t i = 0; i < nbStates_; i++)
00806   {
00807     d2l += (*d2la)[i] * rootFreqs_[i];
00808   }
00809   return d2l;
00810 }
00811 
00812 /******************************************************************************/
00813 
00814 double RNonHomogeneousTreeLikelihood::getD2LikelihoodForASite(size_t site) const
00815 {
00816   // Derivative of the sum is the sum of derivatives:
00817   double d2l = 0;
00818   for (size_t i = 0; i < nbClasses_; i++)
00819   {
00820     d2l += getD2LikelihoodForASiteForARateClass(site, i) * rateDistribution_->getProbability(i);
00821   }
00822   return d2l;
00823 }
00824 
00825 /******************************************************************************/
00826 
00827 double RNonHomogeneousTreeLikelihood::getD2LogLikelihoodForASite(size_t site) const
00828 {
00829   return getD2LikelihoodForASite(site) / getLikelihoodForASite(site)
00830          - pow( getDLikelihoodForASite(site) / getLikelihoodForASite(site), 2);
00831 }
00832 
00833 /******************************************************************************/
00834 
00835 double RNonHomogeneousTreeLikelihood::getD2LogLikelihood() const
00836 {
00837   // Derivative of the sum is the sum of derivatives:
00838   double dl = 0;
00839   for (size_t i = 0; i < nbSites_; i++)
00840   {
00841     dl += getD2LogLikelihoodForASite(i);
00842   }
00843   return dl;
00844 }
00845 
00846 /******************************************************************************/
00847 
00848 double RNonHomogeneousTreeLikelihood::getSecondOrderDerivative(const string& variable) const
00849 throw (Exception)
00850 {
00851   if (!hasParameter(variable))
00852     throw ParameterNotFoundException("RNonHomogeneousTreeLikelihood::getSecondOrderDerivative().", variable);
00853   if (getRateDistributionParameters().hasParameter(variable))
00854   {
00855     throw Exception("Derivatives respective to rate distribution parameter are not implemented.");
00856   }
00857   if (getSubstitutionModelParameters().hasParameter(variable))
00858   {
00859     throw Exception("Derivatives respective to substitution model parameters are not implemented.");
00860   }
00861 
00862   const_cast<RNonHomogeneousTreeLikelihood*>(this)->computeTreeD2Likelihood(variable);
00863   return -getD2LogLikelihood();
00864 }
00865 
00866 /******************************************************************************/
00867 
00868 void RNonHomogeneousTreeLikelihood::computeTreeD2Likelihood(const string& variable)
00869 {
00870   if (variable == "BrLenRoot")
00871   {
00872     const Node* father = tree_->getRootNode();
00873 
00874     // Compute dLikelihoods array for the father node.
00875     // Fist initialize to 1:
00876     VVVdouble* _d2Likelihoods_father = &likelihoodData_->getD2LikelihoodArray(father->getId());
00877     size_t nbSites  = _d2Likelihoods_father->size();
00878     for (size_t i = 0; i < nbSites; i++)
00879     {
00880       VVdouble* _d2Likelihoods_father_i = &(*_d2Likelihoods_father)[i];
00881       for (size_t c = 0; c < nbClasses_; c++)
00882       {
00883         Vdouble* _d2Likelihoods_father_i_c = &(*_d2Likelihoods_father_i)[c];
00884         for (size_t s = 0; s < nbStates_; s++)
00885         {
00886           (*_d2Likelihoods_father_i_c)[s] = 1.;
00887         }
00888       }
00889     }
00890 
00891     size_t nbNodes = father->getNumberOfSons();
00892     for (size_t l = 0; l < nbNodes; l++)
00893     {
00894       const Node* son = father->getSon(l);
00895 
00896       if (son->getId() == root1_)
00897       {
00898         const Node* root1 = father->getSon(0);
00899         const Node* root2 = father->getSon(1);
00900         vector<size_t> * _patternLinks_fatherroot1_ = &likelihoodData_->getArrayPositions(father->getId(), root1->getId());
00901         vector<size_t> * _patternLinks_fatherroot2_ = &likelihoodData_->getArrayPositions(father->getId(), root2->getId());
00902         VVVdouble* _likelihoodsroot1_ = &likelihoodData_->getLikelihoodArray(root1->getId());
00903         VVVdouble* _likelihoodsroot2_ = &likelihoodData_->getLikelihoodArray(root2->getId());
00904         double pos = getParameterValue("RootPosition");
00905 
00906         VVVdouble* d2pxy_root1_ = &d2pxy_[root1_];
00907         VVVdouble* d2pxy_root2_ = &d2pxy_[root2_];
00908         VVVdouble* dpxy_root1_  = &dpxy_[root1_];
00909         VVVdouble* dpxy_root2_  = &dpxy_[root2_];
00910         VVVdouble* pxy_root1_   = &pxy_[root1_];
00911         VVVdouble* pxy_root2_   = &pxy_[root2_];
00912         for (size_t i = 0; i < nbSites; i++)
00913         {
00914           VVdouble* _likelihoodsroot1__i = &(*_likelihoodsroot1_)[(*_patternLinks_fatherroot1_)[i]];
00915           VVdouble* _likelihoodsroot2__i = &(*_likelihoodsroot2_)[(*_patternLinks_fatherroot2_)[i]];
00916           VVdouble* _d2Likelihoods_father_i = &(*_d2Likelihoods_father)[i];
00917           for (size_t c = 0; c < nbClasses_; c++)
00918           {
00919             Vdouble* _likelihoodsroot1__i_c = &(*_likelihoodsroot1__i)[c];
00920             Vdouble* _likelihoodsroot2__i_c = &(*_likelihoodsroot2__i)[c];
00921             Vdouble* _d2Likelihoods_father_i_c = &(*_d2Likelihoods_father_i)[c];
00922             VVdouble* d2pxy_root1__c = &(*d2pxy_root1_)[c];
00923             VVdouble* d2pxy_root2__c = &(*d2pxy_root2_)[c];
00924             VVdouble* dpxy_root1__c  = &(*dpxy_root1_)[c];
00925             VVdouble* dpxy_root2__c  = &(*dpxy_root2_)[c];
00926             VVdouble* pxy_root1__c   = &(*pxy_root1_)[c];
00927             VVdouble* pxy_root2__c   = &(*pxy_root2_)[c];
00928             for (size_t x = 0; x < nbStates_; x++)
00929             {
00930               Vdouble* d2pxy_root1__c_x = &(*d2pxy_root1__c)[x];
00931               Vdouble* d2pxy_root2__c_x = &(*d2pxy_root2__c)[x];
00932               Vdouble* dpxy_root1__c_x  = &(*dpxy_root1__c)[x];
00933               Vdouble* dpxy_root2__c_x  = &(*dpxy_root2__c)[x];
00934               Vdouble* pxy_root1__c_x   = &(*pxy_root1__c)[x];
00935               Vdouble* pxy_root2__c_x   = &(*pxy_root2__c)[x];
00936               double d2l1 = 0, d2l2 = 0, dl1 = 0, dl2 = 0, l1 = 0, l2 = 0;
00937               for (size_t y = 0; y < nbStates_; y++)
00938               {
00939                 d2l1 += (*d2pxy_root1__c_x)[y] * (*_likelihoodsroot1__i_c)[y];
00940                 d2l2 += (*d2pxy_root2__c_x)[y] * (*_likelihoodsroot2__i_c)[y];
00941                 dl1  += (*dpxy_root1__c_x)[y]  * (*_likelihoodsroot1__i_c)[y];
00942                 dl2  += (*dpxy_root2__c_x)[y]  * (*_likelihoodsroot2__i_c)[y];
00943                 l1   += (*pxy_root1__c_x)[y]   * (*_likelihoodsroot1__i_c)[y];
00944                 l2   += (*pxy_root2__c_x)[y]   * (*_likelihoodsroot2__i_c)[y];
00945               }
00946               double d2l = pos * pos * d2l1 * l2 + (1. - pos) * (1. - pos) * d2l2 * l1 + 2 * pos * (1. - pos) * dl1 * dl2;
00947               (*_d2Likelihoods_father_i_c)[x] *= d2l;
00948             }
00949           }
00950         }
00951       }
00952       else if (son->getId() == root2_)
00953       {
00954         //Do nothing, this was accounted when dealing with root1_
00955       }
00956       else
00957       {
00958         //Account for a putative multifurcation:
00959         vector<size_t> * _patternLinks_father_son = &likelihoodData_->getArrayPositions(father->getId(), son->getId());
00960         VVVdouble* _likelihoods_son = &likelihoodData_->getLikelihoodArray(son->getId());
00961 
00962         VVVdouble* pxy__son = &pxy_[son->getId()];
00963         for (size_t i = 0; i < nbSites; i++)
00964         {
00965           VVdouble* _likelihoods_son_i = &(*_likelihoods_son)[(*_patternLinks_father_son)[i]];
00966           VVdouble* _d2Likelihoods_father_i = &(*_d2Likelihoods_father)[i];
00967           for (size_t c = 0; c < nbClasses_; c++)
00968           {
00969             Vdouble* _likelihoods_son_i_c = &(*_likelihoods_son_i)[c];
00970             Vdouble* _d2Likelihoods_father_i_c = &(*_d2Likelihoods_father_i)[c];
00971             VVdouble* pxy__son_c = &(*pxy__son)[c];
00972             for (size_t x = 0; x < nbStates_; x++)
00973             {
00974               double d2l = 0;
00975               Vdouble* pxy__son_c_x = &(*pxy__son_c)[x];
00976               for (size_t y = 0; y < nbStates_; y++)
00977               {
00978                 d2l += (*pxy__son_c_x)[y] * (*_likelihoods_son_i_c)[y];
00979               }
00980               (*_d2Likelihoods_father_i_c)[x] *= d2l;
00981             }
00982           }
00983         }
00984       }
00985     }
00986     return;
00987   }
00988   else if (variable == "RootPosition")
00989   {
00990     const Node* father = tree_->getRootNode();
00991 
00992     // Compute dLikelihoods array for the father node.
00993     // Fist initialize to 1:
00994     VVVdouble* _d2Likelihoods_father = &likelihoodData_->getD2LikelihoodArray(father->getId());
00995     size_t nbSites  = _d2Likelihoods_father->size();
00996     for (size_t i = 0; i < nbSites; i++)
00997     {
00998       VVdouble* _d2Likelihoods_father_i = &(*_d2Likelihoods_father)[i];
00999       for (size_t c = 0; c < nbClasses_; c++)
01000       {
01001         Vdouble* _d2Likelihoods_father_i_c = &(*_d2Likelihoods_father_i)[c];
01002         for (size_t s = 0; s < nbStates_; s++)
01003         {
01004           (*_d2Likelihoods_father_i_c)[s] = 1.;
01005         }
01006       }
01007     }
01008 
01009     size_t nbNodes = father->getNumberOfSons();
01010     for (size_t l = 0; l < nbNodes; l++)
01011     {
01012       const Node* son = father->getSon(l);
01013 
01014       if (son->getId() == root1_)
01015       {
01016         const Node* root1 = father->getSon(0);
01017         const Node* root2 = father->getSon(1);
01018         vector<size_t> * _patternLinks_fatherroot1_ = &likelihoodData_->getArrayPositions(father->getId(), root1->getId());
01019         vector<size_t> * _patternLinks_fatherroot2_ = &likelihoodData_->getArrayPositions(father->getId(), root2->getId());
01020         VVVdouble* _likelihoodsroot1_ = &likelihoodData_->getLikelihoodArray(root1->getId());
01021         VVVdouble* _likelihoodsroot2_ = &likelihoodData_->getLikelihoodArray(root2->getId());
01022         double len = getParameterValue("BrLenRoot");
01023 
01024         VVVdouble* d2pxy_root1_ = &d2pxy_[root1_];
01025         VVVdouble* d2pxy_root2_ = &d2pxy_[root2_];
01026         VVVdouble* dpxy_root1_  = &dpxy_[root1_];
01027         VVVdouble* dpxy_root2_  = &dpxy_[root2_];
01028         VVVdouble* pxy_root1_   = &pxy_[root1_];
01029         VVVdouble* pxy_root2_   = &pxy_[root2_];
01030         for (size_t i = 0; i < nbSites; i++)
01031         {
01032           VVdouble* _likelihoodsroot1__i = &(*_likelihoodsroot1_)[(*_patternLinks_fatherroot1_)[i]];
01033           VVdouble* _likelihoodsroot2__i = &(*_likelihoodsroot2_)[(*_patternLinks_fatherroot2_)[i]];
01034           VVdouble* _d2Likelihoods_father_i = &(*_d2Likelihoods_father)[i];
01035           for (size_t c = 0; c < nbClasses_; c++)
01036           {
01037             Vdouble* _likelihoodsroot1__i_c = &(*_likelihoodsroot1__i)[c];
01038             Vdouble* _likelihoodsroot2__i_c = &(*_likelihoodsroot2__i)[c];
01039             Vdouble* _d2Likelihoods_father_i_c = &(*_d2Likelihoods_father_i)[c];
01040             VVdouble* d2pxy_root1__c = &(*d2pxy_root1_)[c];
01041             VVdouble* d2pxy_root2__c = &(*d2pxy_root2_)[c];
01042             VVdouble* dpxy_root1__c  = &(*dpxy_root1_)[c];
01043             VVdouble* dpxy_root2__c  = &(*dpxy_root2_)[c];
01044             VVdouble* pxy_root1__c   = &(*pxy_root1_)[c];
01045             VVdouble* pxy_root2__c   = &(*pxy_root2_)[c];
01046             for (size_t x = 0; x < nbStates_; x++)
01047             {
01048               Vdouble* d2pxy_root1__c_x = &(*d2pxy_root1__c)[x];
01049               Vdouble* d2pxy_root2__c_x = &(*d2pxy_root2__c)[x];
01050               Vdouble* dpxy_root1__c_x  = &(*dpxy_root1__c)[x];
01051               Vdouble* dpxy_root2__c_x  = &(*dpxy_root2__c)[x];
01052               Vdouble* pxy_root1__c_x   = &(*pxy_root1__c)[x];
01053               Vdouble* pxy_root2__c_x   = &(*pxy_root2__c)[x];
01054               double d2l1 = 0, d2l2 = 0, dl1 = 0, dl2 = 0, l1 = 0, l2 = 0;
01055               for (size_t y = 0; y < nbStates_; y++)
01056               {
01057                 d2l1 += (*d2pxy_root1__c_x)[y] * (*_likelihoodsroot1__i_c)[y];
01058                 d2l2 += (*d2pxy_root2__c_x)[y] * (*_likelihoodsroot2__i_c)[y];
01059                 dl1  += (*dpxy_root1__c_x)[y]  * (*_likelihoodsroot1__i_c)[y];
01060                 dl2  += (*dpxy_root2__c_x)[y]  * (*_likelihoodsroot2__i_c)[y];
01061                 l1   += (*pxy_root1__c_x)[y]   * (*_likelihoodsroot1__i_c)[y];
01062                 l2   += (*pxy_root2__c_x)[y]   * (*_likelihoodsroot2__i_c)[y];
01063               }
01064               double d2l = len * len * (d2l1 * l2 + d2l2 * l1 - 2 * dl1 * dl2);
01065               (*_d2Likelihoods_father_i_c)[x] *= d2l;
01066             }
01067           }
01068         }
01069       }
01070       else if (son->getId() == root2_)
01071       {
01072         //Do nothing, this was accounted when dealing with root1_
01073       }
01074       else
01075       {
01076         //Account for a putative multifurcation:
01077         vector<size_t> * _patternLinks_father_son = &likelihoodData_->getArrayPositions(father->getId(), son->getId());
01078         VVVdouble* _likelihoods_son = &likelihoodData_->getLikelihoodArray(son->getId());
01079 
01080         VVVdouble* pxy__son = &pxy_[son->getId()];
01081         for (size_t i = 0; i < nbSites; i++)
01082         {
01083           VVdouble* _likelihoods_son_i = &(*_likelihoods_son)[(*_patternLinks_father_son)[i]];
01084           VVdouble* _d2Likelihoods_father_i = &(*_d2Likelihoods_father)[i];
01085           for (size_t c = 0; c < nbClasses_; c++)
01086           {
01087             Vdouble* _likelihoods_son_i_c = &(*_likelihoods_son_i)[c];
01088             Vdouble* _d2Likelihoods_father_i_c = &(*_d2Likelihoods_father_i)[c];
01089             VVdouble* pxy__son_c = &(*pxy__son)[c];
01090             for (size_t x = 0; x < nbStates_; x++)
01091             {
01092               double d2l = 0;
01093               Vdouble* pxy__son_c_x = &(*pxy__son_c)[x];
01094               for (size_t y = 0; y < nbStates_; y++)
01095               {
01096                 d2l += (*pxy__son_c_x)[y] * (*_likelihoods_son_i_c)[y];
01097               }
01098               (*_d2Likelihoods_father_i_c)[x] *= d2l;
01099             }
01100           }
01101         }
01102       }
01103     }
01104     return;
01105   }
01106 
01107   // Get the node with the branch whose length must be derivated:
01108   size_t brI = TextTools::to<size_t>(variable.substr(5));
01109   const Node* branch = nodes_[brI];
01110   const Node* father = branch->getFather();
01111 
01112   // Compute dLikelihoods array for the father node.
01113   // Fist initialize to 1:
01114   VVVdouble* _d2Likelihoods_father = &likelihoodData_->getD2LikelihoodArray(father->getId());
01115   size_t nbSites  = _d2Likelihoods_father->size();
01116   for (size_t i = 0; i < nbSites; i++)
01117   {
01118     VVdouble* _d2Likelihoods_father_i = &(*_d2Likelihoods_father)[i];
01119     for (size_t c = 0; c < nbClasses_; c++)
01120     {
01121       Vdouble* _d2Likelihoods_father_i_c = &(*_d2Likelihoods_father_i)[c];
01122       for (size_t s = 0; s < nbStates_; s++)
01123       {
01124         (*_d2Likelihoods_father_i_c)[s] = 1.;
01125       }
01126     }
01127   }
01128 
01129   size_t nbNodes = father->getNumberOfSons();
01130   for (size_t l = 0; l < nbNodes; l++)
01131   {
01132     const Node* son = father->getSon(l);
01133 
01134     vector<size_t> * _patternLinks_father_son = &likelihoodData_->getArrayPositions(father->getId(), son->getId());
01135     VVVdouble* _likelihoods_son = &likelihoodData_->getLikelihoodArray(son->getId());
01136 
01137     if (son == branch)
01138     {
01139       VVVdouble* d2pxy__son = &d2pxy_[son->getId()];
01140       for (size_t i = 0; i < nbSites; i++)
01141       {
01142         VVdouble* _likelihoods_son_i = &(*_likelihoods_son)[(*_patternLinks_father_son)[i]];
01143         VVdouble* _d2Likelihoods_father_i = &(*_d2Likelihoods_father)[i];
01144         for (size_t c = 0; c < nbClasses_; c++)
01145         {
01146           Vdouble* _likelihoods_son_i_c = &(*_likelihoods_son_i)[c];
01147           Vdouble* _d2Likelihoods_father_i_c = &(*_d2Likelihoods_father_i)[c];
01148           VVdouble* d2pxy__son_c = &(*d2pxy__son)[c];
01149           for (size_t x = 0; x < nbStates_; x++)
01150           {
01151             double d2l = 0;
01152             Vdouble* d2pxy__son_c_x = &(*d2pxy__son_c)[x];
01153             for (size_t y = 0; y < nbStates_; y++)
01154             {
01155               d2l += (*d2pxy__son_c_x)[y] * (*_likelihoods_son_i_c)[y];
01156             }
01157             (*_d2Likelihoods_father_i_c)[x] *= d2l;
01158           }
01159         }
01160       }
01161     }
01162     else
01163     {
01164       VVVdouble* pxy__son = &pxy_[son->getId()];
01165       for (size_t i = 0; i < nbSites; i++)
01166       {
01167         VVdouble* _likelihoods_son_i = &(*_likelihoods_son)[(*_patternLinks_father_son)[i]];
01168         VVdouble* _d2Likelihoods_father_i = &(*_d2Likelihoods_father)[i];
01169         for (size_t c = 0; c < nbClasses_; c++)
01170         {
01171           Vdouble* _likelihoods_son_i_c = &(*_likelihoods_son_i)[c];
01172           Vdouble* _d2Likelihoods_father_i_c = &(*_d2Likelihoods_father_i)[c];
01173           VVdouble* pxy__son_c = &(*pxy__son)[c];
01174           for (size_t x = 0; x < nbStates_; x++)
01175           {
01176             double d2l = 0;
01177             Vdouble* pxy__son_c_x = &(*pxy__son_c)[x];
01178             for (size_t y = 0; y < nbStates_; y++)
01179             {
01180               d2l += (*pxy__son_c_x)[y] * (*_likelihoods_son_i_c)[y];
01181             }
01182             (*_d2Likelihoods_father_i_c)[x] *= d2l;
01183           }
01184         }
01185       }
01186     }
01187   }
01188 
01189   // Now we go down the tree toward the root node:
01190   computeDownSubtreeD2Likelihood(father);
01191 }
01192 
01193 /******************************************************************************/
01194 
01195 void RNonHomogeneousTreeLikelihood::computeDownSubtreeD2Likelihood(const Node* node)
01196 {
01197   const Node* father = node->getFather();
01198   // We assume that the _dLikelihoods array has been filled for the current node 'node'.
01199   // We will evaluate the array for the father node.
01200   if (father == 0) return; // We reached the root!
01201 
01202   // Compute dLikelihoods array for the father node.
01203   // Fist initialize to 1:
01204   VVVdouble* _d2Likelihoods_father = &likelihoodData_->getD2LikelihoodArray(father->getId());
01205   size_t nbSites  = _d2Likelihoods_father->size();
01206   for (size_t i = 0; i < nbSites; i++)
01207   {
01208     VVdouble* _d2Likelihoods_father_i = &(*_d2Likelihoods_father)[i];
01209     for (size_t c = 0; c < nbClasses_; c++)
01210     {
01211       Vdouble* _d2Likelihoods_father_i_c = &(*_d2Likelihoods_father_i)[c];
01212       for (size_t s = 0; s < nbStates_; s++)
01213       {
01214         (*_d2Likelihoods_father_i_c)[s] = 1.;
01215       }
01216     }
01217   }
01218 
01219   size_t nbNodes = father->getNumberOfSons();
01220   for (size_t l = 0; l < nbNodes; l++)
01221   {
01222     const Node* son = father->getSon(l);
01223 
01224     VVVdouble* pxy__son = &pxy_[son->getId()];
01225     vector<size_t> * _patternLinks_father_son = &likelihoodData_->getArrayPositions(father->getId(), son->getId());
01226 
01227     if (son == node)
01228     {
01229       VVVdouble* _d2Likelihoods_son = &likelihoodData_->getD2LikelihoodArray(son->getId());
01230       for (size_t i = 0; i < nbSites; i++)
01231       {
01232         VVdouble* _d2Likelihoods_son_i = &(*_d2Likelihoods_son)[(*_patternLinks_father_son)[i]];
01233         VVdouble* _d2Likelihoods_father_i = &(*_d2Likelihoods_father)[i];
01234         for (size_t c = 0; c < nbClasses_; c++)
01235         {
01236           Vdouble* _d2Likelihoods_son_i_c = &(*_d2Likelihoods_son_i)[c];
01237           Vdouble* _d2Likelihoods_father_i_c = &(*_d2Likelihoods_father_i)[c];
01238           VVdouble* pxy__son_c = &(*pxy__son)[c];
01239           for (size_t x = 0; x < nbStates_; x++)
01240           {
01241             double d2l = 0;
01242             Vdouble* pxy__son_c_x = &(*pxy__son_c)[x];
01243             for (size_t y = 0; y < nbStates_; y++)
01244             {
01245               d2l += (*pxy__son_c_x)[y] * (*_d2Likelihoods_son_i_c)[y];
01246             }
01247             (*_d2Likelihoods_father_i_c)[x] *= d2l;
01248           }
01249         }
01250       }
01251     }
01252     else
01253     {
01254       VVVdouble* _likelihoods_son = &likelihoodData_->getLikelihoodArray(son->getId());
01255       for (size_t i = 0; i < nbSites; i++)
01256       {
01257         VVdouble* _likelihoods_son_i = &(*_likelihoods_son)[(*_patternLinks_father_son)[i]];
01258         VVdouble* _d2Likelihoods_father_i = &(*_d2Likelihoods_father)[i];
01259         for (size_t c = 0; c < nbClasses_; c++)
01260         {
01261           Vdouble* _likelihoods_son_i_c = &(*_likelihoods_son_i)[c];
01262           Vdouble* _d2Likelihoods_father_i_c = &(*_d2Likelihoods_father_i)[c];
01263           VVdouble* pxy__son_c = &(*pxy__son)[c];
01264           for (size_t x = 0; x < nbStates_; x++)
01265           {
01266             double dl = 0;
01267             Vdouble* pxy__son_c_x = &(*pxy__son_c)[x];
01268             for (size_t y = 0; y < nbStates_; y++)
01269             {
01270               dl += (*pxy__son_c_x)[y] * (*_likelihoods_son_i_c)[y];
01271             }
01272             (*_d2Likelihoods_father_i_c)[x] *= dl;
01273           }
01274         }
01275       }
01276     }
01277   }
01278 
01279   //Next step: move toward grand father...
01280   computeDownSubtreeD2Likelihood(father);
01281 }
01282 
01283 /******************************************************************************/
01284 
01285 void RNonHomogeneousTreeLikelihood::computeTreeLikelihood()
01286 {
01287   computeSubtreeLikelihood(tree_->getRootNode());
01288 }
01289 
01290 /******************************************************************************/
01291 
01292 void RNonHomogeneousTreeLikelihood::computeSubtreeLikelihood(const Node* node)
01293 {
01294   if (node->isLeaf()) return;
01295 
01296   size_t nbSites  = likelihoodData_->getLikelihoodArray(node->getId()).size();
01297   size_t nbNodes  = node->getNumberOfSons();
01298 
01299   // Must reset the likelihood array first (i.e. set all of them to 1):
01300   VVVdouble* _likelihoods_node = &likelihoodData_->getLikelihoodArray(node->getId());
01301   for (size_t i = 0; i < nbSites; i++)
01302   {
01303     //For each site in the sequence,
01304     VVdouble* _likelihoods_node_i = &(*_likelihoods_node)[i];
01305     for (size_t c = 0; c < nbClasses_; c++)
01306     {
01307       //For each rate classe,
01308       Vdouble* _likelihoods_node_i_c = &(*_likelihoods_node_i)[c];
01309       for (size_t x = 0; x < nbStates_; x++)
01310       {
01311         //For each initial state,
01312         (*_likelihoods_node_i_c)[x] = 1.;
01313       }
01314     }
01315   }
01316 
01317   for (size_t l = 0; l < nbNodes; l++)
01318   {
01319     //For each son node,
01320 
01321     const Node* son = node->getSon(l);
01322 
01323     computeSubtreeLikelihood(son); //Recursive method:
01324 
01325     VVVdouble* pxy__son = &pxy_[son->getId()];
01326     vector<size_t> * _patternLinks_node_son = &likelihoodData_->getArrayPositions(node->getId(), son->getId());
01327     VVVdouble* _likelihoods_son = &likelihoodData_->getLikelihoodArray(son->getId());
01328 
01329     for (size_t i = 0; i < nbSites; i++)
01330     {
01331       //For each site in the sequence,
01332       VVdouble* _likelihoods_son_i = &(*_likelihoods_son)[(*_patternLinks_node_son)[i]];
01333       VVdouble* _likelihoods_node_i = &(*_likelihoods_node)[i];
01334       for (size_t c = 0; c < nbClasses_; c++)
01335       {
01336         //For each rate classe,
01337         Vdouble* _likelihoods_son_i_c = &(*_likelihoods_son_i)[c];
01338         Vdouble* _likelihoods_node_i_c = &(*_likelihoods_node_i)[c];
01339         VVdouble* pxy__son_c = &(*pxy__son)[c];
01340         for (size_t x = 0; x < nbStates_; x++)
01341         {
01342           //For each initial state,
01343           Vdouble* pxy__son_c_x = &(*pxy__son_c)[x];
01344           double likelihood = 0;
01345           for (size_t y = 0; y < nbStates_; y++)
01346           {
01347             likelihood += (*pxy__son_c_x)[y] * (*_likelihoods_son_i_c)[y];
01348           }
01349           (*_likelihoods_node_i_c)[x] *= likelihood;
01350         }
01351       }
01352     }
01353   }
01354 }
01355 
01356 
01357 /******************************************************************************/
01358 
01359 void RNonHomogeneousTreeLikelihood::displayLikelihood(const Node* node)
01360 {
01361   cout << "Likelihoods at node " << node->getName() << ": " << endl;
01362   displayLikelihoodArray(likelihoodData_->getLikelihoodArray(node->getId()));
01363   cout << "                                         ***" << endl;
01364 }
01365 
 All Classes Namespaces Files Functions Variables Typedefs Friends