bpp-phyl  2.2.0
RNonHomogeneousMixedTreeLikelihood.cpp
Go to the documentation of this file.
1 //
2 // File: RNonHomogeneousMixedTreeLikelihood.cpp
3 // Created by: Laurent Gueguen
4 // Created on: jeudi 11 novembre 2010, à 07h 56
5 //
6 
7 /*
8  Copyright or © or Copr. Bio++ Development Team, (November 16, 2004)
9 
10  This software is a computer program whose purpose is to provide classes
11  for phylogenetic data analysis.
12 
13  This software is governed by the CeCILL license under French law and
14  abiding by the rules of distribution of free software. You can use,
15  modify and/ or redistribute the software under the terms of the CeCILL
16  license as circulated by CEA, CNRS and INRIA at the following URL
17  "http://www.cecill.info".
18 
19  As a counterpart to the access to the source code and rights to copy,
20  modify and redistribute granted by the license, users are provided only
21  with a limited warranty and the software's author, the holder of the
22  economic rights, and the successive licensors have only limited
23  liability.
24 
25  In this respect, the user's attention is drawn to the risks associated
26  with loading, using, modifying and/or developing or reproducing the
27  software by the user in light of its specific status of free software,
28  that may mean that it is complicated to manipulate, and that also
29  therefore means that it is reserved for developers and experienced
30  professionals having in-depth computer knowledge. Users are therefore
31  encouraged to load and test the software's suitability as regards their
32  requirements in conditions enabling the security of their systems and/or
33  data to be ensured and, more generally, to use and operate it in the
34  same conditions as regards security.
35 
36  The fact that you are presently reading this means that you have had
37  knowledge of the CeCILL license and that you accept its terms.
38  */
39 
41 #include "../PatternTools.h"
42 #include "../Model/MixedSubstitutionModel.h"
43 #include "../TreeTools.h"
44 
45 #include <Bpp/Numeric/NumConstants.h>
46 #include <Bpp/Text/TextTools.h>
47 #include <Bpp/App/ApplicationTools.h>
48 
49 using namespace bpp;
50 
51 // From the STL:
52 #include <iostream>
53 
54 using namespace std;
55 
56 /******************************************************************************/
57 
59  MixedSubstitutionModelSet* modelSet,
60  DiscreteDistribution* rDist,
61  bool verbose,
62  bool usePatterns)
63 throw (Exception) :
64  RNonHomogeneousTreeLikelihood(tree, modelSet, rDist, verbose, usePatterns),
65  mvTreeLikelihoods_(),
66  hyperNode_(modelSet),
67  upperNode_(tree.getRootId()),
68  main_(true)
69 {
70  if (!modelSet->isFullySetUpFor(tree))
71  throw Exception("RNonHomogeneousMixedTreeLikelihood(constructor). Model set is not fully specified.");
72 
73  for (size_t i=0;i<modelSet->getNumberOfHyperNodes();i++){
74  mvTreeLikelihoods_[tree.getRootId()].push_back(new RNonHomogeneousMixedTreeLikelihood(tree, modelSet, modelSet->getHyperNode(i), upperNode_, rDist, false, usePatterns));
75  }
76 
77 }
78 
79 /******************************************************************************/
80 
82  const SiteContainer& data,
83  MixedSubstitutionModelSet* modelSet,
84  DiscreteDistribution* rDist,
85  bool verbose,
86  bool usePatterns)
87 throw (Exception) :
88  RNonHomogeneousTreeLikelihood(tree, data, modelSet, rDist, verbose, usePatterns),
89  mvTreeLikelihoods_(),
90  hyperNode_(modelSet),
91  upperNode_(tree.getRootId()),
92  main_(true)
93 {
94  if (!modelSet->isFullySetUpFor(tree))
95  throw Exception("RNonHomogeneousMixedTreeLikelihood(constructor). Model set is not fully specified.");
96 
97  for (size_t i=0;i<modelSet->getNumberOfHyperNodes();i++)
98  mvTreeLikelihoods_[tree.getRootId()].push_back(new RNonHomogeneousMixedTreeLikelihood(tree, data, modelSet, modelSet->getHyperNode(i), upperNode_, rDist, false, usePatterns));
99 }
100 
101 /******************************************************************************/
102 
104  MixedSubstitutionModelSet* modelSet,
105  const MixedSubstitutionModelSet::HyperNode& hyperNode,
106  int upperNode,
107  DiscreteDistribution* rDist,
108  bool verbose,
109  bool usePatterns) :
110  RNonHomogeneousTreeLikelihood(tree, modelSet, rDist, verbose, usePatterns),
111  mvTreeLikelihoods_(),
112  hyperNode_(hyperNode),
113  upperNode_(upperNode),
114  main_(false)
115 {
116  if (!modelSet->isFullySetUpFor(tree))
117  throw Exception("RNonHomogeneousMixedTreeLikelihood(constructor). Model set is not fully specified.");
118 
119  init(usePatterns);
120 }
121 
122 /******************************************************************************/
123 
125  const SiteContainer& data,
126  MixedSubstitutionModelSet* modelSet,
127  const MixedSubstitutionModelSet::HyperNode& hyperNode,
128  int upperNode,
129  DiscreteDistribution* rDist,
130  bool verbose,
131  bool usePatterns) :
132  RNonHomogeneousTreeLikelihood(tree, data, modelSet, rDist, verbose, usePatterns),
133  mvTreeLikelihoods_(),
134  hyperNode_(hyperNode),
135  upperNode_(upperNode),
136  main_(false)
137 {
138  if (!modelSet->isFullySetUpFor(tree))
139  throw Exception("RNonHomogeneousMixedTreeLikelihood(constructor). Model set is not fully specified.");
140 
141  init(usePatterns);
142 }
143 
144 /******************************************************************************/
145 
147 {
148  std::vector<int> vDesc; // vector of the explorated descendents
149  int desc;
150  vector<int> vn;
151  size_t nbmodels = modelSet_->getNumberOfModels();
152 
153  const SiteContainer* pdata = getData();
154 
155  const Tree& tree = getTree();
156 
157  vDesc.push_back(upperNode_); // start of the exploration
158 
159  while (vDesc.size() != 0) {
160  desc = vDesc.back();
161  vDesc.pop_back();
162  vector<int> vExpMod; // vector of the ids of the MixedModels which
163  // nodes are not in only one subtree under desc
164 
165  vector<int> vson = tree.getSonsId(desc);
166  std::map<int, vector<int> > mdesc; // map of the subtree nodes for
167  // each son of desc
168  for (size_t i = 0; i < vson.size(); i++)
169  {
170  std::vector<int> vi;
171  TreeTools::getNodesId(tree, vson[i], vi);
172  mdesc[vson[i]] = vi;
173  }
174 
175  for (size_t i = 0; i < nbmodels; i++)
176  {
178 
179  if (node.size()>1)
180  {
181  vn = modelSet_->getNodesWithModel(i); // tree nodes associated to model
182 
183  /* Check if the vn members are in the same subtree */
184  size_t flag = 0; // count of the subtrees that have vn members
185  std::map<int, vector<int> >::iterator it;
186  for (it = mdesc.begin(); it != mdesc.end(); it++)
187  {
188  for (size_t j = 0; j < it->second.size(); j++)
189  {
190  if (it->second[j] != it->first)
191  {
192  if (find(vn.begin(), vn.end(), it->second[j]) != vn.end())
193  {
194  flag += (find(vn.begin(), vn.end(), it->first) != vn.end()) ? 2 : 1; // check if the son
195  // has this model too
196  break;
197  }
198  }
199  else if (find(vn.begin(), vn.end(), it->first) != vn.end())
200  flag++;
201  }
202  if (flag >= 2)
203  break;
204  }
205  if (flag >= 2)
206  vExpMod.push_back(static_cast<int>(i)); // mixed model that must be expanded
207  }
208  }
209 
210  if (vExpMod.size() != 0)
211  {
212  std::map<int, int> mapmodels;
213  size_t ttmodels = 1;
214  for (vector<int>::iterator it = vExpMod.begin(); it != vExpMod.end(); it++)
215  {
216  mapmodels[*it] = static_cast<int>(hyperNode_.getNode(static_cast<size_t>(*it)).size());
217  ttmodels *= static_cast<size_t>(mapmodels[*it]);
218  }
219 
220  for (size_t i = 0; i < ttmodels; i++)
221  {
222  int s = static_cast<int>(i);
224 
225  for (size_t j = 0; j < nbmodels; j++)
226  {
227  if ((hyperNode_.getNode(j).size() >= 1) && find(vExpMod.begin(), vExpMod.end(), static_cast<int>(j)) != vExpMod.end())
228  {
229  hn.setModel(j, Vint(1, hyperNode_.getNode(j)[static_cast<size_t>(s % mapmodels[static_cast<int>(j)])]));
230  s /= mapmodels[static_cast<int>(j)];
231  }
232  }
233  hn.setProbability((dynamic_cast<MixedSubstitutionModelSet*>(modelSet_))->getHyperNodeProbability(hn));
235 
236  if (pdata)
237  pr = new RNonHomogeneousMixedTreeLikelihood(tree, *pdata, dynamic_cast<MixedSubstitutionModelSet*>(modelSet_), hn, desc, rateDistribution_, false, usePatterns);
238  else
239  pr = new RNonHomogeneousMixedTreeLikelihood(tree, dynamic_cast<MixedSubstitutionModelSet*>(modelSet_), hn, desc, rateDistribution_, false, usePatterns);
240  pr->resetParameters_();
241  mvTreeLikelihoods_[desc].push_back(pr);
242  }
243  }
244  else
245  for (size_t i = 0; i < vson.size(); i++)
246  {
247  vDesc.push_back(vson[i]);
248  }
249  }
250 }
251 
252 
253 /******************************************************************************/
254 
258  mvTreeLikelihoods_(),
259  hyperNode_(lik.hyperNode_),
260  upperNode_(lik.upperNode_),
261  main_(lik.main_)
262 {
263  map<int, vector<RNonHomogeneousMixedTreeLikelihood*> >::const_iterator it;
264  for (it = lik.mvTreeLikelihoods_.begin(); it != lik.mvTreeLikelihoods_.end(); it++)
265  {
266  for (size_t i = 0; i < it->second.size(); i++)
267  {
268  mvTreeLikelihoods_[it->first].push_back(new RNonHomogeneousMixedTreeLikelihood(*it->second[i]));
269  }
270  }
271 }
272 
273 /******************************************************************************/
274 
277 {
279 
280  mvTreeLikelihoods_.clear();
281 
282  upperNode_ = lik.upperNode_;
283  main_ = lik.main_;
284 
285  map<int, vector<RNonHomogeneousMixedTreeLikelihood*> >::const_iterator it;
286  for (it = lik.mvTreeLikelihoods_.begin(); it != lik.mvTreeLikelihoods_.end(); it++)
287  {
288  for (size_t i = 0; i < it->second.size(); i++)
289  {
290  mvTreeLikelihoods_[it->first].push_back(new RNonHomogeneousMixedTreeLikelihood(*it->second[i]));
291  }
292  }
293 
295 
296  return *this;
297 }
298 
299 /******************************************************************************/
300 
302 {
303  map<int, vector<RNonHomogeneousMixedTreeLikelihood*> >::iterator it;
304  for (it = mvTreeLikelihoods_.begin(); it != mvTreeLikelihoods_.end(); it++)
305  {
306  for (size_t i = 0; i < it->second.size(); i++)
307  {
308  delete it->second[i];
309  }
310  }
311 }
312 
313 /******************************************************************************/
315 {
316  if (main_)
317  initParameters();
318  else {
320  addParameters_(brLenParameters_);
321  }
322 
323  map<int, vector<RNonHomogeneousMixedTreeLikelihood*> >::iterator it;
324  for (it = mvTreeLikelihoods_.begin(); it != mvTreeLikelihoods_.end(); it++)
325  {
326  for (size_t i = 0; i < it->second.size(); i++)
327  {
328  it->second[i]->initialize();
329  }
330  }
331 
333 }
334 
335 /******************************************************************************/
336 
338 {
339  if (main_)
340  applyParameters();
341  else {
342  for (size_t i = 0; i < nbNodes_; i++)
343  {
344  int id = nodes_[i]->getId();
345  if (reparametrizeRoot_ && id == root1_)
346  {
347  const Parameter* rootBrLen = &getParameter("BrLenRoot");
348  const Parameter* rootPos = &getParameter("RootPosition");
349  nodes_[i]->setDistanceToFather(rootBrLen->getValue() * rootPos->getValue());
350  }
351  else if (reparametrizeRoot_ && id == root2_)
352  {
353  const Parameter* rootBrLen = &getParameter("BrLenRoot");
354  const Parameter* rootPos = &getParameter("RootPosition");
355  nodes_[i]->setDistanceToFather(rootBrLen->getValue() * (1. - rootPos->getValue()));
356  }
357  else
358  {
359  const Parameter* brLen = &getParameter(string("BrLen") + TextTools::toString(i));
360  if (brLen) nodes_[i]->setDistanceToFather(brLen->getValue());
361  }
362  }
363  }
364 
365  map<int, vector<RNonHomogeneousMixedTreeLikelihood*> >::const_iterator it2;
366  for (it2 = mvTreeLikelihoods_.begin(); it2 != mvTreeLikelihoods_.end(); it2++)
367  for (size_t i = 0; i < it2->second.size(); i++){
368  (it2->second)[i]->setProbability((dynamic_cast<MixedSubstitutionModelSet*>(modelSet_))->getHyperNodeProbability((it2->second)[i]->getHyperNode()));
369  }
370 
371  if (main_){
372  for (size_t i=0;i< mvTreeLikelihoods_[upperNode_].size(); i++)
373  mvTreeLikelihoods_[upperNode_][i]->matchParametersValues(params);
375  }
376  else {
377  if (params.getCommonParametersWith(rateDistribution_->getIndependentParameters()).size() > 0)
378  {
380  }
381  else
382  {
383  vector<int> ids;
384  vector<string> tmp = params.getCommonParametersWith(modelSet_->getNodeParameters()).getParameterNames();
385  for (size_t i = 0; i < tmp.size(); i++)
386  {
387  vector<int> tmpv = modelSet_->getNodesWithParameter(tmp[i]);
388  ids = VectorTools::vectorUnion(ids, tmpv);
389  }
390  tmp = params.getCommonParametersWith(brLenParameters_).getParameterNames();
391  vector<const Node*> nodes;
392  for (size_t i = 0; i < ids.size(); i++)
393  {
394  nodes.push_back(idToNode_[ids[i]]);
395  }
396  vector<const Node*> tmpv;
397  bool test = false;
398  for (size_t i = 0; i < tmp.size(); i++)
399  {
400  if (tmp[i] == "BrLenRoot" || tmp[i] == "RootPosition")
401  {
402  if (!test)
403  {
404  tmpv.push_back(tree_->getRootNode()->getSon(0));
405  tmpv.push_back(tree_->getRootNode()->getSon(1));
406  test = true; // Add only once.
407  }
408  }
409  else
410  tmpv.push_back(nodes_[TextTools::to < size_t > (tmp[i].substr(5))]);
411  }
412  nodes = VectorTools::vectorUnion(nodes, tmpv);
413 
414  for (size_t i = 0; i < nodes.size(); i++){
416  }
417  }
418 
419  map<int, vector<RNonHomogeneousMixedTreeLikelihood*> >::iterator it;
420  for (it = mvTreeLikelihoods_.begin(); it != mvTreeLikelihoods_.end(); it++)
421  {
422  for (size_t i = 0; i < it->second.size(); i++)
423  {
424  it->second[i]->matchParametersValues(params);
425  }
426  }
427  }
428 
429  if (main_)
430  {
433  }
434 }
435 
436 /******************************************************************************/
437 void RNonHomogeneousMixedTreeLikelihood::setData(const SiteContainer& sites) throw (Exception)
438 {
440  map<int, vector<RNonHomogeneousMixedTreeLikelihood*> >::iterator it;
441  for (it = mvTreeLikelihoods_.begin(); it != mvTreeLikelihoods_.end(); it++)
442  {
443  for (size_t i = 0; i < it->second.size(); i++)
444  {
445  it->second[i]->setData(sites);
446  }
447  }
448 }
449 
450 
451 /******************************************************************************/
453 {
454  return hyperNode_.getProbability();
455 }
456 
457 /******************************************************************************/
459 {
460  return hyperNode_.setProbability(x);
461 }
462 
463 /******************************************************************************/
464 
466 {
467  // if the subtree is divided in several RNonHomogeneousMixedTreeLikelihood*
468  if (node->isLeaf())
469  return;
470 
471  int nodeId=main_?upperNode_:node->getId();
472  if (mvTreeLikelihoods_.find(nodeId) != mvTreeLikelihoods_.end()) {
473 
474  size_t nbSites = likelihoodData_->getLikelihoodArray(nodeId).size();
475 
476  // Must reset the likelihood array first (i.e. set all of them to 0):
477  VVVdouble* _likelihoods_node = &likelihoodData_->getLikelihoodArray(nodeId);
478  for (size_t i = 0; i < nbSites; i++)
479  {
480  // For each site in the sequence,
481  VVdouble* _likelihoods_node_i = &(*_likelihoods_node)[i];
482  for (size_t c = 0; c < nbClasses_; c++)
483  {
484  // For each rate classe,
485  Vdouble* _likelihoods_node_i_c = &(*_likelihoods_node_i)[c];
486  for (size_t x = 0; x < nbStates_; x++)
487  {
488  // For each initial state,
489  (*_likelihoods_node_i_c)[x] = 0.;
490  }
491  }
492  }
493 
494  if (getProbability()==0)
495  return;
496 
497  vector<RNonHomogeneousMixedTreeLikelihood* > vr = mvTreeLikelihoods_[nodeId];
498  for (size_t t = 0; t < vr.size(); t++)
499  vr[t]->computeSubtreeLikelihood(node);
500 
501  // for each specific subtree
502  for (size_t t = 0; t < vr.size(); t++)
503  {
504  VVVdouble* _vt_likelihoods_node = &vr[t]->likelihoodData_->getLikelihoodArray(nodeId);
505  for (size_t i = 0; i < nbSites; i++)
506  {
507  // For each site in the sequence,
508  VVdouble* _likelihoods_node_i = &(*_likelihoods_node)[i];
509  for (size_t c = 0; c < nbClasses_; c++)
510  {
511  // For each rate classe,
512  Vdouble* _likelihoods_node_i_c = &(*_likelihoods_node_i)[c];
513  Vdouble* _vt_likelihoods_node_i_c = &(*_vt_likelihoods_node)[i][c];
514  for (size_t x = 0; x < nbStates_; x++)
515  {
516  (*_likelihoods_node_i_c)[x] += (*_vt_likelihoods_node_i_c)[x] * vr[t]->getProbability()/getProbability();
517  }
518  }
519  }
520  }
521  }
522 
523 
524  // otherwise...
525 
526  // nb: if the subtree is made of independent branches the computing is
527  // as in the non mixed case, where the mean of the probas of
528  // transition of a mixed model are taken.
529 
530  else
532 }
533 
534 /******************************************************************************
535 * First Order Derivatives *
536 ******************************************************************************/
538 {
539  const Node* father, father2;
540 
541 
542  if (main_)
543  father = tree_->getRootNode();
544  else {
545  if ((variable == "BrLenRoot") || (variable == "RootPosition"))
546  father = tree_->getRootNode();
547  else
548  {
549  size_t brI = TextTools::to<size_t>(variable.substr(5));
550  const Node* branch = nodes_[brI];
551  father = branch->getFather();
552  }
553  }
554 
555  bool flok = 0;
556  while (father){
557  if (mvTreeLikelihoods_.find(father->getId()) != mvTreeLikelihoods_.end()) {
558  flok = 1;
559  break;
560  }
561  if (father->getId() == upperNode_)
562  break;
563  father = father->getFather();
564  }
565 
566  if (flok) { // there is an expanded model above the derivated branch
567  int fatherId = father->getId();
568  // Compute dLikelihoods array for the father node.
569  // Fist initialize to 0:
570  VVVdouble* _dLikelihoods_father = &likelihoodData_->getDLikelihoodArray(fatherId);
571  size_t nbSites = _dLikelihoods_father->size();
572  for (size_t i = 0; i < nbSites; i++) {
573  VVdouble* _dLikelihoods_father_i = &(*_dLikelihoods_father)[i];
574  for (size_t c = 0; c < nbClasses_; c++) {
575  Vdouble* _dLikelihoods_father_i_c = &(*_dLikelihoods_father_i)[c];
576  for (size_t s = 0; s < nbStates_; s++){
577  (*_dLikelihoods_father_i_c)[s] = 0.;
578  }
579  }
580  }
581 
582  if (getProbability()!=0){
583  vector<RNonHomogeneousMixedTreeLikelihood* > vr = mvTreeLikelihoods_[fatherId];
584  for (size_t t = 0; t < vr.size(); t++)
585  vr[t]->computeTreeDLikelihood(variable);
586 
587 
588  // for each specific subtree
589  for (size_t t = 0; t < vr.size(); t++) {
590  VVVdouble* _vt_dLikelihoods_father = &vr[t]->likelihoodData_->getDLikelihoodArray(fatherId);
591  for (size_t i = 0; i < nbSites; i++){
592  // For each site in the sequence,
593  VVdouble* _dLikelihoods_father_i = &(*_dLikelihoods_father)[i];
594  for (size_t c = 0; c < nbClasses_; c++){
595  // For each rate classe,
596  Vdouble* _dLikelihoods_father_i_c = &(*_dLikelihoods_father_i)[c];
597  Vdouble* _vt_dLikelihoods_father_i_c = &(*_vt_dLikelihoods_father)[i][c];
598  for (size_t x = 0; x < nbStates_; x++) {
599  (*_dLikelihoods_father_i_c)[x] += (*_vt_dLikelihoods_father_i_c)[x] * vr[t]->getProbability()/getProbability();
600  }
601  }
602  }
603  }
604  }
606  }
607  else
609 }
610 
612 {
613  const Node* father = node->getFather();
614  // // We assume that the _dLikelihoods array has been filled for the current node 'node'.
615  // // We will evaluate the array for the father node.
616  if (father == 0)
617  return; // We reached the up!
618 
619  if (node->getId() == upperNode_)
620  return; // We reached the top of the subtree
621 
623 }
624 
625 /******************************************************************************
626 * Second Order Derivatives *
627 ******************************************************************************/
629 {
630  const Node* father, father2;
631 
632  if (main_)
633  father = tree_->getRootNode();
634  else {
635  if ((variable == "BrLenRoot") || (variable == "RootPosition"))
636  father = tree_->getRootNode();
637  else
638  {
639  size_t brI = TextTools::to<size_t>(variable.substr(5));
640  const Node* branch = nodes_[brI];
641  father = branch->getFather();
642  }
643  }
644 
645  bool flok = 0;
646  while (father){
647  if (mvTreeLikelihoods_.find(father->getId()) != mvTreeLikelihoods_.end())
648  {
649  flok = 1;
650  break;
651  }
652  if (father->getId() == upperNode_)
653  break;
654  father = father->getFather();
655  }
656 
657  if (flok) // there is an expanded model above the derivated branch
658  {
659  int fatherId = father->getId();
660  // Compute d2Likelihoods array for the father node.
661  // Fist initialize to 0:
662  VVVdouble* _d2Likelihoods_father = &likelihoodData_->getD2LikelihoodArray(fatherId);
663  size_t nbSites = _d2Likelihoods_father->size();
664  for (size_t i = 0; i < nbSites; i++) {
665  VVdouble* _d2Likelihoods_father_i = &(*_d2Likelihoods_father)[i];
666  for (size_t c = 0; c < nbClasses_; c++) {
667  Vdouble* _d2Likelihoods_father_i_c = &(*_d2Likelihoods_father_i)[c];
668  for (size_t s = 0; s < nbStates_; s++) {
669  (*_d2Likelihoods_father_i_c)[s] = 0.;
670  }
671  }
672  }
673 
674  if (getProbability()!=0){
675 
676  vector<RNonHomogeneousMixedTreeLikelihood* > vr = mvTreeLikelihoods_[fatherId];
677  for (size_t t = 0; t < vr.size(); t++)
678  vr[t]->computeTreeD2Likelihood(variable);
679 
680  // for each specific subtree
681  for (size_t t = 0; t < vr.size(); t++) {
682  VVVdouble* _vt_d2Likelihoods_father = &vr[t]->likelihoodData_->getD2LikelihoodArray(fatherId);
683  for (size_t i = 0; i < nbSites; i++) {
684  // For each site in the sequence,
685  VVdouble* _d2Likelihoods_father_i = &(*_d2Likelihoods_father)[i];
686  for (size_t c = 0; c < nbClasses_; c++){
687  // For each rate classe,
688  Vdouble* _d2Likelihoods_father_i_c = &(*_d2Likelihoods_father_i)[c];
689  Vdouble* _vt_d2Likelihoods_father_i_c = &(*_vt_d2Likelihoods_father)[i][c];
690  for (size_t x = 0; x < nbStates_; x++) {
691  (*_d2Likelihoods_father_i_c)[x] += (*_vt_d2Likelihoods_father_i_c)[x] * vr[t]->getProbability() / getProbability();
692  }
693  }
694  }
695  }
696  }
698  }
699  else
701 }
702 
703 
705 {
706  const Node* father = node->getFather();
707  // // We assume that the _dLikelihoods array has been filled for the current node 'node'.
708  // // We will evaluate the array for the father node.
709  if (father == 0)
710  return; // We reached the up!
711 
712  if (node->getId() == upperNode_)
713  return; // We reached the top of the subtree
714 
716 }
717 
718 
719 /*******************************************************************************/
720 
722 {
723  const SubstitutionModel* model = modelSet_->getModelForNode(node->getId());
724  size_t modelnum = modelSet_->getModelIndexForNode(node->getId());
725 
726  vector<const SubstitutionModel*> vModel;
727  vector<double> vProba;
728 
730  if (nd.size() == 0) {
731  vModel.push_back(model);
732  vProba.push_back(1);
733  }
734  else {
735  const MixedSubstitutionModel* mmodel = dynamic_cast<const MixedSubstitutionModel*>(model);
736  double x = 0;
737  for (size_t i = 0; i < nd.size(); ++i){
738  vModel.push_back(mmodel->getNModel(static_cast<size_t>(nd[i])));
739  vProba.push_back(mmodel->getNProbability(static_cast<size_t>(nd[i])));
740  x += vProba[i];
741  }
742  if (x != 0)
743  for (size_t i = 0; i < nd.size(); ++i)
744  vProba[i] /= x;
745  }
746 
747  double l = node->getDistanceToFather();
748  // Computes all pxy and pyx once for all:
749  VVVdouble* pxy__node = &pxy_[node->getId()];
750  for (size_t c = 0; c < nbClasses_; c++) {
751  VVdouble* pxy__node_c = &(*pxy__node)[c];
752  for (size_t x = 0; x < nbStates_; x++){
753  Vdouble* pxy__node_c_x = &(*pxy__node_c)[x];
754  for (size_t y = 0; y < nbStates_; y++){
755  (*pxy__node_c_x)[y] = 0;
756  }
757  }
758 
759  for (size_t i=0;i<vModel.size();i++){
760  RowMatrix<double> Q = vModel[i]->getPij_t(l * rateDistribution_->getCategory(c));
761  for (size_t x = 0; x < nbStates_; x++){
762  Vdouble* pxy__node_c_x = &(*pxy__node_c)[x];
763  for (size_t y = 0; y < nbStates_; y++){
764  (*pxy__node_c_x)[y] += vProba[i] * Q(x, y);
765  }
766  }
767  }
768  }
769 
771  // Computes all dpxy/dt once for all:
772  VVVdouble* dpxy__node = &dpxy_[node->getId()];
773 
774  for (size_t c = 0; c < nbClasses_; c++){
775  VVdouble* dpxy__node_c = &(*dpxy__node)[c];
776  double rc = rateDistribution_->getCategory(c);
777  for (size_t x = 0; x < nbStates_; x++){
778  Vdouble* dpxy__node_c_x = &(*dpxy__node_c)[x];
779  for (size_t y = 0; y < nbStates_; y++){
780  (*dpxy__node_c_x)[y] = 0;
781  }
782  }
783 
784  for (size_t i=0;i<vModel.size();i++){
785  RowMatrix<double> dQ = vModel[i]->getdPij_dt(l * rc);
786 
787  for (size_t x = 0; x < nbStates_; x++){
788  Vdouble* dpxy__node_c_x = &(*dpxy__node_c)[x];
789  for (size_t y = 0; y < nbStates_; y++){
790  (*dpxy__node_c_x)[y] += vProba[i] * rc * dQ(x, y);
791  }
792  }
793  }
794  }
795  }
796 
798  // Computes all d2pxy/dt2 once for all:
799  VVVdouble* d2pxy__node = &d2pxy_[node->getId()];
800  for (size_t c = 0; c < nbClasses_; c++){
801  VVdouble* d2pxy__node_c = &(*d2pxy__node)[c];
802  for (size_t x = 0; x < nbStates_; x++){
803  Vdouble* d2pxy__node_c_x = &(*d2pxy__node_c)[x];
804  for (size_t y = 0; y < nbStates_; y++){
805  (*d2pxy__node_c_x)[y] = 0;
806  }
807  }
808 
809  double rc = rateDistribution_->getCategory(c);
810  for (size_t i=0;i<vModel.size();i++){
811  RowMatrix<double> d2Q = vModel[i]->getd2Pij_dt2(l * rc);
812  for (size_t x = 0; x < nbStates_; x++){
813  Vdouble* d2pxy__node_c_x = &(*d2pxy__node_c)[x];
814  for (size_t y = 0; y < nbStates_; y++){
815  (*d2pxy__node_c_x)[y] += vProba[i] * rc * rc * d2Q(x, y);
816  }
817  }
818  }
819  }
820  }
821 
822 }
823 
824 /*******************************************************************************/
825 
bool isFullySetUpFor(const Tree &tree, bool throwEx=true) const
Check if the model set is fully specified for a given tree.
virtual void computeDownSubtreeDLikelihood(const Node *)
RNonHomogeneousMixedTreeLikelihood(const Tree &tree, MixedSubstitutionModelSet *modelSet, const MixedSubstitutionModelSet::HyperNode &hyperNode, int upperNode, DiscreteDistribution *rDist, bool verbose, bool usePatterns)
Build a new RNonHomogeneousMixeTreeLikelihood object without data.
This class implement the &#39;traditional&#39; way of computing likelihood for a tree, allowing for non-homog...
void setModel(size_t nM, const Vint &vnS)
sets submodel numbers in the nMth mixed model. Checks if all the numbers are valid.
Interface for all substitution models.
virtual void computeTreeD2Likelihood(const std::string &variable)
const SubstitutionModel * getModelForNode(int nodeId) const
Get the model associated to a particular node id.
bool main_
a flag to say if this object is the head of the hierarchy
std::vector< Node * > nodes_
Pointer toward all nodes in the tree.
void setProbability(double x)
sets the probability of this object in the hierarchy
virtual double getNProbability(size_t i) const =0
Returns the probability of a specific model from the mixture.
RNonHomogeneousMixedTreeLikelihood & operator=(const RNonHomogeneousMixedTreeLikelihood &lik)
size_t getModelIndexForNode(int nodeId) const
Get the index in the set of the model associated to a particular node id.
virtual void computeAllTransitionProbabilities()
Fill the pxy_, dpxy_ and d2pxy_ arrays for all nodes.
const SiteContainer * getData() const
Get the dataset for which the likelihood must be evaluated.
void setProbability(double x)
sets the probability
virtual void applyParameters()
All parameters are stored in a parameter list. This function apply these parameters to the substituti...
std::vector< double > getRootFrequencies() const
STL namespace.
double getProbability() const
returns the probability of this object in the hierarchy
virtual const Node * getFather() const
Get the father of this node is there is one.
Definition: Node.h:339
Interface for phylogenetic tree objects.
Definition: Tree.h:148
RNonHomogeneousTreeLikelihood & operator=(const RNonHomogeneousTreeLikelihood &lik)
map< int, vector< RNonHomogeneousMixedTreeLikelihood * > > mvTreeLikelihoods_
the map of the branch numbers to the vectors of the TreeLikelihoods for the expanded model on this br...
virtual bool isLeaf() const
Definition: Node.h:692
ParameterList getNodeParameters() const
Get the parameters corresponding attached to the nodes of the tree.
virtual double getDistanceToFather() const
Get the distance to the father node is there is one, otherwise throw a NodeException.
Definition: Node.h:283
VVVdouble & getDLikelihoodArray(int nodeId)
virtual void initParameters()
This builds the parameters list from all parametrizable objects, i.e. substitution model...
virtual int getId() const
Get the node&#39;s id.
Definition: Node.h:203
MixedSubstitutionModelSet::HyperNode hyperNode_
A specific HyperNode in which the computation is processed. If the probability of this HyperNode is -...
void setData(const SiteContainer &sites)
Set the dataset for which the likelihood must be evaluated.
void computeTransitionProbabilitiesForNode(const Node *node)
Fill the pxy_, dpxy_ and d2pxy_ arrays for one node.
double getProbability() const
returns the probability
Substitution models manager for Mixed Substitution Models. This class inherits from SubstitutionModel...
virtual void computeTreeDLikelihood(const std::string &variable)
void setData(const SiteContainer &sites)
Set the dataset for which the likelihood must be evaluated.
virtual void computeSubtreeLikelihood(const Node *node)
Compute the likelihood for a subtree defined by the Tree::Node node.
std::map< int, const Node * > idToNode_
An index linking nodes to their id, for faster access than the getNode() method.
The phylogenetic node class.
Definition: Node.h:90
int upperNode_
the number of the node under which tree the Treelikelihood is computed.
static std::vector< int > getNodesId(const Tree &tree, int nodeId)
Retrieve all nodes ids nodes from a subtree.
Definition: TreeTools.cpp:153
virtual void computeSubtreeLikelihood(const Node *node)
Compute the likelihood for a subtree defined by the Tree::Node node.
const Tree & getTree() const
Get the tree (topology and branch lengths).
double getLogLikelihood() const
Get the logarithm of the likelihood for the whole dataset.
const std::vector< int > & getNodesWithModel(size_t i) const
Get a list of nodes id for which the given model is associated.
virtual std::vector< int > getSonsId(int parentId) const =0
VVVdouble & getLikelihoodArray(int nodeId)
std::vector< int > getNodesWithParameter(const std::string &name) const
VVVdouble & getD2LikelihoodArray(int nodeId)
virtual const SubstitutionModel * getNModel(size_t i) const =0
Returns a specific model from the mixture.
Interface for Substitution models, defined as a mixture of "simple" substitution models.