bpp-phyl3 3.0.0
MixtureOfTransitionModels.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#include <string>
8
10
11using namespace bpp;
12using namespace std;
13
14MixtureOfTransitionModels::MixtureOfTransitionModels(
15 std::shared_ptr<const Alphabet> alpha,
16 vector<std::unique_ptr<TransitionModelInterface>>& vpModel) :
18 AbstractTransitionModel(alpha, vpModel.size() ? vpModel[0]->getStateMap() : 0, "Mixture."),
19 AbstractMixedTransitionModel(alpha, vpModel.size() ? vpModel[0]->getStateMap() : 0, "Mixture.")
20{
21 size_t i, nbmod = vpModel.size();
22 if (nbmod == 0)
23 throw Exception("MixtureOfTransitionModels::MixtureOfTransitionModels : empty vector of models.");
24
25 for (i = 0; i < nbmod; ++i)
26 {
27 if (!vpModel[i])
28 throw Exception("Empty model number " + TextTools::toString(i) + " in MixtureOfTransitionModels constructor");
29 for (size_t j = i + 1; j < nbmod; ++j)
30 {
31 if (vpModel[i] == vpModel[j])
32 throw Exception("Same model at positions " + TextTools::toString(i) + " and " +
33 TextTools::toString(j) + " in MixtureOfTransitionModels constructor");
34 }
35 }
36
37 // Initialization of modelsContainer_.
38
39 for (i = 0; i < nbmod; i++)
40 {
41 modelsContainer_.push_back(std::move(vpModel[i]));
42 vProbas_.push_back(1.0 / static_cast<double>(nbmod));
43 vRates_.push_back(1.0);
44 }
45
46 // Initialization of parameters_.
47
48 // relative rates and probas
49 for (i = 0; i < nbmod - 1; i++)
50 {
51 addParameter_(new Parameter("Mixture.relproba" + TextTools::toString(i + 1), 1.0 / static_cast<double>(nbmod - i), Parameter::PROP_CONSTRAINT_EX));
52 addParameter_(new Parameter("Mixture.relrate" + TextTools::toString(i + 1), 1.0 / static_cast<double>(nbmod - i), Parameter::PROP_CONSTRAINT_EX));
53 }
54
55 // models parameters
56
57 for (i = 0; i < nbmod; i++)
58 {
59 modelsContainer_[i]->setNamespace("Mixture." + TextTools::toString(i + 1) + "_" + modelsContainer_[i]->getNamespace());
61 }
62
64}
65
67 std::shared_ptr<const Alphabet> alpha,
68 vector<std::unique_ptr<TransitionModelInterface>>& vpModel,
69 Vdouble& vproba,
70 Vdouble& vrate) :
72 AbstractTransitionModel(alpha, vpModel.size() ? vpModel[0]->getStateMap() : 0, "Mixture."),
73 AbstractMixedTransitionModel(alpha, vpModel.size() ? vpModel[0]->getStateMap() : 0, "Mixture.")
74{
75 size_t i, nbmod = vpModel.size();
76
77 for (i = 0; i < nbmod; ++i)
78 {
79 if (!vpModel[i])
80 throw Exception("Empty model number " + TextTools::toString(i) + " in MixtureOfTransitionModels constructor");
81 for (size_t j = i + 1; j < nbmod; ++j)
82 {
83 if (vpModel[i] == vpModel[j])
84 throw Exception("Same model at positions " + TextTools::toString(i) + " and " +
85 TextTools::toString(j) + " in MixtureOfTransitionModels constructor");
86 }
87 }
88
89 double x = 0;
90 double sumrates = 0;
91
92 for (i = 0; i < nbmod; i++)
93 {
94 if (vrate[i] <= 0)
95 throw Exception("Non positive rate: " + TextTools::toString(vrate[i]) + " in MixtureOfTransitionModels constructor.");
96 if (vproba[i] <= 0)
97 throw Exception("Non positive probability: " + TextTools::toString(vproba[i]) + " in MixtureOfTransitionModels constructor.");
98 x += vproba[i];
99 sumrates += vrate[i];
100 }
101
102 if (fabs(1. - x) > NumConstants::SMALL())
103 throw Exception("Probabilities must equal 1 (sum = " + TextTools::toString(x) + ").");
104
105
106 // Initialization of modelsContainer_.
107
108 for (i = 0; i < nbmod; i++)
109 {
110 modelsContainer_.push_back(std::move(vpModel[i]));
111 }
112
113 // rates & probas
114
115 vProbas_.resize(nbmod);
116 vRates_.resize(nbmod);
117
118 // Initialization of parameters_.
119
120 // relative rates and probas
121 x = 0;
122 double y = 0;
123
124 for (i = 0; i < nbmod - 1; ++i)
125 {
126 addParameter_(new Parameter("Mixture.relproba" + TextTools::toString(i + 1), vproba[i] / (1 - x), Parameter::PROP_CONSTRAINT_EX));
127 x += vproba[i];
128 addParameter_(new Parameter("Mixture.relrate" + TextTools::toString(i + 1), vrate[i] / (sumrates - y), Parameter::PROP_CONSTRAINT_EX));
129 y += vrate[i];
130 }
131
132 // models parameters
133
134 for (i = 0; i < nbmod; ++i)
135 {
136 modelsContainer_[i]->setNamespace("Mixture." + TextTools::toString(i + 1) + "_" + modelsContainer_[i]->getNamespace());
138 }
139
141}
142
147{}
148
150{
152
153 return *this;
154}
155
156
158{}
159
161{
162 size_t nbmod = getNumberOfModels();
163
164 for (size_t i = 0; i < nbmod; ++i)
165 {
166 if (nModel(i).getName() == name)
167 return nModel(i);
168 }
169
170 throw NullPointerException("MixtureOfTransitionModels::model. No model with name '" + name + "'.");
171}
172
174{
175 size_t i, j, nbmod = modelsContainer_.size();
176
177 double x, y;
178 x = 1.0;
179
180 for (i = 0; i < nbmod - 1; i++)
181 {
182 y = getParameterValue("relproba" + TextTools::toString(i + 1));
183 vProbas_[i] = x * y;
184 x *= 1 - y;
185 }
186 vProbas_[nbmod - 1] = x;
187
188 x = 1.0;
189 double s = 0;
190 for (i = 0; i < nbmod - 1; i++)
191 {
192 y = getParameterValue("relrate" + TextTools::toString(i + 1));
193 vRates_[i] = x * y;
194 x *= 1 - y;
195 s += vProbas_[i] * vRates_[i];
196 }
197
198 vRates_[nbmod - 1] = x;
199 s += vProbas_[nbmod - 1] * vRates_[nbmod - 1];
200
201 for (i = 0; i < nbmod; i++)
202 {
203 vRates_[i] /= s;
204 }
205
206 // models
207
208 for (i = 0; i < nbmod; i++)
209 {
210 modelsContainer_[i]->setRate(rate_ * vRates_[i]);
211 modelsContainer_[i]->matchParametersValues(getParameters());
212 }
213
214 // / freq_
215
216 for (i = 0; i < getNumberOfStates(); i++)
217 {
218 freq_[i] = 0;
219 for (j = 0; j < modelsContainer_.size(); j++)
220 {
221 freq_[i] += vProbas_[j] * modelsContainer_[j]->freq(i);
222 }
223 }
224}
225
226
227void MixtureOfTransitionModels::setFreq(std::map<int, double>& m)
228{
229 ParameterList pl;
230 for (unsigned int n = 0; n < modelsContainer_.size(); n++)
231 {
232 modelsContainer_[n]->setFreq(m);
234 }
236}
237
239{
241
242 size_t i, nbmod = modelsContainer_.size();
243 double sP = 0;
244 for (const auto& rate:vRates_)
245 {
246 sP += rate;
247 }
248
249 for (i = 0; i < nbmod - 1; i++)
250 {
251 setParameterValue("relrate" + TextTools::toString(i + 1), vRates_[i] / sP);
252 sP -= vRates_[i];
253 }
254}
255
257{
258 size_t i;
259 for (i = 0; i < getNumberOfModels(); i++)
260 {
261 if (getNModel(i)->getName() == desc)
262 break;
263 }
264 if (i == getNumberOfModels())
265 throw Exception("MixtureOfTransitionModels::getSubmodelNumbers model description do not match " + desc);
266
267 Vuint submodnb(1, uint(i));
268
269 return submodnb;
270}
Partial implementation for Mixed Transition models, defined as a mixture of "simple" substitution mod...
const TransitionModelInterface & nModel(size_t i) const override
Returns a specific model from the mixture.
std::shared_ptr< const TransitionModelInterface > getNModel(size_t i) const override
std::vector< double > vProbas_
vector of the probabilities of the models
virtual size_t getNumberOfModels() const override
returns the number of models in the mixture
virtual void setVRates(const Vdouble &vd) override
Sets the rates of the submodels to be proportional to a given vector, with the constraint that the me...
AbstractMixedTransitionModel & operator=(const AbstractMixedTransitionModel &)
std::vector< double > vRates_
vector of the rates of the models.
std::vector< std::shared_ptr< TransitionModelInterface > > modelsContainer_
vector of pointers to TransitionModels.
void addParameters_(const ParameterList &parameters)
void addParameter_(Parameter *parameter)
void setParameterValue(const std::string &name, double value) override
bool matchParametersValues(const ParameterList &parameters) override
std::string getNamespace() const override
const ParameterList & getParameters() const override
double getParameterValue(const std::string &name) const override
Partial implementation of the TransitionModel interface.
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...
size_t getNumberOfStates() const override
Get the number of states.
Transition models defined as a mixture of several substitution models.
virtual void setVRates(const Vdouble &vd) override
Sets the rates of the submodels to follow the constraint that the mean rate of the mixture equals rat...
void updateMatrices_() override
Diagonalize the matrix, and fill the eigenValues_, iEigenValues_, leftEigenVectors_ and rightEigenVe...
MixtureOfTransitionModels(std::shared_ptr< const Alphabet > alpha, std::vector< std::unique_ptr< TransitionModelInterface > > &vpModel)
Constructor of a MixtureOfTransitionModels, where all the models have rate 1 and equal probability.
MixtureOfTransitionModels & operator=(const MixtureOfTransitionModels &)
std::string getName() const override
Get the name of the model.
void setFreq(std::map< int, double > &) override
applies setFreq to all the models of the mixture and recovers the parameters values.
Vuint getSubmodelNumbers(const std::string &desc) const override
Returns the vector of numbers of the submodels in the mixture that match a description of the paramet...
const TransitionModelInterface & model(const std::string &name) const override
retrieve a pointer to the submodel with the given name.
static double SMALL()
virtual void addParameters(const ParameterList &params)
static const std::shared_ptr< IntervalConstraint > PROP_CONSTRAINT_EX
Interface for all transition models.
std::string toString(T t)
Defines the basic types of data flow nodes.
std::vector< double > Vdouble
std::vector< unsigned int > Vuint