bpp-phyl3  3.0.0
RNonHomogeneousMixedTreeLikelihood.cpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: The Bio++ Development Group
2 //
3 // SPDX-License-Identifier: CECILL-2.1
4 
7 #include <Bpp/Text/TextTools.h>
8 
9 #include "../../Model/MixedTransitionModel.h"
10 #include "../../Tree/TreeTools.h"
11 #include "../../PatternTools.h"
13 
14 using namespace bpp;
15 
16 // From the STL:
17 #include <iostream>
18 
19 using namespace std;
20 
21 /******************************************************************************/
22 
24  const Tree& tree,
25  std::shared_ptr<MixedSubstitutionModelSet> modelSet,
26  std::shared_ptr<DiscreteDistributionInterface> rDist,
27  bool verbose,
28  bool usePatterns) :
29  RNonHomogeneousTreeLikelihood(tree, modelSet, rDist, verbose, usePatterns),
30  mvTreeLikelihoods_(),
31  hyperNode_(modelSet),
32  upperNode_(tree.getRootId()),
33  main_(true)
34 {
35  if (!modelSet->isFullySetUpFor(tree))
36  throw Exception("RNonHomogeneousMixedTreeLikelihood(constructor). Model set is not fully specified.");
37 
38  for (size_t i = 0; i < modelSet->getNumberOfHyperNodes(); ++i)
39  {
40  mvTreeLikelihoods_[tree.getRootId()].push_back(
41  shared_ptr<RNonHomogeneousMixedTreeLikelihood>( // Note: cannot use make_shared because of private constructor
43  tree, modelSet, modelSet->getHyperNode(i),
44  upperNode_, rDist, false, usePatterns)
45  )
46  );
47  }
48 }
49 
50 /******************************************************************************/
51 
53  const Tree& tree,
54  const AlignmentDataInterface& data,
55  std::shared_ptr<MixedSubstitutionModelSet> modelSet,
56  std::shared_ptr<DiscreteDistributionInterface> rDist,
57  bool verbose,
58  bool usePatterns) :
59  RNonHomogeneousTreeLikelihood(tree, data, modelSet, rDist, verbose, usePatterns),
60  mvTreeLikelihoods_(),
61  hyperNode_(modelSet),
62  upperNode_(tree.getRootId()),
63  main_(true)
64 {
65  if (!modelSet->isFullySetUpFor(tree))
66  throw Exception("RNonHomogeneousMixedTreeLikelihood(constructor). Model set is not fully specified.");
67 
68  for (size_t i = 0; i < modelSet->getNumberOfHyperNodes(); ++i)
69  {
70  mvTreeLikelihoods_[tree.getRootId()].push_back(
71  shared_ptr<RNonHomogeneousMixedTreeLikelihood>( // Note: cannot use make_shared because of private constructor
73  tree, data, modelSet, modelSet->getHyperNode(i),
74  upperNode_, rDist, false, usePatterns)
75  )
76  );
77  }
78 }
79 
80 /******************************************************************************/
81 
83  const Tree& tree,
84  std::shared_ptr<MixedSubstitutionModelSet> modelSet,
85  const MixedSubstitutionModelSet::HyperNode& hyperNode,
86  int upperNode,
87  std::shared_ptr<DiscreteDistributionInterface> rDist,
88  bool verbose,
89  bool usePatterns) :
90  RNonHomogeneousTreeLikelihood(tree, modelSet, rDist, verbose, usePatterns),
91  mvTreeLikelihoods_(),
92  hyperNode_(hyperNode),
93  upperNode_(upperNode),
94  main_(false)
95 {
96  if (!modelSet->isFullySetUpFor(tree))
97  throw Exception("RNonHomogeneousMixedTreeLikelihood(constructor). Model set is not fully specified.");
98 
99  init(usePatterns);
100 }
101 
102 /******************************************************************************/
103 
105  const Tree& tree,
106  const AlignmentDataInterface& data,
107  std::shared_ptr<MixedSubstitutionModelSet> modelSet,
108  const MixedSubstitutionModelSet::HyperNode& hyperNode,
109  int upperNode,
110  std::shared_ptr<DiscreteDistributionInterface> rDist,
111  bool verbose,
112  bool usePatterns) :
113  RNonHomogeneousTreeLikelihood(tree, data, modelSet, rDist, verbose, usePatterns),
114  mvTreeLikelihoods_(),
115  hyperNode_(hyperNode),
116  upperNode_(upperNode),
117  main_(false)
118 {
119  if (!modelSet->isFullySetUpFor(tree))
120  throw Exception("RNonHomogeneousMixedTreeLikelihood(constructor). Model set is not fully specified.");
121 
122  init(usePatterns);
123 }
124 
125 /******************************************************************************/
126 
128 {
129  std::vector<int> vDesc; // vector of the explorated descendents
130  int desc;
131  vector<int> vn;
132  size_t nbmodels = modelSet_->getNumberOfModels();
133 
134  const Tree& tr = tree();
135 
136  vDesc.push_back(upperNode_); // start of the exploration
137 
138  while (vDesc.size() != 0)
139  {
140  desc = vDesc.back();
141  vDesc.pop_back();
142  vector<int> vExpMod; // vector of the ids of the MixedModels which
143  // nodes are not in only one subtree under desc
144 
145  vector<int> vson = tr.getSonsId(desc);
146  std::map<int, vector<int>> mdesc; // map of the subtree nodes for
147  // each son of desc
148  for (size_t i = 0; i < vson.size(); i++)
149  {
150  std::vector<int> vi;
151  TreeTools::getNodesId(tr, vson[i], vi);
152  mdesc[vson[i]] = vi;
153  }
154 
155  for (size_t i = 0; i < nbmodels; i++)
156  {
158 
159  if (node.size() > 1)
160  {
161  vn = modelSet_->getNodesWithModel(i); // tree nodes associated to model
162 
163  /* Check if the vn members are in the same subtree */
164  size_t flag = 0; // count of the subtrees that have vn members
165  std::map<int, vector<int>>::iterator it;
166  for (it = mdesc.begin(); it != mdesc.end(); it++)
167  {
168  for (size_t j = 0; j < it->second.size(); j++)
169  {
170  if (it->second[j] != it->first)
171  {
172  if (find(vn.begin(), vn.end(), it->second[j]) != vn.end())
173  {
174  flag += (find(vn.begin(), vn.end(), it->first) != vn.end()) ? 2 : 1; // check if the son
175  // has this model too
176  break;
177  }
178  }
179  else if (find(vn.begin(), vn.end(), it->first) != vn.end())
180  flag++;
181  }
182  if (flag >= 2)
183  break;
184  }
185  if (flag >= 2)
186  vExpMod.push_back(static_cast<int>(i)); // mixed model that must be expanded
187  }
188  }
189 
190  if (vExpMod.size() != 0)
191  {
192  std::map<int, int> mapmodels;
193  size_t ttmodels = 1;
194  for (vector<int>::iterator it = vExpMod.begin(); it != vExpMod.end(); it++)
195  {
196  mapmodels[*it] = static_cast<int>(hyperNode_.getNode(static_cast<size_t>(*it)).size());
197  ttmodels *= static_cast<size_t>(mapmodels[*it]);
198  }
199 
200  for (size_t i = 0; i < ttmodels; i++)
201  {
202  int s = static_cast<int>(i);
204 
205  for (size_t j = 0; j < nbmodels; j++)
206  {
207  if ((hyperNode_.getNode(j).size() >= 1) && find(vExpMod.begin(), vExpMod.end(), static_cast<int>(j)) != vExpMod.end())
208  {
209  hn.setModel(j, Vuint(1, hyperNode_.getNode(j)[static_cast<size_t>(s % mapmodels[static_cast<int>(j)])]));
210  s /= mapmodels[static_cast<int>(j)];
211  }
212  }
213  hn.setProbability(dynamic_pointer_cast<MixedSubstitutionModelSet>(modelSet_)->getHyperNodeProbability(hn));
214  shared_ptr<RNonHomogeneousMixedTreeLikelihood> pr;
215 
216  if (hasLikelihoodData())
217  {
218  pr = shared_ptr<RNonHomogeneousMixedTreeLikelihood>( // Note: cannot use make_shared because of private constructor
220  tr,
221  data(),
222  dynamic_pointer_cast<MixedSubstitutionModelSet>(modelSet_),
223  hn, desc,
224  rateDistribution_, false, usePatterns)
225  );
226  }
227  else
228  {
229  pr = shared_ptr<RNonHomogeneousMixedTreeLikelihood>( // Note: cannot use make_shared because of private constructor
231  tr,
232  dynamic_pointer_cast<MixedSubstitutionModelSet>(modelSet_),
233  hn, desc,
234  rateDistribution_, false, usePatterns)
235  );
236  }
237  pr->resetParameters_();
238  mvTreeLikelihoods_[desc].push_back(pr);
239  }
240  }
241  else
242  for (size_t i = 0; i < vson.size(); ++i)
243  {
244  vDesc.push_back(vson[i]);
245  }
246  }
247 }
248 
249 
250 /******************************************************************************/
251 
255  mvTreeLikelihoods_(),
256  hyperNode_(lik.hyperNode_),
257  upperNode_(lik.upperNode_),
258  main_(lik.main_)
259 {
260  for (auto& it : lik.mvTreeLikelihoods_)
261  {
262  for (size_t i = 0; i < it.second.size(); ++i)
263  {
264  mvTreeLikelihoods_[it.first].push_back(
265  make_shared<RNonHomogeneousMixedTreeLikelihood>(*it.second[i])
266  );
267  }
268  }
269 }
270 
271 /******************************************************************************/
272 
275 {
277 
278  mvTreeLikelihoods_.clear();
279 
280  upperNode_ = lik.upperNode_;
281  main_ = lik.main_;
282 
283  for (auto& it : lik.mvTreeLikelihoods_)
284  {
285  for (size_t i = 0; i < it.second.size(); ++i)
286  {
287  mvTreeLikelihoods_[it.first].push_back(
288  make_shared<RNonHomogeneousMixedTreeLikelihood>(*it.second[i])
289  );
290  }
291  }
292 
293  hyperNode_ = lik.hyperNode_;
294 
295  return *this;
296 }
297 
298 /******************************************************************************/
299 
301 
302 /******************************************************************************/
304 {
305  if (main_)
306  initParameters();
307  else
308  {
311  }
312 
313  for (auto& it : mvTreeLikelihoods_)
314  {
315  for (size_t i = 0; i < it.second.size(); ++i)
316  {
317  it.second[i]->initialize();
318  }
319  }
320 
322 }
323 
324 /******************************************************************************/
325 
327 {
328  if (main_)
329  applyParameters();
330  else
331  {
332  for (size_t i = 0; i < nbNodes_; i++)
333  {
334  int id = nodes_[i]->getId();
335  if (reparametrizeRoot_ && id == root1_)
336  {
337  const Parameter* rootBrLen = &parameter("BrLenRoot");
338  const Parameter* rootPos = &parameter("RootPosition");
339  nodes_[i]->setDistanceToFather(rootBrLen->getValue() * rootPos->getValue());
340  }
341  else if (reparametrizeRoot_ && id == root2_)
342  {
343  const Parameter* rootBrLen = &parameter("BrLenRoot");
344  const Parameter* rootPos = &parameter("RootPosition");
345  nodes_[i]->setDistanceToFather(rootBrLen->getValue() * (1. - rootPos->getValue()));
346  }
347  else
348  {
349  const Parameter* brLen = &parameter(string("BrLen") + TextTools::toString(i));
350  if (brLen)
351  nodes_[i]->setDistanceToFather(brLen->getValue());
352  }
353  }
354  }
355 
356  for (auto& it2 : mvTreeLikelihoods_)
357  {
358  for (size_t i = 0; i < it2.second.size(); ++i)
359  {
360  (it2.second)[i]->setProbability(
361  dynamic_pointer_cast<MixedSubstitutionModelSet>(modelSet_)->getHyperNodeProbability(
362  (it2.second)[i]->getHyperNode()
363  )
364  );
365  }
366  }
367 
368  if (main_)
369  {
370  for (size_t i = 0; i < mvTreeLikelihoods_[upperNode_].size(); i++)
371  {
372  mvTreeLikelihoods_[upperNode_][i]->matchParametersValues(params);
373  }
374  rootFreqs_ = modelSet_->getRootFrequencies();
375  }
376  else
377  {
378  if (params.getCommonParametersWith(rateDistribution_->getIndependentParameters()).size() > 0)
379  {
381  }
382  else
383  {
384  vector<int> ids;
385  vector<string> tmp = params.getCommonParametersWith(modelSet_->getNodeParameters()).getParameterNames();
386  for (size_t i = 0; i < tmp.size(); i++)
387  {
388  vector<int> tmpv = modelSet_->getNodesWithParameter(tmp[i]);
389  ids = VectorTools::vectorUnion(ids, tmpv);
390  }
392  vector<const Node*> nodes;
393  for (size_t i = 0; i < ids.size(); ++i)
394  {
395  nodes.push_back(idToNode_[ids[i]]);
396  }
397  vector<const Node*> tmpv;
398  bool test = false;
399  for (size_t i = 0; i < tmp.size(); ++i)
400  {
401  if (tmp[i] == "BrLenRoot" || tmp[i] == "RootPosition")
402  {
403  if (!test)
404  {
405  tmpv.push_back(tree_->getRootNode()->getSon(0));
406  tmpv.push_back(tree_->getRootNode()->getSon(1));
407  test = true; // Add only once.
408  }
409  }
410  else
411  tmpv.push_back(nodes_[TextTools::to< size_t >(tmp[i].substr(5))]);
412  }
413  nodes = VectorTools::vectorUnion(nodes, tmpv);
414 
415  for (size_t i = 0; i < nodes.size(); ++i)
416  {
418  }
419  }
420 
421  for (auto& it : mvTreeLikelihoods_)
422  {
423  for (size_t i = 0; i < it.second.size(); ++i)
424  {
425  it.second[i]->matchParametersValues(params);
426  }
427  }
428  }
429 
430  if (main_)
431  {
434  }
435 }
436 
437 /******************************************************************************/
438 
440 {
442  for (auto& it : mvTreeLikelihoods_)
443  {
444  for (size_t i = 0; i < it.second.size(); ++i)
445  {
446  it.second[i]->setData(sites);
447  }
448  }
449 }
450 
451 
452 /******************************************************************************/
453 
455 {
456  return hyperNode_.getProbability();
457 }
458 
459 /******************************************************************************/
460 
462 {
463  return hyperNode_.setProbability(x);
464 }
465 
466 /******************************************************************************/
467 
469 {
470  // if the subtree is divided in several RNonHomogeneousMixedTreeLikelihood*
471  if (node->isLeaf())
472  return;
473 
474  int nodeId = main_ ? upperNode_ : node->getId();
475  if (mvTreeLikelihoods_.find(nodeId) != mvTreeLikelihoods_.end())
476  {
477  size_t nbSites = likelihoodData_->getLikelihoodArray(nodeId).size();
478 
479  // Must reset the likelihood array first (i.e. set all of them to 0):
480  VVVdouble* _likelihoods_node = &likelihoodData_->getLikelihoodArray(nodeId);
481  for (size_t i = 0; i < nbSites; ++i)
482  {
483  // For each site in the sequence,
484  VVdouble* _likelihoods_node_i = &(*_likelihoods_node)[i];
485  for (size_t c = 0; c < nbClasses_; c++)
486  {
487  // For each rate class,
488  Vdouble* _likelihoods_node_i_c = &(*_likelihoods_node_i)[c];
489  for (size_t x = 0; x < nbStates_; x++)
490  {
491  // For each initial state,
492  (*_likelihoods_node_i_c)[x] = 0.;
493  }
494  }
495  }
496 
497  if (getProbability() == 0)
498  return;
499 
500  auto& vr = mvTreeLikelihoods_[nodeId];
501  for (size_t t = 0; t < vr.size(); t++)
502  {
503  vr[t]->computeSubtreeLikelihood(node);
504  }
505 
506  // for each specific subtree
507  for (size_t t = 0; t < vr.size(); t++)
508  {
509  VVVdouble* _vt_likelihoods_node = &vr[t]->likelihoodData_->getLikelihoodArray(nodeId);
510  for (size_t i = 0; i < nbSites; i++)
511  {
512  // For each site in the sequence,
513  VVdouble* _likelihoods_node_i = &(*_likelihoods_node)[i];
514  for (size_t c = 0; c < nbClasses_; c++)
515  {
516  // For each rate class,
517  Vdouble* _likelihoods_node_i_c = &(*_likelihoods_node_i)[c];
518  Vdouble* _vt_likelihoods_node_i_c = &(*_vt_likelihoods_node)[i][c];
519  for (size_t x = 0; x < nbStates_; x++)
520  {
521  (*_likelihoods_node_i_c)[x] += (*_vt_likelihoods_node_i_c)[x] * vr[t]->getProbability() / getProbability();
522  }
523  }
524  }
525  }
526  }
527 
528 
529  // otherwise...
530 
531  // nb: if the subtree is made of independent branches the computing is
532  // as in the non mixed case, where the mean of the probas of
533  // transition of a mixed model are taken.
534 
535  else
537 }
538 
539 /******************************************************************************
540 * First Order Derivatives *
541 ******************************************************************************/
543 {
544  const Node* father, father2;
545 
546 
547  if (main_)
548  father = tree_->getRootNode();
549  else
550  {
551  if ((variable == "BrLenRoot") || (variable == "RootPosition"))
552  father = tree_->getRootNode();
553  else
554  {
555  size_t brI = TextTools::to<size_t>(variable.substr(5));
556  const Node* branch = nodes_[brI];
557  father = branch->getFather();
558  }
559  }
560 
561  bool flok = 0;
562  while (father)
563  {
564  if (mvTreeLikelihoods_.find(father->getId()) != mvTreeLikelihoods_.end())
565  {
566  flok = 1;
567  break;
568  }
569  if (father->getId() == upperNode_)
570  break;
571  father = father->getFather();
572  }
573 
574  if (flok) // there is an expanded model above the derivated branch
575  {
576  int fatherId = father->getId();
577  // Compute dLikelihoods array for the father node.
578  // Fist initialize to 0:
579  VVVdouble* _dLikelihoods_father = &likelihoodData_->getDLikelihoodArray(fatherId);
580  size_t nbSites = _dLikelihoods_father->size();
581  for (size_t i = 0; i < nbSites; i++)
582  {
583  VVdouble* _dLikelihoods_father_i = &(*_dLikelihoods_father)[i];
584  for (size_t c = 0; c < nbClasses_; c++)
585  {
586  Vdouble* _dLikelihoods_father_i_c = &(*_dLikelihoods_father_i)[c];
587  for (size_t s = 0; s < nbStates_; s++)
588  {
589  (*_dLikelihoods_father_i_c)[s] = 0.;
590  }
591  }
592  }
593 
594  if (getProbability() != 0)
595  {
596  auto& vr = mvTreeLikelihoods_[fatherId];
597  for (size_t t = 0; t < vr.size(); t++)
598  {
599  vr[t]->computeTreeDLikelihood(variable);
600  }
601 
602 
603  // for each specific subtree
604  for (size_t t = 0; t < vr.size(); t++)
605  {
606  VVVdouble* _vt_dLikelihoods_father = &vr[t]->likelihoodData_->getDLikelihoodArray(fatherId);
607  for (size_t i = 0; i < nbSites; i++)
608  {
609  // For each site in the sequence,
610  VVdouble* _dLikelihoods_father_i = &(*_dLikelihoods_father)[i];
611  for (size_t c = 0; c < nbClasses_; c++)
612  {
613  // For each rate class,
614  Vdouble* _dLikelihoods_father_i_c = &(*_dLikelihoods_father_i)[c];
615  Vdouble* _vt_dLikelihoods_father_i_c = &(*_vt_dLikelihoods_father)[i][c];
616  for (size_t x = 0; x < nbStates_; x++)
617  {
618  (*_dLikelihoods_father_i_c)[x] += (*_vt_dLikelihoods_father_i_c)[x] * vr[t]->getProbability() / getProbability();
619  }
620  }
621  }
622  }
623  }
625  }
626  else
628 }
629 
631 {
632  const Node* father = node->getFather();
633  // // We assume that the _dLikelihoods array has been filled for the current node 'node'.
634  // // We will evaluate the array for the father node.
635  if (father == 0)
636  return; // We reached the up!
637 
638  if (node->getId() == upperNode_)
639  return; // We reached the top of the subtree
640 
642 }
643 
644 /******************************************************************************
645 * Second Order Derivatives *
646 ******************************************************************************/
648 {
649  const Node* father, father2;
650 
651  if (main_)
652  father = tree_->getRootNode();
653  else
654  {
655  if ((variable == "BrLenRoot") || (variable == "RootPosition"))
656  father = tree_->getRootNode();
657  else
658  {
659  size_t brI = TextTools::to<size_t>(variable.substr(5));
660  const Node* branch = nodes_[brI];
661  father = branch->getFather();
662  }
663  }
664 
665  bool flok = 0;
666  while (father)
667  {
668  if (mvTreeLikelihoods_.find(father->getId()) != mvTreeLikelihoods_.end())
669  {
670  flok = 1;
671  break;
672  }
673  if (father->getId() == upperNode_)
674  break;
675  father = father->getFather();
676  }
677 
678  if (flok) // there is an expanded model above the derivated branch
679  {
680  int fatherId = father->getId();
681  // Compute d2Likelihoods array for the father node.
682  // Fist initialize to 0:
683  VVVdouble* _d2Likelihoods_father = &likelihoodData_->getD2LikelihoodArray(fatherId);
684  size_t nbSites = _d2Likelihoods_father->size();
685  for (size_t i = 0; i < nbSites; i++)
686  {
687  VVdouble* _d2Likelihoods_father_i = &(*_d2Likelihoods_father)[i];
688  for (size_t c = 0; c < nbClasses_; c++)
689  {
690  Vdouble* _d2Likelihoods_father_i_c = &(*_d2Likelihoods_father_i)[c];
691  for (size_t s = 0; s < nbStates_; s++)
692  {
693  (*_d2Likelihoods_father_i_c)[s] = 0.;
694  }
695  }
696  }
697 
698  if (getProbability() != 0)
699  {
700  auto& vr = mvTreeLikelihoods_[fatherId];
701  for (size_t t = 0; t < vr.size(); t++)
702  {
703  vr[t]->computeTreeD2Likelihood(variable);
704  }
705 
706  // for each specific subtree
707  for (size_t t = 0; t < vr.size(); t++)
708  {
709  VVVdouble* _vt_d2Likelihoods_father = &vr[t]->likelihoodData_->getD2LikelihoodArray(fatherId);
710  for (size_t i = 0; i < nbSites; i++)
711  {
712  // For each site in the sequence,
713  VVdouble* _d2Likelihoods_father_i = &(*_d2Likelihoods_father)[i];
714  for (size_t c = 0; c < nbClasses_; c++)
715  {
716  // For each rate class,
717  Vdouble* _d2Likelihoods_father_i_c = &(*_d2Likelihoods_father_i)[c];
718  Vdouble* _vt_d2Likelihoods_father_i_c = &(*_vt_d2Likelihoods_father)[i][c];
719  for (size_t x = 0; x < nbStates_; x++)
720  {
721  (*_d2Likelihoods_father_i_c)[x] += (*_vt_d2Likelihoods_father_i_c)[x] * vr[t]->getProbability() / getProbability();
722  }
723  }
724  }
725  }
726  }
728  }
729  else
731 }
732 
733 
735 {
736  const Node* father = node->getFather();
737  // // We assume that the _dLikelihoods array has been filled for the current node 'node'.
738  // // We will evaluate the array for the father node.
739  if (father == 0)
740  return; // We reached the up!
741 
742  if (node->getId() == upperNode_)
743  return; // We reached the top of the subtree
744 
746 }
747 
748 
749 /*******************************************************************************/
750 
752 {
753  auto model = modelSet_->getModelForNode(node->getId());
754  size_t modelnum = modelSet_->getModelIndexForNode(node->getId());
755 
756  vector< shared_ptr<const TransitionModelInterface>> vModel;
757  vector<double> vProba;
758 
760  if (nd.size() == 0)
761  {
762  vModel.push_back(model);
763  vProba.push_back(1);
764  }
765  else
766  {
767  auto mmodel = dynamic_pointer_cast<const MixedTransitionModelInterface>(model);
768  double x = 0;
769  for (size_t i = 0; i < nd.size(); ++i)
770  {
771  vModel.push_back(shared_ptr<TransitionModelInterface>(mmodel->nModel(static_cast<size_t>(nd[i])).clone()));
772  vProba.push_back(mmodel->getNProbability(static_cast<size_t>(nd[i])));
773  x += vProba[i];
774  }
775  if (x != 0)
776  for (size_t i = 0; i < nd.size(); ++i)
777  {
778  vProba[i] /= x;
779  }
780  }
781 
782  double l = node->getDistanceToFather();
783  // Computes all pxy and pyx once for all:
784  VVVdouble* pxy__node = &pxy_[node->getId()];
785  for (size_t c = 0; c < nbClasses_; c++)
786  {
787  VVdouble* pxy__node_c = &(*pxy__node)[c];
788  for (size_t x = 0; x < nbStates_; x++)
789  {
790  Vdouble* pxy__node_c_x = &(*pxy__node_c)[x];
791  for (size_t y = 0; y < nbStates_; y++)
792  {
793  (*pxy__node_c_x)[y] = 0;
794  }
795  }
796 
797  for (size_t i = 0; i < vModel.size(); i++)
798  {
799  RowMatrix<double> Q = vModel[i]->getPij_t(l * rateDistribution_->getCategory(c));
800  for (size_t x = 0; x < nbStates_; x++)
801  {
802  Vdouble* pxy__node_c_x = &(*pxy__node_c)[x];
803  for (size_t y = 0; y < nbStates_; y++)
804  {
805  (*pxy__node_c_x)[y] += vProba[i] * Q(x, y);
806  }
807  }
808  }
809  }
810 
812  {
813  // Computes all dpxy/dt once for all:
814  VVVdouble* dpxy__node = &dpxy_[node->getId()];
815 
816  for (size_t c = 0; c < nbClasses_; c++)
817  {
818  VVdouble* dpxy__node_c = &(*dpxy__node)[c];
819  double rc = rateDistribution_->getCategory(c);
820  for (size_t x = 0; x < nbStates_; x++)
821  {
822  Vdouble* dpxy__node_c_x = &(*dpxy__node_c)[x];
823  for (size_t y = 0; y < nbStates_; y++)
824  {
825  (*dpxy__node_c_x)[y] = 0;
826  }
827  }
828 
829  for (size_t i = 0; i < vModel.size(); i++)
830  {
831  RowMatrix<double> dQ = vModel[i]->getdPij_dt(l * rc);
832 
833  for (size_t x = 0; x < nbStates_; x++)
834  {
835  Vdouble* dpxy__node_c_x = &(*dpxy__node_c)[x];
836  for (size_t y = 0; y < nbStates_; y++)
837  {
838  (*dpxy__node_c_x)[y] += vProba[i] * rc* dQ(x, y);
839  }
840  }
841  }
842  }
843  }
844 
846  {
847  // Computes all d2pxy/dt2 once for all:
848  VVVdouble* d2pxy__node = &d2pxy_[node->getId()];
849  for (size_t c = 0; c < nbClasses_; c++)
850  {
851  VVdouble* d2pxy__node_c = &(*d2pxy__node)[c];
852  for (size_t x = 0; x < nbStates_; x++)
853  {
854  Vdouble* d2pxy__node_c_x = &(*d2pxy__node_c)[x];
855  for (size_t y = 0; y < nbStates_; y++)
856  {
857  (*d2pxy__node_c_x)[y] = 0;
858  }
859  }
860 
861  double rc = rateDistribution_->getCategory(c);
862  for (size_t i = 0; i < vModel.size(); i++)
863  {
864  RowMatrix<double> d2Q = vModel[i]->getd2Pij_dt2(l * rc);
865  for (size_t x = 0; x < nbStates_; x++)
866  {
867  Vdouble* d2pxy__node_c_x = &(*d2pxy__node_c)[x];
868  for (size_t y = 0; y < nbStates_; y++)
869  {
870  (*d2pxy__node_c_x)[y] += vProba[i] * rc* rc* d2Q(x, y);
871  }
872  }
873  }
874  }
875  }
876 }
877 
878 /*******************************************************************************/
virtual void initParameters()
This builds the parameters list from all parametrizable objects, i.e. substitution model,...
void initialize() override
Init the likelihood object.
virtual void computeAllTransitionProbabilities()
Fill the pxy_, dpxy_ and d2pxy_ arrays for all nodes.
std::map< int, const Node * > idToNode_
An index linking nodes to their id, for faster access than the getNode() method.
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...
const Parameter & parameter(const std::string &name) const override
virtual void includeParameters_(const ParameterList &parameters)
const AlignmentDataInterface & data() const
Get the dataset for which the likelihood must be evaluated.
const Tree & tree() const
Get the tree (topology and branch lengths).
std::shared_ptr< TreeTemplate< Node > > tree_
void setProbability(double x)
sets the probability
double getProbability() const
returns the probability
void setModel(size_t nM, const Vuint &vnS)
sets submodel numbers in the nMth mixed model. Checks if all the numbers are valid.
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 bool isLeaf() const
Definition: Node.h:667
virtual double getDistanceToFather() const
Get the distance to the father node is there is one, otherwise throw a NodeException.
Definition: Node.h:250
size_t size() const
virtual ParameterList getCommonParametersWith(const ParameterList &params) const
virtual std::vector< std::string > getParameterNames() const
virtual double getValue() const
void computeTransitionProbabilitiesForNode(const Node *node)
Fill the pxy_, dpxy_ and d2pxy_ arrays for one node.
virtual void computeSubtreeLikelihood(const Node *node)
Compute the likelihood for a subtree defined by the Tree::Node node.
RNonHomogeneousMixedTreeLikelihood & operator=(const RNonHomogeneousMixedTreeLikelihood &lik)
std::map< int, std::vector< std::shared_ptr< RNonHomogeneousMixedTreeLikelihood > > > mvTreeLikelihoods_
the map of the branch numbers to the vectors of the TreeLikelihoods for the expanded model on this br...
void setData(const AlignmentDataInterface &sites)
Set the dataset for which the likelihood must be evaluated.
double getProbability() const
returns the probability of this object in the hierarchy
void setProbability(double x)
sets the probability of this object in the hierarchy
MixedSubstitutionModelSet::HyperNode hyperNode_
A specific HyperNode in which the computation is processed. If the probability of this HyperNode is -...
bool main_
a flag to say if this object is the head of the hierarchy
int upperNode_
the number of the node under which tree the Treelikelihood is computed.
This class implement the 'traditional' way of computing likelihood for a tree, allowing for non-homog...
virtual void computeTreeDLikelihood(const std::string &variable)
RNonHomogeneousTreeLikelihood & operator=(const RNonHomogeneousTreeLikelihood &lik)
double getLogLikelihood() const
Get the logarithm of the likelihood for the whole dataset.
void setData(const AlignmentDataInterface &sites)
Set the dataset for which the likelihood must be evaluated.
std::shared_ptr< DRASRTreeLikelihoodData > likelihoodData_
virtual void computeDownSubtreeDLikelihood(const Node *)
virtual void computeTreeD2Likelihood(const std::string &variable)
virtual void computeSubtreeLikelihood(const Node *node)
Compute the likelihood for a subtree defined by the Tree::Node node.
static std::vector< int > getNodesId(const Tree &tree, int nodeId)
Retrieve all nodes ids nodes from a subtree.
Definition: TreeTools.cpp:117
Interface for phylogenetic tree objects.
Definition: Tree.h:115
virtual std::vector< int > getSonsId(int parentId) const =0
virtual int getRootId() const =0
static std::vector< T > vectorUnion(const std::vector< T > &vec1, const std::vector< T > &vec2)
std::string toString(T t)
Defines the basic types of data flow nodes.
std::vector< double > Vdouble
std::vector< VVdouble > VVVdouble
std::vector< Vdouble > VVdouble
std::vector< unsigned int > Vuint