bpp-phyl3 3.0.0
AbstractHomogeneousTreeLikelihood.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
8#include "../../PatternTools.h"
10
11// From bpp-seq:
12#include <Bpp/Seq/SiteTools.h>
14
15using namespace bpp;
16
17// From the STL:
18#include <iostream>
19
20using namespace std;
21
22/******************************************************************************/
23
24AbstractHomogeneousTreeLikelihood::AbstractHomogeneousTreeLikelihood(
25 const Tree& tree,
26 std::shared_ptr<TransitionModelInterface> model,
27 std::shared_ptr<DiscreteDistributionInterface> rDist,
28 bool checkRooted,
29 bool verbose) :
31 model_(0),
32 brLenParameters_(),
33 pxy_(),
34 dpxy_(),
35 d2pxy_(),
36 rootFreqs_(),
37 nodes_(),
38 nbSites_(),
39 nbDistinctSites_(),
40 nbClasses_(),
41 nbStates_(),
42 nbNodes_(),
43 verbose_(),
44 minimumBrLen_(),
45 maximumBrLen_(),
46 brLenConstraint_()
47{
48 init_(tree, model, rDist, checkRooted, verbose);
49}
50
51/******************************************************************************/
52
56 model_(lik.model_),
57 brLenParameters_(lik.brLenParameters_),
58 pxy_(lik.pxy_),
59 dpxy_(lik.dpxy_),
60 d2pxy_(lik.d2pxy_),
61 rootFreqs_(lik.rootFreqs_),
62 nodes_(),
63 nbSites_(lik.nbSites_),
64 nbDistinctSites_(lik.nbDistinctSites_),
65 nbClasses_(lik.nbClasses_),
66 nbStates_(lik.nbStates_),
67 nbNodes_(lik.nbNodes_),
68 verbose_(lik.verbose_),
69 minimumBrLen_(lik.minimumBrLen_),
70 maximumBrLen_(lik.maximumBrLen_),
71 brLenConstraint_(lik.brLenConstraint_->clone())
72{
73 nodes_ = tree_->getNodes();
74 nodes_.pop_back(); // Remove the root node (the last added!).
75}
76
77/******************************************************************************/
78
81{
83 model_ = lik.model_;
85 pxy_ = lik.pxy_;
86 dpxy_ = lik.dpxy_;
87 d2pxy_ = lik.d2pxy_;
89 nodes_ = tree_->getNodes();
90 nodes_.pop_back(); // Remove the root node (the last added!).
91 nbSites_ = lik.nbSites_;
94 nbStates_ = lik.nbStates_;
95 nbNodes_ = lik.nbNodes_;
96 verbose_ = lik.verbose_;
99 brLenConstraint_ = std::shared_ptr<ConstraintInterface>(lik.brLenConstraint_->clone());
100 return *this;
101}
102
103/******************************************************************************/
104
106 const Tree& tree,
107 std::shared_ptr<TransitionModelInterface> model,
108 std::shared_ptr<DiscreteDistributionInterface> rDist,
109 bool checkRooted,
110 bool verbose)
111{
113 tree_ = make_unique<TreeTemplate<Node>>(tree);
114 if (checkRooted && tree_->isRooted())
115 {
116 if (verbose)
117 ApplicationTools::displayWarning("Tree has been unrooted.");
118 tree_->unroot();
119 }
120 nodes_ = tree_->getNodes();
121 nodes_.pop_back(); // Remove the root node (the last added!).
122 nbNodes_ = nodes_.size();
123 nbClasses_ = rateDistribution_->getNumberOfCategories();
124 setModel(model);
125
126 verbose_ = verbose;
127
128 minimumBrLen_ = 0.000001;
129 maximumBrLen_ = 10000;
130 brLenConstraint_ = std::make_shared<IntervalConstraint>(minimumBrLen_, maximumBrLen_, true, true);
131}
132
133/******************************************************************************/
134
135void AbstractHomogeneousTreeLikelihood::setModel(std::shared_ptr<TransitionModelInterface> model)
136{
137 // Check:
138 if (data_)
139 {
140 if (model->getAlphabet()->getAlphabetType() != data_->getAlphabet()->getAlphabetType())
141 throw Exception("AbstractHomogeneousTreeLikelihood::setSubstitutionModel(). Model alphabet do not match existing data.");
142 }
143
144 model_ = model;
145
146 if (data_)
147 {
148 if (model->getNumberOfStates() != model_->getNumberOfStates())
149 setData(*data_); // Have to reinitialize the whole data structure.
150 }
151
152 nbStates_ = model->getNumberOfStates();
153
154 // Allocate transition probabilities arrays:
155 for (unsigned int l = 0; l < nbNodes_; l++)
156 {
157 // For each son node,i
158 Node* son = nodes_[l];
159
160 VVVdouble* pxy__son = &pxy_[son->getId()];
161 pxy__son->resize(nbClasses_);
162 for (unsigned int c = 0; c < nbClasses_; c++)
163 {
164 VVdouble* pxy__son_c = &(*pxy__son)[c];
165 pxy__son_c->resize(nbStates_);
166 for (unsigned int x = 0; x < nbStates_; x++)
167 {
168 (*pxy__son_c)[x].resize(nbStates_);
169 }
170 }
171
172 VVVdouble* dpxy__son = &dpxy_[son->getId()];
173 dpxy__son->resize(nbClasses_);
174 for (unsigned int c = 0; c < nbClasses_; c++)
175 {
176 VVdouble* dpxy__son_c = &(*dpxy__son)[c];
177 dpxy__son_c->resize(nbStates_);
178 for (unsigned int x = 0; x < nbStates_; x++)
179 {
180 (*dpxy__son_c)[x].resize(nbStates_);
181 }
182 }
183
184 VVVdouble* d2pxy__son = &d2pxy_[son->getId()];
185 d2pxy__son->resize(nbClasses_);
186 for (unsigned int c = 0; c < nbClasses_; c++)
187 {
188 VVdouble* d2pxy__son_c = &(*d2pxy__son)[c];
189 d2pxy__son_c->resize(nbStates_);
190 for (unsigned int x = 0; x < nbStates_; x++)
191 {
192 (*d2pxy__son_c)[x].resize(nbStates_);
193 }
194 }
195 }
196}
197
198/******************************************************************************/
199
201{
202 if (initialized_)
203 throw Exception("AbstractHomogeneousTreeLikelihood::initialize(). Object is already initialized.");
204 if (!data_)
205 throw Exception("AbstractHomogeneousTreeLikelihood::initialize(). Data are no set.");
207 initialized_ = true;
209}
210
211/******************************************************************************/
212
214{
215 if (!initialized_)
216 throw Exception("AbstractHomogeneousTreeLikelihood::getBranchLengthsParameters(). Object is not initialized.");
218}
219
220/******************************************************************************/
221
223{
224 if (!initialized_)
225 throw Exception("AbstractHomogeneousTreeLikelihood::getSubstitutionModelParameters(). Object is not initialized.");
226 return model_->getParameters().getCommonParametersWith(getParameters());
227}
228
229/******************************************************************************/
230
232{
233 // Reset parameters:
235
236 // Branch lengths:
239
240 // Substitution model:
241 addParameters_(model_->getIndependentParameters());
242
243 // Rate distribution:
244 addParameters_(rateDistribution_->getIndependentParameters());
245}
246
247/******************************************************************************/
248
250{
251 if (!initialized_)
252 throw Exception("AbstractHomogeneousTreeLikelihood::applyParameters(). Object not initialized.");
253 // Apply branch lengths:
254 // brLenParameters_.matchParametersValues(parameters_); Not necessary!
255 for (unsigned int i = 0; i < nbNodes_; i++)
256 {
257 const Parameter* brLen = &parameter(string("BrLen") + TextTools::toString(i));
258 if (brLen)
259 nodes_[i]->setDistanceToFather(brLen->getValue());
260 }
261 // Apply substitution model parameters:
262 model_->matchParametersValues(getParameters());
263 rootFreqs_ = model_->getFrequencies();
264 // Apply rate distribution parameters:
265 rateDistribution_->matchParametersValues(getParameters());
266}
267
268/******************************************************************************/
269
271{
273 for (unsigned int i = 0; i < nbNodes_; i++)
274 {
275 double d = minimumBrLen_;
276 if (!nodes_[i]->hasDistanceToFather())
277 {
278 if (verbose)
279 ApplicationTools::displayWarning("Missing branch length " + TextTools::toString(i) + ". Value is set to " + TextTools::toString(minimumBrLen_));
280 nodes_[i]->setDistanceToFather(minimumBrLen_);
281 }
282 else
283 {
284 d = nodes_[i]->getDistanceToFather();
285 if (d < minimumBrLen_)
286 {
287 if (verbose)
288 ApplicationTools::displayWarning("Branch length " + TextTools::toString(i) + " is too small: " + TextTools::toString(d) + ". Value is set to " + TextTools::toString(minimumBrLen_));
289 nodes_[i]->setDistanceToFather(minimumBrLen_);
290 d = minimumBrLen_;
291 }
292 if (d > maximumBrLen_)
293 {
294 if (verbose)
295 ApplicationTools::displayWarning("Branch length " + TextTools::toString(i) + " is too big: " + TextTools::toString(d) + ". Value is set to " + TextTools::toString(maximumBrLen_));
296 nodes_[i]->setDistanceToFather(maximumBrLen_);
297 d = maximumBrLen_;
298 }
299 }
301 }
302}
303
304/*******************************************************************************/
305
307{
308 for (unsigned int l = 0; l < nbNodes_; l++)
309 {
310 // For each node,
311 Node* node = nodes_[l];
313 }
314 rootFreqs_ = model_->getFrequencies();
315}
316
317/*******************************************************************************/
318
320{
321 double l = node->getDistanceToFather();
322
323 // Computes all pxy and pyx once for all:
324 VVVdouble* pxy__node = &pxy_[node->getId()];
325 for (unsigned int c = 0; c < nbClasses_; c++)
326 {
327 VVdouble* pxy__node_c = &(*pxy__node)[c];
328 RowMatrix<double> Q = model_->getPij_t(l * rateDistribution_->getCategory(c));
329
330 for (unsigned int x = 0; x < nbStates_; x++)
331 {
332 Vdouble* pxy__node_c_x = &(*pxy__node_c)[x];
333 for (unsigned int y = 0; y < nbStates_; y++)
334 {
335 (*pxy__node_c_x)[y] = Q(x, y);
336 }
337 }
338 }
339
341 {
342 // Computes all dpxy/dt once for all:
343 VVVdouble* dpxy__node = &dpxy_[node->getId()];
344 for (unsigned int c = 0; c < nbClasses_; c++)
345 {
346 VVdouble* dpxy__node_c = &(*dpxy__node)[c];
347 double rc = rateDistribution_->getCategory(c);
348 RowMatrix<double> dQ = model_->getdPij_dt(l * rc);
349 for (unsigned int x = 0; x < nbStates_; x++)
350 {
351 Vdouble* dpxy__node_c_x = &(*dpxy__node_c)[x];
352 for (unsigned int y = 0; y < nbStates_; y++)
353 {
354 (*dpxy__node_c_x)[y] = rc * dQ(x, y);
355 }
356 }
357 }
358 }
359
361 {
362 // Computes all d2pxy/dt2 once for all:
363 VVVdouble* d2pxy__node = &d2pxy_[node->getId()];
364 for (unsigned int c = 0; c < nbClasses_; c++)
365 {
366 VVdouble* d2pxy__node_c = &(*d2pxy__node)[c];
367 double rc = rateDistribution_->getCategory(c);
368 RowMatrix<double> d2Q = model_->getd2Pij_dt2(l * rc);
369 for (unsigned int x = 0; x < nbStates_; x++)
370 {
371 Vdouble* d2pxy__node_c_x = &(*d2pxy__node_c)[x];
372 for (unsigned int y = 0; y < nbStates_; y++)
373 {
374 (*d2pxy__node_c_x)[y] = rc * rc * d2Q(x, y);
375 }
376 }
377 }
378 }
379}
380
381/*******************************************************************************/
Partial implementation of the DiscreteRatesAcrossSitesTreeLikelihood interface.
AbstractDiscreteRatesAcrossSitesTreeLikelihood & operator=(const AbstractDiscreteRatesAcrossSitesTreeLikelihood &tl)
Partial implementation for homogeneous model of the TreeLikelihood interface.
virtual void initParameters()
This builds the parameters list from all parametrizable objects, i.e. substitution model,...
std::vector< Node * > nodes_
Pointer toward all nodes in the tree.
void setModel(std::shared_ptr< TransitionModelInterface > model)
Set the substitution model for this instance.
virtual void applyParameters()
All parameters are stored in a parameter list. This function apply these parameters to the substituti...
std::shared_ptr< TransitionModelInterface > model_
ParameterList getBranchLengthsParameters() const
Get the branch lengths parameters.
virtual void computeTransitionProbabilitiesForNode(const Node *node)
Fill the pxy_, dpxy_ and d2pxy_ arrays for one node.
std::shared_ptr< ConstraintInterface > brLenConstraint_
void init_(const Tree &tree, std::shared_ptr< TransitionModelInterface > model, std::shared_ptr< DiscreteDistributionInterface > rDist, bool checkRooted, bool verbose)
Method called by constructor.
ParameterList getSubstitutionModelParameters() const
Get the parameters associated to substitution model(s).
AbstractHomogeneousTreeLikelihood(const Tree &tree, std::shared_ptr< TransitionModelInterface > model, std::shared_ptr< DiscreteDistributionInterface > rDist, bool checkRooted=true, bool verbose=true)
virtual void computeAllTransitionProbabilities()
Fill the pxy_, dpxy_ and d2pxy_ arrays for all nodes.
AbstractHomogeneousTreeLikelihood & operator=(const AbstractHomogeneousTreeLikelihood &lik)
Assignation operator.
const Parameter & parameter(const std::string &name) const override
virtual void fireParameterChanged(const ParameterList &parameters)
virtual void addParameters_(const ParameterList &parameters)
const ParameterList & getParameters() const override
const Tree & tree() const
Get the tree (topology and branch lengths).
std::unique_ptr< const AlignmentDataInterface > data_
std::shared_ptr< TreeTemplate< Node > > tree_
static void displayWarning(const std::string &text)
The phylogenetic node class.
Definition: Node.h:59
virtual int getId() const
Get the node's id.
Definition: Node.h:170
virtual double getDistanceToFather() const
Get the distance to the father node is there is one, otherwise throw a NodeException.
Definition: Node.h:250
virtual ParameterList getCommonParametersWith(const ParameterList &params) const
virtual void addParameter(const Parameter &param)
virtual void reset()
virtual double getValue() const
virtual void setData(const AlignmentDataInterface &sites)=0
Set the dataset for which the likelihood must be evaluated.
static bool checkIds(const Tree &tree, bool throwException)
Check if the ids are uniques.
Definition: TreeTools.cpp:746
Interface for phylogenetic tree objects.
Definition: Tree.h:115
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