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 
11 using namespace bpp;
12 using namespace std;
13 
14 /******************************************************************************/
15 
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 
32  initCounts_();
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 {
50  initCounts_();
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 {
111  computeExpectations(counts_, length);
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 
152 void 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 
179 double 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 
196 std::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 
230  fillBMatrices_();
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 
249  initBMatrices_();
250  initStates_();
251 
252  initCounts_();
253 
254  fillBMatrices_();
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.