1 | /* boost random/chi_squared_distribution.hpp header file |
2 | * |
3 | * Copyright Steven Watanabe 2011 |
4 | * Distributed under the Boost Software License, Version 1.0. (See |
5 | * accompanying file LICENSE_1_0.txt or copy at |
6 | * http://www.boost.org/LICENSE_1_0.txt) |
7 | * |
8 | * See http://www.boost.org for most recent version including documentation. |
9 | * |
10 | * $Id$ |
11 | */ |
12 | |
13 | #ifndef BOOST_RANDOM_CHI_SQUARED_DISTRIBUTION_HPP_INCLUDED |
14 | #define BOOST_RANDOM_CHI_SQUARED_DISTRIBUTION_HPP_INCLUDED |
15 | |
16 | #include <iosfwd> |
17 | #include <boost/limits.hpp> |
18 | |
19 | #include <boost/random/detail/config.hpp> |
20 | #include <boost/random/gamma_distribution.hpp> |
21 | |
22 | namespace boost { |
23 | namespace random { |
24 | |
25 | /** |
26 | * The chi squared distribution is a real valued distribution with |
27 | * one parameter, @c n. The distribution produces values > 0. |
28 | * |
29 | * The distribution function is |
30 | * \f$\displaystyle P(x) = \frac{x^{(n/2)-1}e^{-x/2}}{\Gamma(n/2)2^{n/2}}\f$. |
31 | */ |
32 | template<class RealType = double> |
33 | class chi_squared_distribution { |
34 | public: |
35 | typedef RealType result_type; |
36 | typedef RealType input_type; |
37 | |
38 | class param_type { |
39 | public: |
40 | typedef chi_squared_distribution distribution_type; |
41 | /** |
42 | * Construct a param_type object. @c n |
43 | * is the parameter of the distribution. |
44 | * |
45 | * Requires: t >=0 && 0 <= p <= 1 |
46 | */ |
47 | explicit param_type(RealType n_arg = RealType(1)) |
48 | : _n(n_arg) |
49 | {} |
50 | /** Returns the @c n parameter of the distribution. */ |
51 | RealType n() const { return _n; } |
52 | #ifndef BOOST_RANDOM_NO_STREAM_OPERATORS |
53 | /** Writes the parameters of the distribution to a @c std::ostream. */ |
54 | template<class CharT, class Traits> |
55 | friend std::basic_ostream<CharT,Traits>& |
56 | operator<<(std::basic_ostream<CharT,Traits>& os, |
57 | const param_type& parm) |
58 | { |
59 | os << parm._n; |
60 | return os; |
61 | } |
62 | |
63 | /** Reads the parameters of the distribution from a @c std::istream. */ |
64 | template<class CharT, class Traits> |
65 | friend std::basic_istream<CharT,Traits>& |
66 | operator>>(std::basic_istream<CharT,Traits>& is, param_type& parm) |
67 | { |
68 | is >> parm._n; |
69 | return is; |
70 | } |
71 | #endif |
72 | /** Returns true if the parameters have the same values. */ |
73 | friend bool operator==(const param_type& lhs, const param_type& rhs) |
74 | { |
75 | return lhs._n == rhs._n; |
76 | } |
77 | /** Returns true if the parameters have different values. */ |
78 | friend bool operator!=(const param_type& lhs, const param_type& rhs) |
79 | { |
80 | return !(lhs == rhs); |
81 | } |
82 | private: |
83 | RealType _n; |
84 | }; |
85 | |
86 | /** |
87 | * Construct a @c chi_squared_distribution object. @c n |
88 | * is the parameter of the distribution. |
89 | * |
90 | * Requires: t >=0 && 0 <= p <= 1 |
91 | */ |
92 | explicit chi_squared_distribution(RealType n_arg = RealType(1)) |
93 | : _impl(static_cast<RealType>(n_arg / 2)) |
94 | { |
95 | } |
96 | |
97 | /** |
98 | * Construct an @c chi_squared_distribution object from the |
99 | * parameters. |
100 | */ |
101 | explicit chi_squared_distribution(const param_type& parm) |
102 | : _impl(static_cast<RealType>(parm.n() / 2)) |
103 | { |
104 | } |
105 | |
106 | /** |
107 | * Returns a random variate distributed according to the |
108 | * chi squared distribution. |
109 | */ |
110 | template<class URNG> |
111 | RealType operator()(URNG& urng) |
112 | { |
113 | return 2 * _impl(urng); |
114 | } |
115 | |
116 | /** |
117 | * Returns a random variate distributed according to the |
118 | * chi squared distribution with parameters specified by @c param. |
119 | */ |
120 | template<class URNG> |
121 | RealType operator()(URNG& urng, const param_type& parm) const |
122 | { |
123 | return chi_squared_distribution(parm)(urng); |
124 | } |
125 | |
126 | /** Returns the @c n parameter of the distribution. */ |
127 | RealType n() const { return 2 * _impl.alpha(); } |
128 | |
129 | /** Returns the smallest value that the distribution can produce. */ |
130 | RealType min BOOST_PREVENT_MACRO_SUBSTITUTION() const { return 0; } |
131 | /** Returns the largest value that the distribution can produce. */ |
132 | RealType max BOOST_PREVENT_MACRO_SUBSTITUTION() const |
133 | { return (std::numeric_limits<RealType>::infinity)(); } |
134 | |
135 | /** Returns the parameters of the distribution. */ |
136 | param_type param() const { return param_type(n()); } |
137 | /** Sets parameters of the distribution. */ |
138 | void param(const param_type& parm) |
139 | { |
140 | typedef gamma_distribution<RealType> impl_type; |
141 | typename impl_type::param_type impl_parm(static_cast<RealType>(parm.n() / 2)); |
142 | _impl.param(impl_parm); |
143 | } |
144 | |
145 | /** |
146 | * Effects: Subsequent uses of the distribution do not depend |
147 | * on values produced by any engine prior to invoking reset. |
148 | */ |
149 | void reset() { _impl.reset(); } |
150 | |
151 | #ifndef BOOST_RANDOM_NO_STREAM_OPERATORS |
152 | /** Writes the parameters of the distribution to a @c std::ostream. */ |
153 | template<class CharT, class Traits> |
154 | friend std::basic_ostream<CharT,Traits>& |
155 | operator<<(std::basic_ostream<CharT,Traits>& os, |
156 | const chi_squared_distribution& c2d) |
157 | { |
158 | os << c2d.param(); |
159 | return os; |
160 | } |
161 | |
162 | /** Reads the parameters of the distribution from a @c std::istream. */ |
163 | template<class CharT, class Traits> |
164 | friend std::basic_istream<CharT,Traits>& |
165 | operator>>(std::basic_istream<CharT,Traits>& is, |
166 | chi_squared_distribution& c2d) |
167 | { |
168 | c2d.read(is); |
169 | return is; |
170 | } |
171 | #endif |
172 | |
173 | /** Returns true if the two distributions will produce the same |
174 | sequence of values, given equal generators. */ |
175 | friend bool operator==(const chi_squared_distribution& lhs, |
176 | const chi_squared_distribution& rhs) |
177 | { |
178 | return lhs._impl == rhs._impl; |
179 | } |
180 | /** Returns true if the two distributions could produce different |
181 | sequences of values, given equal generators. */ |
182 | friend bool operator!=(const chi_squared_distribution& lhs, |
183 | const chi_squared_distribution& rhs) |
184 | { |
185 | return !(lhs == rhs); |
186 | } |
187 | |
188 | private: |
189 | |
190 | /// @cond show_private |
191 | |
192 | template<class CharT, class Traits> |
193 | void read(std::basic_istream<CharT, Traits>& is) { |
194 | param_type parm; |
195 | if(is >> parm) { |
196 | param(parm); |
197 | } |
198 | } |
199 | |
200 | gamma_distribution<RealType> _impl; |
201 | |
202 | /// @endcond |
203 | }; |
204 | |
205 | } |
206 | |
207 | } |
208 | |
209 | #endif |
210 | |