bpp-phyl  2.2.0
RN95s.cpp
Go to the documentation of this file.
1 //
2 // File: RN95s.cpp
3 // Created by: Laurent Guéguen
4 // Created on: jeudi 24 février 2011, à 20h 42
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 "RN95s.h"
41 
42 #include <Bpp/Numeric/Matrix/MatrixTools.h>
43 
44 // From SeqLib:
45 #include <Bpp/Seq/Container/SequenceContainerTools.h>
46 
47 // From the STL:
48 #include <cmath>
49 
50 using namespace bpp;
51 using namespace std;
52 
53 /******************************************************************************/
54 
55 RN95s::RN95s(const NucleicAlphabet* alphabet,
56  double alpha,
57  double beta,
58  double gamma,
59  double delta) :
60  AbstractParameterAliasable("RN95s."),
61  AbstractSubstitutionModel(alphabet, new CanonicalStateMap(alphabet, false), "RN95s."),
62  alpha_(),
63  beta_(),
64  gamma_(),
65  delta_(),
66  r_(),
67  c3_(),
68  c4_(),
69  c8_(),
70  p_(size_, size_),
71  exp1_(),
72  exp3_(),
73  l_()
74 {
75  double f = 2 * (gamma + delta);
76 
77  alpha_ = alpha / f;
78  beta_ = beta / f;
79  gamma_ = gamma / f;
80  delta_ = delta / f;
81 
82  double piA = 0.5 * (beta_ + delta_) / (alpha_ + beta_ + 0.5);
83  double alphaP = (2 * alpha_ * piA + ((0.5 - piA < gamma_) ? 0.5 - piA : gamma_)) / (0.5 - piA);
84  addParameter_(new Parameter("RN95s.thetaA", piA, new IntervalConstraint(0, 0.5, false, false), true));
85  addParameter_(new Parameter("RN95s.gamma", gamma_, new IntervalConstraint(0, 0.5, false, false), true));
86  addParameter_(new Parameter("RN95s.alphaP", alphaP, new IntervalConstraint(1, 1, false), true));
87 
89 }
90 
91 /******************************************************************************/
93 {
94  freq_[0] = getParameterValue("thetaA");
95  double alphaP = getParameterValue("alphaP");
96  gamma_ = getParameterValue("gamma");
97  alpha_ = (alphaP * (0.5 - freq_[0]) - ((0.5 - freq_[0] < gamma_) ? 0.5 - freq_[0] : gamma_)) / (2 * freq_[0]);
98  delta_ = 0.5 - gamma_;
99  beta_ = (2 * freq_[0] * (alpha_ + 0.5) - delta_) / (1 - 2 * freq_[0]);
100 
101  // stationnary frequencies
102 
103  freq_[1] = 0.5 - freq_[0];
104  freq_[2] = freq_[1];
105  freq_[3] = freq_[0];
106 
107  // Generator matrix:
108 
109  generator_(0, 1) = gamma_;
110  generator_(0, 2) = alpha_;
111  generator_(0, 3) = delta_;
112 
113  generator_(0, 0) = -(gamma_ + alpha_ + delta_);
114 
115  generator_(1, 0) = delta_;
116  generator_(1, 2) = gamma_;
117  generator_(1, 3) = beta_;
118 
119  generator_(1, 1) = -(delta_ + beta_ + gamma_);
120 
121  generator_(2, 0) = beta_;
122  generator_(2, 1) = gamma_;
123  generator_(2, 3) = delta_;
124 
125  generator_(2, 2) = -(gamma_ + beta_ + delta_);
126 
127  generator_(3, 0) = delta_;
128  generator_(3, 1) = alpha_;
129  generator_(3, 2) = gamma_;
130 
131  generator_(3, 3) = -(delta_ + alpha_ + gamma_);
132 
133  // Normalization
134 
135  double x = 0;
136  for (unsigned int i = 0; i < 4; i++)
137  {
138  x += generator_(i, i) * freq_[i];
139  }
140 
141  r_ = -1 / x;
142 
143  MatrixTools::scale(generator_, r_);
144 
145  // variables for calculation purposes
146 
147  c3_ = alpha_ + gamma_ + beta_ + delta_;
148  c4_ = gamma_ - alpha_;
149  c8_ = delta_ - beta_;
150 
151 
152  // eigen vectors and values
153 
154  eigenValues_[0] = 0;
155  eigenValues_[1] = -r_;
156  eigenValues_[2] = -c3_ * r_;
157  eigenValues_[3] = -c3_ * r_;
158 
159  rightEigenVectors_(0, 0) = 1.;
160  rightEigenVectors_(1, 0) = 1.;
161  rightEigenVectors_(2, 0) = 1.;
162  rightEigenVectors_(3, 0) = 1.;
163 
164  rightEigenVectors_(0, 1) = 1.;
165  rightEigenVectors_(1, 1) = -1;
166  rightEigenVectors_(2, 1) = 1.;
167  rightEigenVectors_(3, 1) = -1;
168 
169  rightEigenVectors_(0, 2) = (alpha_ * (0.5 - c3_) + gamma_ * 0.5) / (delta_ * (c3_ - 0.5) - beta_ * 0.5);
170  rightEigenVectors_(1, 2) = 1.;
171  rightEigenVectors_(2, 2) = (-beta_ * (0.5 - c3_) - delta_ * 0.5) / (delta_ * (c3_ - 0.5) - beta_ * 0.5);
172  rightEigenVectors_(3, 2) = 1.;
173 
174  rightEigenVectors_(0, 3) = 1.;
175  rightEigenVectors_(1, 3) = (beta_ * (0.5 - c3_) + delta_ * 0.5) / (gamma_ * (c3_ - 0.5) - alpha_ * 0.5);
176  rightEigenVectors_(2, 3) = 1;
177  rightEigenVectors_(3, 3) = (-alpha_ * (0.5 - c3_) - gamma_ * 0.5) / (gamma_ * (c3_ - 0.5) - alpha_ * 0.5);
178 
179 // Need formula
180 
182  {
183  try
184  {
185  MatrixTools::inv(rightEigenVectors_, leftEigenVectors_);
186  isNonSingular_ = true;
187  isDiagonalizable_ = true;
188  for (unsigned int i = 0; i < size_ && isDiagonalizable_; i++)
189  {
190  if (abs(iEigenValues_[i]) > NumConstants::TINY())
191  isDiagonalizable_ = false;
192  }
193  }
194  catch (ZeroDivisionException& e)
195  {
196  ApplicationTools::displayMessage("Singularity during diagonalization. Taylor series used instead.");
197 
198  isNonSingular_ = false;
199  isDiagonalizable_ = false;
200  MatrixTools::Taylor(generator_, 30, vPowGen_);
201  }
202 
203  // and the exchangeability_
204  for (size_t i = 0; i < size_; i++)
205  for (size_t j = 0; j < size_; j++)
206  exchangeability_(i,j) = generator_(i,j) / freq_[j];
207  }
208 }
209 
210 /******************************************************************************/
211 double RN95s::Pij_t(size_t i, size_t j, double d) const
212 {
213  l_ = rate_ * r_ * d;
214  exp1_ = exp(-l_);
215  exp3_ = exp(-c3_ * l_);
216 
217  switch (i)
218  {
219  {
220  // A
221  case 0: {
222  switch (j)
223  {
224  case 0: return freq_[0] - 0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ + (alpha_ * (c3_ - 1.) - 0.5 * c4_) / (c3_ * (c3_ - 1.)) * exp3_; // A
225  case 1: return freq_[1] + 0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ + (delta_ * alpha_ - gamma_ * beta_) / (c3_ * (c3_ - 1.)) * exp3_; // C
226  case 2: return freq_[2] - 0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ - (alpha_ * (c3_ - 1.) - 0.5 * c4_) / (c3_ * (c3_ - 1.)) * exp3_; // G
227  case 3: return freq_[3] + 0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ - (delta_ * alpha_ - gamma_ * beta_) / (c3_ * (c3_ - 1.)) * exp3_; // T, U
228  }
229  }
230  // C
231  case 1: {
232  switch (j)
233  {
234  case 0: return freq_[0] + 0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ + (beta_ * gamma_ - delta_ * alpha_) / (c3_ * (c3_ - 1.)) * exp3_; // A
235  case 1: return freq_[1] - 0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ + (beta_ * (c3_ - 1.) - 0.5 * c8_) / (c3_ * (c3_ - 1.)) * exp3_; // C
236  case 2: return freq_[2] + 0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ - (beta_ * gamma_ - delta_ * alpha_) / (c3_ * (c3_ - 1.)) * exp3_; // G
237  case 3: return freq_[3] - 0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ - (beta_ * (c3_ - 1.) - 0.5 * c8_) / (c3_ * (c3_ - 1.)) * exp3_; // T
238  }
239  }
240  // G
241  case 2: {
242  switch (j)
243  {
244  case 0: return freq_[0] - 0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ + (0.5 * c8_ - beta_ * (c3_ - 1.)) / (c3_ * (c3_ - 1.)) * exp3_; // A
245  case 1: return freq_[1] + 0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ + (delta_ * alpha_ - gamma_ * beta_) / (c3_ * (c3_ - 1.)) * exp3_; // C
246  case 2: return freq_[2] - 0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ - (0.5 * c8_ - beta_ * (c3_ - 1.)) / (c3_ * (c3_ - 1.)) * exp3_; // G
247  case 3: return freq_[3] + 0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ - (delta_ * alpha_ - gamma_ * beta_) / (c3_ * (c3_ - 1.)) * exp3_; // T, U
248  }
249  }
250  }
251  // T, U
252  case 3: {
253  switch (j)
254  {
255  case 0: return freq_[0] + 0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ + (beta_ * gamma_ - delta_ * alpha_) / (c3_ * (c3_ - 1.)) * exp3_; // A
256  case 1: return freq_[1] - 0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ + (0.5 * c4_ - alpha_ * (c3_ - 1.)) / (c3_ * (c3_ - 1.)) * exp3_; // C
257  case 2: return freq_[2] + 0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ - (beta_ * gamma_ - delta_ * alpha_) / (c3_ * (c3_ - 1.)) * exp3_; // G
258  case 3: return freq_[3] - 0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ - (0.5 * c4_ - alpha_ * (c3_ - 1.)) / (c3_ * (c3_ - 1.)) * exp3_; // T
259  }
260  }
261  }
262  return 0;
263 }
264 
265 /******************************************************************************/
266 double RN95s::dPij_dt(size_t i, size_t j, double d) const
267 {
268  l_ = rate_ * r_ * d;
269  exp1_ = -1.* rate_* r_* exp(-1. * l_);
270  exp3_ = -c3_* rate_* r_* exp(-c3_ * l_);
271 
272  switch (i)
273  {
274  {
275  // A
276  case 0: {
277  switch (j)
278  {
279  case 0: return -0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ + (alpha_ * (c3_ - 1.) - 0.5 * c4_) / (c3_ * (c3_ - 1.)) * exp3_; // A
280  case 1: return 0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ + (delta_ * alpha_ - gamma_ * beta_) / (c3_ * (c3_ - 1.)) * exp3_; // C
281  case 2: return -0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ - (alpha_ * (c3_ - 1.) - 0.5 * c4_) / (c3_ * (c3_ - 1.)) * exp3_; // G
282  case 3: return 0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ - (delta_ * alpha_ - gamma_ * beta_) / (c3_ * (c3_ - 1.)) * exp3_; // T, U
283  }
284  }
285  // C
286  case 1: {
287  switch (j)
288  {
289  case 0: return 0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ + (beta_ * gamma_ - delta_ * alpha_) / (c3_ * (c3_ - 1.)) * exp3_; // A
290  case 1: return -0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ + (beta_ * (c3_ - 1.) - 0.5 * c8_) / (c3_ * (c3_ - 1.)) * exp3_; // C
291  case 2: return 0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ - (beta_ * gamma_ - delta_ * alpha_) / (c3_ * (c3_ - 1.)) * exp3_; // G
292  case 3: return -0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ - (beta_ * (c3_ - 1.) - 0.5 * c8_) / (c3_ * (c3_ - 1.)) * exp3_; // T
293  }
294  }
295  // G
296  case 2: {
297  switch (j)
298  {
299  case 0: return -0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ + (0.5 * c8_ - beta_ * (c3_ - 1.)) / (c3_ * (c3_ - 1.)) * exp3_; // A
300  case 1: return 0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ + (delta_ * alpha_ - gamma_ * beta_) / (c3_ * (c3_ - 1.)) * exp3_; // C
301  case 2: return -0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ - (0.5 * c8_ - beta_ * (c3_ - 1.)) / (c3_ * (c3_ - 1.)) * exp3_; // G
302  case 3: return 0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ - (delta_ * alpha_ - gamma_ * beta_) / (c3_ * (c3_ - 1.)) * exp3_; // T, U
303  }
304  }
305  }
306  // T, U
307  case 3: {
308  switch (j)
309  {
310  case 0: return 0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ + (beta_ * gamma_ - delta_ * alpha_) / (c3_ * (c3_ - 1.)) * exp3_; // A
311  case 1: return -0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ + (0.5 * c4_ - alpha_ * (c3_ - 1.)) / (c3_ * (c3_ - 1.)) * exp3_; // C
312  case 2: return 0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ - (beta_ * gamma_ - delta_ * alpha_) / (c3_ * (c3_ - 1.)) * exp3_; // G
313  case 3: return -0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ - (0.5 * c4_ - alpha_ * (c3_ - 1.)) / (c3_ * (c3_ - 1.)) * exp3_; // T
314  }
315  }
316  }
317  return 0;
318 }
319 
320 /******************************************************************************/
321 double RN95s::d2Pij_dt2(size_t i, size_t j, double d) const
322 {
323  l_ = rate_ * r_ * d;
324  exp1_ = 1. * rate_ * r_ * 1.* rate_* r_* exp(-1. * l_);
325  exp3_ = c3_ * rate_ * r_ * c3_ * rate_ * r_ * exp(-c3_ * l_);
326 
327  switch (i)
328  {
329  {
330  // A
331  case 0: {
332  switch (j)
333  {
334  case 0: return -0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ + (alpha_ * (c3_ - 1.) - 0.5 * c4_) / (c3_ * (c3_ - 1.)) * exp3_; // A
335  case 1: return 0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ + (delta_ * alpha_ - gamma_ * beta_) / (c3_ * (c3_ - 1.)) * exp3_; // C
336  case 2: return -0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ - (alpha_ * (c3_ - 1.) - 0.5 * c4_) / (c3_ * (c3_ - 1.)) * exp3_; // G
337  case 3: return 0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ - (delta_ * alpha_ - gamma_ * beta_) / (c3_ * (c3_ - 1.)) * exp3_; // T, U
338  }
339  }
340  // C
341  case 1: {
342  switch (j)
343  {
344  case 0: return 0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ + (beta_ * gamma_ - delta_ * alpha_) / (c3_ * (c3_ - 1.)) * exp3_; // A
345  case 1: return -0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ + (beta_ * (c3_ - 1.) - 0.5 * c8_) / (c3_ * (c3_ - 1.)) * exp3_; // C
346  case 2: return 0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ - (beta_ * gamma_ - delta_ * alpha_) / (c3_ * (c3_ - 1.)) * exp3_; // G
347  case 3: return -0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ - (beta_ * (c3_ - 1.) - 0.5 * c8_) / (c3_ * (c3_ - 1.)) * exp3_; // T
348  }
349  }
350  // G
351  case 2: {
352  switch (j)
353  {
354  case 0: return -0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ + (0.5 * c8_ - beta_ * (c3_ - 1.)) / (c3_ * (c3_ - 1.)) * exp3_; // A
355  case 1: return 0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ + (delta_ * alpha_ - gamma_ * beta_) / (c3_ * (c3_ - 1.)) * exp3_; // C
356  case 2: return -0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ - (0.5 * c8_ - beta_ * (c3_ - 1.)) / (c3_ * (c3_ - 1.)) * exp3_; // G
357  case 3: return 0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ - (delta_ * alpha_ - gamma_ * beta_) / (c3_ * (c3_ - 1.)) * exp3_; // T, U
358  }
359  }
360  }
361  // T, U
362  case 3: {
363  switch (j)
364  {
365  case 0: return 0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ + (beta_ * gamma_ - delta_ * alpha_) / (c3_ * (c3_ - 1.)) * exp3_; // A
366  case 1: return -0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ + (0.5 * c4_ - alpha_ * (c3_ - 1.)) / (c3_ * (c3_ - 1.)) * exp3_; // C
367  case 2: return 0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ - (beta_ * gamma_ - delta_ * alpha_) / (c3_ * (c3_ - 1.)) * exp3_; // G
368  case 3: return -0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ - (0.5 * c4_ - alpha_ * (c3_ - 1.)) / (c3_ * (c3_ - 1.)) * exp3_; // T
369  }
370  }
371  }
372  return 0;
373 }
374 
375 /******************************************************************************/
376 
377 const Matrix<double>& RN95s::getPij_t(double d) const
378 {
379  l_ = rate_ * r_ * d;
380  exp1_ = exp(-1. * l_);
381  exp3_ = exp(-c3_ * l_);
382 
383  // A
384  p_(0, 0) = freq_[0] - 0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ + (alpha_ * (c3_ - 1.) - 0.5 * c4_) / (c3_ * (c3_ - 1.)) * exp3_; // A
385  p_(0, 1) = freq_[1] + 0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ + (delta_ * alpha_ - gamma_ * beta_) / (c3_ * (c3_ - 1.)) * exp3_; // C
386  p_(0, 2) = freq_[2] - 0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ - (alpha_ * (c3_ - 1.) - 0.5 * c4_) / (c3_ * (c3_ - 1.)) * exp3_; // G
387  p_(0, 3) = freq_[3] + 0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ - (delta_ * alpha_ - gamma_ * beta_) / (c3_ * (c3_ - 1.)) * exp3_; // T, U
388  // C
389  p_(1, 0) = freq_[0] + 0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ + (beta_ * gamma_ - delta_ * alpha_) / (c3_ * (c3_ - 1.)) * exp3_; // A
390  p_(1, 1) = freq_[1] - 0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ + (beta_ * (c3_ - 1.) - 0.5 * c8_) / (c3_ * (c3_ - 1.)) * exp3_; // C
391  p_(1, 2) = freq_[2] + 0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ - (beta_ * gamma_ - delta_ * alpha_) / (c3_ * (c3_ - 1.)) * exp3_; // G
392  p_(1, 3) = freq_[3] - 0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ - (beta_ * (c3_ - 1.) - 0.5 * c8_) / (c3_ * (c3_ - 1.)) * exp3_; // T
393  // G
394  p_(2, 0) = freq_[0] - 0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ + (0.5 * c8_ - beta_ * (c3_ - 1.)) / (c3_ * (c3_ - 1.)) * exp3_; // A
395  p_(2, 1) = freq_[1] + 0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ + (delta_ * alpha_ - gamma_ * beta_) / (c3_ * (c3_ - 1.)) * exp3_; // C
396  p_(2, 2) = freq_[2] - 0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ - (0.5 * c8_ - beta_ * (c3_ - 1.)) / (c3_ * (c3_ - 1.)) * exp3_; // G
397  p_(2, 3) = freq_[3] + 0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ - (delta_ * alpha_ - gamma_ * beta_) / (c3_ * (c3_ - 1.)) * exp3_; // T, U
398  // T, U
399  p_(3, 0) = freq_[0] + 0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ + (beta_ * gamma_ - delta_ * alpha_) / (c3_ * (c3_ - 1.)) * exp3_; // A
400  p_(3, 1) = freq_[1] - 0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ + (0.5 * c4_ - alpha_ * (c3_ - 1.)) / (c3_ * (c3_ - 1.)) * exp3_; // C
401  p_(3, 2) = freq_[2] + 0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ - (beta_ * gamma_ - delta_ * alpha_) / (c3_ * (c3_ - 1.)) * exp3_; // G
402  p_(3, 3) = freq_[3] - 0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ - (0.5 * c4_ - alpha_ * (c3_ - 1.)) / (c3_ * (c3_ - 1.)) * exp3_; // T
403 
404  return p_;
405 }
406 
407 /******************************************************************************/
408 
409 const Matrix<double>& RN95s::getdPij_dt(double d) const
410 {
411  l_ = rate_ * r_ * d;
412  exp1_ = -1.* rate_* r_* exp(-1. * l_);
413  exp3_ = -c3_* rate_* r_* exp(-c3_ * l_);
414 
415  // A
416  p_(0, 0) = -0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ + (alpha_ * (c3_ - 1.) - 0.5 * c4_) / (c3_ * (c3_ - 1.)) * exp3_; // A
417  p_(0, 1) = 0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ + (delta_ * alpha_ - gamma_ * beta_) / (c3_ * (c3_ - 1.)) * exp3_; // C
418  p_(0, 2) = -0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ - (alpha_ * (c3_ - 1.) - 0.5 * c4_) / (c3_ * (c3_ - 1.)) * exp3_; // G
419  p_(0, 3) = 0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ - (delta_ * alpha_ - gamma_ * beta_) / (c3_ * (c3_ - 1.)) * exp3_; // T, U
420  // C
421  p_(1, 0) = 0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ + (beta_ * gamma_ - delta_ * alpha_) / (c3_ * (c3_ - 1.)) * exp3_; // A
422  p_(1, 1) = -0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ + (beta_ * (c3_ - 1.) - 0.5 * c8_) / (c3_ * (c3_ - 1.)) * exp3_; // C
423  p_(1, 2) = 0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ - (beta_ * gamma_ - delta_ * alpha_) / (c3_ * (c3_ - 1.)) * exp3_; // G
424  p_(1, 3) = -0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ - (beta_ * (c3_ - 1.) - 0.5 * c8_) / (c3_ * (c3_ - 1.)) * exp3_; // T
425  // G
426  p_(2, 0) = -0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ + (0.5 * c8_ - beta_ * (c3_ - 1.)) / (c3_ * (c3_ - 1.)) * exp3_; // A
427  p_(2, 1) = 0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ + (delta_ * alpha_ - gamma_ * beta_) / (c3_ * (c3_ - 1.)) * exp3_; // C
428  p_(2, 2) = -0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ - (0.5 * c8_ - beta_ * (c3_ - 1.)) / (c3_ * (c3_ - 1.)) * exp3_; // G
429  p_(2, 3) = 0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ - (delta_ * alpha_ - gamma_ * beta_) / (c3_ * (c3_ - 1.)) * exp3_; // T, U
430  // T, U
431  p_(3, 0) = 0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ + (beta_ * gamma_ - delta_ * alpha_) / (c3_ * (c3_ - 1.)) * exp3_; // A
432  p_(3, 1) = -0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ + (0.5 * c4_ - alpha_ * (c3_ - 1.)) / (c3_ * (c3_ - 1.)) * exp3_; // C
433  p_(3, 2) = 0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ - (beta_ * gamma_ - delta_ * alpha_) / (c3_ * (c3_ - 1.)) * exp3_; // G
434  p_(3, 3) = -0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ - (0.5 * c4_ - alpha_ * (c3_ - 1.)) / (c3_ * (c3_ - 1.)) * exp3_; // T
435  return p_;
436 }
437 
438 /******************************************************************************/
439 
440 const Matrix<double>& RN95s::getd2Pij_dt2(double d) const
441 {
442  l_ = rate_ * r_ * d;
443  exp1_ = 1. * rate_ * r_ * 1.* rate_* r_* exp(-1. * l_);
444  exp3_ = c3_ * rate_ * r_ * c3_ * rate_ * r_ * exp(-c3_ * l_);
445 
446  // A
447  p_(0, 0) = -0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ + (alpha_ * (c3_ - 1.) - 0.5 * c4_) / (c3_ * (c3_ - 1.)) * exp3_; // A
448  p_(0, 1) = 0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ + (delta_ * alpha_ - gamma_ * beta_) / (c3_ * (c3_ - 1.)) * exp3_; // C
449  p_(0, 2) = -0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ - (alpha_ * (c3_ - 1.) - 0.5 * c4_) / (c3_ * (c3_ - 1.)) * exp3_; // G
450  p_(0, 3) = 0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ - (delta_ * alpha_ - gamma_ * beta_) / (c3_ * (c3_ - 1.)) * exp3_; // T, U
451  // C
452  p_(1, 0) = 0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ + (beta_ * gamma_ - delta_ * alpha_) / (c3_ * (c3_ - 1.)) * exp3_; // A
453  p_(1, 1) = -0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ + (beta_ * (c3_ - 1.) - 0.5 * c8_) / (c3_ * (c3_ - 1.)) * exp3_; // C
454  p_(1, 2) = 0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ - (beta_ * gamma_ - delta_ * alpha_) / (c3_ * (c3_ - 1.)) * exp3_; // G
455  p_(1, 3) = -0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ - (beta_ * (c3_ - 1.) - 0.5 * c8_) / (c3_ * (c3_ - 1.)) * exp3_; // T
456  // G
457  p_(2, 0) = -0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ + (0.5 * c8_ - beta_ * (c3_ - 1.)) / (c3_ * (c3_ - 1.)) * exp3_; // A
458  p_(2, 1) = 0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ + (delta_ * alpha_ - gamma_ * beta_) / (c3_ * (c3_ - 1.)) * exp3_; // C
459  p_(2, 2) = -0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ - (0.5 * c8_ - beta_ * (c3_ - 1.)) / (c3_ * (c3_ - 1.)) * exp3_; // G
460  p_(2, 3) = 0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ - (delta_ * alpha_ - gamma_ * beta_) / (c3_ * (c3_ - 1.)) * exp3_; // T, U
461  // T, U
462  p_(3, 0) = 0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ + (beta_ * gamma_ - delta_ * alpha_) / (c3_ * (c3_ - 1.)) * exp3_; // A
463  p_(3, 1) = -0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ + (0.5 * c4_ - alpha_ * (c3_ - 1.)) / (c3_ * (c3_ - 1.)) * exp3_; // C
464  p_(3, 2) = 0.5 * c4_ / (1. * (c3_ - 1.)) * exp1_ - (beta_ * gamma_ - delta_ * alpha_) / (c3_ * (c3_ - 1.)) * exp3_; // G
465  p_(3, 3) = -0.5 * c8_ / (1. * (c3_ - 1.)) * exp1_ - (0.5 * c4_ - alpha_ * (c3_ - 1.)) / (c3_ * (c3_ - 1.)) * exp3_;
466 
467  return p_;
468 }
469 
470 /******************************************************************************/
471 void RN95s::setFreq(map<int, double>& freqs)
472 {
473  setParameterValue("thetaA", (freqs[0] + freqs[3]) / 2);
474 
475  updateMatrices();
476 }
477 
478 /******************************************************************************/
479 
bool enableEigenDecomposition()
Tell if eigenValues and Vectors must be computed.
RowMatrix< double > exchangeability_
The exchangeability matrix of the model, defined as . When the model is reversible, this matrix is symetric.
const Matrix< double > & getdPij_dt(double d) const
Definition: RN95s.cpp:409
bool isNonSingular_
boolean value for non-singularity of rightEigenVectors_
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).
const Matrix< double > & getPij_t(double d) const
Definition: RN95s.cpp:377
double alpha_
Definition: RN95s.h:115
Vdouble eigenValues_
The vector of eigen values.
double dPij_dt(size_t i, size_t j, double d) const
Definition: RN95s.cpp:266
double c8_
Definition: RN95s.h:120
STL namespace.
Vdouble freq_
The vector of equilibrium frequencies.
double delta_
Definition: RN95s.h:115
double l_
Definition: RN95s.h:122
double exp1_
Definition: RN95s.h:122
Partial implementation of the SubstitutionModel interface.
double d2Pij_dt2(size_t i, size_t j, double d) const
Definition: RN95s.cpp:321
void updateMatrices()
Diagonalize the matrix, and fill the eigenValues_, iEigenValues_, leftEigenVectors_ and rightEigenVe...
Definition: RN95s.cpp:92
double c4_
Definition: RN95s.h:120
double r_
Definition: RN95s.h:116
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...
double Pij_t(size_t i, size_t j, double d) const
Definition: RN95s.cpp:211
RN95s(const NucleicAlphabet *alphabet, double alpha=1, double beta=1, double gamma=1, double delta=1)
Definition: RN95s.cpp:55
std::vector< RowMatrix< double > > vPowGen_
vector of the powers of generator_ for Taylor development (if rightEigenVectors_ is singular)...
double exp3_
Definition: RN95s.h:122
size_t size_
The size of the generator, i.e. the number of states.
const Matrix< double > & getd2Pij_dt2(double d) const
Definition: RN95s.cpp:440
void setFreq(std::map< int, double > &)
This method takes the average value between observed and .
Definition: RN95s.cpp:471
double gamma_
Definition: RN95s.h:115
double beta_
Definition: RN95s.h:115
RowMatrix< double > p_
Definition: RN95s.h:121
bool isDiagonalizable_
boolean value for diagonalizability in R of the generator_
double c3_
Definition: RN95s.h:120
Vdouble iEigenValues_
The vector of the imaginary part of the eigen values.