bpp-phyl3  3.0.0
AbstractKroneckerWordSubstitutionModel.cpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: The Bio++ Development Group
2 //
3 // SPDX-License-Identifier: CECILL-2.1
4 
7 
9 
10 using namespace bpp;
11 
12 using namespace std;
13 
14 /******************************************************************************/
15 
17  ModelList& modelList,
18  const std::string& prefix) :
20  AbstractWordSubstitutionModel(modelList, prefix),
21  sChangingPos_(),
22  vGenerators_()
23 {
25  for (auto& submod : VSubMod_)
26  {
27  submod->enableEigenDecomposition(false);
28  }
29 
31 }
32 
34  ModelList& modelList,
35  const std::vector<std::set<size_t>>& vPos,
36  const std::string& prefix) :
38  AbstractWordSubstitutionModel(modelList, prefix),
39  sChangingPos_(vPos),
40  vGenerators_()
41 {
43  throw Exception("AbstractKroneckerWordSubstitutionModel::AbstractKroneckerWordSubstitutionModel: Bad set of changing positions ");
44 
46  for (auto& submod : VSubMod_)
47  {
48  submod->enableEigenDecomposition(false);
49  }
50 
52 }
53 
55  unique_ptr<SubstitutionModelInterface> pmodel,
56  unsigned int num,
57  const string& prefix) :
59  AbstractWordSubstitutionModel(std::move(pmodel), num, prefix),
60  sChangingPos_(),
61  vGenerators_()
62 {
64  for (auto& submod : VSubMod_)
65  {
66  submod->enableEigenDecomposition(false);
67  }
68 
70 }
71 
73  unique_ptr<SubstitutionModelInterface> pmodel,
74  unsigned int num,
75  const std::vector<std::set<size_t>>& vPos,
76  const std::string& prefix) :
78  AbstractWordSubstitutionModel(std::move(pmodel), num, prefix),
79  sChangingPos_(vPos),
80  vGenerators_()
81 {
83  throw Exception("AbstractKroneckerWordSubstitutionModel::AbstractKroneckerWordSubstitutionModel: Bad set of changing positions ");
84 
86  for (auto& submod : VSubMod_)
87  {
88  submod->enableEigenDecomposition(false);
89  }
90 
92 }
93 
95  std::shared_ptr<const Alphabet> alph,
96  std::shared_ptr<const StateMapInterface> stateMap,
97  const string& prefix) :
99  AbstractWordSubstitutionModel(alph, stateMap, prefix),
100  sChangingPos_(),
101  vGenerators_()
102 {
104  for (auto& submod : VSubMod_)
105  {
106  submod->enableEigenDecomposition(false);
107  }
108 }
109 
114  sChangingPos_(wrsm.sChangingPos_),
115  vGenerators_(wrsm.vGenerators_)
116 {
117  initGenerators_();
118 }
119 
120 
123 {
127  vGenerators_ = model.vGenerators_;
128 
129  return *this;
130 }
131 
132 
133 void AbstractKroneckerWordSubstitutionModel::setChangingPositions(const vector<std::set<size_t>>& vPos)
134 {
135  sChangingPos_ = vPos;
136 
138  throw Exception("AbstractKroneckerWordSubstitutionModel::setChangingPositions: Bad set of changing positions ");
139 }
140 
141 
143 {
144  vGenerators_.clear();
145 
146  size_t nbmod = VSubMod_.size();
147 
148  size_t size = 1;
149 
150  for (size_t k = 0; k < nbmod; k++)
151  {
152  size *= VSubMod_[k]->getNumberOfStates();
153  vGenerators_.push_back(RowMatrix<double>(size, size));
154  }
155 }
156 
158 {
159  size_t nbmod = VSubMod_.size();
160 
161  for (const auto& i : sChangingPos_)
162  {
163  if (*(--(i.end())) > nbmod || *(i.begin()) == 0)
164  return false;
165  }
166 
167  return true;
168 }
169 
171 {
172  size_t nbmod = VSubMod_.size();
173 
174 // Generator
175 
176  if (sChangingPos_.size() == 0)
177  {
178  vGenerators_[0] = VSubMod_[0]->generator();
179 
180  for (size_t k = 1; k < nbmod - 1; k++)
181  {
182  MatrixTools::kroneckerMult(vGenerators_[k - 1], VSubMod_[k]->generator(), 1., 1., vGenerators_[k], false);
183  }
184 
185  MatrixTools::kroneckerMult(vGenerators_[nbmod - 2], VSubMod_[nbmod - 1]->generator(), 1., 1., generator_, false);
186  }
187  else
188  {
189  bool begin(true);
190 
191  for (const auto& i : sChangingPos_)
192  {
193  size_t pos = 0;
194 
195  for (const auto& iPos : i)
196  {
197  size_t posok = iPos - 1; // position of the next generator to multiply
198 
199  if (pos == 0)
200  {
201  size_t ss = 1;
202  while (pos < posok)
203  {
204  ss *= VSubMod_[pos]->getNumberOfStates();
205  pos++;
206  }
207  if (ss != 1)
208  {
209  MatrixTools::getId(ss, vGenerators_[posok - 1]);
210  MatrixTools::kroneckerMult(vGenerators_[posok - 1], VSubMod_[posok]->generator(), 1., 0., vGenerators_[posok], false);
211  }
212  else
213  vGenerators_[posok] = VSubMod_[0]->generator();
214 
216  }
217  else
218  {
219  while (pos < posok)
220  {
222  pos++;
223  }
224  MatrixTools::kroneckerMult(vGenerators_[posok - 1], VSubMod_[posok]->generator(), 0., 0., vGenerators_[posok], false);
225  }
226 
227  pos++;
228  }
229 
230  while (pos < nbmod)
231  {
233  pos++;
234  }
235 
236  if (begin)
237  {
238  begin = false;
239  generator_ = vGenerators_[nbmod - 1];
240  }
241  else
243  }
244  }
245 }
AbstractKroneckerWordSubstitutionModel & operator=(const AbstractKroneckerWordSubstitutionModel &)
bool checkChangingPositions_()
checks that the vector of changing positions is valid
std::vector< RowMatrix< double > > vGenerators_
vector of generators for computation purposes
AbstractKroneckerWordSubstitutionModel(ModelList &modelList, const std::string &prefix)
Build a new AbstractKroneckerWordSubstitutionModel object from a vector of pointers to SubstitutionMo...
void fillBasicGenerator_()
First fill of the generator, from the position model.
std::vector< std::set< size_t > > sChangingPos_
vector of sets of simultaneously changing positions.
void setChangingPositions(const std::vector< std::set< size_t >> &vPos)
AbstractParameterAliasable & operator=(const AbstractParameterAliasable &ap)
RowMatrix< double > generator_
The generator matrix of the model.
const Matrix< double > & generator() const
bool enableEigenDecomposition()
Tell if eigenValues and Vectors must be computed.
size_t getNumberOfStates() const override
Get the number of states.
Abstract Basal class for words of substitution models.
std::vector< std::shared_ptr< SubstitutionModelInterface > > VSubMod_
AbstractWordSubstitutionModel & operator=(const AbstractWordSubstitutionModel &)
static void add(MatrixA &A, const MatrixB &B)
static void kroneckerMult(const Matrix< Scalar > &A, const Matrix< Scalar > &B, Matrix< Scalar > &O, bool check=true)
static void getId(size_t n, Matrix &O)
static void fillDiag(Matrix &M, Scalar x)
A list of models, for building a WordSubstitutionModel.
Defines the basic types of data flow nodes.