bpp-core3  3.0.0
RandomTools.h
Go to the documentation of this file.
1 //
2 // File: RandomTools.h
3 // Authors:
4 // Julien Dutheil
5 // Sylvain Gaillard
6 // Last modified: 2008-11-06 00:00:00
7 //
8 
9 /*
10  Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
11 
12  This software is a computer program whose purpose is to provide classes
13  for numerical calculus.
14 
15  This software is governed by the CeCILL license under French law and
16  abiding by the rules of distribution of free software. You can use,
17  modify and/ or redistribute the software under the terms of the CeCILL
18  license as circulated by CEA, CNRS and INRIA at the following URL
19  "http://www.cecill.info".
20 
21  As a counterpart to the access to the source code and rights to copy,
22  modify and redistribute granted by the license, users are provided only
23  with a limited warranty and the software's author, the holder of the
24  economic rights, and the successive licensors have only limited
25  liability.
26 
27  In this respect, the user's attention is drawn to the risks associated
28  with loading, using, modifying and/or developing or reproducing the
29  software by the user in light of its specific status of free software,
30  that may mean that it is complicated to manipulate, and that also
31  therefore means that it is reserved for developers and experienced
32  professionals having in-depth computer knowledge. Users are therefore
33  encouraged to load and test the software's suitability as regards their
34  requirements in conditions enabling the security of their systems and/or
35  data to be ensured and, more generally, to use and operate it in the
36  same conditions as regards security.
37 
38  The fact that you are presently reading this means that you have had
39  knowledge of the CeCILL license and that you accept its terms.
40 */
41 
42 #ifndef BPP_NUMERIC_RANDOM_RANDOMTOOLS_H
43 #define BPP_NUMERIC_RANDOM_RANDOMTOOLS_H
44 
45 
46 #include "../../Exceptions.h"
47 #include "../VectorExceptions.h"
48 #include "../VectorTools.h"
49 #include "RandomFactory.h"
50 
51 // From the STL:
52 #include <cmath>
53 #include <cassert>
54 #include <ctime>
55 #include <vector>
56 #include <algorithm>
57 
58 namespace bpp
59 {
72 {
73 public:
75  virtual ~RandomTools() {}
76 
77 private:
81  static double incompletebetafe(double a,
82  double b,
83  double x,
84  double big,
85  double biginv);
86  static double incompletebetafe2(double a,
87  double b,
88  double x,
89  double big,
90  double biginv);
91  static double incompletebetaps(double a,
92  double b,
93  double x,
94  double maxgam);
95 
96 public:
98 
106  static double giveRandomNumberBetweenZeroAndEntry(double entry, const RandomFactory& generator = * DEFAULT_GENERATOR);
107 
113  static bool flipCoin(const RandomFactory& generator = * DEFAULT_GENERATOR);
114 
122  template<class intType>
123  static intType giveIntRandomNumberBetweenZeroAndEntry(intType entry, const RandomFactory& generator = * DEFAULT_GENERATOR)
124  {
125  return static_cast<intType>(giveRandomNumberBetweenZeroAndEntry(static_cast<double>(entry), generator));
126  }
127 
133  static void setSeed(long seed);
134 
141  static double randGaussian(double mean, double variance, const RandomFactory& generator = * DEFAULT_GENERATOR);
142 
148  static double randGamma(double dblAlpha, const RandomFactory& generator = * DEFAULT_GENERATOR);
149 
156  static double randGamma(double alpha, double beta, const RandomFactory& generator = * DEFAULT_GENERATOR);
157 
164  static double randBeta(double alpha, double beta, const RandomFactory& generator = * DEFAULT_GENERATOR);
165 
171  static double randExponential(double mean, const RandomFactory& generator = * DEFAULT_GENERATOR);
172 
187  template<class T>
188  static T pickOne(std::vector<T>& v, bool replace = false)
189  {
190  if (v.empty())
191  throw EmptyVectorException<T>("RandomTools::pickOne: input vector is empty", &v);
192  size_t pos = RandomTools::giveIntRandomNumberBetweenZeroAndEntry<size_t>(v.size());
193  if (replace)
194  return v[pos];
195  else
196  {
197  T e = v[pos];
198  v[pos] = v.back();
199  v.pop_back();
200  return e;
201  }
202  }
203 
213  template<class T>
214  static T pickOne(const std::vector<T>& v)
215  {
216  if (v.empty())
217  throw EmptyVectorException<T>("RandomTools::pickOne: input vector is empty", &v);
218  size_t pos = RandomTools::giveIntRandomNumberBetweenZeroAndEntry<size_t>(v.size());
219  return v[pos];
220  }
221 
239  template<class T>
240  static void getSample(const std::vector<T>& vin, std::vector<T>& vout, bool replace = false)
241  {
242  if (vout.size() > vin.size() && !replace)
243  throw IndexOutOfBoundsException("RandomTools::getSample: size exceeded v.size.", vout.size(), 0, vin.size());
244  if (replace)
245  {
246  for (size_t i = 0; i < vout.size(); i++)
247  vout[i] = pickOne(vin);
248  }
249  else
250  {
251  std::vector<size_t> hat(vin.size());
252  std::iota(hat.begin(), hat.end(), 0);
253  std::random_shuffle(hat.begin(), hat.end());
254  for (size_t i = 0; i < vout.size(); i++)
255  vout[i] = vin[hat[i]];
256  }
257  }
258 
274  template<class T>
275  static T pickOne(std::vector<T>& v, std::vector<double>& w, bool replace = false)
276  {
277  if (v.empty())
278  throw EmptyVectorException<T>("RandomTools::pickOne (with weight): input vector is empty", &v);
279  // Compute cumulative sum of weights:
280  std::vector<double> sumw = VectorTools::cumSum(w);
281  // Convert to cumulative distribution:
282  sumw /= sumw.back();
283  // Get random positions:
285  size_t pos = v.size() - 1;
286  for (size_t i = 0; i < v.size(); ++i)
287  {
288  if (prob < sumw[i])
289  {
290  pos = i;
291  break;
292  }
293  }
294  if (replace)
295  return v[pos];
296  else
297  {
298  T e = v[pos];
299  v[pos] = v.back();
300  v.pop_back();
301  w[pos] = w.back();
302  w.pop_back();
303  return e;
304  }
305  }
306 
320  template<class T>
321  static T pickOne(const std::vector<T>& v, const std::vector<double>& w)
322  {
323  if (v.empty())
324  throw EmptyVectorException<T>("RandomTools::pickOne (with weight): input vector is empty", &v);
325  // Compute cumulative sum of weights:
326  std::vector<double> sumw = VectorTools::cumSum(w);
327  // Convert to cumulative distribution:
328  sumw /= sumw.back();
329  // Get random positions:
331  size_t pos = v.size() - 1;
332  for (size_t i = 0; i < v.size(); ++i)
333  {
334  if (prob < sumw[i])
335  {
336  pos = i;
337  break;
338  }
339  }
340  return v[pos];
341  }
342 
354  static size_t pickFromCumSum(const std::vector<double>& w)
355  {
357  size_t pos = 0;
358  while (pos < w.size() - 1)
359  {
360  if (prob <= w[pos])
361  return pos;
362  pos += 1;
363  }
364  return w.size() - 1;
365  }
366 
392  template<class T>
393  static void getSample(const std::vector<T>& vin, const std::vector<double>& w, std::vector<T>& vout, bool replace = false)
394  {
395  if (vout.size() > vin.size() && !replace)
396  throw IndexOutOfBoundsException("RandomTools::getSample (with weights): size exceeded v.size.", vout.size(), 0, vin.size());
397  std::vector<size_t> hat(vin.size());
398  std::iota(hat.begin(), hat.end(), 0);
399  if (replace)
400  {
401  for (size_t i = 0; i < vout.size(); i++)
402  vout[i] = vin[pickOne(hat, w)];
403  }
404  else
405  {
406  std::vector<double> w2(w); // non const copy
407  for (size_t i = 0; i < vout.size(); i++)
408  {
409  vout[i] = vin[pickOne(hat, w2, false)];
410  }
411  }
412  }
413 
424  static std::vector<size_t> randMultinomial(size_t n, const std::vector<double>& probs);
425 
451  static double qNorm(double prob);
452 
472  static double qNorm(double prob, double mu, double sigma);
473 
480  static double lnGamma(double alpha) { return std::lgamma(alpha); }
481 
498  static double incompleteGamma(double x, double alpha, double ln_gamma_alpha);
499 
500 
515  static double qChisq(double prob, double v);
516 
524  static double pChisq(double x, double v)
525  {
526  if (x < 0) return 0;
527  return pGamma(x, v / 2, 0.5);
528  }
529 
538  static double qGamma(double prob, double alpha, double beta)
539  {
540  return qChisq(prob, 2.0 * (alpha)) / (2.0 * (beta));
541  }
542 
553  static double pGamma(double x, double alpha, double beta)
554  {
555  if (alpha < 0) throw Exception("RandomTools::pGamma. Negative alpha is not allowed.");
556  if (beta < 0) throw Exception("RandomTools::pGamma. Negative beta is not allowed.");
557  if (alpha == 0.) return 1.;
558  return incompleteGamma(beta * x, alpha, lnGamma(alpha));
559  }
560 
583  static double pNorm(double z);
584 
585  /* @brief Normal cumulative function.
586  *
587  * Returns Prob{x<=z} where x ~ N(mu,sigma^2)
588 
589  * @param z the value.
590  * @param mu The mean of the distribution
591  * @param sigma The standard deviation of the distribution
592  * @return The corresponding probability.
593  */
594 
595  static double pNorm(double z, double mu, double sigma);
596 
607  static double lnBeta(double alpha, double beta);
608 
622  static double incompleteBeta(double x, double alpha, double beta);
623  static double pBeta(double x, double alpha, double beta)
624  {
625  return incompleteBeta(x, alpha, beta);
626  }
627 
641  static double qBeta(double prob, double alpha, double beta);
642 
645 private:
646  static double DblGammaGreaterThanOne(double dblAlpha, const RandomFactory& generator);
647  static double DblGammaLessThanOne(double dblAlpha, const RandomFactory& generator);
648 };
649 } // end of namespace bpp.
650 #endif // BPP_NUMERIC_RANDOM_RANDOMTOOLS_H
Exception thrown when an empty vector was found.
Exception base class. Overload exception constructor (to control the exceptions mechanism)....
Definition: Exceptions.h:59
Index out of bounds exception class.
Definition: Exceptions.h:170
This is the interface for the Random Number Generators.
Definition: RandomFactory.h:55
Utilitary function dealing with random numbers.
Definition: RandomTools.h:72
static double DblGammaLessThanOne(double dblAlpha, const RandomFactory &generator)
static double pNorm(double z)
Normal cumulative function.
static T pickOne(std::vector< T > &v, bool replace=false)
Pick (and extract) one element randomly in a vector and return it.
Definition: RandomTools.h:188
static T pickOne(const std::vector< T > &v)
Pick one element randomly in a vector and return it.
Definition: RandomTools.h:214
static double incompleteBeta(double x, double alpha, double beta)
Returns the regularized incomplete beta function .
static double randExponential(double mean, const RandomFactory &generator= *DEFAULT_GENERATOR)
Definition: RandomTools.cpp:97
static double giveRandomNumberBetweenZeroAndEntry(double entry, const RandomFactory &generator= *DEFAULT_GENERATOR)
Get a double random value (between 0 and specified range).
Definition: RandomTools.cpp:63
static double lnBeta(double alpha, double beta)
Computes given and .
static double qChisq(double prob, double v)
quantile function.
static void setSeed(long seed)
Set the default generator seed.
Definition: RandomTools.cpp:56
static std::vector< size_t > randMultinomial(size_t n, const std::vector< double > &probs)
Get a random state from a set of probabilities/scores.
static size_t pickFromCumSum(const std::vector< double > &w)
Pick one index from a cumsum vector of probabilities.
Definition: RandomTools.h:354
static double randGamma(double dblAlpha, const RandomFactory &generator= *DEFAULT_GENERATOR)
Definition: RandomTools.cpp:81
static double qBeta(double prob, double alpha, double beta)
The Beta quantile function.
static double pChisq(double x, double v)
cumulative probability function.
Definition: RandomTools.h:524
static double incompletebetafe(double a, double b, double x, double big, double biginv)
functions for the computation of incompleteBeta
static double DblGammaGreaterThanOne(double dblAlpha, const RandomFactory &generator)
static double randBeta(double alpha, double beta, const RandomFactory &generator= *DEFAULT_GENERATOR)
static bool flipCoin(const RandomFactory &generator= *DEFAULT_GENERATOR)
Get a boolean random value.
Definition: RandomTools.cpp:71
virtual ~RandomTools()
Definition: RandomTools.h:75
static double pGamma(double x, double alpha, double beta)
cumulative probability function.
Definition: RandomTools.h:553
static RandomFactory * DEFAULT_GENERATOR
Definition: RandomTools.h:97
static double incompleteGamma(double x, double alpha, double ln_gamma_alpha)
Returns the incomplete gamma ratio I(x,alpha).
static void getSample(const std::vector< T > &vin, std::vector< T > &vout, bool replace=false)
Sample a vector.
Definition: RandomTools.h:240
static T pickOne(const std::vector< T > &v, const std::vector< double > &w)
Pick one element in a vector, with associated probability weights.
Definition: RandomTools.h:321
static double incompletebetaps(double a, double b, double x, double maxgam)
static double randGaussian(double mean, double variance, const RandomFactory &generator= *DEFAULT_GENERATOR)
Definition: RandomTools.cpp:76
static double pBeta(double x, double alpha, double beta)
Definition: RandomTools.h:623
static void getSample(const std::vector< T > &vin, const std::vector< double > &w, std::vector< T > &vout, bool replace=false)
Sample a vector, with associated probability weights.
Definition: RandomTools.h:393
static T pickOne(std::vector< T > &v, std::vector< double > &w, bool replace=false)
Pick one element in a vector, with associated probability weights.
Definition: RandomTools.h:275
static double qGamma(double prob, double alpha, double beta)
The Gamma quantile function.
Definition: RandomTools.h:538
static double lnGamma(double alpha)
Computes given .
Definition: RandomTools.h:480
static intType giveIntRandomNumberBetweenZeroAndEntry(intType entry, const RandomFactory &generator= *DEFAULT_GENERATOR)
Get an integer random value (between 0 and specified range).
Definition: RandomTools.h:123
static double qNorm(double prob)
Normal quantile function.
static double incompletebetafe2(double a, double b, double x, double big, double biginv)
static std::vector< T > cumSum(const std::vector< T > &v1)
Definition: VectorTools.h:662