• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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          */
param_type(RealType n_arg=RealType (1))47         explicit param_type(RealType n_arg = RealType(1))
48           : _n(n_arg)
49         {}
50         /** Returns the @c n parameter of the distribution. */
n() const51         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>&
operator <<(std::basic_ostream<CharT,Traits> & os,const param_type & parm)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>&
operator >>(std::basic_istream<CharT,Traits> & is,param_type & parm)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. */
operator ==(const param_type & lhs,const param_type & rhs)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. */
operator !=(const param_type & lhs,const param_type & rhs)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      */
chi_squared_distribution(RealType n_arg=RealType (1))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      */
chi_squared_distribution(const param_type & parm)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>
operator ()(URNG & 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>
operator ()(URNG & urng,const param_type & parm) const121     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. */
n() const127     RealType n() const { return 2 * _impl.alpha(); }
128 
129     /** Returns the smallest value that the distribution can produce. */
BOOST_PREVENT_MACRO_SUBSTITUTION() const130     RealType min BOOST_PREVENT_MACRO_SUBSTITUTION() const { return 0; }
131     /** Returns the largest value that the distribution can produce. */
BOOST_PREVENT_MACRO_SUBSTITUTION() const132     RealType max BOOST_PREVENT_MACRO_SUBSTITUTION() const
133     { return (std::numeric_limits<RealType>::infinity)(); }
134 
135     /** Returns the parameters of the distribution. */
param() const136     param_type param() const { return param_type(n()); }
137     /** Sets parameters of the distribution. */
param(const param_type & parm)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      */
reset()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>&
operator <<(std::basic_ostream<CharT,Traits> & os,const chi_squared_distribution & c2d)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>&
operator >>(std::basic_istream<CharT,Traits> & is,chi_squared_distribution & c2d)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. */
operator ==(const chi_squared_distribution & lhs,const chi_squared_distribution & rhs)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. */
operator !=(const chi_squared_distribution & lhs,const chi_squared_distribution & rhs)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>
read(std::basic_istream<CharT,Traits> & is)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