bpp-phyl3  3.0.0
RN95s.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 #include "RN95s.h"
8 
9 // From the STL:
10 #include <cmath>
11 
12 using namespace bpp;
13 using namespace std;
14 
15 /******************************************************************************/
16 
18  shared_ptr<const NucleicAlphabet> alphabet,
19  double alpha,
20  double beta,
21  double gamma,
22  double delta) :
24  AbstractNucleotideSubstitutionModel(alphabet, make_shared<CanonicalStateMap>(alphabet, false), "RN95s."),
25  alpha_(),
26  beta_(),
27  gamma_(),
28  delta_()
29 {
30  double f = alpha + beta + gamma + delta;
31 
32  alpha_ = alpha / f;
33  beta_ = beta / f;
34  gamma_ = gamma / f;
35  delta_ = delta / f;
36 
37  addParameter_(new Parameter("RN95s.theta", alpha_ + gamma_, std::make_shared<IntervalConstraint>(0.001, 0.999, true, true)));
40 
41  computeFrequencies(false);
43 }
44 
45 /******************************************************************************/
46 
48 {
49  double theta = getParameterValue("theta");
50  double alphaP = getParameterValue("alphaP");
51  double betaP = getParameterValue("betaP");
52 
53  alpha_ = alphaP * theta;
54  gamma_ = theta - alpha_;
55  beta_ = betaP * (1 - theta);
56  delta_ = 1 - theta - beta_;
57 
58  // stationnary frequencies
59 
60  freq_[1] = freq_[2] = theta / 2;
61  freq_[3] = freq_[0] = (1 - theta) / 2;
62 
63  // Generator matrix:
64 
65  generator_(0, 1) = gamma_;
66  generator_(0, 2) = alpha_;
67  generator_(0, 3) = delta_;
68 
69  generator_(0, 0) = -(gamma_ + alpha_ + delta_);
70 
71  generator_(1, 0) = delta_;
72  generator_(1, 2) = gamma_;
73  generator_(1, 3) = beta_;
74 
75  generator_(1, 1) = -(delta_ + beta_ + gamma_);
76 
77  generator_(2, 0) = beta_;
78  generator_(2, 1) = gamma_;
79  generator_(2, 3) = delta_;
80 
81  generator_(2, 2) = -(gamma_ + beta_ + delta_);
82 
83  generator_(3, 0) = delta_;
84  generator_(3, 1) = alpha_;
85  generator_(3, 2) = gamma_;
86 
87  generator_(3, 3) = -(delta_ + alpha_ + gamma_);
88 
89  // Normalization
90 
91  double x = 0;
92  for (unsigned int i = 0; i < 4; i++)
93  {
94  x += generator_(i, i) * freq_[i];
95  }
96 
97  double r_ = isScalable() ? -1 / x : 1;
98 
99  setScale(r_);
100 
101  // variables for calculation purposes
102 
103  double c_1 = gamma_ + delta_ - beta_ - alpha_;
104  double c_2 = delta_ * gamma_ - alpha_ * beta_;
105  double c_3 = beta_ * gamma_ - alpha_ * delta_;
106 
107  // eigen vectors and values
108 
109  eigenValues_[0] = -2 * (gamma_ + delta_) * r_;
110  eigenValues_[1] = -r_;
111  eigenValues_[2] = -r_;
112  eigenValues_[3] = 0;
113 
114  rightEigenVectors_(0, 0) = 1.;
115  rightEigenVectors_(1, 0) = -1.;
116  rightEigenVectors_(2, 0) = 1.;
117  rightEigenVectors_(3, 0) = -1.;
118 
119  rightEigenVectors_(0, 1) = c_2;
120  rightEigenVectors_(1, 1) = 0;
121  rightEigenVectors_(2, 1) = (beta_ - delta_) * (delta_ + beta_);
122  rightEigenVectors_(3, 1) = -c_3;
123 
124  rightEigenVectors_(0, 2) = 0;
125  rightEigenVectors_(1, 2) = c_2;
126  rightEigenVectors_(2, 2) = c_3;
127  rightEigenVectors_(3, 2) = (alpha_ - gamma_) * (alpha_ + gamma_);
128 
129  rightEigenVectors_(0, 3) = 1;
130  rightEigenVectors_(1, 3) = 1;
131  rightEigenVectors_(2, 3) = 1;
132  rightEigenVectors_(3, 3) = 1;
133 
134 // Need formula
135 
136  if (abs(c_1) < NumConstants::TINY() || abs(c_2) < NumConstants::TINY())
137  {
138  ApplicationTools::displayMessage("Singularity during diagonalization of RN95s. Taylor series used instead.");
139  isNonSingular_ = false;
140  isDiagonalizable_ = false;
142  }
143  else
144  {
145  isNonSingular_ = true;
146  isDiagonalizable_ = true;
147 
148  leftEigenVectors_(0, 0) = (delta_ - beta_) / (2 * c_1);
149  leftEigenVectors_(0, 1) = (alpha_ - gamma_) / (2 * c_1);
150  leftEigenVectors_(0, 2) = -leftEigenVectors_(0, 1);
151  leftEigenVectors_(0, 3) = -leftEigenVectors_(0, 0);
152 
153  leftEigenVectors_(1, 0) = (gamma_ * (gamma_ + delta_) - alpha_ * (alpha_ + beta_)) / (c_1 * c_2);
154  leftEigenVectors_(1, 1) = c_3 / (c_1 * c_2);
155  leftEigenVectors_(1, 2) = -leftEigenVectors_(1, 0);
156  leftEigenVectors_(1, 3) = -leftEigenVectors_(1, 1);
157 
158  leftEigenVectors_(2, 0) = leftEigenVectors_(1, 3);
159  leftEigenVectors_(2, 1) = (delta_ * (gamma_ + delta_) - beta_ * (alpha_ + beta_)) / (c_1 * c_2);
160  leftEigenVectors_(2, 2) = leftEigenVectors_(1, 1);
161  leftEigenVectors_(2, 3) = -leftEigenVectors_(2, 1);
162 
163  leftEigenVectors_(3, 0) = (1 - theta) / 2;
164  leftEigenVectors_(3, 1) = theta / 2;
165  leftEigenVectors_(3, 2) = leftEigenVectors_(3, 1);
166  leftEigenVectors_(3, 3) = leftEigenVectors_(3, 0);
167  }
168 
169  // and the exchangeability_
170  for (size_t i = 0; i < size_; i++)
171  {
172  for (size_t j = 0; j < size_; j++)
173  {
174  exchangeability_(i, j) = generator_(i, j) / freq_[j];
175  }
176  }
177 }
178 
179 
180 /******************************************************************************/
181 void RN95s::setFreq(map<int, double>& freqs)
182 {
183  setParameterValue("thetaA", (freqs[0] + freqs[3]) / 2);
184  updateMatrices_();
185 }
186 
187 /******************************************************************************/
Specialisation abstract class for nucleotide substitution model.
void addParameter_(Parameter *parameter)
void setParameterValue(const std::string &name, double value) override
double getParameterValue(const std::string &name) const override
RowMatrix< double > generator_
The generator matrix of the model.
bool isDiagonalizable_
boolean value for diagonalizability in R of the generator_
bool isNonSingular_
boolean value for non-singularity of rightEigenVectors_
std::vector< RowMatrix< double > > vPowGen_
vector of the powers of generator_ for Taylor development (if rightEigenVectors_ is singular).
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.
virtual bool isScalable() const
returns if model is scalable
RowMatrix< double > rightEigenVectors_
The matrix made of right eigen vectors (by column).
void setScale(double scale)
Multiplies the current generator by the given scale.
size_t size_
The number of states.
Vdouble freq_
The vector of equilibrium frequencies.
static void displayMessage(const std::string &text)
This class implements a state map where all resolved states are modeled.
Definition: StateMap.h:168
static void Taylor(const Matrix &A, size_t p, std::vector< RowMatrix< Scalar >> &vO)
static double TINY()
static const std::shared_ptr< IntervalConstraint > PROP_CONSTRAINT_EX
void setFreq(std::map< int, double > &) override
This method takes the average value between observed and .
Definition: RN95s.cpp:181
double delta_
Definition: RN95s.h:113
void updateMatrices_() override
Diagonalize the matrix, and fill the eigenValues_, iEigenValues_, leftEigenVectors_ and rightEigenVe...
Definition: RN95s.cpp:47
RN95s(std::shared_ptr< const NucleicAlphabet > alphabet, double alpha=0.25, double beta=0.25, double gamma=0.25, double delta=0.25)
Definition: RN95s.cpp:17
double gamma_
Definition: RN95s.h:113
double alpha_
Definition: RN95s.h:113
double beta_
Definition: RN95s.h:113
Defines the basic types of data flow nodes.
ExtendedFloat abs(const ExtendedFloat &ef)