bpp-phyl3 3.0.0
WordSubstitutionModel.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: The Bio++ Development Group
2//
3// SPDX-License-Identifier: CECILL-2.1
4
8
10
11// From SeqLib:
14
15using namespace bpp;
16
17// From the STL:
18#include <cmath>
19
20using namespace std;
21
22/******************************************************************************/
23
24WordSubstitutionModel::WordSubstitutionModel(
25 ModelList& modelList,
26 const std::string& prefix) :
27 AbstractParameterAliasable((prefix == "") ? "Word." : prefix),
29 modelList,
30 (prefix == "") ? "Word." : prefix)
31{
32 size_t i, nbmod = VSubMod_.size();
33
34 // relative rates
35 for (i = 0; i < nbmod - 1; i++)
36 {
37 addParameter_(new Parameter("Word.relrate" + TextTools::toString(i + 1), 1.0 / static_cast<int>(nbmod - i), Parameter::PROP_CONSTRAINT_EX));
38 }
39
40 enableEigenDecomposition(false); // the product of the position
41 // specific transition probabilities
42
43 computeFrequencies(false); // it is done in AbstractWordSubstitutionModel
45}
46
48 std::shared_ptr<const Alphabet> alph,
49 std::shared_ptr<const StateMapInterface> stateMap,
50 const string& prefix) :
51 AbstractParameterAliasable((prefix == "") ? "Word." : prefix),
52 AbstractWordSubstitutionModel(alph, stateMap, (prefix == "") ? "Word." : prefix)
53{
54 enableEigenDecomposition(false); // the product of the position
55 // specific transition probabilities
56 computeFrequencies(false); // it is done in AbstractWordSubstitutionModel
57}
58
60 std::unique_ptr<SubstitutionModelInterface> pmodel,
61 unsigned int num,
62 const std::string& prefix) :
63 AbstractParameterAliasable((prefix == "") ? "Word." : prefix),
64 AbstractWordSubstitutionModel(std::move(pmodel),
65 num,
66 (prefix == "") ? "Word." : prefix)
67{
68 size_t i;
69
70 // relative rates
71 for (i = 0; i < num - 1; i++)
72 {
73 addParameter_(new Parameter("Word.relrate" + TextTools::toString(i + 1), 1.0 / static_cast<int>(num - i ), Parameter::PROP_CONSTRAINT_EX));
74 }
75
76 enableEigenDecomposition(false); // the product of the position
77 // specific transition probabilities
78 computeFrequencies(false); // it is done in AbstractWordSubstitutionModel
80}
81
83{
84 size_t i, nbmod = VSubMod_.size();
85 double x, y;
86 x = 1.0;
87
88 for (i = 0; i < nbmod - 1; i++)
89 {
90 y = getParameterValue("relrate" + TextTools::toString(i + 1));
91 Vrate_[i] = x * y;
92 x *= 1 - y;
93 }
94 Vrate_[nbmod - 1] = x;
95
97}
98
100{
101 size_t nbmod = VSubMod_.size();
102 size_t i, p, j, m;
103 size_t salph = getAlphabet()->getSize();
104
105 // freq_ for this generator
106
107 for (i = 0; i < salph; i++)
108 {
109 freq_[i] = 1;
110 j = i;
111 for (p = nbmod; p > 0; p--)
112 {
113 m = VSubMod_[p - 1]->getNumberOfStates();
114 freq_[i] *= VSubMod_[p - 1]->getFrequencies()[j % m];
115 j /= m;
116 }
117 }
118}
119
121{
122 vector<const Matrix<double>*> vM;
123 size_t nbmod = VSubMod_.size();
124 size_t i, j;
125
126 for (i = 0; i < nbmod; i++)
127 {
128 vM.push_back(&VSubMod_[i]->getPij_t(d * Vrate_[i] * rate_));
129 }
130
131 size_t t;
132 double x;
133 size_t i2, j2;
134 size_t nbStates = getNumberOfStates();
135 size_t p;
136
137 for (i = 0; i < nbStates; i++)
138 {
139 for (j = 0; j < nbStates; j++)
140 {
141 x = 1.;
142 i2 = i;
143 j2 = j;
144 for (p = nbmod; p > 0; p--)
145 {
146 t = VSubMod_[p - 1]->getNumberOfStates();
147 x *= (*vM[p - 1])(i2 % t, j2 % t);
148 i2 /= t;
149 j2 /= t;
150 }
151 pijt_(i, j) = x;
152 }
153 }
154
155 return pijt_;
156}
157
159{
160 vector<const Matrix<double>*> vM, vdM;
161 size_t nbmod = VSubMod_.size();
162 size_t i, j;
163
164 for (i = 0; i < nbmod; i++)
165 {
166 vM.push_back(&VSubMod_[i]->getPij_t(d * Vrate_[i] * rate_));
167 vdM.push_back(&VSubMod_[i]->getdPij_dt(d * Vrate_[i] * rate_));
168 }
169
170 size_t t;
171 double x, r;
172 size_t i2, j2;
173 size_t nbStates = getNumberOfStates();
174 size_t p, q;
175
176 for (i = 0; i < nbStates; i++)
177 {
178 for (j = 0; j < nbStates; j++)
179 {
180 r = 0;
181 for (q = 0; q < nbmod; q++)
182 {
183 i2 = i;
184 j2 = j;
185 x = 1;
186 for (p = nbmod; p > 0; p--)
187 {
188 t = VSubMod_[p - 1]->getNumberOfStates();
189 if (q != p - 1)
190 x *= (*vM[p - 1])(i2 % t, j2 % t);
191 else
192 x *= rate_ * Vrate_[p - 1] * (*vdM[p - 1])(i2 % t, j2 % t);
193 i2 /= t;
194 j2 /= t;
195 }
196 r += x;
197 }
198 dpijt_(i, j) = r;
199 }
200 }
201 return dpijt_;
202}
203
205
206{
207 vector<const Matrix<double>*> vM, vdM, vd2M;
208 size_t nbmod = VSubMod_.size();
209 size_t i, j;
210
211 for (i = 0; i < nbmod; i++)
212 {
213 vM.push_back(&VSubMod_[i]->getPij_t(d * Vrate_[i] * rate_));
214 vdM.push_back(&VSubMod_[i]->getdPij_dt(d * Vrate_[i] * rate_));
215 vd2M.push_back(&VSubMod_[i]->getd2Pij_dt2(d * Vrate_[i] * rate_));
216 }
217
218
219 double r, x;
220 size_t p, b, q, t;
221
222 size_t i2, j2;
223 size_t nbStates = getNumberOfStates();
224
225
226 for (i = 0; i < nbStates; i++)
227 {
228 for (j = 0; j < nbStates; j++)
229 {
230 r = 0;
231 for (q = 1; q < nbmod; q++)
232 {
233 for (b = 0; b < q; b++)
234 {
235 x = 1;
236 i2 = i;
237 j2 = j;
238 for (p = nbmod; p > 0; p--)
239 {
240 t = VSubMod_[p - 1]->getNumberOfStates();
241 if ((p - 1 == q) || (p - 1 == b))
242 x *= rate_ * Vrate_[p - 1] * (*vdM[p - 1])(i2 % t, j2 % t);
243 else
244 x *= (*vM[p - 1])(i2 % t, j2 % t);
245
246 i2 /= t;
247 j2 /= t;
248 }
249 r += x;
250 }
251 }
252
253 r *= 2;
254
255 for (q = 0; q < nbmod; q++)
256 {
257 x = 1;
258 i2 = i;
259 j2 = j;
260 for (p = nbmod; p > 0; p--)
261 {
262 t = VSubMod_[p - 1]->getNumberOfStates();
263 if (q != p - 1)
264 x *= (*vM[p - 1])(i2 % t, j2 % t);
265 else
266 x *= rate_ * rate_ * Vrate_[p - 1] * Vrate_[p - 1] * (*vd2M[p - 1])(i2 % t, j2 % t);
267
268 i2 /= t;
269 j2 /= t;
270 }
271 r += x;
272 }
273 d2pijt_(i, j) = r;
274 }
275 }
276 return d2pijt_;
277}
278
280{
281 return "Word";
282}
void addParameter_(Parameter *parameter)
double getParameterValue(const std::string &name) const override
bool enableEigenDecomposition()
Tell if eigenValues and Vectors must be computed.
RowMatrix< double > pijt_
These ones are for bookkeeping:
Vdouble freq_
The vector of equilibrium frequencies.
std::shared_ptr< const Alphabet > getAlphabet() const override
double rate_
The rate of the model (default: 1). The generator (and all its vectorial components) is independent o...
size_t getNumberOfStates() const override
Get the number of states.
Abstract Basal class for words of substitution models.
void updateMatrices_()
Diagonalize the matrix, and fill the eigenValues_, iEigenValues_, leftEigenVectors_ and rightEigenVe...
std::vector< std::shared_ptr< SubstitutionModelInterface > > VSubMod_
A list of models, for building a WordSubstitutionModel.
static const std::shared_ptr< IntervalConstraint > PROP_CONSTRAINT_EX
virtual void updateMatrices_() override
Diagonalize the matrix, and fill the eigenValues_, iEigenValues_, leftEigenVectors_ and rightEigenVe...
virtual void completeMatrices_() override
Called by updateMatrices to handle specific modifications for inheriting classes.
WordSubstitutionModel(ModelList &modelList, const std::string &prefix="")
Build a new WordSubstitutionModel object from a Vector of pointers to SubstitutionModels.
virtual const RowMatrix< double > & getdPij_dt(double d) const override
virtual const RowMatrix< double > & getd2Pij_dt2(double d) const override
virtual const RowMatrix< double > & getPij_t(double d) const override
virtual std::string getName() const override
Get the name of the model.
std::string toString(T t)
Defines the basic types of data flow nodes.