]> git.donarmstrong.com Git - rsem.git/blob - boost/random/geometric_distribution.hpp
Updated boost to v1.55.0
[rsem.git] / boost / random / geometric_distribution.hpp
1 /* boost random/geometric_distribution.hpp header file
2  *
3  * Copyright Jens Maurer 2000-2001
4  * Copyright Steven Watanabe 2011
5  * Distributed under the Boost Software License, Version 1.0. (See
6  * accompanying file LICENSE_1_0.txt or copy at
7  * http://www.boost.org/LICENSE_1_0.txt)
8  *
9  * See http://www.boost.org for most recent version including documentation.
10  *
11  * $Id: geometric_distribution.hpp 74867 2011-10-09 23:13:31Z steven_watanabe $
12  *
13  * Revision history
14  *  2001-02-18  moved to individual header files
15  */
16
17 #ifndef BOOST_RANDOM_GEOMETRIC_DISTRIBUTION_HPP
18 #define BOOST_RANDOM_GEOMETRIC_DISTRIBUTION_HPP
19
20 #include <boost/config/no_tr1/cmath.hpp>          // std::log
21 #include <iosfwd>
22 #include <ios>
23 #include <boost/assert.hpp>
24 #include <boost/random/detail/config.hpp>
25 #include <boost/random/detail/operators.hpp>
26 #include <boost/random/uniform_01.hpp>
27
28 namespace boost {
29 namespace random {
30
31 /**
32  * An instantiation of the class template @c geometric_distribution models
33  * a \random_distribution.  The distribution produces positive
34  * integers which are the number of bernoulli trials
35  * with probability @c p required to get one that fails.
36  *
37  * For the geometric distribution, \f$p(i) = p(1-p)^{i}\f$.
38  *
39  * @xmlwarning
40  * This distribution has been updated to match the C++ standard.
41  * Its behavior has changed from the original
42  * boost::geometric_distribution.  A backwards compatible
43  * wrapper is provided in namespace boost.
44  * @endxmlwarning
45  */
46 template<class IntType = int, class RealType = double>
47 class geometric_distribution
48 {
49 public:
50     typedef RealType input_type;
51     typedef IntType result_type;
52
53     class param_type
54     {
55     public:
56
57         typedef geometric_distribution distribution_type;
58
59         /** Constructs the parameters with p. */
60         explicit param_type(RealType p_arg = RealType(0.5))
61           : _p(p_arg)
62         {
63             BOOST_ASSERT(RealType(0) < _p && _p < RealType(1));
64         }
65
66         /** Returns the p parameter of the distribution. */
67         RealType p() const { return _p; }
68
69         /** Writes the parameters to a std::ostream. */
70         BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
71         {
72             os << parm._p;
73             return os;
74         }
75
76         /** Reads the parameters from a std::istream. */
77         BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
78         {
79             double p_in;
80             if(is >> p_in) {
81                 if(p_in > RealType(0) && p_in < RealType(1)) {
82                     parm._p = p_in;
83                 } else {
84                     is.setstate(std::ios_base::failbit);
85                 }
86             }
87             return is;
88         }
89
90         /** Returns true if the two sets of parameters are equal. */
91         BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
92         { return lhs._p == rhs._p; }
93
94         /** Returns true if the two sets of parameters are different. */
95         BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
96
97
98     private:
99         RealType _p;
100     };
101
102     /**
103      * Contructs a new geometric_distribution with the paramter @c p.
104      *
105      * Requires: 0 < p < 1
106      */
107     explicit geometric_distribution(const RealType& p = RealType(0.5))
108       : _p(p)
109     {
110         BOOST_ASSERT(RealType(0) < _p && _p < RealType(1));
111         init();
112     }
113
114     /** Constructs a new geometric_distribution from its parameters. */
115     explicit geometric_distribution(const param_type& parm)
116       : _p(parm.p())
117     {
118         init();
119     }
120
121     // compiler-generated copy ctor and assignment operator are fine
122
123     /** Returns: the distribution parameter @c p  */
124     RealType p() const { return _p; }
125
126     /** Returns the smallest value that the distribution can produce. */
127     IntType min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return IntType(0); }
128
129     /** Returns the largest value that the distribution can produce. */
130     IntType max BOOST_PREVENT_MACRO_SUBSTITUTION () const
131     { return (std::numeric_limits<IntType>::max)(); }
132
133     /** Returns the parameters of the distribution. */
134     param_type param() const { return param_type(_p); }
135
136     /** Sets the parameters of the distribution. */
137     void param(const param_type& parm)
138     {
139         _p = parm.p();
140         init();
141     }
142   
143     /**
144      * Effects: Subsequent uses of the distribution do not depend
145      * on values produced by any engine prior to invoking reset.
146      */
147     void reset() { }
148
149     /**
150      * Returns a random variate distributed according to the
151      * geometric_distribution.
152      */
153     template<class Engine>
154     result_type operator()(Engine& eng) const
155     {
156         using std::log;
157         using std::floor;
158         RealType x = RealType(1) - boost::uniform_01<RealType>()(eng);
159         return IntType(floor(log(x) / _log_1mp));
160     }
161
162     /**
163      * Returns a random variate distributed according to the
164      * geometric distribution with parameters specified by param.
165      */
166     template<class Engine>
167     result_type operator()(Engine& eng, const param_type& parm) const
168     { return geometric_distribution(parm)(eng); }
169
170     /** Writes the distribution to a @c std::ostream. */
171     BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, geometric_distribution, gd)
172     {
173         os << gd._p;
174         return os;
175     }
176
177     /** Reads the distribution from a @c std::istream. */
178     BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, geometric_distribution, gd)
179     {
180         param_type parm;
181         if(is >> parm) {
182             gd.param(parm);
183         }
184         return is;
185     }
186
187     /**
188      * Returns true if the two distributions will produce identical
189      * sequences of values given equal generators.
190      */
191     BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(geometric_distribution, lhs, rhs)
192     { return lhs._p == rhs._p; }
193
194     /**
195      * Returns true if the two distributions may produce different
196      * sequences of values given equal generators.
197      */
198     BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(geometric_distribution)
199
200 private:
201
202     /// \cond show_private
203
204     void init()
205     {
206         using std::log;
207         _log_1mp = log(1 - _p);
208     }
209
210     RealType _p;
211     RealType _log_1mp;
212
213     /// \endcond
214 };
215
216 } // namespace random
217
218 /// \cond show_deprecated
219
220 /**
221  * Provided for backwards compatibility.  This class is
222  * deprecated.  It provides the old behavior of geometric_distribution
223  * with \f$p(i) = (1-p) p^{i-1}\f$.
224  */
225 template<class IntType = int, class RealType = double>
226 class geometric_distribution
227 {
228 public:
229     typedef RealType input_type;
230     typedef IntType result_type;
231
232     explicit geometric_distribution(RealType p_arg = RealType(0.5))
233       : _impl(1 - p_arg) {}
234
235     RealType p() const { return 1 - _impl.p(); }
236
237     void reset() {}
238
239     template<class Engine>
240     IntType operator()(Engine& eng) const { return _impl(eng) + IntType(1); }
241
242     BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, geometric_distribution, gd)
243     {
244         os << gd.p();
245         return os;
246     }
247
248     BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, geometric_distribution, gd)
249     {
250         RealType val;
251         if(is >> val) {
252             typename impl_type::param_type impl_param(1 - val);
253             gd._impl.param(impl_param);
254         }
255         return is;
256     }
257
258 private:
259     typedef random::geometric_distribution<IntType, RealType> impl_type;
260     impl_type _impl;
261 };
262
263 /// \endcond
264
265 } // namespace boost
266
267 #endif // BOOST_RANDOM_GEOMETRIC_DISTRIBUTION_HPP