1 /* boost random/fisher_f_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_FISHER_F_DISTRIBUTION_HPP 14 #define BOOST_RANDOM_FISHER_F_DISTRIBUTION_HPP 15 16 #include <iosfwd> 17 #include <istream> 18 #include <boost/config.hpp> 19 #include <boost/limits.hpp> 20 #include <boost/random/detail/operators.hpp> 21 #include <boost/random/chi_squared_distribution.hpp> 22 23 namespace boost { 24 namespace random { 25 26 /** 27 * The Fisher F distribution is a real valued distribution with two 28 * parameters m and n. 29 * 30 * It has \f$\displaystyle p(x) = 31 * \frac{\Gamma((m+n)/2)}{\Gamma(m/2)\Gamma(n/2)} 32 * \left(\frac{m}{n}\right)^{m/2} 33 * x^{(m/2)-1} \left(1+\frac{mx}{n}\right)^{-(m+n)/2} 34 * \f$. 35 */ 36 template<class RealType = double> 37 class fisher_f_distribution { 38 public: 39 typedef RealType result_type; 40 typedef RealType input_type; 41 42 class param_type { 43 public: 44 typedef fisher_f_distribution distribution_type; 45 46 /** 47 * Constructs a @c param_type from the "m" and "n" parameters 48 * of the distribution. 49 * 50 * Requires: m > 0 and n > 0 51 */ param_type(RealType m_arg=RealType (1.0),RealType n_arg=RealType (1.0))52 explicit param_type(RealType m_arg = RealType(1.0), 53 RealType n_arg = RealType(1.0)) 54 : _m(m_arg), _n(n_arg) 55 {} 56 57 /** Returns the "m" parameter of the distribtuion. */ m() const58 RealType m() const { return _m; } 59 /** Returns the "n" parameter of the distribution. */ n() const60 RealType n() const { return _n; } 61 62 /** Writes a @c param_type to a @c std::ostream. */ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os,param_type,parm)63 BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm) 64 { os << parm._m << ' ' << parm._n; return os; } 65 66 /** Reads a @c param_type from a @c std::istream. */ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is,param_type,parm)67 BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm) 68 { is >> parm._m >> std::ws >> parm._n; return is; } 69 70 /** Returns true if the two sets of parameters are the same. */ BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type,lhs,rhs)71 BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs) 72 { return lhs._m == rhs._m && lhs._n == rhs._n; } 73 74 /** Returns true if the two sets of parameters are the different. */ 75 BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type) 76 77 private: 78 RealType _m; 79 RealType _n; 80 }; 81 82 /** 83 * Constructs a @c fisher_f_distribution from its "m" and "n" parameters. 84 * 85 * Requires: m > 0 and n > 0 86 */ fisher_f_distribution(RealType m_arg=RealType (1.0),RealType n_arg=RealType (1.0))87 explicit fisher_f_distribution(RealType m_arg = RealType(1.0), 88 RealType n_arg = RealType(1.0)) 89 : _impl_m(m_arg), _impl_n(n_arg) 90 {} 91 /** Constructs an @c fisher_f_distribution from its parameters. */ fisher_f_distribution(const param_type & parm)92 explicit fisher_f_distribution(const param_type& parm) 93 : _impl_m(parm.m()), _impl_n(parm.n()) 94 {} 95 96 /** 97 * Returns a random variate distributed according to the 98 * F distribution. 99 */ 100 template<class URNG> operator ()(URNG & urng)101 RealType operator()(URNG& urng) 102 { 103 return (_impl_m(urng) * n()) / (_impl_n(urng) * m()); 104 } 105 106 /** 107 * Returns a random variate distributed according to the 108 * F distribution with parameters specified by @c param. 109 */ 110 template<class URNG> operator ()(URNG & urng,const param_type & parm) const111 RealType operator()(URNG& urng, const param_type& parm) const 112 { 113 return fisher_f_distribution(parm)(urng); 114 } 115 116 /** Returns the "m" parameter of the distribution. */ m() const117 RealType m() const { return _impl_m.n(); } 118 /** Returns the "n" parameter of the distribution. */ n() const119 RealType n() const { return _impl_n.n(); } 120 121 /** Returns the smallest value that the distribution can produce. */ BOOST_PREVENT_MACRO_SUBSTITUTION() const122 RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return 0; } 123 /** Returns the largest value that the distribution can produce. */ BOOST_PREVENT_MACRO_SUBSTITUTION() const124 RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const 125 { return std::numeric_limits<RealType>::infinity(); } 126 127 /** Returns the parameters of the distribution. */ param() const128 param_type param() const { return param_type(m(), n()); } 129 /** Sets the parameters of the distribution. */ param(const param_type & parm)130 void param(const param_type& parm) 131 { 132 typedef chi_squared_distribution<RealType> impl_type; 133 typename impl_type::param_type m_param(parm.m()); 134 _impl_m.param(m_param); 135 typename impl_type::param_type n_param(parm.n()); 136 _impl_n.param(n_param); 137 } 138 139 /** 140 * Effects: Subsequent uses of the distribution do not depend 141 * on values produced by any engine prior to invoking reset. 142 */ reset()143 void reset() { } 144 145 /** Writes an @c fisher_f_distribution to a @c std::ostream. */ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os,fisher_f_distribution,fd)146 BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, fisher_f_distribution, fd) 147 { 148 os << fd.param(); 149 return os; 150 } 151 152 /** Reads an @c fisher_f_distribution from a @c std::istream. */ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is,fisher_f_distribution,fd)153 BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, fisher_f_distribution, fd) 154 { 155 param_type parm; 156 if(is >> parm) { 157 fd.param(parm); 158 } 159 return is; 160 } 161 162 /** 163 * Returns true if the two instances of @c fisher_f_distribution will 164 * return identical sequences of values given equal generators. 165 */ BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(fisher_f_distribution,lhs,rhs)166 BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(fisher_f_distribution, lhs, rhs) 167 { return lhs._impl_m == rhs._impl_m && lhs._impl_n == rhs._impl_n; } 168 169 /** 170 * Returns true if the two instances of @c fisher_f_distribution will 171 * return different sequences of values given equal generators. 172 */ 173 BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(fisher_f_distribution) 174 175 private: 176 chi_squared_distribution<RealType> _impl_m; 177 chi_squared_distribution<RealType> _impl_n; 178 }; 179 180 } // namespace random 181 } // namespace boost 182 183 #endif // BOOST_RANDOM_EXTREME_VALUE_DISTRIBUTION_HPP 184