bpp-phyl3 3.0.0
DRHomogeneousTreeLikelihood.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: The Bio++ Development Group
2//
3// SPDX-License-Identifier: CECILL-2.1
4
5#include "../../PatternTools.h"
7
8// From SeqLib:
9#include <Bpp/Seq/SiteTools.h>
12
13#include <Bpp/Text/TextTools.h>
15
16using namespace bpp;
17
18// From the STL:
19#include <iostream>
20
21using namespace std;
22
23/******************************************************************************/
24
25DRHomogeneousTreeLikelihood::DRHomogeneousTreeLikelihood(
26 const Tree& tree,
27 std::shared_ptr<TransitionModelInterface> model,
28 std::shared_ptr<DiscreteDistributionInterface> rDist,
29 bool checkRooted,
30 bool verbose) :
31 AbstractHomogeneousTreeLikelihood(tree, model, rDist, checkRooted, verbose),
32 likelihoodData_(),
33 minusLogLik_(-1.)
34{
35 init_();
36}
37
38/******************************************************************************/
39
41 const Tree& tree,
42 const AlignmentDataInterface& data,
43 std::shared_ptr<TransitionModelInterface> model,
44 std::shared_ptr<DiscreteDistributionInterface> rDist,
45 bool checkRooted,
46 bool verbose) :
47 AbstractHomogeneousTreeLikelihood(tree, model, rDist, checkRooted, verbose),
48 likelihoodData_(),
49 minusLogLik_(-1.)
50{
51 init_();
53}
54
55/******************************************************************************/
56
58{
59 likelihoodData_ = make_unique<DRASDRTreeLikelihoodData>(
60 tree_,
61 rateDistribution_->getNumberOfCategories());
62}
63
64/******************************************************************************/
65
68 likelihoodData_(),
69 minusLogLik_(-1.)
70{
71 likelihoodData_ = unique_ptr<DRASDRTreeLikelihoodData>(lik.likelihoodData_->clone());
72 likelihoodData_->setTree(tree_);
74}
75
76/******************************************************************************/
77
79{
81 likelihoodData_ = unique_ptr<DRASDRTreeLikelihoodData>(lik.likelihoodData_->clone());
82 likelihoodData_->setTree(tree_);
84 return *this;
85}
86
87/******************************************************************************/
88
90{
91 data_ = PatternTools::getSequenceSubset(sites, *tree_->getRootNode());
92 if (verbose_)
93 ApplicationTools::displayTask("Initializing data structure");
94 likelihoodData_->initLikelihoods(*data_, *model_);
95 if (verbose_)
97
98 nbSites_ = likelihoodData_->getNumberOfSites();
99 nbDistinctSites_ = likelihoodData_->getNumberOfDistinctSites();
100 nbStates_ = likelihoodData_->getNumberOfStates();
101
102 if (verbose_)
103 ApplicationTools::displayResult("Number of distinct sites",
105 initialized_ = false;
106}
107
108/******************************************************************************/
109
111{
112 double l = 1.;
113 Vdouble* lik = &likelihoodData_->getRootRateSiteLikelihoodArray();
114 const vector<unsigned int>* w = &likelihoodData_->getWeights();
115 for (size_t i = 0; i < nbDistinctSites_; i++)
116 {
117 l *= std::pow((*lik)[i], (int)(*w)[i]);
118 }
119
120 return l;
121}
122
123/******************************************************************************/
124
126{
127 double ll = 0;
128 Vdouble* lik = &likelihoodData_->getRootRateSiteLikelihoodArray();
129 const vector<unsigned int>* w = &likelihoodData_->getWeights();
130 vector<double> la(nbDistinctSites_);
131 for (size_t i = 0; i < nbDistinctSites_; i++)
132 {
133 la[i] = (*w)[i] * log((*lik)[i]);
134 }
135
136 sort(la.begin(), la.end());
137 for (size_t i = nbDistinctSites_; i > 0; i--)
138 {
139 ll += la[i - 1];
140 }
141 return ll;
142}
143
144/******************************************************************************/
145
147{
148 return likelihoodData_->getRootRateSiteLikelihoodArray()[likelihoodData_->getRootArrayPosition(site)];
149}
150
151/******************************************************************************/
152
154{
155 return log(likelihoodData_->getRootRateSiteLikelihoodArray()[likelihoodData_->getRootArrayPosition(site)]);
156}
157
158/******************************************************************************/
160{
161 return likelihoodData_->getRootSiteLikelihoodArray()[likelihoodData_->getRootArrayPosition(site)][rateClass];
162}
163
164/******************************************************************************/
165
167{
168 return log(likelihoodData_->getRootSiteLikelihoodArray()[likelihoodData_->getRootArrayPosition(site)][rateClass]);
169}
170
171/******************************************************************************/
172
173double DRHomogeneousTreeLikelihood::getLikelihoodForASiteForARateClassForAState(size_t site, size_t rateClass, int state) const
174{
175 return likelihoodData_->getRootLikelihoodArray()[likelihoodData_->getRootArrayPosition(site)][rateClass][static_cast<size_t>(state)];
176}
177
178/******************************************************************************/
179
180double DRHomogeneousTreeLikelihood::getLogLikelihoodForASiteForARateClassForAState(size_t site, size_t rateClass, int state) const
181{
182 return log(likelihoodData_->getRootLikelihoodArray()[likelihoodData_->getRootArrayPosition(site)][rateClass][static_cast<size_t>(state)]);
183}
184
185/******************************************************************************/
186
188{
189 setParametersValues(parameters);
190}
191
192/******************************************************************************/
193
195{
197
198 if (rateDistribution_->getParameters().getCommonParametersWith(params).size() > 0
199 || model_->getParameters().getCommonParametersWith(params).size() > 0)
200 {
201 // Rate parameter changed, need to recompute all probs:
203 }
204 else if (params.size() > 0)
205 {
206 // We may save some computations:
207 for (size_t i = 0; i < params.size(); i++)
208 {
209 string s = params[i].getName();
210 if (s.substr(0, 5) == "BrLen")
211 {
212 // Branch length parameter:
213 computeTransitionProbabilitiesForNode(nodes_[TextTools::to< size_t >(s.substr(5))]);
214 }
215 }
216 }
217
220 {
222 }
224 {
226 }
227
229}
230
231/******************************************************************************/
232
234{
235 if (!isInitialized())
236 throw Exception("DRHomogeneousTreeLikelihood::getValue(). Instance is not initialized.");
237 return minusLogLik_;
238}
239
240/******************************************************************************
241 * First Order Derivatives *
242 ******************************************************************************/
244{
245 const Node* father = node->getFather();
246 VVVdouble* likelihoods_father_node = &likelihoodData_->getLikelihoodArray(father->getId(), node->getId());
247 Vdouble* dLikelihoods_node = &likelihoodData_->getDLikelihoodArray(node->getId());
248 VVVdouble* dpxy_node = &dpxy_[node->getId()];
249 VVVdouble larray;
250 computeLikelihoodAtNode_(father, larray, node);
251
252 Vdouble* rootLikelihoodsSR = &likelihoodData_->getRootRateSiteLikelihoodArray();
253
254 double dLi, dLic, dLicx;
255
256 for (size_t i = 0; i < nbDistinctSites_; i++)
257 {
258 VVdouble* likelihoods_father_node_i = &(*likelihoods_father_node)[i];
259 VVdouble* larray_i = &larray[i];
260 dLi = 0;
261 for (size_t c = 0; c < nbClasses_; c++)
262 {
263 Vdouble* likelihoods_father_node_i_c = &(*likelihoods_father_node_i)[c];
264 Vdouble* larray_i_c = &(*larray_i)[c];
265 VVdouble* dpxy_node_c = &(*dpxy_node)[c];
266 dLic = 0;
267 for (size_t x = 0; x < nbStates_; x++)
268 {
269 Vdouble* dpxy_node_c_x = &(*dpxy_node_c)[x];
270 dLicx = 0;
271 for (size_t y = 0; y < nbStates_; y++)
272 {
273 dLicx += (*dpxy_node_c_x)[y] * (*likelihoods_father_node_i_c)[y];
274 }
275 dLicx *= (*larray_i_c)[x];
276 dLic += dLicx;
277 }
278 dLi += rateDistribution_->getProbability(c) * dLic;
279 }
280
281 (*dLikelihoods_node)[i] = dLi / (*rootLikelihoodsSR)[i];
282 // cout << dLi << "\t" << (*rootLikelihoodsSR)[i] << endl;
283 }
284}
285
286/******************************************************************************/
287
289{
290 for (size_t k = 0; k < nbNodes_; k++)
291 {
293 }
294}
295
296/******************************************************************************/
297
298double DRHomogeneousTreeLikelihood::getFirstOrderDerivative(const std::string& variable) const
299{
300 if (!hasParameter(variable))
301 throw ParameterNotFoundException("DRHomogeneousTreeLikelihood::getFirstOrderDerivative().", variable);
303 {
304 throw Exception("Derivatives respective to rate distribution parameters are not implemented.");
305 }
307 {
308 throw Exception("Derivatives respective to substitution model parameters are not implemented.");
309 }
310
311 //
312 // Computation for branch lengths:
313 //
314
315 // Get the node with the branch whose length must be derivated:
316 size_t brI = TextTools::to<size_t>(variable.substr(5));
317 const Node* branch = nodes_[brI];
318 Vdouble* dLikelihoods_branch = &likelihoodData_->getDLikelihoodArray(branch->getId());
319 double d = 0;
320 const vector<unsigned int>* w = &likelihoodData_->getWeights();
321 for (size_t i = 0; i < nbDistinctSites_; i++)
322 {
323 d += (*w)[i] * (*dLikelihoods_branch)[i];
324 }
325
326 return -d;
327}
328
329/******************************************************************************
330 * Second Order Derivatives *
331 ******************************************************************************/
333{
334 const Node* father = node->getFather();
335 VVVdouble* likelihoods_father_node = &likelihoodData_->getLikelihoodArray(father->getId(), node->getId());
336 Vdouble* d2Likelihoods_node = &likelihoodData_->getD2LikelihoodArray(node->getId());
337 VVVdouble* d2pxy_node = &d2pxy_[node->getId()];
338 VVVdouble larray;
339 computeLikelihoodAtNode_(father, larray, node);
340 Vdouble* rootLikelihoodsSR = &likelihoodData_->getRootRateSiteLikelihoodArray();
341
342 double d2Li, d2Lic, d2Licx;
343
344 for (size_t i = 0; i < nbDistinctSites_; i++)
345 {
346 VVdouble* likelihoods_father_node_i = &(*likelihoods_father_node)[i];
347 VVdouble* larray_i = &larray[i];
348 d2Li = 0;
349 for (size_t c = 0; c < nbClasses_; c++)
350 {
351 Vdouble* likelihoods_father_node_i_c = &(*likelihoods_father_node_i)[c];
352 Vdouble* larray_i_c = &(*larray_i)[c];
353 VVdouble* d2pxy_node_c = &(*d2pxy_node)[c];
354 d2Lic = 0;
355 for (size_t x = 0; x < nbStates_; x++)
356 {
357 Vdouble* d2pxy_node_c_x = &(*d2pxy_node_c)[x];
358 d2Licx = 0;
359 for (size_t y = 0; y < nbStates_; y++)
360 {
361 d2Licx += (*d2pxy_node_c_x)[y] * (*likelihoods_father_node_i_c)[y];
362 }
363 d2Licx *= (*larray_i_c)[x];
364 d2Lic += d2Licx;
365 }
366 d2Li += rateDistribution_->getProbability(c) * d2Lic;
367 }
368 (*d2Likelihoods_node)[i] = d2Li / (*rootLikelihoodsSR)[i];
369 }
370}
371
372/******************************************************************************/
373
375{
376 for (size_t k = 0; k < nbNodes_; k++)
377 {
379 }
380}
381
382/******************************************************************************/
383
384double DRHomogeneousTreeLikelihood::getSecondOrderDerivative(const std::string& variable) const
385{
386 if (!hasParameter(variable))
387 throw ParameterNotFoundException("DRHomogeneousTreeLikelihood::getSecondOrderDerivative().", variable);
389 {
390 throw Exception("Derivatives respective to rate distribution parameters are not implemented.");
391 }
393 {
394 throw Exception("Derivatives respective to substitution model parameters are not implemented.");
395 }
396
397 //
398 // Computation for branch lengths:
399 //
400
401 // Get the node with the branch whose length must be derivated:
402 size_t brI = TextTools::to<size_t>(variable.substr(5));
403 const Node* branch = nodes_[brI];
404 Vdouble* _dLikelihoods_branch = &likelihoodData_->getDLikelihoodArray(branch->getId());
405 Vdouble* _d2Likelihoods_branch = &likelihoodData_->getD2LikelihoodArray(branch->getId());
406 double d2 = 0;
407 const vector<unsigned int>* w = &likelihoodData_->getWeights();
408 for (size_t i = 0; i < nbDistinctSites_; i++)
409 {
410 d2 += (*w)[i] * ((*_d2Likelihoods_branch)[i] - pow((*_dLikelihoods_branch)[i], 2));
411 }
412 return -d2;
413}
414
415/******************************************************************************/
416
418{
419 for (size_t n = 0; n < node->getNumberOfSons(); n++)
420 {
421 const Node* subNode = node->getSon(n);
422 resetLikelihoodArray(likelihoodData_->getLikelihoodArray(node->getId(), subNode->getId()));
423 }
424 if (node->hasFather())
425 {
426 const Node* father = node->getFather();
427 resetLikelihoodArray(likelihoodData_->getLikelihoodArray(node->getId(), father->getId()));
428 }
429}
430
431/******************************************************************************/
432
434{
438}
439
440/******************************************************************************/
441
443{
444 // if(node->isLeaf()) return;
445 // cout << node->getId() << "\t" << (node->hasName()?node->getName():"") << endl;
446 if (node->getNumberOfSons() == 0)
447 return;
448
449 // Set all likelihood arrays to 1 for a start:
451
452 map<int, VVVdouble>* _likelihoods_node = &likelihoodData_->getLikelihoodArrays(node->getId());
453 size_t nbNodes = node->getNumberOfSons();
454 for (size_t l = 0; l < nbNodes; l++)
455 {
456 // For each son node...
457
458 const Node* son = node->getSon(l);
459 VVVdouble* _likelihoods_node_son = &(*_likelihoods_node)[son->getId()];
460
461 if (son->isLeaf())
462 {
463 VVdouble* _likelihoods_leaf = &likelihoodData_->getLeafLikelihoods(son->getId());
464 for (size_t i = 0; i < nbDistinctSites_; i++)
465 {
466 // For each site in the sequence,
467 Vdouble* _likelihoods_leaf_i = &(*_likelihoods_leaf)[i];
468 VVdouble* _likelihoods_node_son_i = &(*_likelihoods_node_son)[i];
469 for (size_t c = 0; c < nbClasses_; c++)
470 {
471 // For each rate class,
472 Vdouble* _likelihoods_node_son_i_c = &(*_likelihoods_node_son_i)[c];
473 for (size_t x = 0; x < nbStates_; x++)
474 {
475 // For each initial state,
476 (*_likelihoods_node_son_i_c)[x] = (*_likelihoods_leaf_i)[x];
477 }
478 }
479 }
480 }
481 else
482 {
483 computeSubtreeLikelihoodPostfix(son); // Recursive method:
484 size_t nbSons = son->getNumberOfSons();
485 map<int, VVVdouble>* _likelihoods_son = &likelihoodData_->getLikelihoodArrays(son->getId());
486
487 vector<const VVVdouble*> iLik(nbSons);
488 vector<const VVVdouble*> tProb(nbSons);
489 for (size_t n = 0; n < nbSons; n++)
490 {
491 const Node* sonSon = son->getSon(n);
492 tProb[n] = &pxy_[sonSon->getId()];
493 iLik[n] = &(*_likelihoods_son)[sonSon->getId()];
494 }
495 computeLikelihoodFromArrays(iLik, tProb, *_likelihoods_node_son, nbSons, nbDistinctSites_, nbClasses_, nbStates_, false);
496 }
497 }
498}
499
500/******************************************************************************/
501
503{
504 if (!node->hasFather())
505 {
506 // 'node' is the root of the tree.
507 // Just call the method on each son node:
508 size_t nbSons = node->getNumberOfSons();
509 for (size_t n = 0; n < nbSons; n++)
510 {
512 }
513 return;
514 }
515 else
516 {
517 const Node* father = node->getFather();
518 map<int, VVVdouble>* _likelihoods_node = &likelihoodData_->getLikelihoodArrays(node->getId());
519 map<int, VVVdouble>* _likelihoods_father = &likelihoodData_->getLikelihoodArrays(father->getId());
520 VVVdouble* _likelihoods_node_father = &(*_likelihoods_node)[father->getId()];
521 if (node->isLeaf())
522 {
523 resetLikelihoodArray(*_likelihoods_node_father);
524 }
525
526 if (father->isLeaf())
527 {
528 // If the tree is rooted by a leaf
529 VVdouble* _likelihoods_leaf = &likelihoodData_->getLeafLikelihoods(father->getId());
530 for (size_t i = 0; i < nbDistinctSites_; i++)
531 {
532 // For each site in the sequence,
533 Vdouble* _likelihoods_leaf_i = &(*_likelihoods_leaf)[i];
534 VVdouble* _likelihoods_node_father_i = &(*_likelihoods_node_father)[i];
535 for (size_t c = 0; c < nbClasses_; c++)
536 {
537 // For each rate class,
538 Vdouble* _likelihoods_node_father_i_c = &(*_likelihoods_node_father_i)[c];
539 for (size_t x = 0; x < nbStates_; x++)
540 {
541 // For each initial state,
542 (*_likelihoods_node_father_i_c)[x] = (*_likelihoods_leaf_i)[x];
543 }
544 }
545 }
546 }
547 else
548 {
549 vector<const Node*> nodes;
550 // Add brothers:
551 size_t nbFatherSons = father->getNumberOfSons();
552 for (size_t n = 0; n < nbFatherSons; n++)
553 {
554 const Node* son = father->getSon(n);
555 if (son->getId() != node->getId())
556 nodes.push_back(son); // This is a real brother, not current node!
557 }
558 // Now the real stuff... We've got to compute the likelihoods for the
559 // subtree defined by node 'father'.
560 // This is the same as postfix method, but with different subnodes.
561
562 size_t nbSons = nodes.size(); // In case of a bifurcating tree, this is equal to 1, excepted for the root.
563
564 vector<const VVVdouble*> iLik(nbSons);
565 vector<const VVVdouble*> tProb(nbSons);
566 for (size_t n = 0; n < nbSons; n++)
567 {
568 const Node* fatherSon = nodes[n];
569 tProb[n] = &pxy_[fatherSon->getId()];
570 iLik[n] = &(*_likelihoods_father)[fatherSon->getId()];
571 }
572
573 if (father->hasFather())
574 {
575 const Node* fatherFather = father->getFather();
576 computeLikelihoodFromArrays(iLik, tProb, &(*_likelihoods_father)[fatherFather->getId()], &pxy_[father->getId()], *_likelihoods_node_father, nbSons, nbDistinctSites_, nbClasses_, nbStates_, false);
577 }
578 else
579 {
580 computeLikelihoodFromArrays(iLik, tProb, *_likelihoods_node_father, nbSons, nbDistinctSites_, nbClasses_, nbStates_, false);
581 }
582 }
583
584 if (!father->hasFather())
585 {
586 // We have to account for the root frequencies:
587 for (size_t i = 0; i < nbDistinctSites_; i++)
588 {
589 VVdouble* _likelihoods_node_father_i = &(*_likelihoods_node_father)[i];
590 for (size_t c = 0; c < nbClasses_; c++)
591 {
592 Vdouble* _likelihoods_node_father_i_c = &(*_likelihoods_node_father_i)[c];
593 for (size_t x = 0; x < nbStates_; x++)
594 {
595 (*_likelihoods_node_father_i_c)[x] *= rootFreqs_[x];
596 }
597 }
598 }
599 }
600
601 // Call the method on each son node:
602 size_t nbNodeSons = node->getNumberOfSons();
603 for (size_t i = 0; i < nbNodeSons; i++)
604 {
605 computeSubtreeLikelihoodPrefix(node->getSon(i)); // Recursive method.
606 }
607 }
608}
609
610/******************************************************************************/
611
613{
614 const Node* root = tree_->getRootNode();
615 VVVdouble* rootLikelihoods = &likelihoodData_->getRootLikelihoodArray();
616 // Set all likelihoods to 1 for a start:
617 if (root->isLeaf())
618 {
619 VVdouble* leavesLikelihoods_root = &likelihoodData_->getLeafLikelihoods(root->getId());
620 for (size_t i = 0; i < nbDistinctSites_; i++)
621 {
622 VVdouble* rootLikelihoods_i = &(*rootLikelihoods)[i];
623 Vdouble* leavesLikelihoods_root_i = &(*leavesLikelihoods_root)[i];
624 for (size_t c = 0; c < nbClasses_; c++)
625 {
626 Vdouble* rootLikelihoods_i_c = &(*rootLikelihoods_i)[c];
627 for (size_t x = 0; x < nbStates_; x++)
628 {
629 (*rootLikelihoods_i_c)[x] = (*leavesLikelihoods_root_i)[x];
630 }
631 }
632 }
633 }
634 else
635 {
636 resetLikelihoodArray(*rootLikelihoods);
637 }
638
639 map<int, VVVdouble>* likelihoods_root = &likelihoodData_->getLikelihoodArrays(root->getId());
640 size_t nbNodes = root->getNumberOfSons();
641 vector<const VVVdouble*> iLik(nbNodes);
642 vector<const VVVdouble*> tProb(nbNodes);
643 for (size_t n = 0; n < nbNodes; n++)
644 {
645 const Node* son = root->getSon(n);
646 tProb[n] = &pxy_[son->getId()];
647 iLik[n] = &(*likelihoods_root)[son->getId()];
648 }
649 computeLikelihoodFromArrays(iLik, tProb, *rootLikelihoods, nbNodes, nbDistinctSites_, nbClasses_, nbStates_, false);
650
651 Vdouble p = rateDistribution_->getProbabilities();
652 VVdouble* rootLikelihoodsS = &likelihoodData_->getRootSiteLikelihoodArray();
653 Vdouble* rootLikelihoodsSR = &likelihoodData_->getRootRateSiteLikelihoodArray();
654 for (size_t i = 0; i < nbDistinctSites_; i++)
655 {
656 // For each site in the sequence,
657 VVdouble* rootLikelihoods_i = &(*rootLikelihoods)[i];
658 Vdouble* rootLikelihoodsS_i = &(*rootLikelihoodsS)[i];
659 (*rootLikelihoodsSR)[i] = 0;
660 for (size_t c = 0; c < nbClasses_; c++)
661 {
662 // For each rate class,
663 Vdouble* rootLikelihoods_i_c = &(*rootLikelihoods_i)[c];
664 double* rootLikelihoodsS_i_c = &(*rootLikelihoodsS_i)[c];
665 (*rootLikelihoodsS_i_c) = 0;
666 for (size_t x = 0; x < nbStates_; x++)
667 {
668 // For each initial state,
669 (*rootLikelihoodsS_i_c) += rootFreqs_[x] * (*rootLikelihoods_i_c)[x];
670 }
671 (*rootLikelihoodsSR)[i] += p[c] * (*rootLikelihoodsS_i_c);
672 }
673
674 // Final checking (for numerical errors):
675 if ((*rootLikelihoodsSR)[i] < 0)
676 (*rootLikelihoodsSR)[i] = 0.;
677 }
678}
679
680/******************************************************************************/
681
682void DRHomogeneousTreeLikelihood::computeLikelihoodAtNode_(const Node* node, VVVdouble& likelihoodArray, const Node* sonNode) const
683{
684 // const Node * node = tree_->getNode(nodeId);
685 int nodeId = node->getId();
686 likelihoodArray.resize(nbDistinctSites_);
687 map<int, VVVdouble>* likelihoods_node = &likelihoodData_->getLikelihoodArrays(nodeId);
688
689 // Initialize likelihood array:
690 if (node->isLeaf())
691 {
692 VVdouble* leavesLikelihoods_node = &likelihoodData_->getLeafLikelihoods(nodeId);
693 for (size_t i = 0; i < nbDistinctSites_; i++)
694 {
695 VVdouble* likelihoodArray_i = &likelihoodArray[i];
696 Vdouble* leavesLikelihoods_node_i = &(*leavesLikelihoods_node)[i];
697 likelihoodArray_i->resize(nbClasses_);
698 for (size_t c = 0; c < nbClasses_; c++)
699 {
700 Vdouble* likelihoodArray_i_c = &(*likelihoodArray_i)[c];
701 likelihoodArray_i_c->resize(nbStates_);
702 for (size_t x = 0; x < nbStates_; x++)
703 {
704 (*likelihoodArray_i_c)[x] = (*leavesLikelihoods_node_i)[x];
705 }
706 }
707 }
708 }
709 else
710 {
711 // Otherwise:
712 // Set all likelihoods to 1 for a start:
713 for (size_t i = 0; i < nbDistinctSites_; i++)
714 {
715 VVdouble* likelihoodArray_i = &likelihoodArray[i];
716 likelihoodArray_i->resize(nbClasses_);
717 for (size_t c = 0; c < nbClasses_; c++)
718 {
719 Vdouble* likelihoodArray_i_c = &(*likelihoodArray_i)[c];
720 likelihoodArray_i_c->resize(nbStates_);
721 for (size_t x = 0; x < nbStates_; x++)
722 {
723 (*likelihoodArray_i_c)[x] = 1.;
724 }
725 }
726 }
727 }
728
729 size_t nbNodes = node->getNumberOfSons();
730
731 vector<const VVVdouble*> iLik;
732 vector<const VVVdouble*> tProb;
733 bool test = false;
734 for (size_t n = 0; n < nbNodes; n++)
735 {
736 const Node* son = node->getSon(n);
737 if (son != sonNode)
738 {
739 tProb.push_back(&pxy_[son->getId()]);
740 iLik.push_back(&(*likelihoods_node)[son->getId()]);
741 }
742 else
743 {
744 test = true;
745 }
746 }
747 if (sonNode)
748 {
749 if (test)
750 nbNodes--;
751 else
752 throw Exception("DRHomogeneousTreeLikelihood::computeLikelihoodAtNode_(...). 'sonNode' not found as a son of 'node'.");
753 }
754
755 if (node->hasFather())
756 {
757 const Node* father = node->getFather();
758 computeLikelihoodFromArrays(iLik, tProb, &(*likelihoods_node)[father->getId()], &pxy_[nodeId], likelihoodArray, nbNodes, nbDistinctSites_, nbClasses_, nbStates_, false);
759 }
760 else
761 {
762 computeLikelihoodFromArrays(iLik, tProb, likelihoodArray, nbNodes, nbDistinctSites_, nbClasses_, nbStates_, false);
763
764 // We have to account for the equilibrium frequencies:
765 for (size_t i = 0; i < nbDistinctSites_; i++)
766 {
767 VVdouble* likelihoodArray_i = &likelihoodArray[i];
768 for (size_t c = 0; c < nbClasses_; c++)
769 {
770 Vdouble* likelihoodArray_i_c = &(*likelihoodArray_i)[c];
771 for (size_t x = 0; x < nbStates_; x++)
772 {
773 (*likelihoodArray_i_c)[x] *= rootFreqs_[x];
774 }
775 }
776 }
777 }
778}
779
780/******************************************************************************/
781
783 const vector<const VVVdouble*>& iLik,
784 const vector<const VVVdouble*>& tProb,
785 VVVdouble& oLik,
786 size_t nbNodes,
787 size_t nbDistinctSites,
788 size_t nbClasses,
789 size_t nbStates,
790 bool reset)
791{
792 if (reset)
794
795 for (size_t n = 0; n < nbNodes; n++)
796 {
797 const VVVdouble* pxy_n = tProb[n];
798 const VVVdouble* iLik_n = iLik[n];
799
800 for (size_t i = 0; i < nbDistinctSites; i++)
801 {
802 // For each site in the sequence,
803 const VVdouble* iLik_n_i = &(*iLik_n)[i];
804 VVdouble* oLik_i = &(oLik)[i];
805
806 for (size_t c = 0; c < nbClasses; c++)
807 {
808 // For each rate class,
809 const Vdouble* iLik_n_i_c = &(*iLik_n_i)[c];
810 Vdouble* oLik_i_c = &(*oLik_i)[c];
811 const VVdouble* pxy_n_c = &(*pxy_n)[c];
812 for (size_t x = 0; x < nbStates; x++)
813 {
814 // For each initial state,
815 const Vdouble* pxy_n_c_x = &(*pxy_n_c)[x];
816 double likelihood = 0;
817 for (size_t y = 0; y < nbStates; y++)
818 {
819 likelihood += (*pxy_n_c_x)[y] * (*iLik_n_i_c)[y];
820 }
821 // We store this conditional likelihood into the corresponding array:
822 (*oLik_i_c)[x] *= likelihood;
823 }
824 }
825 }
826 }
827}
828
829/******************************************************************************/
830
832 const vector<const VVVdouble*>& iLik,
833 const vector<const VVVdouble*>& tProb,
834 const VVVdouble* iLikR,
835 const VVVdouble* tProbR,
836 VVVdouble& oLik,
837 size_t nbNodes,
838 size_t nbDistinctSites,
839 size_t nbClasses,
840 size_t nbStates,
841 bool reset)
842{
843 if (reset)
845
846 for (size_t n = 0; n < nbNodes; n++)
847 {
848 const VVVdouble* pxy_n = tProb[n];
849 const VVVdouble* iLik_n = iLik[n];
850
851 for (size_t i = 0; i < nbDistinctSites; i++)
852 {
853 // For each site in the sequence,
854 const VVdouble* iLik_n_i = &(*iLik_n)[i];
855 VVdouble* oLik_i = &(oLik)[i];
856
857 for (size_t c = 0; c < nbClasses; c++)
858 {
859 // For each rate class,
860 const Vdouble* iLik_n_i_c = &(*iLik_n_i)[c];
861 Vdouble* oLik_i_c = &(*oLik_i)[c];
862 const VVdouble* pxy_n_c = &(*pxy_n)[c];
863 for (size_t x = 0; x < nbStates; x++)
864 {
865 // For each initial state,
866 const Vdouble* pxy_n_c_x = &(*pxy_n_c)[x];
867 double likelihood = 0;
868 for (size_t y = 0; y < nbStates; y++)
869 {
870 // cout << "1:" << (* pxy_n_c_x)[y] << endl;
871 // cout << "2:" << (* iLik_n_i_c)[y] << endl;
872 likelihood += (*pxy_n_c_x)[y] * (*iLik_n_i_c)[y];
873 // cout << i << "\t" << c << "\t" << x << "\t" << y << "\t" << (* pxy__son_c_x)[y] << "\t" << (* likelihoods_root_son_i_c)[y] << endl;
874 }
875 // We store this conditional likelihood into the corresponding array:
876 (*oLik_i_c)[x] *= likelihood;
877 }
878 }
879 }
880 }
881
882 // Now deal with the subtree containing the root:
883 for (size_t i = 0; i < nbDistinctSites; i++)
884 {
885 // For each site in the sequence,
886 const VVdouble* iLikR_i = &(*iLikR)[i];
887 VVdouble* oLik_i = &(oLik)[i];
888
889 for (size_t c = 0; c < nbClasses; c++)
890 {
891 // For each rate class,
892 const Vdouble* iLikR_i_c = &(*iLikR_i)[c];
893 Vdouble* oLik_i_c = &(*oLik_i)[c];
894 const VVdouble* pxyR_c = &(*tProbR)[c];
895 for (size_t x = 0; x < nbStates; x++)
896 {
897 double likelihood = 0;
898 for (size_t y = 0; y < nbStates; y++)
899 {
900 // For each final state,
901 const Vdouble* pxyR_c_y = &(*pxyR_c)[y];
902 likelihood += (*pxyR_c_y)[x] * (*iLikR_i_c)[y];
903 }
904 // We store this conditional likelihood into the corresponding array:
905 (*oLik_i_c)[x] *= likelihood;
906 }
907 }
908 }
909}
910
911/******************************************************************************/
912
914{
915 cout << "Likelihoods at node " << node->getId() << ": " << endl;
916 for (size_t n = 0; n < node->getNumberOfSons(); n++)
917 {
918 const Node* subNode = node->getSon(n);
919 cout << "Array for sub-node " << subNode->getId() << endl;
920 displayLikelihoodArray(likelihoodData_->getLikelihoodArray(node->getId(), subNode->getId()));
921 }
922 if (node->hasFather())
923 {
924 const Node* father = node->getFather();
925 cout << "Array for father node " << father->getId() << endl;
926 displayLikelihoodArray(likelihoodData_->getLikelihoodArray(node->getId(), father->getId()));
927 }
928 cout << " ***" << endl;
929}
930
931/*******************************************************************************/
static void displayLikelihoodArray(const VVVdouble &likelihoodArray)
Print the likelihood array to terminal (debugging tool).
static void resetLikelihoodArray(VVVdouble &likelihoodArray)
Set all conditional likelihoods to 1.
Partial implementation for homogeneous model of the TreeLikelihood interface.
std::vector< Node * > nodes_
Pointer toward all nodes in the tree.
virtual void applyParameters()
All parameters are stored in a parameter list. This function apply these parameters to the substituti...
std::shared_ptr< TransitionModelInterface > model_
virtual void computeTransitionProbabilitiesForNode(const Node *node)
Fill the pxy_, dpxy_ and d2pxy_ arrays for one node.
ParameterList getRateDistributionParameters() const
Get the parameters associated to the rate distribution.
ParameterList getSubstitutionModelParameters() const
Get the parameters associated to substitution model(s).
virtual void computeAllTransitionProbabilities()
Fill the pxy_, dpxy_ and d2pxy_ arrays for all nodes.
AbstractHomogeneousTreeLikelihood & operator=(const AbstractHomogeneousTreeLikelihood &lik)
Assignation operator.
void setParametersValues(const ParameterList &parameters) override
bool hasParameter(const std::string &name) const override
const AlignmentDataInterface & data() const
Get the dataset for which the likelihood must be evaluated.
std::unique_ptr< const AlignmentDataInterface > data_
std::shared_ptr< TreeTemplate< Node > > tree_
static void displayTask(const std::string &text, bool eof=false)
static void displayTaskDone()
static void displayResult(const std::string &text, const T &result)
This class implements the likelihood computation for a tree using the double-recursive algorithm.
double getLikelihoodForASiteForARateClassForAState(size_t site, size_t rateClass, int state) const override
Get the likelihood for a site knowing its rate class and its ancestral state.
virtual void fireParameterChanged(const ParameterList &params) override
double getLikelihoodForASiteForARateClass(size_t site, size_t rateClass) const override
Get the likelihood for a site knowing its rate class.
double getLikelihood() const override
Get the likelihood for the whole dataset.
static void computeLikelihoodFromArrays(const std::vector< const VVVdouble * > &iLik, const std::vector< const VVVdouble * > &tProb, VVVdouble &oLik, size_t nbNodes, size_t nbDistinctSites, size_t nbClasses, size_t nbStates, bool reset=true)
Compute conditional likelihoods.
double getSecondOrderDerivative(const std::string &variable) const override
virtual void resetLikelihoodArrays(const Node *node)
double getFirstOrderDerivative(const std::string &variable) const override
double getValue() const override
Function and NNISearchable interface.
double getLikelihoodForASite(size_t site) const override
Get the likelihood for a site.
void init_()
Method called by constructors.
double getLogLikelihoodForASiteForARateClassForAState(size_t site, size_t rateClass, int state) const override
Get the logarithm of the likelihood for a site knowing its rate class and its ancestral state.
virtual void computeTreeDLikelihoodAtNode(const Node *node)
void setParameters(const ParameterList &parameters) override
Implements the Function interface.
virtual void displayLikelihood(const Node *node)
This method is mainly for debugging purpose.
virtual void computeTreeD2LikelihoodAtNode(const Node *node)
virtual void computeLikelihoodAtNode_(const Node *node, VVVdouble &likelihoodArray, const Node *sonNode=0) const
double getLogLikelihood() const override
Get the logarithm of the likelihood for the whole dataset.
DRHomogeneousTreeLikelihood(const Tree &tree, std::shared_ptr< TransitionModelInterface > model, std::shared_ptr< DiscreteDistributionInterface > rDist, bool checkRooted=true, bool verbose=true)
Build a new DRHomogeneousTreeLikelihood object without data.
virtual void computeSubtreeLikelihoodPrefix(const Node *node)
double getLogLikelihoodForASite(size_t site) const override
Get the logarithm of the likelihood for a site.
void setData(const AlignmentDataInterface &sites) override
Set the dataset for which the likelihood must be evaluated.
std::unique_ptr< DRASDRTreeLikelihoodData > likelihoodData_
DRHomogeneousTreeLikelihood & operator=(const DRHomogeneousTreeLikelihood &lik)
double getLogLikelihoodForASiteForARateClass(size_t site, size_t rateClass) const override
Get the logarithm of the likelihood for a site knowing its rate class.
virtual void computeSubtreeLikelihoodPostfix(const Node *node)
The phylogenetic node class.
Definition: Node.h:59
virtual int getId() const
Get the node's id.
Definition: Node.h:170
virtual const Node * getFather() const
Get the father of this node is there is one.
Definition: Node.h:306
virtual const Node * getSon(size_t pos) const
Definition: Node.h:362
virtual bool isLeaf() const
Definition: Node.h:679
virtual bool hasFather() const
Tell if this node has a father node.
Definition: Node.h:346
virtual size_t getNumberOfSons() const
Definition: Node.h:355
size_t size() const
static std::unique_ptr< AlignmentDataInterface > getSequenceSubset(const AlignmentDataInterface &sequenceSet, const std::shared_ptr< N > node, const AssociationTreeGraphImplObserver< N, E, I > &tree)
Extract the sequences corresponding to a given subtree.
Definition: PatternTools.h:44
Interface for phylogenetic tree objects.
Definition: Tree.h:115
std::string toString(T t)
Defines the basic types of data flow nodes.
double log(const ExtendedFloat &ef)
std::vector< double > Vdouble
ExtendedFloat pow(const ExtendedFloat &ef, double exp)
std::vector< VVdouble > VVVdouble
std::vector< Vdouble > VVdouble