annotate DEPENDENCIES/generic/include/boost/random/non_central_chi_squared_distribution.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents f46d142149f5
children
rev   line source
Chris@102 1 /* boost random/non_central_chi_squared_distribution.hpp header file
Chris@102 2 *
Chris@102 3 * Copyright Thijs van den Berg 2014
Chris@102 4 *
Chris@102 5 * Distributed under the Boost Software License, Version 1.0. (See
Chris@102 6 * accompanying file LICENSE_1_0.txt or copy at
Chris@102 7 * http://www.boost.org/LICENSE_1_0.txt)
Chris@102 8 *
Chris@102 9 * See http://www.boost.org for most recent version including documentation.
Chris@102 10 *
Chris@102 11 * $Id$
Chris@102 12 */
Chris@102 13
Chris@102 14 #ifndef BOOST_RANDOM_NON_CENTRAL_CHI_SQUARED_DISTRIBUTION_HPP
Chris@102 15 #define BOOST_RANDOM_NON_CENTRAL_CHI_SQUARED_DISTRIBUTION_HPP
Chris@102 16
Chris@102 17 #include <boost/config/no_tr1/cmath.hpp>
Chris@102 18 #include <iosfwd>
Chris@102 19 #include <istream>
Chris@102 20 #include <boost/limits.hpp>
Chris@102 21 #include <boost/random/detail/config.hpp>
Chris@102 22 #include <boost/random/detail/operators.hpp>
Chris@102 23 #include <boost/random/uniform_real_distribution.hpp>
Chris@102 24 #include <boost/random/normal_distribution.hpp>
Chris@102 25 #include <boost/random/chi_squared_distribution.hpp>
Chris@102 26 #include <boost/random/poisson_distribution.hpp>
Chris@102 27
Chris@102 28 namespace boost {
Chris@102 29 namespace random {
Chris@102 30
Chris@102 31 /**
Chris@102 32 * The noncentral chi-squared distribution is a real valued distribution with
Chris@102 33 * two parameter, @c k and @c lambda. The distribution produces values > 0.
Chris@102 34 *
Chris@102 35 * This is the distribution of the sum of squares of k Normal distributed
Chris@102 36 * variates each with variance one and \f$\lambda\f$ the sum of squares of the
Chris@102 37 * normal means.
Chris@102 38 *
Chris@102 39 * The distribution function is
Chris@102 40 * \f$\displaystyle P(x) = \frac{1}{2} e^{-(x+\lambda)/2} \left( \frac{x}{\lambda} \right)^{k/4-1/2} I_{k/2-1}( \sqrt{\lambda x} )\f$.
Chris@102 41 * where \f$\displaystyle I_\nu(z)\f$ is a modified Bessel function of the
Chris@102 42 * first kind.
Chris@102 43 *
Chris@102 44 * The algorithm is taken from
Chris@102 45 *
Chris@102 46 * @blockquote
Chris@102 47 * "Monte Carlo Methods in Financial Engineering", Paul Glasserman,
Chris@102 48 * 2003, XIII, 596 p, Stochastic Modelling and Applied Probability, Vol. 53,
Chris@102 49 * ISBN 978-0-387-21617-1, p 124, Fig. 3.5.
Chris@102 50 * @endblockquote
Chris@102 51 */
Chris@102 52 template <typename RealType = double>
Chris@102 53 class non_central_chi_squared_distribution {
Chris@102 54 public:
Chris@102 55 typedef RealType result_type;
Chris@102 56 typedef RealType input_type;
Chris@102 57
Chris@102 58 class param_type {
Chris@102 59 public:
Chris@102 60 typedef non_central_chi_squared_distribution distribution_type;
Chris@102 61
Chris@102 62 /**
Chris@102 63 * Constructs the parameters of a non_central_chi_squared_distribution.
Chris@102 64 * @c k and @c lambda are the parameter of the distribution.
Chris@102 65 *
Chris@102 66 * Requires: k > 0 && lambda > 0
Chris@102 67 */
Chris@102 68 explicit
Chris@102 69 param_type(RealType k_arg = RealType(1), RealType lambda_arg = RealType(1))
Chris@102 70 : _k(k_arg), _lambda(lambda_arg)
Chris@102 71 {
Chris@102 72 BOOST_ASSERT(k_arg > RealType(0));
Chris@102 73 BOOST_ASSERT(lambda_arg > RealType(0));
Chris@102 74 }
Chris@102 75
Chris@102 76 /** Returns the @c k parameter of the distribution */
Chris@102 77 RealType k() const { return _k; }
Chris@102 78
Chris@102 79 /** Returns the @c lambda parameter of the distribution */
Chris@102 80 RealType lambda() const { return _lambda; }
Chris@102 81
Chris@102 82 /** Writes the parameters of the distribution to a @c std::ostream. */
Chris@102 83 BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
Chris@102 84 {
Chris@102 85 os << parm._k << ' ' << parm._lambda;
Chris@102 86 return os;
Chris@102 87 }
Chris@102 88
Chris@102 89 /** Reads the parameters of the distribution from a @c std::istream. */
Chris@102 90 BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
Chris@102 91 {
Chris@102 92 is >> parm._k >> std::ws >> parm._lambda;
Chris@102 93 return is;
Chris@102 94 }
Chris@102 95
Chris@102 96 /** Returns true if the parameters have the same values. */
Chris@102 97 BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
Chris@102 98 { return lhs._k == rhs._k && lhs._lambda == rhs._lambda; }
Chris@102 99
Chris@102 100 /** Returns true if the parameters have different values. */
Chris@102 101 BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
Chris@102 102
Chris@102 103 private:
Chris@102 104 RealType _k;
Chris@102 105 RealType _lambda;
Chris@102 106 };
Chris@102 107
Chris@102 108 /**
Chris@102 109 * Construct a @c non_central_chi_squared_distribution object. @c k and
Chris@102 110 * @c lambda are the parameter of the distribution.
Chris@102 111 *
Chris@102 112 * Requires: k > 0 && lambda > 0
Chris@102 113 */
Chris@102 114 explicit
Chris@102 115 non_central_chi_squared_distribution(RealType k_arg = RealType(1), RealType lambda_arg = RealType(1))
Chris@102 116 : _param(k_arg, lambda_arg)
Chris@102 117 {
Chris@102 118 BOOST_ASSERT(k_arg > RealType(0));
Chris@102 119 BOOST_ASSERT(lambda_arg > RealType(0));
Chris@102 120 }
Chris@102 121
Chris@102 122 /**
Chris@102 123 * Construct a @c non_central_chi_squared_distribution object from the parameter.
Chris@102 124 */
Chris@102 125 explicit
Chris@102 126 non_central_chi_squared_distribution(const param_type& parm)
Chris@102 127 : _param( parm )
Chris@102 128 { }
Chris@102 129
Chris@102 130 /**
Chris@102 131 * Returns a random variate distributed according to the
Chris@102 132 * non central chi squared distribution specified by @c param.
Chris@102 133 */
Chris@102 134 template<typename URNG>
Chris@102 135 RealType operator()(URNG& eng, const param_type& parm) const
Chris@102 136 { return non_central_chi_squared_distribution(parm)(eng); }
Chris@102 137
Chris@102 138 /**
Chris@102 139 * Returns a random variate distributed according to the
Chris@102 140 * non central chi squared distribution.
Chris@102 141 */
Chris@102 142 template<typename URNG>
Chris@102 143 RealType operator()(URNG& eng)
Chris@102 144 {
Chris@102 145 using std::sqrt;
Chris@102 146 if (_param.k() > 1) {
Chris@102 147 boost::random::normal_distribution<RealType> n_dist;
Chris@102 148 boost::random::chi_squared_distribution<RealType> c_dist(_param.k() - RealType(1));
Chris@102 149 RealType _z = n_dist(eng);
Chris@102 150 RealType _x = c_dist(eng);
Chris@102 151 RealType term1 = _z + sqrt(_param.lambda());
Chris@102 152 return term1*term1 + _x;
Chris@102 153 }
Chris@102 154 else {
Chris@102 155 boost::random::poisson_distribution<> p_dist(_param.lambda()/RealType(2));
Chris@102 156 boost::random::poisson_distribution<>::result_type _p = p_dist(eng);
Chris@102 157 boost::random::chi_squared_distribution<RealType> c_dist(_param.k() + RealType(2)*_p);
Chris@102 158 return c_dist(eng);
Chris@102 159 }
Chris@102 160 }
Chris@102 161
Chris@102 162 /** Returns the @c k parameter of the distribution. */
Chris@102 163 RealType k() const { return _param.k(); }
Chris@102 164
Chris@102 165 /** Returns the @c lambda parameter of the distribution. */
Chris@102 166 RealType lambda() const { return _param.lambda(); }
Chris@102 167
Chris@102 168 /** Returns the parameters of the distribution. */
Chris@102 169 param_type param() const { return _param; }
Chris@102 170
Chris@102 171 /** Sets parameters of the distribution. */
Chris@102 172 void param(const param_type& parm) { _param = parm; }
Chris@102 173
Chris@102 174 /** Resets the distribution, so that subsequent uses does not depend on values already produced by it.*/
Chris@102 175 void reset() {}
Chris@102 176
Chris@102 177 /** Returns the smallest value that the distribution can produce. */
Chris@102 178 RealType min BOOST_PREVENT_MACRO_SUBSTITUTION() const
Chris@102 179 { return RealType(0); }
Chris@102 180
Chris@102 181 /** Returns the largest value that the distribution can produce. */
Chris@102 182 RealType max BOOST_PREVENT_MACRO_SUBSTITUTION() const
Chris@102 183 { return (std::numeric_limits<RealType>::infinity)(); }
Chris@102 184
Chris@102 185 /** Writes the parameters of the distribution to a @c std::ostream. */
Chris@102 186 BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, non_central_chi_squared_distribution, dist)
Chris@102 187 {
Chris@102 188 os << dist.param();
Chris@102 189 return os;
Chris@102 190 }
Chris@102 191
Chris@102 192 /** reads the parameters of the distribution from a @c std::istream. */
Chris@102 193 BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, non_central_chi_squared_distribution, dist)
Chris@102 194 {
Chris@102 195 param_type parm;
Chris@102 196 if(is >> parm) {
Chris@102 197 dist.param(parm);
Chris@102 198 }
Chris@102 199 return is;
Chris@102 200 }
Chris@102 201
Chris@102 202 /** Returns true if two distributions have the same parameters and produce
Chris@102 203 the same sequence of random numbers given equal generators.*/
Chris@102 204 BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(non_central_chi_squared_distribution, lhs, rhs)
Chris@102 205 { return lhs.param() == rhs.param(); }
Chris@102 206
Chris@102 207 /** Returns true if two distributions have different parameters and/or can produce
Chris@102 208 different sequences of random numbers given equal generators.*/
Chris@102 209 BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(non_central_chi_squared_distribution)
Chris@102 210
Chris@102 211 private:
Chris@102 212
Chris@102 213 /// @cond show_private
Chris@102 214 param_type _param;
Chris@102 215 /// @endcond
Chris@102 216 };
Chris@102 217
Chris@102 218 } // namespace random
Chris@102 219 } // namespace boost
Chris@102 220
Chris@102 221 #endif