bpp-core3  3.0.0
Simplex.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 "../NumConstants.h"
6 #include "../VectorTools.h"
7 #include "Simplex.h"
8 
9 using namespace bpp;
10 using namespace std;
11 
12 Simplex::Simplex(const std::vector<double>& probas, unsigned short method, bool allowNull, const std::string& name) : AbstractParameterAliasable(name),
13  dim_(probas.size()),
14  method_(method),
15  vProb_(),
16  valpha_()
17 {
18  if (dim_ == 0)
19  return;
20 
21  double sum = VectorTools::sum(probas);
22  if (fabs(1. - sum) > NumConstants::SMALL())
23  throw Exception("Simplex. Probabilities must equal 1 (sum =" + TextTools::toString(sum) + ").");
24 
25  std::shared_ptr<ConstraintInterface> pc = (allowNull ? Parameter::PROP_CONSTRAINT_IN : Parameter::PROP_CONSTRAINT_EX);
26 
27  for (auto& p : probas)
28  {
29  vProb_.push_back(p);
30  }
31 
32  double y = 1;
33  switch (method_)
34  {
35  case 1:
36  for (size_t i = 0; i < dim_ - 1; i++)
37  {
38  addParameter_(new Parameter(name + "theta" + TextTools::toString(i + 1), vProb_[i] / y, pc));
39  y -= vProb_[i];
40  }
41  break;
42  case 2:
43  for (size_t i = 0; i < dim_ - 1; i++)
44  {
45  addParameter_(new Parameter(name + "theta" + TextTools::toString(i + 1), vProb_[i] / (vProb_[i] + vProb_[i + 1]), pc));
46  }
47  for (size_t i = 0; i < dim_ - 1; i++)
48  {
49  valpha_.push_back(vProb_[i + 1] / vProb_[i]);
50  }
51  break;
52  case 3:
53  for (size_t i = 1; i < dim_; i++)
54  {
55  size_t o = i;
56  size_t li2 = 0; // rank of the strongest bit
57  while (o)
58  {
59  li2++;
60  o = o >> 1;
61  }
62 
63  double i1 = 0, i0 = 0;
64  size_t j = 0;
65  size_t pi = i & ~(1 << (li2 - 1));
66  while (j < dim_)
67  {
68  size_t t = (j << li2) + pi;
69  if (t >= dim_)
70  break;
71  else
72  i0 += vProb_[t];
73  t += (1 << (li2 - 1));
74  if (t < dim_)
75  i1 += vProb_[t];
76  j++;
77  }
78  addParameter_(new Parameter(name + "theta" + TextTools::toString(i), i1 / (i0 + i1), pc));
79  }
80  break;
81  }
82 }
83 
84 Simplex::Simplex(size_t dim, unsigned short method, bool allowNull, const std::string& name) :
86  dim_(dim),
87  method_(method),
88  vProb_(),
89  valpha_()
90 {
91  if (dim_ == 0)
92  return;
93 
94  for (size_t i = 0; i < dim_; i++)
95  {
96  vProb_.push_back(1. / static_cast<double>(dim_));
97  }
98 
100 
101  double y = 1;
102  switch (method_)
103  {
104  case 1:
105  for (size_t i = 0; i < dim_ - 1; i++)
106  {
107  addParameter_(new Parameter(name + "theta" + TextTools::toString(i + 1), vProb_[i] / y, pc));
108  y -= vProb_[i];
109  }
110  break;
111  case 2:
112  for (size_t i = 0; i < dim_ - 1; i++)
113  {
114  addParameter_(new Parameter(name + "theta" + TextTools::toString(i + 1), 0.5, pc));
115  }
116  for (size_t i = 0; i < dim_ - 1; i++)
117  {
118  valpha_.push_back(1.);
119  }
120  break;
121  case 3:
122  for (size_t i = 0; i < dim_ - 1; i++)
123  {
124  addParameter_(new Parameter(name + "theta" + TextTools::toString(i + 1), 0.5, pc));
125  }
127 
128  break;
129  }
130 }
131 
133 {
134  if (dim_ == 0)
135  return;
136 
137  double x = 1.0;
138  switch (method_)
139  {
140  case 1:
141  double th;
142  for (unsigned int i = 0; i < dim_ - 1; i++)
143  {
144  th = getParameterValue("theta" + TextTools::toString(i + 1));
145  vProb_[i] = th * x;
146  x *= 1 - th;
147  }
148  vProb_[dim_ - 1] = x;
149  break;
150  case 2:
151  for (unsigned int i = 0; i < dim_ - 1; i++)
152  {
153  th = getParameterValue("theta" + TextTools::toString(i + 1));
154  valpha_[i] = (1 - th) / th;
155  }
156  th = 1;
157  vProb_[0] = 1;
158  x = 1.0;
159  for (unsigned int i = 0; i < dim_ - 1; i++)
160  {
161  th *= valpha_[i];
162  vProb_[i + 1] = th;
163  x += vProb_[i + 1];
164  }
165 
166  if (x > NumConstants::TINY()) // avoid rounding pb
167  for (auto& vp : vProb_)
168  {
169  vp /= x;
170  }
171  else
172  for (auto& vp : vProb_)
173  {
174  vp = 1.0 / double(dim_);
175  }
176 
177  break;
178  case 3:
179  size_t o = dim_;
180  size_t ld2 = 0; // rank of the strongest bit
181  while (o)
182  {
183  ld2++;
184  o = o >> 1;
185  }
186  for (size_t i = 0; i < dim_; i++)
187  {
188  x = 1;
189  size_t ld = ld2;
190  size_t k = i;
191  while (ld)
192  {
193  if (k >> (ld - 1))
194  x *= getParameterValue("theta" + TextTools::toString(k));
195  else
196  {
197  if ((k + (1 << (ld - 1))) < dim_)
198  x *= 1 - getParameterValue("theta" + TextTools::toString(k + (1 << (ld - 1))));
199  }
200  k &= ~(1 << (--ld));
201  }
202  vProb_[i] = x;
203  }
204  break;
205  }
206 }
207 
208 
209 void Simplex::setFrequencies(const std::vector<double>& probas)
210 {
211  if (dim_ == 0)
212  return;
213 
214  double sum = VectorTools::sum(probas);
215  if (fabs(1. - sum) > NumConstants::SMALL())
216  throw Exception("Simplex::setFrequencies. Probabilities must equal 1 (sum =" + TextTools::toString(sum) + ").");
217 
218  double y = 1;
219 
220  ParameterList pl;
221  switch (method_)
222  {
223  case 1:
224  for (unsigned int i = 0; i < dim_ - 1; i++)
225  {
226  pl.addParameter(Parameter(getNamespace() + "theta" + TextTools::toString(i + 1), probas[i] / y));
227  y -= probas[i];
228  }
229  break;
230  case 2:
231  for (unsigned int i = 0; i < dim_ - 1; i++)
232  {
233  pl.addParameter(Parameter(getNamespace() + "theta" + TextTools::toString(i + 1), probas[i] / (probas[i] + probas[i + 1])));
234  valpha_[i] = probas[i + 1] / probas[i];
235  }
236  break;
237  case 3:
238  for (size_t i = 1; i < dim_; i++)
239  {
240  size_t o = i;
241  size_t li2 = 0; // rank of the strongest bit
242  while (o)
243  {
244  li2++;
245  o = o >> 1;
246  }
247 
248  double i1 = 0, i0 = 0;
249  size_t j = 0;
250  size_t pi = i & ~(1 << (li2 - 1));
251  while (j < dim_)
252  {
253  size_t t = (j << li2) + pi;
254  if (t >= dim_)
255  break;
256  else
257  i0 += probas[t];
258  t += (1 << (li2 - 1));
259  if (t < dim_)
260  i1 += probas[t];
261  j++;
262  }
263  pl.addParameter(Parameter(getNamespace() + "theta" + TextTools::toString(i), i1 / (i0 + i1)));
264  }
265  break;
266  }
267 
269 }
270 
271 
272 /*****************************/
273 
274 OrderedSimplex::OrderedSimplex(const std::vector<double>& probas, unsigned short method, bool allowNull, const std::string& name) :
275  Simplex(probas.size(), method, allowNull, name),
276  vValues_(probas)
277 {
279 }
280 
282 {
284  const auto& probs = Simplex::getFrequencies();
285 
286  auto dim = probs.size();
287 
288  double x = 0;
289  for (auto i = dim; i > 0; i--)
290  {
291  x += probs[i - 1] / (int)i;
292  vValues_[i - 1] = x;
293  }
294 }
295 
296 void OrderedSimplex::setFrequencies(const std::vector<double>& vValues)
297 {
298  vValues_ = vValues;
299 
300  auto dim = vValues.size();
301  Vdouble vprob(dim);
302 
303  for (size_t i = 0; i < dim - 1; ++i)
304  {
305  vprob[i] = static_cast<double>(i + 1) * (vValues[i] - vValues[i + 1]);
306  }
307 
308  vprob[dim - 1] = static_cast<double>(dim) * vValues[dim - 1];
310 }
void setFrequencies(const std::vector< double > &)
Definition: Simplex.cpp:209
std::string getNamespace() const override
void fireParameterChanged(const ParameterList &parameters)
Notify the class when one or several parameters have changed.
Definition: Simplex.cpp:281
const std::vector< double > & getFrequencies() const
Definition: Simplex.h:136
void fireParameterChanged(const ParameterList &parameters)
Notify the class when one or several parameters have changed.
Definition: Simplex.cpp:132
std::vector< double > vProb_
Definition: Simplex.h:86
static T sum(const std::vector< T > &v1)
Definition: VectorTools.h:587
STL namespace.
This class is designed to facilitate the manipulation of parameters.
Definition: Parameter.h:97
void addParameter_(Parameter *parameter)
std::vector< double > vValues_
Definition: Simplex.h:167
size_t dim_
The dimension+1 of the space simplex (ie the number of probabilities).
Definition: Simplex.h:74
double getParameterValue(const std::string &name) const override
Get the value for parameter of name &#39;name&#39;.
OrderedSimplex(size_t dim, unsigned short method=0, bool allowNull=false, const std::string &name="Simplex.")
Builds a new Simplex object from a number of probabilities. They are initialized equal.
Definition: Simplex.h:184
A Simplex object, used to define sets of probabilities that sum 1.
Definition: Simplex.h:66
The parameter list object.
Definition: ParameterList.h:27
A partial implementation of the Parametrizable interface.
bool matchParametersValues(const ParameterList &parameters) override
Update the parameters from parameters.
static double TINY()
Definition: NumConstants.h:46
std::vector< double > valpha_
just used with local ratio (method 2)
Definition: Simplex.h:91
static const std::shared_ptr< IntervalConstraint > PROP_CONSTRAINT_EX
Definition: Parameter.h:312
Simplex(size_t dim, unsigned short method=0, bool allowNull=false, const std::string &name="Simplex.")
Builds a new Simplex object from a number of probabilities. They are initialized equal.
Definition: Simplex.cpp:84
std::vector< double > Vdouble
Definition: VectorTools.h:34
static const std::shared_ptr< IntervalConstraint > PROP_CONSTRAINT_IN
Definition: Parameter.h:311
void setFrequencies(const std::vector< double > &)
Definition: Simplex.cpp:296
static double SMALL()
Definition: NumConstants.h:45
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
std::string toString(T t)
General template method to convert to a string.
Definition: TextTools.h:115
unsigned short method_
the method of parametrization.
Definition: Simplex.h:84