bpp-core3  3.0.0
DirichletDiscreteDistribution.cpp
Go to the documentation of this file.
1 //
2 // File: DirichletDiscreteDistribution.cpp
3 // Authors:
4 // Laurent Guéguen
5 // Created: jeudi 2 septembre 2010, à 17h 03
6 //
7 
8 /*
9  Copyright or © or Copr. CNRS, (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 "../NumConstants.h"
44 #include "../Random/RandomTools.h"
47 
48 using namespace bpp;
49 
50 // From the STL:
51 #include <cmath>
52 
53 using namespace std;
54 
58  AbstractParameterAliasable("Dirichlet."),
59  vpBDD_()
60 {
61  if (vn.size() <= 0 || vn.size() != valpha.size() - 1)
62  throw Exception("Wrong number of categories for Dirichlet distribution: " + TextTools::toString(vn.size()));
63 
64  for (size_t j = 0; j < valpha.size(); j++)
65  {
66  addParameter_(new Parameter("Dirichlet.alpha_" + TextTools::toString(j + 1), valpha[j], std::make_shared<IntervalConstraint>(1, 0.0001, true)));
67  }
68 
69  for (size_t j = 0; j < vn.size(); j++)
70  {
71  if (vn[j] <= 0)
72  throw Exception("Wrong number of categories in Dirichlet distribution constructor: " + TextTools::toString(vn[j]));
73  }
74 
75  for (size_t j = 0; j < vn.size(); j++)
76  {
77  vpBDD_.push_back(new BetaDiscreteDistribution(vn[j], 1, 1));
78  }
79 
80  discretize(valpha);
81 }
82 
84 {
85  for (unsigned int i = 0; i < vpBDD_.size(); i++)
86  {
87  delete vpBDD_[i];
88  }
89 }
90 
91 /******************************************************************************/
92 
94 {
97 }
98 
99 /******************************************************************************/
100 
102 {
103  Vdouble valpha;
104 
105  for (size_t j = 0; j < vpBDD_.size() + 1; j++)
106  {
107  valpha.push_back(getParameterValue("alpha_" + TextTools::toString(j + 1)));
108  }
109 
110  discretize(valpha);
111 }
112 
113 /******************************************************************************/
114 
116 {
117  /* discretization of Dirichlet distribution with equal proportions in
118  each category */
119 
120  double x;
121  ParameterList pL;
122  pL.addParameter(Parameter("Beta.alpha", 1));
123  pL.addParameter(Parameter("Beta.beta", 1));
124  for (unsigned int j = 0; j < vpBDD_.size(); j++)
125  {
126  x = 0;
127  for (unsigned int i = j + 1; i < valpha.size(); i++)
128  {
129  x += valpha[i];
130  }
131 
132  pL.setParameterValue("Beta.alpha", valpha[j]);
133  pL.setParameterValue("Beta.beta", x);
134 
135  vpBDD_[j]->matchParametersValues(pL);
136  }
137 }
138 
139 
140 /******************************************************************************/
141 
143 {
144  size_t n = 1;
145 
146  for (size_t j = 0; j < vpBDD_.size(); j++)
147  {
148  n *= vpBDD_[j]->getNumberOfCategories();
149  }
150 
151  return n;
152 }
153 
154 /******************************************************************************/
155 
157 {
158  if (value.size() != vpBDD_.size() + 1)
159  throw Exception("Bad Vdouble parameter in DirichletDiscreteDistribution::getValueCategory");
160 
161  Vdouble vd;
162  double y, sumc = 0;
163 
164  for (size_t j = 0; j < vpBDD_.size(); j++)
165  {
166  if (1 - sumc < NumConstants::VERY_TINY())
167  y = vpBDD_[j]->getValueCategory(NumConstants::VERY_TINY());
168  else
169  y = vpBDD_[j]->getValueCategory(value[j] / (1 - sumc)) * (1 - sumc);
170  sumc += y;
171  vd.push_back(y);
172  }
173  vd.push_back(1 - sumc);
174  return vd;
175 }
176 
177 /******************************************************************************/
178 
180 {
181  if (category.size() != vpBDD_.size() + 1)
182  throw Exception("Bad Vdouble parameter in DirichletDiscreteDistribution::getProbability");
183 
184  double sumc = 0;
185  double p = 1;
186 
187  for (size_t j = 0; j < vpBDD_.size(); j++)
188  {
189  p *= vpBDD_[j]->getProbability(category[j] / (1 - sumc));
190  sumc += category[j];
191  }
192  return p;
193 }
194 
195 /******************************************************************************/
196 
198 {
199  VVdouble vvd1, vvd2;
200  Vdouble vdj, vd;
201  double sumc = 0;
202 
203  vdj = vpBDD_[0]->getCategories();
204  for (size_t k = 0; k < vdj.size(); k++)
205  {
206  vd.push_back(vdj[k]);
207  vvd1.push_back(vd);
208  vd.pop_back();
209  }
210 
211  for (size_t j = 1; j < vpBDD_.size(); j++)
212  {
213  vdj = vpBDD_[j]->getCategories();
214  vvd2.clear();
215  for (size_t i = 0; i < vvd1.size(); i++)
216  {
217  vd = vvd1[i];
218  sumc = 0;
219  for (size_t k = 0; k < vd.size(); k++)
220  {
221  sumc += vd[k];
222  }
223  for (size_t k = 0; k < vdj.size(); k++)
224  {
225  vd.push_back(vdj[k] * (1 - sumc));
226  vvd2.push_back(vd);
227  vd.pop_back();
228  }
229  }
230  vvd1 = vvd2;
231  }
232 
233  vvd2.clear();
234  for (size_t i = 0; i < vvd1.size(); i++)
235  {
236  vd = vvd1[i];
237  sumc = 0;
238  for (size_t k = 0; k < vd.size(); k++)
239  {
240  sumc += vd[k];
241  }
242  vd.push_back(1 - sumc);
243  vvd2.push_back(vd);
244  }
245 
246  return vvd2;
247 }
248 
249 /******************************************************************************/
250 
252 {
253  Vdouble vd;
254  double x, sumc = 0;
255  for (unsigned int j = 0; j < vpBDD_.size(); j++)
256  {
257  x = vpBDD_[j]->rand() * (1 - sumc);
258  sumc += x;
259  vd.push_back(x);
260  }
261 
262  vd.push_back(1 - sumc);
263  return vd;
264 }
265 
266 /******************************************************************************/
267 
269 {
270  Vdouble vd;
271  double x, sumc = 0;
272  for (unsigned int j = 0; j < vpBDD_.size(); j++)
273  {
274  x = vpBDD_[j]->randC() * (1 - sumc);
275  sumc += x;
276  vd.push_back(x);
277  }
278 
279  vd.push_back(1 - sumc);
280  return vd;
281 }
282 
283 /******************************************************************************/
A partial implementation of the Parametrizable interface.
void addParameter_(Parameter *parameter)
virtual void fireParameterChanged(const ParameterList &parameters)
Notify the class when one or several parameters have changed.
double getParameterValue(const std::string &name) const
Get the value for parameter of name 'name'.
Discretized Beta distribution with parameters alpha and beta, on a given interval....
Vdouble randC() const
Draw a random vector from the continuous version of this distribution.
DirichletDiscreteDistribution(std::vector< size_t > vn, Vdouble valpha)
Build a new discretized Dirichlet distribution.
Vdouble rand() const
Draw a random vector from this distribution.
std::vector< BetaDiscreteDistribution * > vpBDD_
void fireParameterChanged(const ParameterList &parameters)
Notify the class when one or several parameters have changed.
virtual double getProbability(Vdouble &category) const
Exception base class. Overload exception constructor (to control the exceptions mechanism)....
Definition: Exceptions.h:59
static double VERY_TINY()
Definition: NumConstants.h:83
The parameter list object.
Definition: ParameterList.h:65
virtual void setParameterValue(const std::string &name, double value)
Set the value of parameter with name name to be equal to value.
virtual void addParameter(const Parameter &param)
Add a new parameter at the end of the list.
This class is designed to facilitate the manipulation of parameters.
Definition: Parameter.h:135
std::string toString(T t)
General template method to convert to a string.
Definition: TextTools.h:153
std::vector< double > Vdouble
Definition: VectorTools.h:70
std::vector< Vdouble > VVdouble
Definition: VectorTools.h:71