|
bpp-phyl
2.1.0
|
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