Initial Commit
This commit is contained in:
@@ -0,0 +1,221 @@
|
||||
/* boost random/non_central_chi_squared_distribution.hpp header file
|
||||
*
|
||||
* Copyright Thijs van den Berg 2014
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0. (See
|
||||
* accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org for most recent version including documentation.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef BOOST_RANDOM_NON_CENTRAL_CHI_SQUARED_DISTRIBUTION_HPP
|
||||
#define BOOST_RANDOM_NON_CENTRAL_CHI_SQUARED_DISTRIBUTION_HPP
|
||||
|
||||
#include <boost/config/no_tr1/cmath.hpp>
|
||||
#include <iosfwd>
|
||||
#include <istream>
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/random/detail/config.hpp>
|
||||
#include <boost/random/detail/operators.hpp>
|
||||
#include <boost/random/uniform_real_distribution.hpp>
|
||||
#include <boost/random/normal_distribution.hpp>
|
||||
#include <boost/random/chi_squared_distribution.hpp>
|
||||
#include <boost/random/poisson_distribution.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace random {
|
||||
|
||||
/**
|
||||
* The noncentral chi-squared distribution is a real valued distribution with
|
||||
* two parameter, @c k and @c lambda. The distribution produces values > 0.
|
||||
*
|
||||
* This is the distribution of the sum of squares of k Normal distributed
|
||||
* variates each with variance one and \f$\lambda\f$ the sum of squares of the
|
||||
* normal means.
|
||||
*
|
||||
* The distribution function is
|
||||
* \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$.
|
||||
* where \f$\displaystyle I_\nu(z)\f$ is a modified Bessel function of the
|
||||
* first kind.
|
||||
*
|
||||
* The algorithm is taken from
|
||||
*
|
||||
* @blockquote
|
||||
* "Monte Carlo Methods in Financial Engineering", Paul Glasserman,
|
||||
* 2003, XIII, 596 p, Stochastic Modelling and Applied Probability, Vol. 53,
|
||||
* ISBN 978-0-387-21617-1, p 124, Fig. 3.5.
|
||||
* @endblockquote
|
||||
*/
|
||||
template <typename RealType = double>
|
||||
class non_central_chi_squared_distribution {
|
||||
public:
|
||||
typedef RealType result_type;
|
||||
typedef RealType input_type;
|
||||
|
||||
class param_type {
|
||||
public:
|
||||
typedef non_central_chi_squared_distribution distribution_type;
|
||||
|
||||
/**
|
||||
* Constructs the parameters of a non_central_chi_squared_distribution.
|
||||
* @c k and @c lambda are the parameter of the distribution.
|
||||
*
|
||||
* Requires: k > 0 && lambda > 0
|
||||
*/
|
||||
explicit
|
||||
param_type(RealType k_arg = RealType(1), RealType lambda_arg = RealType(1))
|
||||
: _k(k_arg), _lambda(lambda_arg)
|
||||
{
|
||||
BOOST_ASSERT(k_arg > RealType(0));
|
||||
BOOST_ASSERT(lambda_arg > RealType(0));
|
||||
}
|
||||
|
||||
/** Returns the @c k parameter of the distribution */
|
||||
RealType k() const { return _k; }
|
||||
|
||||
/** Returns the @c lambda parameter of the distribution */
|
||||
RealType lambda() const { return _lambda; }
|
||||
|
||||
/** Writes the parameters of the distribution to a @c std::ostream. */
|
||||
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
|
||||
{
|
||||
os << parm._k << ' ' << parm._lambda;
|
||||
return os;
|
||||
}
|
||||
|
||||
/** Reads the parameters of the distribution from a @c std::istream. */
|
||||
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
|
||||
{
|
||||
is >> parm._k >> std::ws >> parm._lambda;
|
||||
return is;
|
||||
}
|
||||
|
||||
/** Returns true if the parameters have the same values. */
|
||||
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
|
||||
{ return lhs._k == rhs._k && lhs._lambda == rhs._lambda; }
|
||||
|
||||
/** Returns true if the parameters have different values. */
|
||||
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
|
||||
|
||||
private:
|
||||
RealType _k;
|
||||
RealType _lambda;
|
||||
};
|
||||
|
||||
/**
|
||||
* Construct a @c non_central_chi_squared_distribution object. @c k and
|
||||
* @c lambda are the parameter of the distribution.
|
||||
*
|
||||
* Requires: k > 0 && lambda > 0
|
||||
*/
|
||||
explicit
|
||||
non_central_chi_squared_distribution(RealType k_arg = RealType(1), RealType lambda_arg = RealType(1))
|
||||
: _param(k_arg, lambda_arg)
|
||||
{
|
||||
BOOST_ASSERT(k_arg > RealType(0));
|
||||
BOOST_ASSERT(lambda_arg > RealType(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a @c non_central_chi_squared_distribution object from the parameter.
|
||||
*/
|
||||
explicit
|
||||
non_central_chi_squared_distribution(const param_type& parm)
|
||||
: _param( parm )
|
||||
{ }
|
||||
|
||||
/**
|
||||
* Returns a random variate distributed according to the
|
||||
* non central chi squared distribution specified by @c param.
|
||||
*/
|
||||
template<typename URNG>
|
||||
RealType operator()(URNG& eng, const param_type& parm) const
|
||||
{ return non_central_chi_squared_distribution(parm)(eng); }
|
||||
|
||||
/**
|
||||
* Returns a random variate distributed according to the
|
||||
* non central chi squared distribution.
|
||||
*/
|
||||
template<typename URNG>
|
||||
RealType operator()(URNG& eng)
|
||||
{
|
||||
using std::sqrt;
|
||||
if (_param.k() > 1) {
|
||||
boost::random::normal_distribution<RealType> n_dist;
|
||||
boost::random::chi_squared_distribution<RealType> c_dist(_param.k() - RealType(1));
|
||||
RealType _z = n_dist(eng);
|
||||
RealType _x = c_dist(eng);
|
||||
RealType term1 = _z + sqrt(_param.lambda());
|
||||
return term1*term1 + _x;
|
||||
}
|
||||
else {
|
||||
boost::random::poisson_distribution<> p_dist(_param.lambda()/RealType(2));
|
||||
boost::random::poisson_distribution<>::result_type _p = p_dist(eng);
|
||||
boost::random::chi_squared_distribution<RealType> c_dist(_param.k() + RealType(2)*_p);
|
||||
return c_dist(eng);
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the @c k parameter of the distribution. */
|
||||
RealType k() const { return _param.k(); }
|
||||
|
||||
/** Returns the @c lambda parameter of the distribution. */
|
||||
RealType lambda() const { return _param.lambda(); }
|
||||
|
||||
/** Returns the parameters of the distribution. */
|
||||
param_type param() const { return _param; }
|
||||
|
||||
/** Sets parameters of the distribution. */
|
||||
void param(const param_type& parm) { _param = parm; }
|
||||
|
||||
/** Resets the distribution, so that subsequent uses does not depend on values already produced by it.*/
|
||||
void reset() {}
|
||||
|
||||
/** Returns the smallest value that the distribution can produce. */
|
||||
RealType min BOOST_PREVENT_MACRO_SUBSTITUTION() const
|
||||
{ return RealType(0); }
|
||||
|
||||
/** Returns the largest value that the distribution can produce. */
|
||||
RealType max BOOST_PREVENT_MACRO_SUBSTITUTION() const
|
||||
{ return (std::numeric_limits<RealType>::infinity)(); }
|
||||
|
||||
/** Writes the parameters of the distribution to a @c std::ostream. */
|
||||
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, non_central_chi_squared_distribution, dist)
|
||||
{
|
||||
os << dist.param();
|
||||
return os;
|
||||
}
|
||||
|
||||
/** reads the parameters of the distribution from a @c std::istream. */
|
||||
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, non_central_chi_squared_distribution, dist)
|
||||
{
|
||||
param_type parm;
|
||||
if(is >> parm) {
|
||||
dist.param(parm);
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
/** Returns true if two distributions have the same parameters and produce
|
||||
the same sequence of random numbers given equal generators.*/
|
||||
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(non_central_chi_squared_distribution, lhs, rhs)
|
||||
{ return lhs.param() == rhs.param(); }
|
||||
|
||||
/** Returns true if two distributions have different parameters and/or can produce
|
||||
different sequences of random numbers given equal generators.*/
|
||||
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(non_central_chi_squared_distribution)
|
||||
|
||||
private:
|
||||
|
||||
/// @cond show_private
|
||||
param_type _param;
|
||||
/// @endcond
|
||||
};
|
||||
|
||||
} // namespace random
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user