bpp-phyl3  3.0.0
BinarySubstitutionModel.cpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: The Bio++ Development Group
2 //
3 // SPDX-License-Identifier: CECILL-2.1
4 
6 
7 // From the STL:
8 #include <cmath>
9 
10 using namespace bpp;
11 
13 
14 using namespace std;
15 
16 /******************************************************************************/
17 
19  shared_ptr<const BinaryAlphabet> alpha,
20  double kappa) :
21  AbstractParameterAliasable("Binary."),
22  // AbstractSubstitutionModel(alpha, new CanonicalStateMap(alpha, false), "Binary."),
23  AbstractReversibleSubstitutionModel(alpha, std::shared_ptr<const StateMapInterface>(new CanonicalStateMap(alpha, false)), "Binary."),
24  kappa_(kappa),
25  lambda_(0),
26  exp_(0),
27  p_(size_, size_)
28 {
31 }
32 
33 /******************************************************************************/
34 
36 {
37  kappa_ = getParameterValue("kappa"); // alpha/beta
38  lambda_ = (kappa_ + 1) * (kappa_ + 1) / (2 * kappa_);
39 
40  // Frequencies:
41  freq_[0] = 1 / (kappa_ + 1);
42  freq_[1] = kappa_ / (kappa_ + 1);
43 
44  // Generator:
45  generator_(0, 0) = rate_ * -(kappa_ + 1) / 2;
46  generator_(0, 1) = rate_ * (kappa_ + 1) / 2;
47  generator_(1, 0) = rate_ * (kappa_ + 1) / (2 * kappa_);
48  generator_(1, 1) = rate_ * -(kappa_ + 1) / (2 * kappa_);
49 
50  // Eigen values:
51  eigenValues_[0] = 0;
52  eigenValues_[1] = -rate_ * lambda_;
53 
54  // Eigen vectors:
55  leftEigenVectors_(0, 0) = 1 / (kappa_ + 1);
56  leftEigenVectors_(0, 1) = kappa_ / (kappa_ + 1);
57  if (kappa_ != 1.0)
58  {
59  leftEigenVectors_(1, 0) = (kappa_ - 1) / (kappa_ + 1);
60  leftEigenVectors_(1, 1) = -(kappa_ - 1) / (kappa_ + 1);
61  }
62  else
63  {
64  leftEigenVectors_(1, 0) = 1;
65  leftEigenVectors_(1, 1) = -1;
66  }
67 
68  rightEigenVectors_(0, 0) = 1;
69  rightEigenVectors_(1, 0) = 1;
70 
71  if (kappa_ != 1.0)
72  {
73  rightEigenVectors_(0, 1) = kappa_ / (kappa_ - 1);
74  rightEigenVectors_(1, 1) = -1 / (kappa_ - 1);
75  }
76  else
77  {
78  rightEigenVectors_(0, 1) = 1 / 2;
79  rightEigenVectors_(1, 1) = -1 / 2;
80  }
81 }
82 
83 /******************************************************************************/
84 
85 double BinarySubstitutionModel::Pij_t(size_t i, size_t j, double d) const
86 {
87  exp_ = exp(-lambda_ * rate_ * d);
88 
89  switch (i)
90  {
91  case 0:
92  switch (j)
93  {
94  case 0: return (1 + kappa_ * exp_) / (kappa_ + 1);
95  case 1: return kappa_ / (kappa_ + 1) * (1 - exp_);
96  default: return 0;
97  }
98  case 1:
99  switch (j)
100  {
101  case 0: return (1 - exp_) / (kappa_ + 1);
102  case 1: return (kappa_ + exp_) / (kappa_ + 1);
103  default: return 0;
104  }
105  default: return 0;
106  }
107 }
108 
109 /******************************************************************************/
110 
111 double BinarySubstitutionModel::dPij_dt(size_t i, size_t j, double d) const
112 {
113  exp_ = rate_ * exp(-lambda_ * rate_ * d);
114 
115  switch (i)
116  {
117  case 0:
118  switch (j)
119  {
120  case 0: return -(kappa_ + 1) / 2 * exp_;
121  case 1: return (kappa_ + 1) / 2 * exp_;
122  default: return 0;
123  }
124  case 1:
125  switch (j)
126  {
127  case 0: return (kappa_ + 1) / (2 * kappa_) * exp_;
128  case 1: return -(kappa_ + 1) / (2 * kappa_) * exp_;
129  default: return 0;
130  }
131  default: return 0;
132  }
133 }
134 
135 /******************************************************************************/
136 
137 double BinarySubstitutionModel::d2Pij_dt2(size_t i, size_t j, double d) const
138 {
139  exp_ = rate_ * rate_ * exp(-lambda_ * rate_ * d);
140 
141  switch (i)
142  {
143  case 0:
144  switch (j)
145  {
146  case 0: return lambda_ * (kappa_ + 1) / 2 * exp_;
147  case 1: return -lambda_ * (kappa_ + 1) / 2 * exp_;
148  default: return 0;
149  }
150  case 1:
151  switch (j)
152  {
153  case 0: return -lambda_ * (kappa_ + 1) / (2 * kappa_) * exp_;
154  case 1: return lambda_ * (kappa_ + 1) / (2 * kappa_) * exp_;
155  default: return 0;
156  }
157  default: return 0;
158  }
159 }
160 
161 /******************************************************************************/
162 
164 {
165  exp_ = exp(-lambda_ * rate_ * d);
166 
167  p_(0, 0) = (1 + kappa_ * exp_) / (kappa_ + 1);
168  p_(0, 1) = kappa_ / (kappa_ + 1) * (1 - exp_);
169 
170  p_(1, 0) = (1 - exp_) / (kappa_ + 1);
171  p_(1, 1) = (kappa_ + exp_) / (kappa_ + 1);
172 
173  return p_;
174 }
175 
177 {
178  exp_ = rate_ * exp(-lambda_ * rate_ * d);
179 
180  p_(0, 0) = -(kappa_ + 1) / 2 * exp_;
181  p_(0, 1) = (kappa_ + 1) / 2 * exp_;
182 
183  p_(1, 0) = (kappa_ + 1) / (2 * kappa_) * exp_;
184  p_(1, 1) = -(kappa_ + 1) / (2 * kappa_) * exp_;
185 
186  return p_;
187 }
188 
190 {
191  exp_ = rate_ * rate_ * exp(-lambda_ * rate_ * d);
192 
193  p_(0, 0) = lambda_ * (kappa_ + 1) / 2 * exp_;
194  p_(0, 1) = -lambda_ * (kappa_ + 1) / 2 * exp_;
195  p_(1, 0) = -lambda_ * (kappa_ + 1) / (2 * kappa_) * exp_;
196  p_(1, 1) = lambda_ * (kappa_ + 1) / (2 * kappa_) * exp_;
197 
198  return p_;
199 }
200 
201 /******************************************************************************/
202 
203 void BinarySubstitutionModel::setFreq(std::map<int, double>& freqs)
204 {
205  kappa_ = freqs[1] / freqs[0];
206  setParameterValue("kappa", kappa_);
207  updateMatrices_();
208 }
void addParameter_(Parameter *parameter)
void setParameterValue(const std::string &name, double value) override
std::string getNamespace() const override
double getParameterValue(const std::string &name) const override
Partial implementation of the ReversibleSubstitutionModel interface.
RowMatrix< double > generator_
The generator matrix of the model.
Vdouble eigenValues_
The vector of eigen values.
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).
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...
double d2Pij_dt2(size_t i, size_t j, double d) const
double Pij_t(size_t i, size_t j, double d) const
void updateMatrices_()
Compute and diagonalize the matrix, and fill the eigenValues_, leftEigenVectors_ and rightEigenVecto...
void setFreq(std::map< int, double > &freqs)
Set equilibrium frequencies.
const Matrix< double > & getPij_t(double d) const
const Matrix< double > & getdPij_dt(double d) const
const Matrix< double > & getd2Pij_dt2(double d) const
double dPij_dt(size_t i, size_t j, double d) const
BinarySubstitutionModel(std::shared_ptr< const BinaryAlphabet > alpha, double kappa=1.)
This class implements a state map where all resolved states are modeled.
Definition: StateMap.h:168
static const std::shared_ptr< IntervalConstraint > R_PLUS_STAR
Map the states of a given alphabet which have a model state.
Definition: StateMap.h:25
Defines the basic types of data flow nodes.
ExtendedFloat exp(const ExtendedFloat &ef)