Binomial.h
Go to the documentation of this file.
1 /*!
2  *
3  *
4  * \brief Implements a binomial distribution.
5  *
6  *
7  *
8  * \author O. Krause
9  * \date 2010-01-01
10  *
11  *
12  * \par Copyright 1995-2017 Shark Development Team
13  *
14  * <BR><HR>
15  * This file is part of Shark.
16  * <http://shark-ml.org/>
17  *
18  * Shark is free software: you can redistribute it and/or modify
19  * it under the terms of the GNU Lesser General Public License as published
20  * by the Free Software Foundation, either version 3 of the License, or
21  * (at your option) any later version.
22  *
23  * Shark is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26  * GNU Lesser General Public License for more details.
27  *
28  * You should have received a copy of the GNU Lesser General Public License
29  * along with Shark. If not, see <http://www.gnu.org/licenses/>.
30  *
31  */
32 #ifndef SHARK_RNG_BINOMIAL_H
33 #define SHARK_RNG_BINOMIAL_H
34 
35 #include <shark/Rng/Rng.h>
36 
37 #include <boost/random.hpp>
38 #include <boost/math/special_functions.hpp>
39 #include <boost/random/binomial_distribution.hpp>
40 
41 #include <cmath>
42 
43 namespace shark{
44 
45  /**
46  * \brief Models a binomial distribution with parameters p and n.
47  */
48  template<typename RngType = shark::DefaultRngType>
49  class Binomial:public boost::variate_generator<RngType*,boost::binomial_distribution<> > {
50  private:
51  typedef boost::variate_generator<RngType*,boost::binomial_distribution<> > Base;
52  public:
53 
54  /**
55  * \brief C'tor, initializes parameters n and p, initializes for a custom RNG.
56  * \param [in,out] rng The random number generator.
57  * \param [in] n Parameter n.descibing the number of coin tosses
58  * \param [in] prob Parameter p.
59  */
60  Binomial(RngType & rng, unsigned int n=1,double prob=0.5 )
61  :Base(&rng,boost::binomial_distribution<>(n,prob))
62  {}
63 
64  /**
65  * \brief Injects the default sampling operator.
66  */
67  using Base::operator();
68 
69  /**
70  * \brief Samples a random number from the distribution with parameter n and p.
71  */
72  long operator()(unsigned int n,double prob) {
73  boost::binomial_distribution<> dist(n,prob);
74  return dist(Base::engine());
75  }
76 
77  /**
78  * \brief Accesses the parameter p of the distirbution.
79  */
80  double prob()const {
81  return Base::distribution().p();
82  }
83 
84  /**
85  * \brief Adjusts the parameter p of the distribution.
86  */
87  void prob(double newProb) {
88  Base::distribution()=boost::binomial_distribution<>(n(),newProb);
89  }
90 
91  /**
92  * \brief Accesses the parameter n of the distribution.
93  */
94  unsigned int n() const {
95  return Base::distribution().t();
96  }
97 
98  /**
99  * \brief Adjusts the parameter n of the distribution.
100  */
101  void n(unsigned int newN) {
102  Base::distribution()=boost::binomial_distribution<>(newN,prob());
103  }
104 
105  /**
106  * \brief Implements the pmf of the distribution.
107  * \param [in] k Number of successful trials.
108  * \returns The probability of k successful in n total trials.
109  * \throws std::overflow_error if the result is too large to be represented in type double.
110  */
111  double p(long k) const {
112  return(
113  boost::math::binomial_coefficient<double>(n(),k) *
114  std::pow(prob(), static_cast<double>( k ) ) *
115  std::pow(1.0-prob(),static_cast<double>( n()-k ) )
116  );
117  }
118 
119  };
120 
121  ///\brief Returns a random number from Binomial(n,p) by drawing random numbers from rng
122  template<class RngType>
123  unsigned int binomial(RngType& rng, unsigned int n, double pHeads){
124  Binomial<RngType> dist(rng, n, pHeads);
125  return dist();
126  }
127 }
128 #endif
129 
130 
131 
132