bpp-core3  3.0.0
DirichletDiscreteDistribution.cpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: The Bio++ Development Group
2 //
3 // SPDX-License-Identifier: CECILL-2.1
4 
5 #include "../../Text/TextTools.h"
6 #include "../NumConstants.h"
7 #include "../Random/RandomTools.h"
10 
11 using namespace bpp;
12 
13 // From the STL:
14 #include <cmath>
15 
16 using namespace std;
17 
21  AbstractParameterAliasable("Dirichlet."),
22  vpBDD_()
23 {
24  if (vn.size() <= 0 || vn.size() != valpha.size() - 1)
25  throw Exception("Wrong number of categories for Dirichlet distribution: " + TextTools::toString(vn.size()));
26 
27  for (size_t j = 0; j < valpha.size(); j++)
28  {
29  addParameter_(new Parameter("Dirichlet.alpha_" + TextTools::toString(j + 1), valpha[j], std::make_shared<IntervalConstraint>(1, 0.0001, true)));
30  }
31 
32  for (size_t j = 0; j < vn.size(); j++)
33  {
34  if (vn[j] <= 0)
35  throw Exception("Wrong number of categories in Dirichlet distribution constructor: " + TextTools::toString(vn[j]));
36  }
37 
38  for (size_t j = 0; j < vn.size(); j++)
39  {
40  vpBDD_.push_back(new BetaDiscreteDistribution(vn[j], 1, 1));
41  }
42 
43  discretize(valpha);
44 }
45 
47 {
48  for (unsigned int i = 0; i < vpBDD_.size(); i++)
49  {
50  delete vpBDD_[i];
51  }
52 }
53 
54 /******************************************************************************/
55 
57 {
60 }
61 
62 /******************************************************************************/
63 
65 {
66  Vdouble valpha;
67 
68  for (size_t j = 0; j < vpBDD_.size() + 1; j++)
69  {
70  valpha.push_back(getParameterValue("alpha_" + TextTools::toString(j + 1)));
71  }
72 
73  discretize(valpha);
74 }
75 
76 /******************************************************************************/
77 
79 {
80  /* discretization of Dirichlet distribution with equal proportions in
81  each category */
82 
83  double x;
84  ParameterList pL;
85  pL.addParameter(Parameter("Beta.alpha", 1));
86  pL.addParameter(Parameter("Beta.beta", 1));
87  for (unsigned int j = 0; j < vpBDD_.size(); j++)
88  {
89  x = 0;
90  for (unsigned int i = j + 1; i < valpha.size(); i++)
91  {
92  x += valpha[i];
93  }
94 
95  pL.setParameterValue("Beta.alpha", valpha[j]);
96  pL.setParameterValue("Beta.beta", x);
97 
98  vpBDD_[j]->matchParametersValues(pL);
99  }
100 }
101 
102 
103 /******************************************************************************/
104 
106 {
107  size_t n = 1;
108 
109  for (size_t j = 0; j < vpBDD_.size(); j++)
110  {
111  n *= vpBDD_[j]->getNumberOfCategories();
112  }
113 
114  return n;
115 }
116 
117 /******************************************************************************/
118 
120 {
121  if (value.size() != vpBDD_.size() + 1)
122  throw Exception("Bad Vdouble parameter in DirichletDiscreteDistribution::getValueCategory");
123 
124  Vdouble vd;
125  double y, sumc = 0;
126 
127  for (size_t j = 0; j < vpBDD_.size(); j++)
128  {
129  if (1 - sumc < NumConstants::VERY_TINY())
131  else
132  y = vpBDD_[j]->getValueCategory(value[j] / (1 - sumc)) * (1 - sumc);
133  sumc += y;
134  vd.push_back(y);
135  }
136  vd.push_back(1 - sumc);
137  return vd;
138 }
139 
140 /******************************************************************************/
141 
143 {
144  if (category.size() != vpBDD_.size() + 1)
145  throw Exception("Bad Vdouble parameter in DirichletDiscreteDistribution::getProbability");
146 
147  double sumc = 0;
148  double p = 1;
149 
150  for (size_t j = 0; j < vpBDD_.size(); j++)
151  {
152  p *= vpBDD_[j]->getProbability(category[j] / (1 - sumc));
153  sumc += category[j];
154  }
155  return p;
156 }
157 
158 /******************************************************************************/
159 
161 {
162  VVdouble vvd1, vvd2;
163  Vdouble vdj, vd;
164  double sumc = 0;
165 
166  vdj = vpBDD_[0]->getCategories();
167  for (size_t k = 0; k < vdj.size(); k++)
168  {
169  vd.push_back(vdj[k]);
170  vvd1.push_back(vd);
171  vd.pop_back();
172  }
173 
174  for (size_t j = 1; j < vpBDD_.size(); j++)
175  {
176  vdj = vpBDD_[j]->getCategories();
177  vvd2.clear();
178  for (size_t i = 0; i < vvd1.size(); i++)
179  {
180  vd = vvd1[i];
181  sumc = 0;
182  for (size_t k = 0; k < vd.size(); k++)
183  {
184  sumc += vd[k];
185  }
186  for (size_t k = 0; k < vdj.size(); k++)
187  {
188  vd.push_back(vdj[k] * (1 - sumc));
189  vvd2.push_back(vd);
190  vd.pop_back();
191  }
192  }
193  vvd1 = vvd2;
194  }
195 
196  vvd2.clear();
197  for (size_t i = 0; i < vvd1.size(); i++)
198  {
199  vd = vvd1[i];
200  sumc = 0;
201  for (size_t k = 0; k < vd.size(); k++)
202  {
203  sumc += vd[k];
204  }
205  vd.push_back(1 - sumc);
206  vvd2.push_back(vd);
207  }
208 
209  return vvd2;
210 }
211 
212 /******************************************************************************/
213 
215 {
216  Vdouble vd;
217  double x, sumc = 0;
218  for (unsigned int j = 0; j < vpBDD_.size(); j++)
219  {
220  x = vpBDD_[j]->rand() * (1 - sumc);
221  sumc += x;
222  vd.push_back(x);
223  }
224 
225  vd.push_back(1 - sumc);
226  return vd;
227 }
228 
229 /******************************************************************************/
230 
232 {
233  Vdouble vd;
234  double x, sumc = 0;
235  for (unsigned int j = 0; j < vpBDD_.size(); j++)
236  {
237  x = vpBDD_[j]->randC() * (1 - sumc);
238  sumc += x;
239  vd.push_back(x);
240  }
241 
242  vd.push_back(1 - sumc);
243  return vd;
244 }
245 
246 /******************************************************************************/
Vdouble rand() const
Draw a random vector from this distribution.
STL namespace.
This class is designed to facilitate the manipulation of parameters.
Definition: Parameter.h:97
void addParameter_(Parameter *parameter)
Discretized Beta distribution with parameters alpha and beta, on a given interval. On default, the interval is , but it can be restricted.
static double VERY_TINY()
Definition: NumConstants.h:47
virtual void setParameterValue(const std::string &name, double value)
Set the value of parameter with name name to be equal to value.
double getParameterValue(const std::string &name) const override
Get the value for parameter of name &#39;name&#39;.
The parameter list object.
Definition: ParameterList.h:27
virtual void fireParameterChanged(const ParameterList &parameters)
Notify the class when one or several parameters have changed.
A partial implementation of the Parametrizable interface.
std::vector< double > Vdouble
Definition: VectorTools.h:34
DirichletDiscreteDistribution(std::vector< size_t > vn, Vdouble valpha)
Build a new discretized Dirichlet distribution.
virtual double getProbability(Vdouble &category) const
void fireParameterChanged(const ParameterList &parameters)
Notify the class when one or several parameters have changed.
virtual void addParameter(const Parameter &param)
Add a new parameter at the end of the list.
Exception base class. Overload exception constructor (to control the exceptions mechanism). Destructor is already virtual (from std::exception)
Definition: Exceptions.h:20
Vdouble randC() const
Draw a random vector from the continuous version of this distribution.
std::vector< BetaDiscreteDistribution *> vpBDD_
std::string toString(T t)
General template method to convert to a string.
Definition: TextTools.h:115
std::vector< Vdouble > VVdouble
Definition: VectorTools.h:35