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