bpp-phyl  2.2.0
MixtureOfSubstitutionModels.cpp
Go to the documentation of this file.
1 //
2 // File: MixtureOfSubstitutionModels.cpp
3 // Created by: Laurent Gueguen
4 // Date: mardi 14 septembre 2010, à 20h 43
5 //
6 /*
7  Copyright or © or Copr. Bio++ Development Team, (November 16, 2004)
8 
9  This software is a computer program whose purpose is to provide classes
10  for phylogenetic data analysis.
11 
12  This software is governed by the CeCILL license under French law and
13  abiding by the rules of distribution of free software. You can use,
14  modify and/ or redistribute the software under the terms of the CeCILL
15  license as circulated by CEA, CNRS and INRIA at the following URL
16  "http://www.cecill.info".
17 
18  As a counterpart to the access to the source code and rights to copy,
19  modify and redistribute granted by the license, users are provided only
20  with a limited warranty and the software's author, the holder of the
21  economic rights, and the successive licensors have only limited
22  liability.
23 
24  In this respect, the user's attention is drawn to the risks associated
25  with loading, using, modifying and/or developing or reproducing the
26  software by the user in light of its specific status of free software,
27  that may mean that it is complicated to manipulate, and that also
28  therefore means that it is reserved for developers and experienced
29  professionals having in-depth computer knowledge. Users are therefore
30  encouraged to load and test the software's suitability as regards their
31  requirements in conditions enabling the security of their systems and/or
32  data to be ensured and, more generally, to use and operate it in the
33  same conditions as regards security.
34 
35  The fact that you are presently reading this means that you have had
36  knowledge of the CeCILL license and that you accept its terms.
37  */
38 
40 
41 #include <Bpp/Numeric/NumConstants.h>
42 #include <Bpp/Text/TextTools.h>
43 
44 #include <string>
45 
46 using namespace bpp;
47 using namespace std;
48 
50  const Alphabet* alpha,
51  vector<SubstitutionModel*> vpModel) :
52  AbstractParameterAliasable("Mixture."),
53  AbstractMixedSubstitutionModel(alpha, vpModel[0]->getStateMap().clone(), "Mixture.")
54 {
55  size_t i, nbmod = vpModel.size();
56 
57  for (i = 0; i < nbmod; i++)
58  {
59  if (!vpModel[i])
60  throw Exception("Empty model number " + TextTools::toString(i) + " in MixtureOfSubstitutionModels constructor");
61  for (size_t j = i + 1; j < nbmod; j++)
62  {
63  if (vpModel[i] == vpModel[j])
64  throw Exception("Same model at positions " + TextTools::toString(i) + " and " +
65  TextTools::toString(j) + " in MixtureOfSubstitutionModels constructor");
66  }
67  }
68 
69  // Initialization of modelsContainer_.
70 
71  for (i = 0; i < nbmod; i++)
72  {
73  modelsContainer_.push_back(vpModel[i]);
74  vProbas_.push_back(1.0 / static_cast<double>(nbmod));
75  vRates_.push_back(1.0);
76  }
77 
78  // Initialization of parameters_.
79 
80  // relative rates and probas
81  for (i = 0; i < nbmod - 1; i++)
82  {
83  addParameter_(new Parameter("Mixture.relproba" + TextTools::toString(i + 1), 1.0 / static_cast<double>(nbmod - i), &Parameter::PROP_CONSTRAINT_EX));
84  addParameter_(new Parameter("Mixture.relrate" + TextTools::toString(i + 1), 1.0 / static_cast<double>(nbmod - i), &Parameter::PROP_CONSTRAINT_EX));
85  }
86 
87  // models parameters
88 
89  for (i = 0; i < nbmod; i++)
90  {
91  modelsContainer_[i]->setNamespace("Mixture." + TextTools::toString(i + 1) + "_" + vpModel[i]->getNamespace());
92  addParameters_(vpModel[i]->getParameters());
93  }
94 
95  for (i = 0; i < nbmod; i++)
96  {
97  vpModel[i]->addRateParameter();
98  }
99 
100  updateMatrices();
101 }
102 
104  const Alphabet* alpha,
105  vector<SubstitutionModel*> vpModel,
106  Vdouble& vproba,
107  Vdouble& vrate) :
108  AbstractParameterAliasable("Mixture."),
109  AbstractMixedSubstitutionModel(alpha, vpModel[0]->getStateMap().clone(), "Mixture.")
110 {
111  size_t i, nbmod = vpModel.size();
112 
113  for (i = 0; i < nbmod; i++)
114  {
115  if (!vpModel[i])
116  throw Exception("Empty model number " + TextTools::toString(i) + " in MixtureOfSubstitutionModels constructor");
117  for (size_t j = i + 1; j < nbmod; j++)
118  {
119  if (vpModel[i] == vpModel[j])
120  throw Exception("Same model at positions " + TextTools::toString(i) + " and " +
121  TextTools::toString(j) + " in MixtureOfSubstitutionModels constructor");
122  }
123  }
124 
125  double x = 0;
126  double y = 0;
127 
128  for (i = 0; i < nbmod; i++)
129  {
130  if (vrate[i] <= 0)
131  throw Exception("Non positive rate: " + TextTools::toString(vrate[i]) + " in MixtureOfSubstitutionModels constructor.");
132  if (vproba[i] <= 0)
133  throw Exception("Non positive probability: " + TextTools::toString(vproba[i]) + " in MixtureOfSubstitutionModels constructor.");
134  x += vproba[i];
135  y += vproba[i] * vrate[i];
136  }
137 
138  if (fabs(1. - x) > NumConstants::SMALL())
139  throw Exception("Probabilities must equal 1 (sum = " + TextTools::toString(x) + ").");
140  if (fabs(1. - y) > NumConstants::SMALL())
141  throw Exception("Expectation on rates must equal 1 (E =" + TextTools::toString(y) + ").");
142 
143 
144  // Initialization of modelsContainer_.
145 
146  for (i = 0; i < nbmod; i++)
147  {
148  modelsContainer_.push_back(vpModel[i]);
149  }
150 
151  // rates & probas
152 
153  for (i = 0; i < nbmod; i++)
154  {
155  vProbas_.push_back(1.0 / static_cast<double>(nbmod));
156  vRates_.push_back(1.0);
157  }
158 
159  // Initialization of parameters_.
160 
161 
162  // relative rates and probas
163  x = 0; y = 0;
164 
165  for (i = 0; i < nbmod - 1; i++)
166  {
167  addParameter_(new Parameter("Mixture.relproba" + TextTools::toString(i + 1), vproba[i] / (1 - x), &Parameter::PROP_CONSTRAINT_EX));
168  x += vproba[i];
169  addParameter_(new Parameter("Mixture.relrate" + TextTools::toString(i + 1), vproba[i] * vrate[i] / (1 - y), &Parameter::PROP_CONSTRAINT_EX));
170  y += vproba[i] * vrate[i];
171  }
172 
173  // models parameters
174 
175  for (i = 0; i < nbmod; i++)
176  {
177  modelsContainer_[i]->setNamespace("Mixture." + TextTools::toString(i + 1) + "_" + vpModel[i]->getNamespace());
178  addParameters_(vpModel[i]->getParameters());
179  }
180 
181  for (i = 0; i < nbmod; i++)
182  {
183  vpModel[i]->addRateParameter();
184  }
185 
186  updateMatrices();
187 }
188 
190  AbstractParameterAliasable(msm),
192 {}
193 
195 {
197 
198  return *this;
199 }
200 
201 
203 {}
204 
205 
207 {
208  size_t i, j, nbmod = modelsContainer_.size();
209 
210  double x, y;
211  x = 1.0;
212 
213  for (i = 0; i < nbmod - 1; i++)
214  {
215  y = getParameterValue("relproba" + TextTools::toString(i + 1));
216  vProbas_[i] = x * y;
217  x *= 1 - y;
218  }
219  vProbas_[nbmod - 1] = x;
220 
221  x = 1.0;
222  bool approx = false; // used when some categories are avoided
223  double s = 0;
224  for (i = 0; i < nbmod - 1; i++)
225  {
226  y = getParameterValue("relrate" + TextTools::toString(i + 1));
227  if (vProbas_[i] < NumConstants::SMALL())
228  {
229  vRates_[i] = NumConstants::SMALL();
230  approx = true;
231  }
232  else
233  {
234  vRates_[i] = x * y / vProbas_[i];
235  s += x * y;
236  }
237  x *= 1 - y;
238  }
239 
240  if (vProbas_[nbmod - 1] < NumConstants::SMALL())
241  {
242  vRates_[nbmod - 1] = NumConstants::SMALL();
243  approx = true;
244  }
245  else
246  {
247  vRates_[nbmod - 1] = x / vProbas_[nbmod - 1];
248  s += x;
249  }
250 
251  if (approx)
252  for (i = 0; i < nbmod; i++)
253  {
254  vRates_[i] /= s;
255  }
256 
257  // / models
258 
259  for (i = 0; i < nbmod; i++)
260  {
261  modelsContainer_[i]->setRate(vRates_[i]);
262  modelsContainer_[i]->matchParametersValues(getParameters());
263  }
264 
265  // / freq_
266 
267  for (i = 0; i < getNumberOfStates(); i++)
268  {
269  freq_[i] = 0;
270  for (j = 0; j < modelsContainer_.size(); j++)
271  {
272  freq_[i] += vProbas_[j] * modelsContainer_[j]->freq(i);
273  }
274  }
275 }
276 
277 void MixtureOfSubstitutionModels::setFreq(std::map<int, double>& m)
278 {
279  ParameterList pl;
280  for (unsigned int n = 0; n < modelsContainer_.size(); n++)
281  {
282  modelsContainer_[n]->setFreq(m);
283  pl.addParameters(modelsContainer_[n]->getParameters());
284  }
285  matchParametersValues(pl);
286 }
287 
289 {
291 
292  size_t i, nbmod = modelsContainer_.size();
293  double sP = 0;
294  for (i = 0; i < nbmod - 1; i++)
295  {
296  sP += vProbas_[i];
297  }
298 
299  double y = 0;
300  for (i = 0; i < nbmod - 1; i++)
301  {
302  setParameterValue("relrate" + TextTools::toString(i + 1), vProbas_[i] / sP * vRates_[i] / (1 - y));
303  y += vProbas_[i] / sP * vRates_[i];
304  }
305 }
306 
308 {
309  size_t i;
310  for (i = 0; i < getNumberOfModels(); i++)
311  {
312  if (getNModel(i)->getName() == desc)
313  break;
314  }
315  if (i == getNumberOfModels())
316  throw Exception("MixtureOfSubstitutionModels::getSubmodelNumbers model description do not match " + desc);
317 
318  Vint submodnb;
319  submodnb.push_back(static_cast<int>(i));
320 
321  return submodnb;
322 }
void setFreq(std::map< int, double > &)
applies setFreq to all the models of the mixture and recovers the parameters values.
virtual size_t getNumberOfModels() const
returns the number of models in the mixture
MixtureOfSubstitutionModels & operator=(const MixtureOfSubstitutionModels &)
STL namespace.
virtual void setVRates(const Vdouble &vd)
Sets the rates of the submodels to be proportional to a given vector, with the constraint that the me...
Vdouble freq_
The vector of equilibrium frequencies.
void updateMatrices()
Diagonalize the matrix, and fill the eigenValues_, iEigenValues_, leftEigenVectors_ and rightEigenVe...
Partial implementation for Mixed Substitution models, defined as a mixture of "simple" substitution m...
virtual std::string getName() const =0
Get the name of the model.
AbstractMixedSubstitutionModel & operator=(const AbstractMixedSubstitutionModel &)
MixtureOfSubstitutionModels(const Alphabet *alpha, std::vector< SubstitutionModel *> vpModel)
Constructor of a MixtureOfSubstitutionModels, where all the models have rate 1 and equal probability...
Vint getSubmodelNumbers(std::string &desc) const
Returns the vector of numbers of the submodels in the mixture that match a description of the paramet...
std::vector< double > vRates_
vector of the rates of the models.
virtual void setVRates(const Vdouble &vd)
Sets the rates of the submodels to follow the constraint that the mean rate of the mixture equals rat...
virtual const SubstitutionModel * getNModel(size_t i) const
Returns a specific model from the mixture.
virtual size_t getNumberOfStates() const
From SubstitutionModel interface.
std::vector< SubstitutionModel * > modelsContainer_
vector of pointers to SubstitutionModels.
Substitution models defined as a mixture of several substitution models.
std::vector< double > vProbas_
vector of the probabilities of the models