bpp-phyl3 3.0.0
DecompositionSubstitutionCount.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 <typeinfo>
6#include <vector>
7
10
11using namespace bpp;
12using namespace std;
13
14/******************************************************************************/
15
16DecompositionSubstitutionCount::DecompositionSubstitutionCount(
17 std::shared_ptr<const SubstitutionModelInterface> model,
18 std::shared_ptr<const SubstitutionRegisterInterface> reg,
19 std::shared_ptr<const AlphabetIndex2> weights,
20 std::shared_ptr<const AlphabetIndex2> distances) :
24 DecompositionMethods(model, reg),
25 counts_(reg->getNumberOfSubstitutionTypes()),
26 currentLength_(0)
27{
28 // Check compatibility between model and substitution register:
29 if (typeid(model->getAlphabet()) != typeid(reg->getAlphabet()))
30 throw Exception("DecompositionSubstitutionCount (constructor): alphabets do not match between register and model.");
31
33
37}
38
40 std::shared_ptr<const SubstitutionRegisterInterface> reg,
41 std::shared_ptr<const AlphabetIndex2> weights,
42 std::shared_ptr<const AlphabetIndex2> distances) :
47 counts_(reg->getNumberOfSubstitutionTypes()),
48 currentLength_(0)
49{
51}
52
53
55{
56 counts_.resize(register_->getNumberOfSubstitutionTypes());
57 // Re-initialize all count matrices according to substitution register.
58 for (size_t i = 0; i < register_->getNumberOfSubstitutionTypes(); ++i)
59 {
60 counts_[i].resize(nbStates_, nbStates_);
61 }
62}
63
64/*************************************************/
65
67{
68 if (!model_)
69 throw Exception("DecompositionSubstitutionCount::fillBMatrices_: model not defined.");
70
71 vector<int> supportedStates = model_->getAlphabetStates();
72 for (size_t j = 0; j < nbStates_; ++j)
73 {
74 for (size_t k = 0; k < nbStates_; ++k)
75 {
76 size_t i = register_->getType(j, k);
77 if (i > 0 && k != j)
78 {
79 bMatrices_[i - 1](j, k) = model_->Qij(j, k);
80 }
81 }
82 }
83
84 if (distances_)
86}
87
89{
90 if (!model_)
91 throw Exception("DecompositionSubstitutionCount::setDistanceBMatrices_: model not defined.");
92
93 vector<int> supportedStates = model_->getAlphabetStates();
94 for (size_t j = 0; j < nbStates_; ++j)
95 {
96 for (size_t k = 0; k < nbStates_; ++k)
97 {
98 size_t i = register_->getType(j, k);
99 if (i > 0 && k != j)
100 {
101 bMatrices_[i - 1](j, k) *= distances_->getIndex(supportedStates[j], supportedStates[k]);
102 }
103 }
104 }
105}
106
107/******************************************************************************/
108
110{
112
113 // Now we must divide by pijt and account for putative weights:
114 vector<int> supportedStates = model_->getAlphabetStates();
115 RowMatrix<double> P = model_->getPij_t(length);
116 for (size_t i = 0; i < nbTypes_; i++)
117 {
118 for (size_t j = 0; j < nbStates_; j++)
119 {
120 for (size_t k = 0; k < nbStates_; k++)
121 {
122 counts_[i](j, k) /= P(j, k);
123 if (!std::isnormal(counts_[i](j, k)))
124 counts_[i](j, k) = 0.;
125 if (weights_)
126 counts_[i](j, k) *= weights_->getIndex(supportedStates[j], supportedStates[k]);
127 }
128 }
129 }
130}
131
132/******************************************************************************/
133
135 double length, size_t type) const
136{
137 if (!model_)
138 throw Exception("DecompositionSubstitutionCount::getAllNumbersOfSubstitutions: model not defined.");
139
140 if (length < 0)
141 throw Exception("DecompositionSubstitutionCount::getAllNumbersOfSubstitutions. Negative branch length: " + TextTools::toString(length) + ".");
142 if (length != currentLength_)
143 {
144 computeCounts_(length);
145 currentLength_ = length;
146 }
147 return make_unique<RowMatrix<double>>(counts_[type - 1]);
148}
149
150/******************************************************************************/
151
152void DecompositionSubstitutionCount::storeAllNumbersOfSubstitutions(double length, size_t type, Eigen::MatrixXd& mat) const
153{
154 if (!model_)
155 throw Exception("DecompositionSubstitutionCount::storeAllNumbersOfSubstitutions: model not defined.");
156
157 if (length < 0)
158 throw Exception("DecompositionSubstitutionCount::getAllNumbersOfSubstitutions. Negative branch length: " + TextTools::toString(length) + ".");
159 if (length != currentLength_)
160 {
161 computeCounts_(length);
162 currentLength_ = length;
163 }
164
165 mat.resize(Eigen::Index(nbStates_), Eigen::Index(nbStates_));
166
167 const auto& ct = counts_[type - 1];
168 for (size_t i = 0; i < nbStates_; i++)
169 {
170 for (size_t j = 0; j < nbStates_; j++)
171 {
172 mat(Eigen::Index(i), Eigen::Index(j)) = isnan(ct(i, j)) ? 0 : ct(i, j);
173 }
174 }
175}
176
177/******************************************************************************/
178
179double DecompositionSubstitutionCount::getNumberOfSubstitutions(size_t initialState, size_t finalState, double length, size_t type) const
180{
181 if (!model_)
182 throw Exception("DecompositionSubstitutionCount::getNumberOfSubstitutions: model not defined.");
183
184 if (length < 0)
185 throw Exception("DecompositionSubstitutionCount::getNumbersOfSubstitutions. Negative branch length: " + TextTools::toString(length) + ".");
186 if (length != currentLength_)
187 {
188 computeCounts_(length);
189 currentLength_ = length;
190 }
191 return counts_[type - 1](initialState, finalState);
192}
193
194/******************************************************************************/
195
196std::vector<double> DecompositionSubstitutionCount::getNumberOfSubstitutionsPerType(size_t initialState, size_t finalState, double length) const
197{
198 if (!model_)
199 throw Exception("DecompositionSubstitutionCount::getNumberOfSubstitutionsPerType: model not defined.");
200
201 if (length < 0)
202 throw Exception("DecompositionSubstitutionCount::getNumbersOfSubstitutions. Negative branch length: " + TextTools::toString(length) + ".");
203
204 if (length != currentLength_)
205 {
206 computeCounts_(length);
207 currentLength_ = length;
208 }
209 std::vector<double> v(getNumberOfSubstitutionTypes());
210 for (size_t t = 0; t < getNumberOfSubstitutionTypes(); ++t)
211 {
212 v[t] = counts_[t](initialState, finalState);
213 }
214 return v;
215}
216
217/******************************************************************************/
218
220 std::shared_ptr<const SubstitutionModelInterface> model)
221{
222 // Check compatibility between model and substitution register:
223 if (typeid(model->getAlphabet()) != typeid(register_->getAlphabet()))
224 throw Exception("DecompositionMethods::setSubstitutionModel: alphabets do not match between register and model.");
225
227
228 initCounts_();
229
232
233 // Recompute counts:
234 if (currentLength_ > 0)
236}
237
238/******************************************************************************/
239
241{
242 if (!model_)
243 return;
244
245 // Check compatibility between model and substitution register:
246 if (model_->getAlphabet()->getAlphabetType() != register_->getAlphabet()->getAlphabetType())
247 throw Exception("DecompositionMethods::substitutionRegisterHasChanged: alphabets do not match between register and model.");
248
250 initStates_();
251
252 initCounts_();
253
256
257 // Recompute counts:
258 if (currentLength_ > 0)
260}
261
262/******************************************************************************/
263
265{
266 if (typeid(weights_->getAlphabet()) != typeid(register_->getAlphabet()))
267 throw Exception("DecompositionSubstitutionCount::weightsHaveChanged. Incorrect alphabet type.");
268
269 if (!model_)
270 return;
271
272 // Recompute counts:
273 if (currentLength_ > 0)
275}
276
277
279{
280 if (distances_->getAlphabet()->getAlphabetType() != register_->getAlphabet()->getAlphabetType())
281 throw Exception("DecompositionSubstitutionCount::distancesHaveChanged. Incorrect alphabet type.");
282
283 if (!model_)
284 return;
285
286 // Recompute counts:
289
290 if (currentLength_ > 0)
292}
293
294/******************************************************************************/
Partial implementation of the SubstitutionCount interface.
std::shared_ptr< const SubstitutionRegisterInterface > register_
Partial implementation of the SubstitutionDistance interface.
std::shared_ptr< const AlphabetIndex2 > distances_
Partial implementation of the WeightedSubstitutionCount interface.
std::shared_ptr< const AlphabetIndex2 > weights_
Methods useful for analytical substitution count and rewards using the eigen decomposition method.
void computeExpectations(RowMatrix< double > &mapping, double length) const
void setSubstitutionModel(std::shared_ptr< const SubstitutionModelInterface > model)
Set the substitution model.
std::shared_ptr< const SubstitutionModelInterface > model_
std::vector< RowMatrix< double > > bMatrices_
computation matrices
double getNumberOfSubstitutions(size_t initialState, size_t finalState, double length, size_t type=1) const override
Get the number of susbstitutions on a branch, given the initial and final states, and the branch leng...
DecompositionSubstitutionCount(std::shared_ptr< const SubstitutionModelInterface > model, std::shared_ptr< const SubstitutionRegisterInterface > reg, std::shared_ptr< const AlphabetIndex2 > weights=nullptr, std::shared_ptr< const AlphabetIndex2 > distances=nullptr)
std::vector< RowMatrix< double > > counts_
std::unique_ptr< Matrix< double > > getAllNumbersOfSubstitutions(double length, size_t type=1) const override
Get the numbers of susbstitutions on a branch, for each initial and final states, and given the branc...
std::vector< double > getNumberOfSubstitutionsPerType(size_t initialState, size_t finalState, double length) const override
Get the numbers of susbstitutions on a branch for all types, for an initial and final states,...
void storeAllNumbersOfSubstitutions(double length, size_t type, Eigen::MatrixXd &mat) const override
Stores the numbers of susbstitutions on a branch, for each initial and final states,...
void setSubstitutionModel(std::shared_ptr< const SubstitutionModelInterface > model) override
Set the substitution model.
virtual size_t getNumberOfSubstitutionTypes() const
Short cut function, equivalent to getSubstitutionRegister().getNumberOfSubstitutionTypes().
std::string toString(T t)
Defines the basic types of data flow nodes.