bpp-phyl3  3.0.0
JCnuc.cpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: The Bio++ Development Group
2 //
3 // SPDX-License-Identifier: CECILL-2.1
4 
5 #include "JCnuc.h"
6 
7 using namespace bpp;
8 
9 #include <cmath>
10 
11 using namespace std;
12 
13 /******************************************************************************/
14 
15 JCnuc::JCnuc(shared_ptr<const NucleicAlphabet> alpha) :
17  AbstractReversibleNucleotideSubstitutionModel(alpha, make_shared<CanonicalStateMap>(alpha, false), "JC69."),
18  exp_(),
19  p_(size_, size_)
20 {
22 }
23 
24 /******************************************************************************/
25 
27 {
28  // Frequencies:
29  freq_[0] = freq_[1] = freq_[2] = freq_[3] = 1. / 4.;
30 
31  // Generator and exchangeabilities:
32  for (size_t i = 0; i < 4; ++i)
33  {
34  for (size_t j = 0; j < 4; ++j)
35  {
36  generator_(i, j) = (i == j) ? -1. : 1. / 3.;
37  exchangeability_(i, j) = generator_(i, j) * 4.;
38  }
39  }
40 
41  // Eigen values:
42  eigenValues_[0] = 0;
43  eigenValues_[1] = eigenValues_[2] = eigenValues_[3] = -4. / 3.;
44 
45  // Eigen vectors:
46  for (size_t i = 0; i < 4; i++)
47  {
48  leftEigenVectors_(0, i) = 1. / 4.;
49  }
50  for (size_t i = 1; i < 4; i++)
51  {
52  for (size_t j = 0; j < 4; j++)
53  {
54  leftEigenVectors_(i, j) = -1. / 4.;
55  }
56  }
57  leftEigenVectors_(1, 2) = 3. / 4.;
58  leftEigenVectors_(2, 1) = 3. / 4.;
59  leftEigenVectors_(3, 0) = 3. / 4.;
60 
61  for (size_t i = 0; i < 4; i++)
62  {
63  rightEigenVectors_(i, 0) = 1.;
64  }
65  for (size_t i = 1; i < 4; i++)
66  {
67  rightEigenVectors_(3, i) = -1.;
68  }
69  for (size_t i = 0; i < 3; i++)
70  {
71  for (size_t j = 1; j < 4; j++)
72  {
73  rightEigenVectors_(i, j) = 0.;
74  }
75  }
76  rightEigenVectors_(2, 1) = 1.;
77  rightEigenVectors_(1, 2) = 1.;
78  rightEigenVectors_(0, 3) = 1.;
79 }
80 
81 /******************************************************************************/
82 
83 double JCnuc::Pij_t(size_t i, size_t j, double d) const
84 {
85  if (i == j)
86  return 1. / 4. + 3. / 4. * exp(-rate_ * 4. / 3. * d);
87  else
88  return 1. / 4. - 1. / 4. * exp(-rate_ * 4. / 3. * d);
89 }
90 
91 /******************************************************************************/
92 
93 double JCnuc::dPij_dt(size_t i, size_t j, double d) const
94 {
95  if (i == j)
96  return -exp(-rate_ * 4. / 3. * d) * rate_;
97  else
98  return 1. / 3. * exp(-rate_ * 4. / 3. * d) * rate_;
99 }
100 
101 /******************************************************************************/
102 
103 double JCnuc::d2Pij_dt2(size_t i, size_t j, double d) const
104 {
105  if (i == j)
106  return 4. / 3. * exp(-rate_ * 4. / 3. * d) * rate_ * rate_;
107  else
108  return -4. / 9. * exp(-rate_ * 4. / 3. * d) * rate_ * rate_;
109 }
110 
111 /******************************************************************************/
112 
113 const Matrix<double>& JCnuc::getPij_t(double d) const
114 {
115  exp_ = exp(-4. / 3. * d * rate_);
116  for (size_t i = 0; i < size_; i++)
117  {
118  for (size_t j = 0; j < size_; j++)
119  {
120  p_(i, j) = (i == j) ? 1. / 4. + 3. / 4. * exp_ : 1. / 4. - 1. / 4. * exp_;
121  }
122  }
123  return p_;
124 }
125 
126 const Matrix<double>& JCnuc::getdPij_dt(double d) const
127 {
128  exp_ = exp(-4. / 3. * d * rate_);
129  for (size_t i = 0; i < size_; i++)
130  {
131  for (size_t j = 0; j < size_; j++)
132  {
133  p_(i, j) = rate_ * ((i == j) ? -exp_ : 1. / 3. * exp_);
134  }
135  }
136  return p_;
137 }
138 
139 const Matrix<double>& JCnuc::getd2Pij_dt2(double d) const
140 {
141  exp_ = exp(-4. / 3. * d * rate_);
142  for (size_t i = 0; i < size_; i++)
143  {
144  for (size_t j = 0; j < size_; j++)
145  {
146  p_(i, j) = rate_ * rate_ * ((i == j) ? 4. / 3. * exp_ : -4. / 9. * exp_);
147  }
148  }
149  return p_;
150 }
151 
152 /******************************************************************************/
Specialisation abstract class for reversible nucleotide substitution model.
RowMatrix< double > generator_
The generator matrix of the model.
Vdouble eigenValues_
The vector of eigen values.
RowMatrix< double > exchangeability_
The exchangeability matrix of the model, defined as . When the model is reversible,...
RowMatrix< double > leftEigenVectors_
The matrix made of left eigen vectors (by row) if rightEigenVectors_ is non-singular.
RowMatrix< double > rightEigenVectors_
The matrix made of right eigen vectors (by column).
size_t size_
The number of states.
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...
This class implements a state map where all resolved states are modeled.
Definition: StateMap.h:168
double dPij_dt(size_t i, size_t j, double d) const override
Definition: JCnuc.cpp:93
double d2Pij_dt2(size_t i, size_t j, double d) const override
Definition: JCnuc.cpp:103
const Matrix< double > & getd2Pij_dt2(double d) const override
Definition: JCnuc.cpp:139
double Pij_t(size_t i, size_t j, double d) const override
Definition: JCnuc.cpp:83
RowMatrix< double > p_
Definition: JCnuc.h:100
JCnuc(std::shared_ptr< const NucleicAlphabet > alpha)
Definition: JCnuc.cpp:15
void updateMatrices_() override
Definition: JCnuc.cpp:26
double exp_
Definition: JCnuc.h:99
const Matrix< double > & getPij_t(double d) const override
Definition: JCnuc.cpp:113
const Matrix< double > & getdPij_dt(double d) const override
Definition: JCnuc.cpp:126
Defines the basic types of data flow nodes.
ExtendedFloat exp(const ExtendedFloat &ef)