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 
15 using namespace bpp;
16 
17 // From the STL:
18 #include <cmath>
19 
20 using namespace std;
21 
22 /******************************************************************************/
23 
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.
std::shared_ptr< const Alphabet > getAlphabet() const override
RowMatrix< double > pijt_
These ones are for bookkeeping:
Vdouble freq_
The vector of equilibrium frequencies.
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.