bpp-phyl3  3.0.0
LikelihoodCalculationOnABranch.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 <list>
6 #include <numeric>
7 #include <unordered_map>
8 
13 
14 using namespace std;
15 using namespace bpp;
16 using namespace numeric;
17 using namespace Eigen;
18 
19 LikelihoodCalculationOnABranch::LikelihoodCalculationOnABranch(
20  Context& context,
22  uint edgeId) :
24  numberOfSites_(likcalsp.getNumberOfSites()),
25  likelihoodMatrixDim_({likcalsp.stateMap().getNumberOfModelStates(), likcalsp.getNumberOfDistinctSites()}),
26  model_(likcalsp.getNumberOfClasses() ? likcalsp.getTreeNode(0)->getEdge(edgeId)->getModel() : 0),
27  rootPatternLinks_(likcalsp.getRootPatternLinks()),
28  rootWeights_(likcalsp.getRootWeights()),
29  catProb_(likcalsp.catProb_), vRateCatEdges_()
30 {
31  auto nbCl = likcalsp.getNumberOfClasses();
32  // ensure that all likelihoods exist
33  likcalsp.makeLikelihoodsTree();
34  for (size_t ncl = 0; ncl < nbCl; ncl++)
35  {
36  auto tr = likcalsp.getTreeNode(ncl);
37 
38  const auto& dagId = likcalsp.getEdgesIds(edgeId, ncl);
39  auto catEdge = make_shared<RateCategoryEdge>();
40  for (const auto& did:dagId)
41  {
42  auto ft = likcalsp.getForwardLikelihoodTree(ncl);
43  catEdge->vBotLik_.push_back(ft->getNode(ft->getSon(did)));
44  catEdge->vTopLik_.push_back(likcalsp.getBackwardLikelihoodTree(ncl)->getEdge(did));
45  }
46 
47  catEdge->brlen_ = likcalsp.getTreeNode(ncl)->getEdge(dagId[0])->getBrLen();
48  vRateCatEdges_.push_back(*catEdge);
49  }
50  shareParameters_(likcalsp.getParameters());
51 }
52 
55  numberOfSites_(lik.numberOfSites_),
56  likelihoodMatrixDim_(lik.likelihoodMatrixDim_),
57  model_(lik.model_),
58  rootPatternLinks_(lik.rootPatternLinks_),
59  rootWeights_(lik.rootWeights_),
60  catProb_(lik.catProb_),
61  vRateCatEdges_(lik.vRateCatEdges_)
62 {}
63 
65 {
66  if (shrunk)
67  return vRateCatEdges_[nCat].siteLik_->targetValue();
68  else
69  return expandVector(vRateCatEdges_[nCat].siteLik_)->targetValue();
70 }
71 
73 {
74  auto nbCat = vRateCatEdges_.size();
75  auto allLk = std::make_shared<AllRatesSiteLikelihoods>(nbCat, shrunk ? getNumberOfDistinctSites() : numberOfSites_);
76 
77  for (size_t nCat = 0; nCat < nbCat; nCat++)
78  {
79  allLk->row(Eigen::Index(nCat)) = getSiteLikelihoodsForAClass(nCat, shrunk);
80  }
81 
82  return *allLk;
83 }
84 
85 
86 /****************************************
87 * Construction methods
88 ****************************************/
90 {
91  if (!model_)
92  throw Exception("LikelihoodCalculationOnABranch::makeLikelihoods_: Missing model");
93 
94  auto nbDistSite = Eigen::Index(getNumberOfDistinctSites());
95  auto nbState = Eigen::Index(stateMap().getNumberOfModelStates());
96 
97  std::shared_ptr<ConditionalLikelihood> cond(0);
98 
99  SiteLikelihoodsRef distinctSiteLikelihoodsNode;
100 
102 
103  const auto model = getModel();
104 
105  auto zero = getContext_().getZero();
106 
107  std::vector<std::shared_ptr<Node_DF>> vCond;
108 
109  std::vector<NodeRef> vLikRate;
110 
111  for (auto& rateCat: vRateCatEdges_)
112  {
113  auto transitionMatrix = ConfiguredParametrizable::createMatrix<ConfiguredModel, TransitionMatrixFromModel, Eigen::MatrixXd>(getContext_(), {model, rateCat.brlen_, zero}, transitionMatrixDimension(static_cast<size_t>(nbState)));
114 
115  for (size_t i = 0; i < rateCat.vBotLik_.size(); i++)
116  {
117  auto forwardEdge = ForwardTransition::create (
118  getContext_(), {transitionMatrix, rateCat.vBotLik_[i]}, likelihoodMatrixDim_);
119 
120  cond = BuildConditionalLikelihood::create (
121  getContext_(), {rateCat.vTopLik_[i], forwardEdge}, likelihoodMatrixDim_);
122 
123  if (rateCat.vBotLik_.size() > 1)
124  vCond.push_back(cond);
125  }
126 
127  /*
128  * If several DAG nodes related with this species node, sum the
129  * likelihoods of all (already multiplied by their probability).
130  *
131  */
132 
133 
134  if (vCond.size() > 1)
136 
138  getContext_(), {one, cond}, RowVectorDimension (nbDistSite));
139 
140  vLikRate.push_back(rateCat.siteLik_);
141  }
142 
143  if (catProb_)
144  {
146  vLikRate.push_back(catProb);
147  distinctSiteLikelihoodsNode = CWiseMean<RowLik, ReductionOf<RowLik>, RowLik>::create(getContext_(), std::move(vLikRate), RowVectorDimension (nbDistSite));
148  }
149  else
150  distinctSiteLikelihoodsNode = vRateCatEdges_[0].siteLik_;
151 
152 
153  // likelihoods per distinct site
154  setSiteLikelihoods(distinctSiteLikelihoodsNode, true);
155 
156  // likelihoods per site
158 
159  // global likelihood
160  ValueRef<DataLik> val;
161  if (rootPatternLinks_)
162  val = TotalLogLikelihood::create (getContext_(), {distinctSiteLikelihoodsNode, rootWeights_}, RowVectorDimension (Eigen::Index (nbDistSite)));
163  else
164  val = TotalLogLikelihood::create (getContext_(), {distinctSiteLikelihoodsNode}, RowVectorDimension (Eigen::Index (nbDistSite)));
165 
166  setLikelihoodNode(val);
167 }
168 
169 
171 {
172  rootPatternLinks_.reset();
173  rootWeights_.reset();
174 
175  vRateCatEdges_.clear();
176 
178 }
void setSiteLikelihoods(SiteLikelihoodsRef ll, bool shrunk=false)
static std::shared_ptr< Self > create(Context &c, const Dimension< T > &dim)
Build a new ConstantOne node of the given dimension.
Context for dataflow node construction.
Definition: DataFlow.h:527
NodeRef getZero()
Definition: DataFlow.h:568
static ValueRef< R > create(Context &c, NodeRefVec &&deps, const Dimension< R > &dim)
Build a new Convert node with the given output dimensions.
LikelihoodCalculationOnABranch(Context &context, LikelihoodCalculationSingleProcess &likcalsp, uint edgeId)
ValueRef< RowLik > expandVector(ValueRef< RowLik > vector)
const StateMapInterface & stateMap() const
std::shared_ptr< ConfiguredModel > model_
AllRatesSiteLikelihoods getSiteLikelihoodsForAllClasses(bool shrunk=false)
Output array (Classes X Sites) of likelihoods for all sites & classes.
std::vector< RateCategoryEdge > vRateCatEdges_
std::shared_ptr< SiteWeights > rootWeights_
The frequency of each site.
std::shared_ptr< ConfiguredModel > getModel()
RowLik getSiteLikelihoodsForAClass(size_t nCat, bool shrunk=false)
Get site likelihoods for a rate category.
void setLikelihoodNode(ValueRef< DataLik > ll)
static ValueRef< R > create(Context &c, NodeRefVec &&deps, const Dimension< R > &dim)
Build a new MatrixProduct node with the given output dimensions.
virtual size_t getNumberOfModelStates() const =0
static ValueRef< DataLik > create(Context &c, NodeRefVec &&deps, const Dimension< F > &mDim)
Build a new SumOfLogarithms node with the given input matrix dimensions.
T one(const Dimension< T > &)
T zero(const Dimension< T > &)
Defines the basic types of data flow nodes.
std::shared_ptr< Value< T > > ValueRef
Shared pointer alias for Value<T>.
Definition: DataFlow.h:84
ValueRef< RowLik > SiteLikelihoodsRef
MatrixDimension transitionMatrixDimension(std::size_t nbState)
Definition: Model.h:19