bpp-core3  3.0.0
MixtureOfDiscreteDistributions.cpp
Go to the documentation of this file.
1 //
2 // File: MixtureOfDiscreteDistributions.cpp
3 // Authors:
4 // Laurent Guéguen
5 // Created: mercredi 9 juin 2010, à 23h 09
6 //
7 
8 /*
9  Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
10 
11  This software is a computer program whose purpose is to provide classes
12  for numerical calculus.
13 
14  This software is governed by the CeCILL license under French law and
15  abiding by the rules of distribution of free software. You can use,
16  modify and/ or redistribute the software under the terms of the CeCILL
17  license as circulated by CEA, CNRS and INRIA at the following URL
18  "http://www.cecill.info".
19 
20  As a counterpart to the access to the source code and rights to copy,
21  modify and redistribute granted by the license, users are provided only
22  with a limited warranty and the software's author, the holder of the
23  economic rights, and the successive licensors have only limited
24  liability.
25 
26  In this respect, the user's attention is drawn to the risks associated
27  with loading, using, modifying and/or developing or reproducing the
28  software by the user in light of its specific status of free software,
29  that may mean that it is complicated to manipulate, and that also
30  therefore means that it is reserved for developers and experienced
31  professionals having in-depth computer knowledge. Users are therefore
32  encouraged to load and test the software's suitability as regards their
33  requirements in conditions enabling the security of their systems and/or
34  data to be ensured and, more generally, to use and operate it in the
35  same conditions as regards security.
36 
37  The fact that you are presently reading this means that you have had
38  knowledge of the CeCILL license and that you accept its terms.
39 */
40 
41 
42 #include "../../Text/TextTools.h"
43 #include "../../Utils/MapTools.h"
44 #include "../NumConstants.h"
46 
47 using namespace bpp;
48 using namespace std;
49 
50 MixtureOfDiscreteDistributions::MixtureOfDiscreteDistributions(const vector<DiscreteDistribution*>& distributions,
51  const vector<double>& probas ) :
52  AbstractDiscreteDistribution(1, "Mixture."),
53  vdd_(),
54  probas_(),
55  vNestedPrefix_()
56 {
57  if (distributions.size() != probas.size())
58  {
59  throw Exception("MixtureOfDiscreteDistributions. Distributions and probabilities vectors must have the same size (" + TextTools::toString(distributions.size()) + " != " + TextTools::toString(probas.size()) + ").");
60  }
61 
62  size_t size = distributions.size();
63  for (size_t i = 0; i < size; i++)
64  {
65  if (distributions[i] == 0)
66  throw Exception("MixtureOfDiscreteDistributions. Null DiscreteDistribution* in argument vector at index " + TextTools::toString(i));
67  }
68 
69  for (size_t i = 0; i < size; i++)
70  {
71  probas_.push_back(probas[i]);
72  }
73 
74  double sum = VectorTools::sum(probas);
75  if (fabs(1. - sum) > precision())
76  throw Exception("MixtureOfDiscreteDistributions. Probabilities must equal 1 (sum =" + TextTools::toString(sum) + ").");
77 
78  double y = 1;
79  for (size_t i = 0; i < size - 1; i++)
80  {
81  addParameter_(new Parameter("Mixture.theta" + TextTools::toString(i + 1), probas[i] / y, Parameter::PROP_CONSTRAINT_IN));
82  y -= probas[i];
83  }
84 
85 
86  for (size_t i = 0; i < size; i++)
87  {
88  vdd_.push_back(distributions[i]->clone());
89  }
90 
91  // Parameters
92 
93  for (size_t i = 0; i < size; i++)
94  {
95  vNestedPrefix_.push_back(TextTools::toString(i + 1) + "_" + distributions[i]->getNamespace());
96  }
97 
98  for (size_t i = 0; i < size; i++)
99  {
100  vdd_[i]->setNamespace("Mixture." + vNestedPrefix_[i]);
101  }
102 
103  for (size_t i = 0; i < size; i++)
104  {
106  }
107 
109 }
110 
113  vdd_(),
114  probas_(),
115  vNestedPrefix_()
116 {
117  for (size_t i = 0; i < mdd.vdd_.size(); i++)
118  {
119  probas_.push_back(mdd.probas_[i]);
120  vdd_.push_back(mdd.vdd_[i]->clone());
121  vNestedPrefix_.push_back(mdd.vNestedPrefix_[i]);
122  }
123 }
124 
126 {
128  vdd_.clear();
129  probas_.clear();
130  vNestedPrefix_.clear();
131 
132  for (size_t i = 0; i < mdd.vdd_.size(); i++)
133  {
134  probas_.push_back(mdd.probas_[i]);
135  vdd_.push_back(mdd.vdd_[i]->clone());
136  vNestedPrefix_.push_back(mdd.vNestedPrefix_[i]);
137  }
138 
139  return *this;
140 }
141 
143 {
144  for (size_t i = 0; i < vdd_.size(); i++)
145  {
146  delete vdd_[i];
147  }
148 
149  vdd_.clear();
150 }
151 
153 {
154  for (size_t i = 0; i < vdd_.size(); i++)
155  {
156  vdd_[i]->setNumberOfCategories(nbClasses);
157  }
158 
160 }
161 
162 
164 {
166  size_t size = vdd_.size();
167  double x = 1.0;
168  for (size_t i = 0; i < size - 1; i++)
169  {
170  probas_[i] = getParameterValue("theta" + TextTools::toString(i + 1)) * x;
171  x *= 1 - getParameterValue("theta" + TextTools::toString(i + 1));
172  }
173 
174  probas_[size - 1] = x;
175 
176 
177  for (size_t i = 0; i < size; i++)
178  {
179  vdd_[i]->matchParametersValues(parameters);
180  }
181 
183 }
184 
186 {
187  size_t size = vdd_.size();
188  distribution_.clear();
189  // calculation of distribution
190 
191  for (size_t i = 0; i < size; i++)
192  {
193  vector<double> values = vdd_[i]->getCategories();
194  for (size_t j = 0; j < values.size(); j++)
195  {
196  distribution_[values[j]] = 0;
197  }
198  }
199 
200  for (size_t i = 0; i < size; i++)
201  {
202  vector<double> values = vdd_[i]->getCategories();
203  vector<double> probas2 = vdd_[i]->getProbabilities();
204  for (size_t j = 0; j < values.size(); j++)
205  {
206  distribution_[values[j]] += probas2[j] * probas_[i];
207  }
208  }
209 
211 
212  // intMinMax_
213 
214  double uB, lB;
215  uB = -NumConstants::VERY_BIG();
216  lB = NumConstants::VERY_BIG();
217 
218  bool suB = true, slB = true;
219 
220  for (size_t i = 0; i < size; i++)
221  {
222  if (vdd_[i]->getLowerBound() <= lB)
223  {
224  lB = vdd_[i]->getLowerBound();
225  slB = vdd_[i]->strictLowerBound();
226  }
227  if (vdd_[i]->getUpperBound() >= uB)
228  {
229  uB = vdd_[i]->getUpperBound();
230  suB = vdd_[i]->strictUpperBound();
231  }
232  }
233 
234  intMinMax_->setLowerBound(lB, slB);
235  intMinMax_->setUpperBound(uB, suB);
236 
237  // Compute midpoint bounds_:
238  vector<double> values = MapTools::getKeys<double, double, AbstractDiscreteDistribution::Order>(distribution_);
239 
240  bounds_.resize(numberOfCategories_ - 1);
241 
242  // Fill from 0 to numberOfCategories_-1 with midpoints:
243  for (size_t i = 0; i < numberOfCategories_ - 1; i++)
244  {
245  bounds_[i] = (values[i] + values[i + 1]) / 2.;
246  }
247 }
248 
250 {
251  if (median_ != median)
252  {
253  median_ = median;
254  for (size_t i = 0; i < vdd_.size(); i++)
255  {
256  vdd_[i]->setMedian(median);
257  }
259  }
260 }
262 {
263  for (size_t i = 0; i < vdd_.size(); i++)
264  {
265  vdd_[i]->discretize();
266  }
267 
269 }
270 
272 {
273  double s = 0;
274  for (size_t i = 0; i < vdd_.size(); i++)
275  {
276  s += probas_[i] * vdd_[i]->pProb(x);
277  }
278  return s;
279 }
280 
282 {
283  throw Exception("MixtureOfDiscreteDistributions::qProb to difficult to compute: not implemented");
284  return 0;
285 }
286 
288 {
289  double s = 0;
290  for (size_t i = 0; i < vdd_.size(); i++)
291  {
292  s += probas_[i] * vdd_[i]->Expectation(a);
293  }
294  return s;
295 }
296 
298 {
299  for (size_t i = 0; i < vdd_.size(); i++)
300  {
301  vdd_[i]->restrictToConstraint(c);
302  }
303 
305 }
306 
307 /******************************************************************************/
308 
310 {
312  // We also need to update the namespace of the nested distributions:
313  for (size_t i = 0; i < vdd_.size(); i++)
314  {
315  vdd_[i]->setNamespace(prefix + vNestedPrefix_[i]);
316  }
317 }
Partial implementation of the DiscreteDistribution interface.
std::map< double, double, Order > distribution_
double getLowerBound() const
methods about the range of the definition
AbstractDiscreteDistribution & operator=(const AbstractDiscreteDistribution &adde)
std::shared_ptr< IntervalConstraint > intMinMax_
the interval where the distribution is defined/restricted.
void addParameters_(const ParameterList &parameters)
void addParameter_(Parameter *parameter)
void setNamespace(const std::string &prefix)
Set the namespace for the parameter names.
virtual void fireParameterChanged(const ParameterList &parameters)
Notify the class when one or several parameters have changed.
const ParameterList & getParameters() const
Get all parameters available.
double getParameterValue(const std::string &name) const
Get the value for parameter of name 'name'.
The constraint interface.
Definition: Constraints.h:66
Exception base class. Overload exception constructor (to control the exceptions mechanism)....
Definition: Exceptions.h:59
A Discrete distribution object defined by a vector of Discrete Distributions and a set of probabiliti...
void setMedian(bool median)
Sets the median value to true to say that the value in a class is proportional to the median value of...
void restrictToConstraint(const Constraint &c)
Restricts the distribution to the domain where the constraint is respected, in addition of other pred...
std::vector< DiscreteDistribution * > vdd_
double Expectation(double a) const
Return a primitive function used for the expectation of the continuous version of the distribution,...
double qProb(double x) const
Return the quantile of the continuous version of the distribution, ie y such that .
void discretize()
Discretizes the distribution in equiprobable classes.
MixtureOfDiscreteDistributions * clone() const
Create a copy of this object and send a pointer to it.
MixtureOfDiscreteDistributions(const std::vector< DiscreteDistribution * > &distributions, const std::vector< double > &probas)
Builds a new MixtureOfDiscreteDistributions object from a vector of Discrete Distributions and a vect...
MixtureOfDiscreteDistributions & operator=(const MixtureOfDiscreteDistributions &mdd)
double pProb(double x) const
Return the cumulative quantile of the continuous version of the distribution, ie .
void fireParameterChanged(const ParameterList &parameters)
Notify the class when one or several parameters have changed.
void setNamespace(const std::string &prefix)
Set the namespace for the parameter names.
void setNumberOfCategories(size_t nbClasses)
sets the number of categories of EACH submodel to nbClasses, so the number of categories of the mixtu...
static double VERY_BIG()
Definition: NumConstants.h:84
The parameter list object.
Definition: ParameterList.h:65
This class is designed to facilitate the manipulation of parameters.
Definition: Parameter.h:135
static const std::shared_ptr< IntervalConstraint > PROP_CONSTRAINT_IN
Definition: Parameter.h:329
static T sum(const std::vector< T > &v1)
Definition: VectorTools.h:624
std::string toString(T t)
General template method to convert to a string.
Definition: TextTools.h:153