1 /* boost random/gamma_distribution.hpp header file
\r
3 * Copyright Jens Maurer 2002
\r
4 * Distributed under the Boost Software License, Version 1.0. (See
\r
5 * accompanying file LICENSE_1_0.txt or copy at
\r
6 * http://www.boost.org/LICENSE_1_0.txt)
\r
8 * See http://www.boost.org for most recent version including documentation.
\r
10 * $Id: gamma_distribution.hpp 52492 2009-04-19 14:55:57Z steven_watanabe $
\r
14 #ifndef BOOST_RANDOM_GAMMA_DISTRIBUTION_HPP
\r
15 #define BOOST_RANDOM_GAMMA_DISTRIBUTION_HPP
\r
17 #include <boost/config/no_tr1/cmath.hpp>
\r
19 #include <boost/limits.hpp>
\r
20 #include <boost/static_assert.hpp>
\r
21 #include <boost/random/detail/config.hpp>
\r
22 #include <boost/random/exponential_distribution.hpp>
\r
27 template<class RealType = double>
\r
28 class gamma_distribution
\r
31 typedef RealType input_type;
\r
32 typedef RealType result_type;
\r
34 #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
\r
35 BOOST_STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer);
\r
38 explicit gamma_distribution(const result_type& alpha_arg = result_type(1))
\r
39 : _exp(result_type(1)), _alpha(alpha_arg)
\r
41 assert(_alpha > result_type(0));
\r
45 // compiler-generated copy ctor and assignment operator are fine
\r
47 RealType alpha() const { return _alpha; }
\r
49 void reset() { _exp.reset(); }
\r
51 template<class Engine>
\r
52 result_type operator()(Engine& eng)
\r
54 #ifndef BOOST_NO_STDC_NAMESPACE
\r
55 // allow for Koenig lookup
\r
56 using std::tan; using std::sqrt; using std::exp; using std::log;
\r
59 if(_alpha == result_type(1)) {
\r
61 } else if(_alpha > result_type(1)) {
\r
62 // Can we have a boost::mathconst please?
\r
63 const result_type pi = result_type(3.14159265358979323846);
\r
65 result_type y = tan(pi * eng());
\r
66 result_type x = sqrt(result_type(2)*_alpha-result_type(1))*y
\r
67 + _alpha-result_type(1);
\r
68 if(x <= result_type(0))
\r
71 (result_type(1)+y*y) * exp((_alpha-result_type(1))
\r
72 *log(x/(_alpha-result_type(1)))
\r
73 - sqrt(result_type(2)*_alpha
\r
74 -result_type(1))*y))
\r
78 } else /* alpha < 1.0 */ {
\r
80 result_type u = eng();
\r
81 result_type y = _exp(eng);
\r
87 x = result_type(1)+y;
\r
88 q = _p + (result_type(1)-_p) * pow(x, _alpha-result_type(1));
\r
97 #ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
\r
98 template<class CharT, class Traits>
\r
99 friend std::basic_ostream<CharT,Traits>&
\r
100 operator<<(std::basic_ostream<CharT,Traits>& os, const gamma_distribution& gd)
\r
106 template<class CharT, class Traits>
\r
107 friend std::basic_istream<CharT,Traits>&
\r
108 operator>>(std::basic_istream<CharT,Traits>& is, gamma_distribution& gd)
\r
110 is >> std::ws >> gd._alpha;
\r
119 #ifndef BOOST_NO_STDC_NAMESPACE
\r
120 // allow for Koenig lookup
\r
123 _p = exp(result_type(1)) / (_alpha + exp(result_type(1)));
\r
126 exponential_distribution<RealType> _exp;
\r
127 result_type _alpha;
\r
128 // some data precomputed from the parameters
\r
132 } // namespace boost
\r
134 #endif // BOOST_RANDOM_GAMMA_DISTRIBUTION_HPP
\r