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 
16 using namespace bpp;
17 
18 // From the STL:
19 #include <iostream>
20 
21 using namespace std;
22 
23 /******************************************************************************/
24 
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_();
52  setData(data);
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 /******************************************************************************/
159 double DRHomogeneousTreeLikelihood::getLikelihoodForASiteForARateClass(size_t site, size_t rateClass) const
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 
173 double 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 
180 double 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 {
196  applyParameters();
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 
298 double 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 
384 double 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 {
435  computeSubtreeLikelihoodPostfix(tree_->getRootNode());
436  computeSubtreeLikelihoodPrefix(tree_->getRootNode());
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:
450  resetLikelihoodArrays(node);
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 
682 void 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)
793  resetLikelihoodArray(oLik);
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)
844  resetLikelihoodArray(oLik);
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 * getSon(size_t pos) const
Definition: Node.h:362
virtual const Node * getFather() const
Get the father of this node is there is one.
Definition: Node.h:306
virtual bool isLeaf() const
Definition: Node.h:667
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