bpp-phyl3  3.0.0
MarkovModulatedSubstitutionModel.cpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: The Bio++ Development Group
2 //
3 // SPDX-License-Identifier: CECILL-2.1
4 
8 
10 
11 using namespace bpp;
12 using namespace std;
13 
14 /******************************************************************************/
15 
17  const MarkovModulatedSubstitutionModel& model) :
19  model_ (model.model_->clone()),
20  stateMap_ (model.stateMap_),
21  nbStates_ (model.nbStates_),
22  nbRates_ (model.nbRates_),
23  rates_ (model.rates_),
24  ratesExchangeability_(model.ratesExchangeability_),
25  ratesFreq_ (model.ratesFreq_),
26  ratesGenerator_ (model.ratesGenerator_),
27  generator_ (model.generator_),
28  exchangeability_ (model.exchangeability_),
29  leftEigenVectors_ (model.leftEigenVectors_),
30  rightEigenVectors_ (model.rightEigenVectors_),
31  eigenValues_ (model.eigenValues_),
32  iEigenValues_ (model.iEigenValues_),
33  eigenDecompose_ (model.eigenDecompose_),
34  compFreq_ (model.compFreq_),
35  pijt_ (model.pijt_),
36  dpijt_ (model.dpijt_),
37  d2pijt_ (model.d2pijt_),
38  freq_ (model.freq_),
39  normalizeRateChanges_(model.normalizeRateChanges_),
40  nestedPrefix_ (model.nestedPrefix_)
41 {}
42 
45 {
46  AbstractParametrizable::operator=(model);
47  model_.reset(model.model_->clone());
48  stateMap_ = model.stateMap_;
49  nbStates_ = model.nbStates_;
50  nbRates_ = model.nbRates_;
51  rates_ = model.rates_;
53  ratesFreq_ = model.ratesFreq_;
55  generator_ = model.generator_;
59  eigenValues_ = model.eigenValues_;
62  compFreq_ = model.compFreq_;
63  pijt_ = model.pijt_;
64  dpijt_ = model.dpijt_;
65  d2pijt_ = model.d2pijt_;
66  freq_ = model.freq_;
69  return *this;
70 }
71 
72 /******************************************************************************/
73 
75 {
76  // ratesGenerator_ and rates_ must be initialized!
77  nbStates_ = model_->getNumberOfStates();
79  RowMatrix<double> Tmp1, Tmp2;
83 
84  MatrixTools::MatrixTools::getId< RowMatrix<double>>(nbStates_, Tmp1);
87 
88  MatrixTools::diag(1. / ratesFreq_, Tmp1);
89  MatrixTools::mult(rates_, Tmp1, Tmp2);
90  MatrixTools::kroneckerMult(Tmp2, model_->exchangeabilityMatrix(), exchangeability_);
91 
92  MatrixTools::diag(1 / model_->getFrequencies(), Tmp1);
95  freq_ = VectorTools::kroneckerMult(ratesFreq_, model_->getFrequencies());
97  {
98  // Normalization:
99  double scale = getScale();
100  setScale(1. / scale);
101 
102  // Normalize exchangeability matrix too:
103  if (isScalable())
105  }
106 
107  // Compute eigen values and vectors:
108  eigenValues_.resize(nbRates_ * nbStates_);
109  iEigenValues_.resize(nbRates_ * nbStates_);
114 
115  vector<double> modelEigenValues = model_->getEigenValues();
116  RowMatrix<double> modelRightEigenVectors = model_->getColumnRightEigenVectors();
117  for (unsigned int i = 0; i < nbStates_; i++)
118  {
120  MatrixTools::scale(tmp, modelEigenValues[i]);
122  EigenValue<double> ev(tmp);
123  vector<double> values = ev.getRealEigenValues();
124  RowMatrix<double> vectors = ev.getV();
125  for (size_t j = 0; j < nbRates_; j++)
126  {
127  size_t c = i * nbRates_ + j; // Current eigen value index.
128  eigenValues_[c] = values[j];
129  // Compute the Kronecker product of the jth vector and the ith modelRightEigenVector.
130  for (unsigned int ii = 0; ii < nbRates_; ii++)
131  {
132  double vii = vectors(ii, j);
133  for (unsigned int jj = 0; jj < nbStates_; jj++)
134  {
135  rightEigenVectors_(ii * nbStates_ + jj, c) = vii * modelRightEigenVectors(jj, i);
136  }
137  }
138  }
139  }
140  // Now compute left eigen vectors by inversion:
142 }
143 
145 {
146  for (size_t i = 0; i < getNumberOfStates(); i++)
147  {
148  double lambda = 0;
149  Vdouble& row = generator_.getRow(i);
150 
151  for (size_t j = 0; j < getNumberOfStates(); j++)
152  {
153  if (j != i)
154  lambda += row[j];
155  }
156  row[i] = -lambda;
157  }
158 }
159 
160 /******************************************************************************/
161 
163 {
164  if (t == 0)
165  MatrixTools::getId< RowMatrix<double>>(nbStates_ * nbRates_, pijt_);
166  else
168  return pijt_;
169 }
170 
172 {
174  return dpijt_;
175 }
176 
178 {
180  return d2pijt_;
181 }
182 
183 /******************************************************************************/
184 
185 double MarkovModulatedSubstitutionModel::getInitValue(size_t i, int state) const
186 {
187  if (i >= (nbStates_ * nbRates_))
188  throw IndexOutOfBoundsException("MarkovModulatedSubstitutionModel::getInitValue", i, 0, nbStates_ * nbRates_ - 1);
189  if (state < 0 || !model_->getAlphabet()->isIntInAlphabet(state))
190  throw BadIntException(state, "MarkovModulatedSubstitutionModel::getInitValue. Character " + model_->getAlphabet()->intToChar(state) + " is not allowed in model.", getAlphabet().get());
191  vector<int> states = model_->getAlphabet()->getAlias(state);
192  for (size_t j = 0; j < states.size(); j++)
193  {
194  if (getAlphabetStateAsInt(i) == states[j])
195  return 1.;
196  }
197  return 0.;
198 }
199 
200 /******************************************************************************/
201 
203 {
205  // We also need to update the namespace of the nested model:
206  model_->setNamespace(prefix + nestedPrefix_);
207 }
208 
209 /******************************************************************************/
void setNamespace(const std::string &prefix)
const RowMatrix< Real > & getV() const
const std::vector< Real > & getRealEigenValues() const
Partial implementation of the Markov-modulated class of substitution models.
bool compFreq_
Tell if the equilibrium frequencies should be computed from the generator.
RowMatrix< double > rightEigenVectors_
The matrix made of right eigen vectors (by column).
double getInitValue(size_t i, int state) const override
bool isScalable() const override
returns if model is scalable
std::shared_ptr< const MarkovModulatedStateMap > stateMap_
std::unique_ptr< ReversibleSubstitutionModelInterface > model_
void setScale(double scale) override
Multiplies the current generator by the given scale.
const Matrix< double > & getdPij_dt(double t) const override
MarkovModulatedSubstitutionModel & operator=(const MarkovModulatedSubstitutionModel &model)
const Matrix< double > & getPij_t(double t) const override
int getAlphabetStateAsInt(size_t index) const override
Vdouble iEigenValues_
The vector of imaginary parts of the eigen values (zero in case of reversible pmodel).
std::shared_ptr< const Alphabet > getAlphabet() const override
MarkovModulatedSubstitutionModel(std::unique_ptr< ReversibleSubstitutionModelInterface > model, unsigned int nbRates, bool normalizeRateChanges, const std::string &prefix)
Build a new MarkovModulatedSubstitutionModel object.
RowMatrix< double > pijt_
These ones are for bookkeeping:
const Matrix< double > & getd2Pij_dt2(double t) const override
double getScale() const override
Get the scalar product of diagonal elements of the generator and the frequencies vector....
RowMatrix< double > exchangeability_
The exchangeability matrix of the model.
Vdouble freq_
The vector of equilibrium frequencies.
RowMatrix< double > generator_
The generator matrix of the model.
void setDiagonal() override
set the diagonal of the generator such that sum on each line equals 0.
bool eigenDecompose_
Tell if the eigen decomposition should be performed.
Vdouble eigenValues_
The vector of real parts of eigen values.
RowMatrix< double > leftEigenVectors_
The matrix made of left eigen vectors (by row).
void setNamespace(const std::string &prefix) override
size_t getNumberOfStates() const override
Get the number of states.
static Scalar inv(const Matrix< Scalar > &A, Matrix< Scalar > &O)
static void add(MatrixA &A, const MatrixB &B)
static void mult(const Matrix< Scalar > &A, const Matrix< Scalar > &B, Matrix< Scalar > &O)
static void kroneckerMult(const Matrix< Scalar > &A, const Matrix< Scalar > &B, Matrix< Scalar > &O, bool check=true)
static void diag(const std::vector< Scalar > &D, Matrix< Scalar > &O)
static void scale(Matrix &A, Scalar a, Scalar b=0)
size_t getNumberOfColumns() const
const std::vector< double > & getRow(size_t i) const
void resize(size_t nRows, size_t nCols)
static double exp(const T &x)
static std::vector< T > kroneckerMult(const std::vector< T > &v1, const std::vector< T > &v2)
static std::vector< T > sqr(const std::vector< T > &v1)
Defines the basic types of data flow nodes.
std::vector< double > Vdouble