bpp-phyl  2.2.0
TN93.cpp
Go to the documentation of this file.
1 //
2 // File: TN93.cpp
3 // Created by: Julien Dutheil
4 // Created on: Thu Jan 22 10:26:51 2004
5 //
6 
7 /*
8 Copyright or © or Copr. Bio++ Development Team, (November 16, 2004)
9 
10 This software is a computer program whose purpose is to provide classes
11 for phylogenetic data analysis.
12 
13 This software is governed by the CeCILL license under French law and
14 abiding by the rules of distribution of free software. You can use,
15 modify and/ or redistribute the software under the terms of the CeCILL
16 license as circulated by CEA, CNRS and INRIA at the following URL
17 "http://www.cecill.info".
18 
19 As a counterpart to the access to the source code and rights to copy,
20 modify and redistribute granted by the license, users are provided only
21 with a limited warranty and the software's author, the holder of the
22 economic rights, and the successive licensors have only limited
23 liability.
24 
25 In this respect, the user's attention is drawn to the risks associated
26 with loading, using, modifying and/or developing or reproducing the
27 software by the user in light of its specific status of free software,
28 that may mean that it is complicated to manipulate, and that also
29 therefore means that it is reserved for developers and experienced
30 professionals having in-depth computer knowledge. Users are therefore
31 encouraged to load and test the software's suitability as regards their
32 requirements in conditions enabling the security of their systems and/or
33 data to be ensured and, more generally, to use and operate it in the
34 same conditions as regards security.
35 
36 The fact that you are presently reading this means that you have had
37 knowledge of the CeCILL license and that you accept its terms.
38 */
39 
40 #include "TN93.h"
41 #include "../FrequenciesSet/NucleotideFrequenciesSet.h"
42 
43 #include <Bpp/Numeric/Matrix/MatrixTools.h>
44 #include <Bpp/Numeric/Matrix/EigenValue.h>
45 
46 // From bpp-seq:
47 #include <Bpp/Seq/Container/SequenceContainerTools.h>
48 
49 // From the STL:
50 #include <cmath>
51 
52 using namespace std;
53 
54 using namespace bpp;
55 
56 /******************************************************************************/
57 
58 TN93::TN93(
59  const NucleicAlphabet* alpha,
60  double kappa1,
61  double kappa2,
62  double piA,
63  double piC,
64  double piG,
65  double piT):
66  AbstractParameterAliasable("TN93."),
67  AbstractReversibleSubstitutionModel(alpha, new CanonicalStateMap(alpha, false), "TN93."),
68  kappa1_(kappa1), kappa2_(kappa2),
69  piA_(piA), piC_(piC), piG_(piG), piT_(piT), piY_(), piR_(),
70  r_(), k1_(), k2_(),
71  theta_(piG + piC), theta1_(piA / (1. - theta_)), theta2_(piG / theta_),
72  exp1_(), exp21_(), exp22_(), l_(), p_(size_, size_)
73 {
74  addParameter_(new Parameter("TN93.kappa1", kappa1, &Parameter::R_PLUS_STAR));
75  addParameter_(new Parameter("TN93.kappa2", kappa2, &Parameter::R_PLUS_STAR));
76  addParameter_(new Parameter("TN93.theta" , theta_ , &FrequenciesSet::FREQUENCE_CONSTRAINT_SMALL));
77  addParameter_(new Parameter("TN93.theta1", theta1_, &FrequenciesSet::FREQUENCE_CONSTRAINT_SMALL));
78  addParameter_(new Parameter("TN93.theta2", theta2_, &FrequenciesSet::FREQUENCE_CONSTRAINT_SMALL));
79  p_.resize(size_, size_);
81 }
82 
83 /******************************************************************************/
84 
86 {
87  kappa1_ = getParameterValue("kappa1");
88  kappa2_ = getParameterValue("kappa2");
89  theta_ = getParameterValue("theta" );
90  theta1_ = getParameterValue("theta1");
91  theta2_ = getParameterValue("theta2");
92  piA_ = theta1_ * (1. - theta_);
93  piC_ = (1. - theta2_) * theta_;
94  piG_ = theta2_ * theta_;
95  piT_ = (1. - theta1_) * (1. - theta_);
96  piR_ = piA_ + piG_;
97  piY_ = piT_ + piC_;
98  r_ = 1. / (2. * (piA_ * piC_ + piC_ * piG_ + piA_ * piT_ + piG_ * piT_ + kappa2_ * piC_ * piT_ + kappa1_ * piA_ * piG_));
99  k1_ = kappa2_ * piY_ + piR_;
100  k2_ = kappa1_ * piR_ + piY_;
101 
102  freq_[0] = piA_;
103  freq_[1] = piC_;
104  freq_[2] = piG_;
105  freq_[3] = piT_;
106 
107  generator_(0, 0) = -( piC_ + kappa1_*piG_ + piT_);
108  generator_(1, 1) = -( piA_ + piG_ + kappa2_*piT_);
109  generator_(2, 2) = -(kappa1_*piA_ + piC_ + piT_);
110  generator_(3, 3) = -( piA_ + kappa2_*piC_ + piG_ );
111 
112  generator_(1, 0) = piA_;
113  generator_(3, 0) = piA_;
114  generator_(0, 1) = piC_;
115  generator_(2, 1) = piC_;
116  generator_(1, 2) = piG_;
117  generator_(3, 2) = piG_;
118  generator_(0, 3) = piT_;
119  generator_(2, 3) = piT_;
120 
121  generator_(2, 0) = kappa1_ * piA_;
122  generator_(3, 1) = kappa2_ * piC_;
123  generator_(0, 2) = kappa1_ * piG_;
124  generator_(1, 3) = kappa2_ * piT_;
125 
126  // Normalization:
127  MatrixTools::scale(generator_, r_);
128 
129  // Exchangeability:
130  exchangeability_(0,0) = generator_(0,0) / piA_;
131  exchangeability_(0,1) = generator_(0,1) / piC_;
132  exchangeability_(0,2) = generator_(0,2) / piG_;
133  exchangeability_(0,3) = generator_(0,3) / piT_;
134 
135  exchangeability_(1,0) = generator_(1,0) / piA_;
136  exchangeability_(1,1) = generator_(1,1) / piC_;
137  exchangeability_(1,2) = generator_(1,2) / piG_;
138  exchangeability_(1,3) = generator_(1,3) / piT_;
139 
140  exchangeability_(2,0) = generator_(2,0) / piA_;
141  exchangeability_(2,1) = generator_(2,1) / piC_;
142  exchangeability_(2,2) = generator_(2,2) / piG_;
143  exchangeability_(2,3) = generator_(2,3) / piT_;
144 
145  exchangeability_(3,0) = generator_(3,0) / piA_;
146  exchangeability_(3,1) = generator_(3,1) / piC_;
147  exchangeability_(3,2) = generator_(3,2) / piG_;
148  exchangeability_(3,3) = generator_(3,3) / piT_;
149 
150  // We are not sure that the values are computed in this order :p
151  // Eigen values:
152  //eigenValues_[0] = 0;
153  //eigenValues_[1] = -r * (kappa2 * piY + piR);
154  //eigenValues_[2] = -r * (kappa1 * piR + piY);
155  //eigenValues_[3] = -r;
156 
157  // Eigen vectors and values:
158  EigenValue<double> ev(generator_);
159  rightEigenVectors_ = ev.getV();
160  MatrixTools::inv(rightEigenVectors_, leftEigenVectors_);
161  eigenValues_ = ev.getRealEigenValues();
162 }
163 
164 /******************************************************************************/
165 
166 double TN93::Pij_t(size_t i, size_t j, double d) const
167 {
168  l_ = rate_ * r_ * d;
169  exp1_ = exp(-l_);
170  exp22_ = exp(-k2_ * l_);
171  exp21_ = exp(-k1_ * l_);
172 
173  switch(i)
174  {
175  //A
176  case 0 : {
177  switch(j) {
178  case 0 : return piA_ * (1. + (piY_/piR_) * exp1_) + (piG_/piR_) * exp22_; //A
179  case 1 : return piC_ * (1. - exp1_); //C
180  case 2 : return piG_ * (1. + (piY_/piR_) * exp1_) - (piG_/piR_) * exp22_; //G
181  case 3 : return piT_ * (1. - exp1_); //T, U
182  }
183  }
184  //C
185  case 1 : {
186  switch(j) {
187  case 0 : return piA_ * (1. - exp1_); //A
188  case 1 : return piC_ * (1. + (piR_/piY_) * exp1_) + (piT_/piY_) * exp21_; //C
189  case 2 : return piG_ * (1. - exp1_); //G
190  case 3 : return piT_ * (1. + (piR_/piY_) * exp1_) - (piT_/piY_) * exp21_; //T, U
191  }
192  }
193  //G
194  case 2 : {
195  switch(j) {
196  case 0 : return piA_ * (1. + (piY_/piR_) * exp1_) - (piA_/piR_) * exp22_; //A
197  case 1 : return piC_ * (1. - exp1_); //C
198  case 2 : return piG_ * (1. + (piY_/piR_) * exp1_) + (piA_/piR_) * exp22_; //G
199  case 3 : return piT_ * (1. - exp1_); //T, U
200  }
201  }
202  //T, U
203  case 3 : {
204  switch(j) {
205  case 0 : return piA_ * (1. - exp1_); //A
206  case 1 : return piC_ * (1. + (piR_/piY_) * exp1_) - (piC_/piY_) * exp21_; //C
207  case 2 : return piG_ * (1. - exp1_); //G
208  case 3 : return piT_ * (1. + (piR_/piY_) * exp1_) + (piC_/piY_) * exp21_; //T, U
209  }
210  }
211  }
212  return 0;
213 }
214 
215 /******************************************************************************/
216 
217 double TN93::dPij_dt(size_t i, size_t j, double d) const
218 {
219  l_ = rate_ * r_ * d;
220  exp1_ = exp(-l_);
221  exp22_ = exp(-k2_ * l_);
222  exp21_ = exp(-k1_ * l_);
223 
224  switch(i)
225  {
226  //A
227  case 0 : {
228  switch(j) {
229  case 0 : return rate_ * r_ * (piA_ * -(piY_/piR_) * exp1_ - (piG_/piR_) * k2_ * exp22_); //A
230  case 1 : return rate_ * r_ * (piC_ * exp1_); //C
231  case 2 : return rate_ * r_ * (piG_ * -(piY_/piR_) * exp1_ + (piG_/piR_) * k2_ * exp22_); //G
232  case 3 : return rate_ * r_ * (piT_ * exp1_); //T, U
233  }
234  }
235  //C
236  case 1 : {
237  switch(j) {
238  case 0 : return rate_ * r_ * (piA_ * exp1_); //A
239  case 1 : return rate_ * r_ * (piC_ * -(piR_/piY_) * exp1_ - (piT_/piY_) * k1_ * exp21_); //C
240  case 2 : return rate_ * r_ * (piG_ * exp1_); //G
241  case 3 : return rate_ * r_ * (piT_ * -(piR_/piY_) * exp1_ + (piT_/piY_) * k1_ * exp21_); //T, U
242  }
243  }
244  //G
245  case 2 : {
246  switch(j) {
247  case 0 : return rate_ * r_ * (piA_ * -(piY_/piR_) * exp1_ + (piA_/piR_) * k2_ * exp22_); //A
248  case 1 : return rate_ * r_ * (piC_ * exp1_); //C
249  case 2 : return rate_ * r_ * (piG_ * -(piY_/piR_) * exp1_ - (piA_/piR_) * k2_ * exp22_); //G
250  case 3 : return rate_ * r_ * (piT_ * exp1_); //T, U
251  }
252  }
253  //T, U
254  case 3 : {
255  switch(j) {
256  case 0 : return rate_ * r_ * (piA_ * exp1_); //A
257  case 1 : return rate_ * r_ * (piC_ * -(piR_/piY_) * exp1_ + (piC_/piY_) * k1_ * exp21_); //C
258  case 2 : return rate_ * r_ * (piG_ * exp1_); //G
259  case 3 : return rate_ * r_ * (piT_ * -(piR_/piY_) * exp1_ - (piC_/piY_) * k1_ * exp21_); //T, U
260  }
261  }
262  }
263  return 0;
264 }
265 
266 /******************************************************************************/
267 
268 double TN93::d2Pij_dt2(size_t i, size_t j, double d) const
269 {
270  double r_2 = rate_ * rate_ * r_ * r_;
271  l_ = rate_ * r_ * d;
272  double k1_2 = k1_ * k1_;
273  double k2_2 = k2_ * k2_;
274  exp1_ = exp(-l_);
275  exp22_ = exp(-k2_ * l_);
276  exp21_ = exp(-k1_ * l_);
277 
278  switch(i)
279  {
280  //A
281  case 0 : {
282  switch(j) {
283  case 0 : return r_2 * (piA_ * (piY_/piR_) * exp1_ + (piG_/piR_) * k2_2 * exp22_); //A
284  case 1 : return r_2 * (piC_ * - exp1_); //C
285  case 2 : return r_2 * (piG_ * (piY_/piR_) * exp1_ - (piG_/piR_) * k2_2 * exp22_); //G
286  case 3 : return r_2 * (piT_ * - exp1_); //T, U
287  }
288  }
289  //C
290  case 1 : {
291  switch(j) {
292  case 0 : return r_2 * (piA_ * - exp1_); //A
293  case 1 : return r_2 * (piC_ * (piR_/piY_) * exp1_ + (piT_/piY_) * k1_2 * exp21_); //C
294  case 2 : return r_2 * (piG_ * - exp1_); //G
295  case 3 : return r_2 * (piT_ * (piR_/piY_) * exp1_ - (piT_/piY_) * k1_2 * exp21_); //T, U
296  }
297  }
298  //G
299  case 2 : {
300  switch(j) {
301  case 0 : return r_2 * (piA_ * (piY_/piR_) * exp1_ - (piA_/piR_) * k2_2 * exp22_); //A
302  case 1 : return r_2 * (piC_ * - exp1_); //C
303  case 2 : return r_2 * (piG_ * (piY_/piR_) * exp1_ + (piA_/piR_) * k2_2 * exp22_); //G
304  case 3 : return r_2 * (piT_ * - exp1_); //T, U
305  }
306  }
307  //T, U
308  case 3 : {
309  switch(j) {
310  case 0 : return r_2 * (piA_ * - exp1_); //A
311  case 1 : return r_2 * (piC_ * (piR_/piY_) * exp1_ - (piC_/piY_) * k1_2 * exp21_); //C
312  case 2 : return r_2 * (piG_ * - exp1_); //G
313  case 3 : return r_2 * (piT_ * (piR_/piY_) * exp1_ + (piC_/piY_) * k1_2 * exp21_); //T, U
314  }
315  }
316  }
317  return 0;
318 }
319 
320 /******************************************************************************/
321 
322 const Matrix<double> & TN93::getPij_t(double d) const
323 {
324  l_ = rate_ * r_ * d;
325  exp1_ = exp(-l_);
326  exp22_ = exp(-k2_ * l_);
327  exp21_ = exp(-k1_ * l_);
328 
329  //A
330  p_(0, 0) = piA_ * (1. + (piY_/piR_) * exp1_) + (piG_/piR_) * exp22_; //A
331  p_(0, 1) = piC_ * (1. - exp1_); //C
332  p_(0, 2) = piG_ * (1. + (piY_/piR_) * exp1_) - (piG_/piR_) * exp22_; //G
333  p_(0, 3) = piT_ * (1. - exp1_); //T, U
334 
335  //C
336  p_(1, 0) = piA_ * (1. - exp1_); //A
337  p_(1, 1) = piC_ * (1. + (piR_/piY_) * exp1_) + (piT_/piY_) * exp21_; //C
338  p_(1, 2) = piG_ * (1. - exp1_); //G
339  p_(1, 3) = piT_ * (1. + (piR_/piY_) * exp1_) - (piT_/piY_) * exp21_; //T, U
340 
341  //G
342  p_(2, 0) = piA_ * (1. + (piY_/piR_) * exp1_) - (piA_/piR_) * exp22_; //A
343  p_(2, 1) = piC_ * (1. - exp1_); //C
344  p_(2, 2) = piG_ * (1. + (piY_/piR_) * exp1_) + (piA_/piR_) * exp22_; //G
345  p_(2, 3) = piT_ * (1. - exp1_); //T, U
346 
347  //T, U
348  p_(3, 0) = piA_ * (1. - exp1_); //A
349  p_(3, 1) = piC_ * (1. + (piR_/piY_) * exp1_) - (piC_/piY_) * exp21_; //C
350  p_(3, 2) = piG_ * (1. - exp1_); //G
351  p_(3, 3) = piT_ * (1. + (piR_/piY_) * exp1_) + (piC_/piY_) * exp21_; //T, U
352 
353  return p_;
354 }
355 
356 const Matrix<double> & TN93::getdPij_dt(double d) const
357 {
358  l_ = rate_ * r_ * d;
359  exp1_ = exp(-l_);
360  exp22_ = exp(-k2_ * l_);
361  exp21_ = exp(-k1_ * l_);
362 
363  //A
364  p_(0, 0) = rate_ * r_ * (piA_ * -(piY_/piR_) * exp1_ - (piG_/piR_) * k2_ * exp22_); //A
365  p_(0, 1) = rate_ * r_ * (piC_ * exp1_); //C
366  p_(0, 2) = rate_ * r_ * (piG_ * -(piY_/piR_) * exp1_ + (piG_/piR_) * k2_ * exp22_); //G
367  p_(0, 3) = rate_ * r_ * (piT_ * exp1_); //T, U
368 
369  //C
370  p_(1, 0) = rate_ * r_ * (piA_ * exp1_); //A
371  p_(1, 1) = rate_ * r_ * (piC_ * -(piR_/piY_) * exp1_ - (piT_/piY_) * k1_ * exp21_); //C
372  p_(1, 2) = rate_ * r_ * (piG_ * exp1_); //G
373  p_(1, 3) = rate_ * r_ * (piT_ * -(piR_/piY_) * exp1_ + (piT_/piY_) * k1_ * exp21_); //T, U
374 
375  //G
376  p_(2, 0) = rate_ * r_ * (piA_ * -(piY_/piR_) * exp1_ + (piA_/piR_) * k2_ * exp22_); //A
377  p_(2, 1) = rate_ * r_ * (piC_ * exp1_); //C
378  p_(2, 2) = rate_ * r_ * (piG_ * -(piY_/piR_) * exp1_ - (piA_/piR_) * k2_ * exp22_); //G
379  p_(2, 3) = rate_ * r_ * (piT_ * exp1_); //T, U
380 
381  //T, U
382  p_(3, 0) = rate_ * r_ * (piA_ * exp1_); //A
383  p_(3, 1) = rate_ * r_ * (piC_ * -(piR_/piY_) * exp1_ + (piC_/piY_) * k1_ * exp21_); //C
384  p_(3, 2) = rate_ * r_ * (piG_ * exp1_); //G
385  p_(3, 3) = rate_ * r_ * (piT_ * -(piR_/piY_) * exp1_ - (piC_/piY_) * k1_ * exp21_); //T, U
386 
387  return p_;
388 }
389 
390 const Matrix<double> & TN93::getd2Pij_dt2(double d) const
391 {
392  double r_2 = rate_ * rate_ * r_ * r_;
393  l_ = rate_ * r_ * d;
394  double k1_2 = k1_ * k1_;
395  double k2_2 = k2_ * k2_;
396  exp1_ = exp(-l_);
397  exp22_ = exp(-k2_ * l_);
398  exp21_ = exp(-k1_ * l_);
399 
400  //A
401  p_(0, 0) = r_2 * (piA_ * (piY_/piR_) * exp1_ + (piG_/piR_) * k2_2 * exp22_); //A
402  p_(0, 1) = r_2 * (piC_ * - exp1_); //C
403  p_(0, 2) = r_2 * (piG_ * (piY_/piR_) * exp1_ - (piG_/piR_) * k2_2 * exp22_); //G
404  p_(0, 3) = r_2 * (piT_ * - exp1_); //T, U
405 
406  //C
407  p_(1, 0) = r_2 * (piA_ * - exp1_); //A
408  p_(1, 1) = r_2 * (piC_ * (piR_/piY_) * exp1_ + (piT_/piY_) * k1_2 * exp21_); //C
409  p_(1, 2) = r_2 * (piG_ * - exp1_); //G
410  p_(1, 3) = r_2 * (piT_ * (piR_/piY_) * exp1_ - (piT_/piY_) * k1_2 * exp21_); //T, U
411 
412  //G
413  p_(2, 0) = r_2 * (piA_ * (piY_/piR_) * exp1_ - (piA_/piR_) * k2_2 * exp22_); //A
414  p_(2, 1) = r_2 * (piC_ * - exp1_); //C
415  p_(2, 2) = r_2 * (piG_ * (piY_/piR_) * exp1_ + (piA_/piR_) * k2_2 * exp22_); //G
416  p_(2, 3) = r_2 * (piT_ * - exp1_); //T, U
417 
418  //T, U
419  p_(3, 0) = r_2 * (piA_ * - exp1_); //A
420  p_(3, 1) = r_2 * (piC_ * (piR_/piY_) * exp1_ - (piC_/piY_) * k1_2 * exp21_); //C
421  p_(3, 2) = r_2 * (piG_ * - exp1_); //G
422  p_(3, 3) = r_2 * (piT_ * (piR_/piY_) * exp1_ + (piC_/piY_) * k1_2 * exp21_); //T, U
423 
424  return p_;
425 }
426 
427 /******************************************************************************/
428 
429 void TN93::setFreq(std::map<int, double>& freqs)
430 {
431  piA_ = freqs[0];
432  piC_ = freqs[1];
433  piG_ = freqs[2];
434  piT_ = freqs[3];
435  vector<string> thetas(3);
436  thetas[0] = getNamespace() + "theta";
437  thetas[1] = getNamespace() + "theta1";
438  thetas[2] = getNamespace() + "theta2";
439  ParameterList pl = getParameters().subList(thetas);
440  pl[0].setValue(piC_ + piG_);
441  pl[1].setValue(piA_ / (piA_ + piT_));
442  pl[2].setValue(piG_ / (piC_ + piG_));
443  setParametersValues(pl);
444 }
445 
446 /******************************************************************************/
447 
double k2_
Definition: TN93.h:135
RowMatrix< double > exchangeability_
The exchangeability matrix of the model, defined as . When the model is reversible, this matrix is symetric.
double piC_
Definition: TN93.h:135
double exp22_
Definition: TN93.h:136
double piA_
Definition: TN93.h:135
double exp1_
Definition: TN93.h:136
This class implements a state map where all resolved states are modeled.
Definition: StateMap.h:161
RowMatrix< double > rightEigenVectors_
The matrix made of right eigen vectors (by column).
Vdouble eigenValues_
The vector of eigen values.
double theta2_
Definition: TN93.h:135
STL namespace.
double theta_
Definition: TN93.h:135
Vdouble freq_
The vector of equilibrium frequencies.
double piT_
Definition: TN93.h:135
double piY_
Definition: TN93.h:135
double piG_
Definition: TN93.h:135
double kappa2_
Definition: TN93.h:135
double kappa1_
Definition: TN93.h:135
Partial implementation of the ReversibleSubstitutionModel interface.
void setFreq(std::map< int, double > &freqs)
This method is over-defined to actualize the corresponding parameters piA, piT, piG and piC too...
Definition: TN93.cpp:429
double l_
Definition: TN93.h:136
double d2Pij_dt2(size_t i, size_t j, double d) const
Definition: TN93.cpp:268
static IntervalConstraint FREQUENCE_CONSTRAINT_SMALL
double Pij_t(size_t i, size_t j, double d) const
Definition: TN93.cpp:166
double exp21_
Definition: TN93.h:136
RowMatrix< double > leftEigenVectors_
The matrix made of left eigen vectors (by row) if rightEigenVectors_ is non-singular.
RowMatrix< double > generator_
The generator matrix of the model.
double rate_
The rate of the model (default: 1). The generator (and all its vectorial components) is independent o...
const Matrix< double > & getd2Pij_dt2(double d) const
Definition: TN93.cpp:390
double r_
Definition: TN93.h:135
double piR_
Definition: TN93.h:135
const Matrix< double > & getPij_t(double d) const
Definition: TN93.cpp:322
size_t size_
The size of the generator, i.e. the number of states.
const Matrix< double > & getdPij_dt(double d) const
Definition: TN93.cpp:356
RowMatrix< double > p_
Definition: TN93.h:137
double theta1_
Definition: TN93.h:135
double dPij_dt(size_t i, size_t j, double d) const
Definition: TN93.cpp:217
double k1_
Definition: TN93.h:135
void updateMatrices()
Compute and diagonalize the matrix, and fill the eigenValues_, leftEigenVectors_ and rightEigenVecto...
Definition: TN93.cpp:85