bpp-phyl3 3.0.0
LaplaceSubstitutionCount.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: The Bio++ Development Group
2//
3// SPDX-License-Identifier: CECILL-2.1
4
6
8
9using namespace bpp;
10using namespace std;
11
12/******************************************************************************/
13
14void LaplaceSubstitutionCount::computeCounts(double length) const
15{
16 RowMatrix<double> Q = model_->generator();
17 // L is the diagonal matrix with all substitution rates.
18 size_t s = Q.getNumberOfRows();
19 RowMatrix<double> QL(s, s);
20 for (size_t i = 0; i < s; i++)
21 {
22 for (size_t j = 0; j < s; j++)
23 {
24 QL(i, j) = ((i == j) ? 0. : Q(i, j));
25 }
26 }
27
29 RowMatrix<double> M2(s, s);
30 RowMatrix<double> M3(s, s);
31 RowMatrix<double> M4(s, s);
32 RowMatrix<double> M5(s, s);
33 for (size_t n = 1; n < cutOff_; ++n)
34 {
35 MatrixTools::fill(M2, 0.);
36 for (size_t p = 0; p < n; ++p)
37 {
38 MatrixTools::pow(Q, p, M3); // Q^p -> M5
39 MatrixTools::mult(M3, QL, M4); // Q^p . QL -> M4
40 MatrixTools::pow(Q, n - p - 1, M3); // Q^(n-p-1) -> M3
41 MatrixTools::mult(M4, M3, M5); // Q^p . QL . Q^(n-p-1) -> M5
42 MatrixTools::add(M2, M5);
43 }
44 MatrixTools::scale(M2, pow(length, static_cast<double>(n)) / static_cast<double>(NumTools::fact(n)));
46 }
47
48 // Now we must divide by pijt:
49 RowMatrix<double> P = model_->getPij_t(length);
50 for (size_t i = 0; i < s; i++)
51 {
52 for (size_t j = 0; j < s; j++)
53 {
54 m_(i, j) /= P(i, j);
55 }
56 }
57}
58
59/******************************************************************************/
60
61double LaplaceSubstitutionCount::getNumberOfSubstitutions(size_t initialState, size_t finalState, double length, size_t type) const
62{
63 if (!model_)
64 throw Exception("LaplaceSubstitutionCount::getNumberOfSubstitutions: model not defined.");
65
66 if (length == currentLength_)
67 return m_(initialState, finalState);
68 if (length < 0.000001)
69 return initialState == finalState ? 0. : 1.; // Limit case!
70 // Else we need to recompute M:
71 computeCounts(length);
72
73 currentLength_ = length;
74 return m_(initialState, finalState);
75}
76
77/******************************************************************************/
78
79unique_ptr<Matrix<double>> LaplaceSubstitutionCount::getAllNumbersOfSubstitutions(double length, size_t type) const
80{
81 if (!model_)
82 throw Exception("LaplaceSubstitutionCount::getAllNumbersOfSubstitutions: model not defined.");
83
84 if (length == currentLength_)
85 return make_unique<RowMatrix<double>>(m_);
86 if (length < 0.000001) // Limit case!
87 {
88 size_t s = model_->getAlphabet()->getSize();
89 for (size_t i = 0; i < s; i++)
90 {
91 for (size_t j = 0; j < s; j++)
92 {
93 m_(i, j) = i == j ? 0. : 1.;
94 }
95 }
96 }
97 else
98 {
99 // Else we need to recompute M:
100 computeCounts(length);
101 }
102
103 currentLength_ = length;
104
105 return make_unique<RowMatrix<double>>(m_);
106}
107
108/******************************************************************************/
109
110void LaplaceSubstitutionCount::storeAllNumbersOfSubstitutions(double length, size_t type, Eigen::MatrixXd& mat) const
111{
112 if (!model_)
113 throw Exception("LaplaceSubstitutionCount::storeAllNumbersOfSubstitutions: model not defined.");
114
115 auto s = Eigen::Index(model_->getAlphabet()->getSize());
116 if (length == currentLength_)
117 mat = Eigen::MatrixXd::Zero(s, s);
118
119 if (length < 0.000001) // Limit case!
120 {
121 for (auto i = 0; i < s; i++)
122 {
123 for (auto j = 0; j < s; j++)
124 {
125 mat(i, j) = i == j ? 0. : 1.;
126 }
127 }
128 }
129 else
130 {
131 // Else we need to recompute M:
132 computeCounts(length);
133 }
134
135 currentLength_ = length;
136
137 mat.resize(s, s);
138
139 for (auto i = 0; i < s; i++)
140 {
141 for (auto j = 0; j < s; j++)
142 {
143 mat(i, j) = std::isnan(m_(size_t(i), size_t(j))) ? 0 : m_(size_t(i), size_t(j));
144 }
145 }
146}
147
148/******************************************************************************/
149
151 shared_ptr<const SubstitutionModelInterface> model)
152{
153 model_ = model;
154 if (!model)
155 return;
156
157 size_t n = model->alphabet().getSize();
158 m_.resize(n, n);
159 // Recompute counts:
160 if (currentLength_ > 0)
162}
163
164/******************************************************************************/
std::shared_ptr< const SubstitutionModelInterface > model_
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 associated with this count, if relevant.
void computeCounts(double length) const
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...
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...
static void pow(const Matrix &A, size_t p, Matrix &O)
static void add(MatrixA &A, const MatrixB &B)
static void mult(const Matrix< Scalar > &A, const Matrix< Scalar > &B, Matrix< Scalar > &O)
static void scale(Matrix &A, Scalar a, Scalar b=0)
static void fill(Matrix &M, Scalar x)
static T fact(T n)
size_t getNumberOfRows() const
void resize(size_t nRows, size_t nCols)
Defines the basic types of data flow nodes.
ExtendedFloat pow(const ExtendedFloat &ef, double exp)