Added boost header
This commit is contained in:
325
test/external/boost/math/distributions/bernoulli.hpp
vendored
Normal file
325
test/external/boost/math/distributions/bernoulli.hpp
vendored
Normal file
@@ -0,0 +1,325 @@
|
||||
// boost\math\distributions\bernoulli.hpp
|
||||
|
||||
// Copyright John Maddock 2006.
|
||||
// Copyright Paul A. Bristow 2007.
|
||||
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
// http://en.wikipedia.org/wiki/bernoulli_distribution
|
||||
// http://mathworld.wolfram.com/BernoulliDistribution.html
|
||||
|
||||
// bernoulli distribution is the discrete probability distribution of
|
||||
// the number (k) of successes, in a single Bernoulli trials.
|
||||
// It is a version of the binomial distribution when n = 1.
|
||||
|
||||
// But note that the bernoulli distribution
|
||||
// (like others including the poisson, binomial & negative binomial)
|
||||
// is strictly defined as a discrete function: only integral values of k are envisaged.
|
||||
// However because of the method of calculation using a continuous gamma function,
|
||||
// it is convenient to treat it as if a continous function,
|
||||
// and permit non-integral values of k.
|
||||
// To enforce the strict mathematical model, users should use floor or ceil functions
|
||||
// on k outside this function to ensure that k is integral.
|
||||
|
||||
#ifndef BOOST_MATH_SPECIAL_BERNOULLI_HPP
|
||||
#define BOOST_MATH_SPECIAL_BERNOULLI_HPP
|
||||
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#include <boost/math/tools/config.hpp>
|
||||
#include <boost/math/distributions/complement.hpp> // complements
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp> // error checks
|
||||
#include <boost/math/special_functions/fpclassify.hpp> // isnan.
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace math
|
||||
{
|
||||
namespace bernoulli_detail
|
||||
{
|
||||
// Common error checking routines for bernoulli distribution functions:
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_success_fraction(const char* function, const RealType& p, RealType* result, const Policy& /* pol */)
|
||||
{
|
||||
if(!(boost::math::isfinite)(p) || (p < 0) || (p > 1))
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Success fraction argument is %1%, but must be >= 0 and <= 1 !", p, Policy());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_dist(const char* function, const RealType& p, RealType* result, const Policy& /* pol */)
|
||||
{
|
||||
return check_success_fraction(function, p, result, Policy());
|
||||
}
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_dist_and_k(const char* function, const RealType& p, RealType k, RealType* result, const Policy& pol)
|
||||
{
|
||||
if(check_dist(function, p, result, Policy()) == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(!(boost::math::isfinite)(k) || !((k == 0) || (k == 1)))
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Number of successes argument is %1%, but must be 0 or 1 !", k, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_dist_and_prob(const char* function, RealType p, RealType prob, RealType* result, const Policy& /* pol */)
|
||||
{
|
||||
if(check_dist(function, p, result, Policy()) && detail::check_probability(function, prob, result, Policy()) == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} // namespace bernoulli_detail
|
||||
|
||||
|
||||
template <class RealType = double, class Policy = policies::policy<> >
|
||||
class bernoulli_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
|
||||
bernoulli_distribution(RealType p = 0.5) : m_p(p)
|
||||
{ // Default probability = half suits 'fair' coin tossing
|
||||
// where probability of heads == probability of tails.
|
||||
RealType result; // of checks.
|
||||
bernoulli_detail::check_dist(
|
||||
"boost::math::bernoulli_distribution<%1%>::bernoulli_distribution",
|
||||
m_p,
|
||||
&result, Policy());
|
||||
} // bernoulli_distribution constructor.
|
||||
|
||||
RealType success_fraction() const
|
||||
{ // Probability.
|
||||
return m_p;
|
||||
}
|
||||
|
||||
private:
|
||||
RealType m_p; // success_fraction
|
||||
}; // template <class RealType> class bernoulli_distribution
|
||||
|
||||
typedef bernoulli_distribution<double> bernoulli;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const bernoulli_distribution<RealType, Policy>& /* dist */)
|
||||
{ // Range of permissible values for random variable k = {0, 1}.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(static_cast<RealType>(0), static_cast<RealType>(1));
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> support(const bernoulli_distribution<RealType, Policy>& /* dist */)
|
||||
{ // Range of supported values for random variable k = {0, 1}.
|
||||
// This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
|
||||
return std::pair<RealType, RealType>(static_cast<RealType>(0), static_cast<RealType>(1));
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mean(const bernoulli_distribution<RealType, Policy>& dist)
|
||||
{ // Mean of bernoulli distribution = p (n = 1).
|
||||
return dist.success_fraction();
|
||||
} // mean
|
||||
|
||||
// Rely on dereived_accessors quantile(half)
|
||||
//template <class RealType>
|
||||
//inline RealType median(const bernoulli_distribution<RealType, Policy>& dist)
|
||||
//{ // Median of bernoulli distribution is not defined.
|
||||
// return tools::domain_error<RealType>(BOOST_CURRENT_FUNCTION, "Median is not implemented, result is %1%!", std::numeric_limits<RealType>::quiet_NaN());
|
||||
//} // median
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType variance(const bernoulli_distribution<RealType, Policy>& dist)
|
||||
{ // Variance of bernoulli distribution =p * q.
|
||||
return dist.success_fraction() * (1 - dist.success_fraction());
|
||||
} // variance
|
||||
|
||||
template <class RealType, class Policy>
|
||||
RealType pdf(const bernoulli_distribution<RealType, Policy>& dist, const RealType& k)
|
||||
{ // Probability Density/Mass Function.
|
||||
BOOST_FPU_EXCEPTION_GUARD
|
||||
// Error check:
|
||||
RealType result = 0; // of checks.
|
||||
if(false == bernoulli_detail::check_dist_and_k(
|
||||
"boost::math::pdf(bernoulli_distribution<%1%>, %1%)",
|
||||
dist.success_fraction(), // 0 to 1
|
||||
k, // 0 or 1
|
||||
&result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
// Assume k is integral.
|
||||
if (k == 0)
|
||||
{
|
||||
return 1 - dist.success_fraction(); // 1 - p
|
||||
}
|
||||
else // k == 1
|
||||
{
|
||||
return dist.success_fraction(); // p
|
||||
}
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const bernoulli_distribution<RealType, Policy>& dist, const RealType& k)
|
||||
{ // Cumulative Distribution Function Bernoulli.
|
||||
RealType p = dist.success_fraction();
|
||||
// Error check:
|
||||
RealType result = 0;
|
||||
if(false == bernoulli_detail::check_dist_and_k(
|
||||
"boost::math::cdf(bernoulli_distribution<%1%>, %1%)",
|
||||
p,
|
||||
k,
|
||||
&result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if (k == 0)
|
||||
{
|
||||
return 1 - p;
|
||||
}
|
||||
else
|
||||
{ // k == 1
|
||||
return 1;
|
||||
}
|
||||
} // bernoulli cdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const complemented2_type<bernoulli_distribution<RealType, Policy>, RealType>& c)
|
||||
{ // Complemented Cumulative Distribution Function bernoulli.
|
||||
RealType const& k = c.param;
|
||||
bernoulli_distribution<RealType, Policy> const& dist = c.dist;
|
||||
RealType p = dist.success_fraction();
|
||||
// Error checks:
|
||||
RealType result = 0;
|
||||
if(false == bernoulli_detail::check_dist_and_k(
|
||||
"boost::math::cdf(bernoulli_distribution<%1%>, %1%)",
|
||||
p,
|
||||
k,
|
||||
&result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if (k == 0)
|
||||
{
|
||||
return p;
|
||||
}
|
||||
else
|
||||
{ // k == 1
|
||||
return 0;
|
||||
}
|
||||
} // bernoulli cdf complement
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const bernoulli_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
{ // Quantile or Percent Point Bernoulli function.
|
||||
// Return the number of expected successes k either 0 or 1.
|
||||
// for a given probability p.
|
||||
|
||||
RealType result = 0; // of error checks:
|
||||
if(false == bernoulli_detail::check_dist_and_prob(
|
||||
"boost::math::quantile(bernoulli_distribution<%1%>, %1%)",
|
||||
dist.success_fraction(),
|
||||
p,
|
||||
&result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if (p <= (1 - dist.success_fraction()))
|
||||
{ // p <= pdf(dist, 0) == cdf(dist, 0)
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
} // quantile
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const complemented2_type<bernoulli_distribution<RealType, Policy>, RealType>& c)
|
||||
{ // Quantile or Percent Point bernoulli function.
|
||||
// Return the number of expected successes k for a given
|
||||
// complement of the probability q.
|
||||
//
|
||||
// Error checks:
|
||||
RealType q = c.param;
|
||||
const bernoulli_distribution<RealType, Policy>& dist = c.dist;
|
||||
RealType result = 0;
|
||||
if(false == bernoulli_detail::check_dist_and_prob(
|
||||
"boost::math::quantile(bernoulli_distribution<%1%>, %1%)",
|
||||
dist.success_fraction(),
|
||||
q,
|
||||
&result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (q <= 1 - dist.success_fraction())
|
||||
{ // // q <= cdf(complement(dist, 0)) == pdf(dist, 0)
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
} // quantile complemented.
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mode(const bernoulli_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
return static_cast<RealType>((dist.success_fraction() <= 0.5) ? 0 : 1); // p = 0.5 can be 0 or 1
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType skewness(const bernoulli_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING; // Aid ADL for sqrt.
|
||||
RealType p = dist.success_fraction();
|
||||
return (1 - 2 * p) / sqrt(p * (1 - p));
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis_excess(const bernoulli_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType p = dist.success_fraction();
|
||||
// Note Wolfram says this is kurtosis in text, but gamma2 is the kurtosis excess,
|
||||
// and Wikipedia also says this is the kurtosis excess formula.
|
||||
// return (6 * p * p - 6 * p + 1) / (p * (1 - p));
|
||||
// But Wolfram kurtosis article gives this simpler formula for kurtosis excess:
|
||||
return 1 / (1 - p) + 1/p -6;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis(const bernoulli_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType p = dist.success_fraction();
|
||||
return 1 / (1 - p) + 1/p -6 + 3;
|
||||
// Simpler than:
|
||||
// return (6 * p * p - 6 * p + 1) / (p * (1 - p)) + 3;
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
// This include must be at the end, *after* the accessors
|
||||
// for this distribution have been defined, in order to
|
||||
// keep compilers that support two-phase lookup happy.
|
||||
#include <boost/math/distributions/detail/derived_accessors.hpp>
|
||||
|
||||
#endif // BOOST_MATH_SPECIAL_BERNOULLI_HPP
|
||||
|
||||
|
||||
|
||||
544
test/external/boost/math/distributions/beta.hpp
vendored
Normal file
544
test/external/boost/math/distributions/beta.hpp
vendored
Normal file
@@ -0,0 +1,544 @@
|
||||
// boost\math\distributions\beta.hpp
|
||||
|
||||
// Copyright John Maddock 2006.
|
||||
// Copyright Paul A. Bristow 2006.
|
||||
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
// http://en.wikipedia.org/wiki/Beta_distribution
|
||||
// http://www.itl.nist.gov/div898/handbook/eda/section3/eda366h.htm
|
||||
// http://mathworld.wolfram.com/BetaDistribution.html
|
||||
|
||||
// The Beta Distribution is a continuous probability distribution.
|
||||
// The beta distribution is used to model events which are constrained to take place
|
||||
// within an interval defined by maxima and minima,
|
||||
// so is used extensively in PERT and other project management systems
|
||||
// to describe the time to completion.
|
||||
// The cdf of the beta distribution is used as a convenient way
|
||||
// of obtaining the sum over a set of binomial outcomes.
|
||||
// The beta distribution is also used in Bayesian statistics.
|
||||
|
||||
#ifndef BOOST_MATH_DIST_BETA_HPP
|
||||
#define BOOST_MATH_DIST_BETA_HPP
|
||||
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#include <boost/math/special_functions/beta.hpp> // for beta.
|
||||
#include <boost/math/distributions/complement.hpp> // complements.
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp> // error checks
|
||||
#include <boost/math/special_functions/fpclassify.hpp> // isnan.
|
||||
#include <boost/math/tools/roots.hpp> // for root finding.
|
||||
|
||||
#if defined (BOOST_MSVC)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4702) // unreachable code
|
||||
// in domain_error_imp in error_handling
|
||||
#endif
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace math
|
||||
{
|
||||
namespace beta_detail
|
||||
{
|
||||
// Common error checking routines for beta distribution functions:
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_alpha(const char* function, const RealType& alpha, RealType* result, const Policy& pol)
|
||||
{
|
||||
if(!(boost::math::isfinite)(alpha) || (alpha <= 0))
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Alpha argument is %1%, but must be > 0 !", alpha, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // bool check_alpha
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_beta(const char* function, const RealType& beta, RealType* result, const Policy& pol)
|
||||
{
|
||||
if(!(boost::math::isfinite)(beta) || (beta <= 0))
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Beta argument is %1%, but must be > 0 !", beta, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // bool check_beta
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_prob(const char* function, const RealType& p, RealType* result, const Policy& pol)
|
||||
{
|
||||
if((p < 0) || (p > 1) || !(boost::math::isfinite)(p))
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Probability argument is %1%, but must be >= 0 and <= 1 !", p, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // bool check_prob
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_x(const char* function, const RealType& x, RealType* result, const Policy& pol)
|
||||
{
|
||||
if(!(boost::math::isfinite)(x) || (x < 0) || (x > 1))
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"x argument is %1%, but must be >= 0 and <= 1 !", x, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // bool check_x
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_dist(const char* function, const RealType& alpha, const RealType& beta, RealType* result, const Policy& pol)
|
||||
{ // Check both alpha and beta.
|
||||
return check_alpha(function, alpha, result, pol)
|
||||
&& check_beta(function, beta, result, pol);
|
||||
} // bool check_dist
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_dist_and_x(const char* function, const RealType& alpha, const RealType& beta, RealType x, RealType* result, const Policy& pol)
|
||||
{
|
||||
return check_dist(function, alpha, beta, result, pol)
|
||||
&& beta_detail::check_x(function, x, result, pol);
|
||||
} // bool check_dist_and_x
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_dist_and_prob(const char* function, const RealType& alpha, const RealType& beta, RealType p, RealType* result, const Policy& pol)
|
||||
{
|
||||
return check_dist(function, alpha, beta, result, pol)
|
||||
&& check_prob(function, p, result, pol);
|
||||
} // bool check_dist_and_prob
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_mean(const char* function, const RealType& mean, RealType* result, const Policy& pol)
|
||||
{
|
||||
if(!(boost::math::isfinite)(mean) || (mean <= 0))
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"mean argument is %1%, but must be > 0 !", mean, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // bool check_mean
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_variance(const char* function, const RealType& variance, RealType* result, const Policy& pol)
|
||||
{
|
||||
if(!(boost::math::isfinite)(variance) || (variance <= 0))
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"variance argument is %1%, but must be > 0 !", variance, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // bool check_variance
|
||||
} // namespace beta_detail
|
||||
|
||||
// typedef beta_distribution<double> beta;
|
||||
// is deliberately NOT included to avoid a name clash with the beta function.
|
||||
// Use beta_distribution<> mybeta(...) to construct type double.
|
||||
|
||||
template <class RealType = double, class Policy = policies::policy<> >
|
||||
class beta_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
|
||||
beta_distribution(RealType alpha = 1, RealType beta = 1) : m_alpha(alpha), m_beta(beta)
|
||||
{
|
||||
RealType result;
|
||||
beta_detail::check_dist(
|
||||
"boost::math::beta_distribution<%1%>::beta_distribution",
|
||||
m_alpha,
|
||||
m_beta,
|
||||
&result, Policy());
|
||||
} // beta_distribution constructor.
|
||||
// Accessor functions:
|
||||
RealType alpha() const
|
||||
{
|
||||
return m_alpha;
|
||||
}
|
||||
RealType beta() const
|
||||
{ // .
|
||||
return m_beta;
|
||||
}
|
||||
|
||||
// Estimation of the alpha & beta parameters.
|
||||
// http://en.wikipedia.org/wiki/Beta_distribution
|
||||
// gives formulae in section on parameter estimation.
|
||||
// Also NIST EDA page 3 & 4 give the same.
|
||||
// http://www.itl.nist.gov/div898/handbook/eda/section3/eda366h.htm
|
||||
// http://www.epi.ucdavis.edu/diagnostictests/betabuster.html
|
||||
|
||||
static RealType find_alpha(
|
||||
RealType mean, // Expected value of mean.
|
||||
RealType variance) // Expected value of variance.
|
||||
{
|
||||
static const char* function = "boost::math::beta_distribution<%1%>::find_alpha";
|
||||
RealType result = 0; // of error checks.
|
||||
if(false ==
|
||||
beta_detail::check_mean(
|
||||
function, mean, &result, Policy())
|
||||
&&
|
||||
beta_detail::check_variance(
|
||||
function, variance, &result, Policy())
|
||||
)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return mean * (( (mean * (1 - mean)) / variance)- 1);
|
||||
} // RealType find_alpha
|
||||
|
||||
static RealType find_beta(
|
||||
RealType mean, // Expected value of mean.
|
||||
RealType variance) // Expected value of variance.
|
||||
{
|
||||
static const char* function = "boost::math::beta_distribution<%1%>::find_beta";
|
||||
RealType result = 0; // of error checks.
|
||||
if(false ==
|
||||
beta_detail::check_mean(
|
||||
function, mean, &result, Policy())
|
||||
&&
|
||||
beta_detail::check_variance(
|
||||
function, variance, &result, Policy())
|
||||
)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return (1 - mean) * (((mean * (1 - mean)) /variance)-1);
|
||||
} // RealType find_beta
|
||||
|
||||
// Estimate alpha & beta from either alpha or beta, and x and probability.
|
||||
// Uses for these parameter estimators are unclear.
|
||||
|
||||
static RealType find_alpha(
|
||||
RealType beta, // from beta.
|
||||
RealType x, // x.
|
||||
RealType probability) // cdf
|
||||
{
|
||||
static const char* function = "boost::math::beta_distribution<%1%>::find_alpha";
|
||||
RealType result = 0; // of error checks.
|
||||
if(false ==
|
||||
beta_detail::check_prob(
|
||||
function, probability, &result, Policy())
|
||||
&&
|
||||
beta_detail::check_beta(
|
||||
function, beta, &result, Policy())
|
||||
&&
|
||||
beta_detail::check_x(
|
||||
function, x, &result, Policy())
|
||||
)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return ibeta_inva(beta, x, probability, Policy());
|
||||
} // RealType find_alpha(beta, a, probability)
|
||||
|
||||
static RealType find_beta(
|
||||
// ibeta_invb(T b, T x, T p); (alpha, x, cdf,)
|
||||
RealType alpha, // alpha.
|
||||
RealType x, // probability x.
|
||||
RealType probability) // probability cdf.
|
||||
{
|
||||
static const char* function = "boost::math::beta_distribution<%1%>::find_beta";
|
||||
RealType result = 0; // of error checks.
|
||||
if(false ==
|
||||
beta_detail::check_prob(
|
||||
function, probability, &result, Policy())
|
||||
&&
|
||||
beta_detail::check_alpha(
|
||||
function, alpha, &result, Policy())
|
||||
&&
|
||||
beta_detail::check_x(
|
||||
function, x, &result, Policy())
|
||||
)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return ibeta_invb(alpha, x, probability, Policy());
|
||||
} // RealType find_beta(alpha, x, probability)
|
||||
|
||||
private:
|
||||
RealType m_alpha; // Two parameters of the beta distribution.
|
||||
RealType m_beta;
|
||||
}; // template <class RealType, class Policy> class beta_distribution
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const beta_distribution<RealType, Policy>& /* dist */)
|
||||
{ // Range of permissible values for random variable x.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(static_cast<RealType>(0), static_cast<RealType>(1));
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> support(const beta_distribution<RealType, Policy>& /* dist */)
|
||||
{ // Range of supported values for random variable x.
|
||||
// This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
|
||||
return std::pair<RealType, RealType>(static_cast<RealType>(0), static_cast<RealType>(1));
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mean(const beta_distribution<RealType, Policy>& dist)
|
||||
{ // Mean of beta distribution = np.
|
||||
return dist.alpha() / (dist.alpha() + dist.beta());
|
||||
} // mean
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType variance(const beta_distribution<RealType, Policy>& dist)
|
||||
{ // Variance of beta distribution = np(1-p).
|
||||
RealType a = dist.alpha();
|
||||
RealType b = dist.beta();
|
||||
return (a * b) / ((a + b ) * (a + b) * (a + b + 1));
|
||||
} // variance
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mode(const beta_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
static const char* function = "boost::math::mode(beta_distribution<%1%> const&)";
|
||||
|
||||
RealType result;
|
||||
if ((dist.alpha() <= 1))
|
||||
{
|
||||
result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"mode undefined for alpha = %1%, must be > 1!", dist.alpha(), Policy());
|
||||
return result;
|
||||
}
|
||||
|
||||
if ((dist.beta() <= 1))
|
||||
{
|
||||
result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"mode undefined for beta = %1%, must be > 1!", dist.beta(), Policy());
|
||||
return result;
|
||||
}
|
||||
RealType a = dist.alpha();
|
||||
RealType b = dist.beta();
|
||||
return (a-1) / (a + b - 2);
|
||||
} // mode
|
||||
|
||||
//template <class RealType, class Policy>
|
||||
//inline RealType median(const beta_distribution<RealType, Policy>& dist)
|
||||
//{ // Median of beta distribution is not defined.
|
||||
// return tools::domain_error<RealType>(function, "Median is not implemented, result is %1%!", std::numeric_limits<RealType>::quiet_NaN());
|
||||
//} // median
|
||||
|
||||
//But WILL be provided by the derived accessor as quantile(0.5).
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType skewness(const beta_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING // ADL of std functions.
|
||||
RealType a = dist.alpha();
|
||||
RealType b = dist.beta();
|
||||
return (2 * (b-a) * sqrt(a + b + 1)) / ((a + b + 2) * sqrt(a * b));
|
||||
} // skewness
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis_excess(const beta_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType a = dist.alpha();
|
||||
RealType b = dist.beta();
|
||||
RealType a_2 = a * a;
|
||||
RealType n = 6 * (a_2 * a - a_2 * (2 * b - 1) + b * b * (b + 1) - 2 * a * b * (b + 2));
|
||||
RealType d = a * b * (a + b + 2) * (a + b + 3);
|
||||
return n / d;
|
||||
} // kurtosis_excess
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis(const beta_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
return 3 + kurtosis_excess(dist);
|
||||
} // kurtosis
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType pdf(const beta_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{ // Probability Density/Mass Function.
|
||||
BOOST_FPU_EXCEPTION_GUARD
|
||||
|
||||
static const char* function = "boost::math::pdf(beta_distribution<%1%> const&, %1%)";
|
||||
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
RealType a = dist.alpha();
|
||||
RealType b = dist.beta();
|
||||
|
||||
// Argument checks:
|
||||
RealType result = 0;
|
||||
if(false == beta_detail::check_dist_and_x(
|
||||
function,
|
||||
a, b, x,
|
||||
&result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
using boost::math::beta;
|
||||
return ibeta_derivative(a, b, x, Policy());
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const beta_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{ // Cumulative Distribution Function beta.
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::cdf(beta_distribution<%1%> const&, %1%)";
|
||||
|
||||
RealType a = dist.alpha();
|
||||
RealType b = dist.beta();
|
||||
|
||||
// Argument checks:
|
||||
RealType result = 0;
|
||||
if(false == beta_detail::check_dist_and_x(
|
||||
function,
|
||||
a, b, x,
|
||||
&result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
// Special cases:
|
||||
if (x == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (x == 1)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return ibeta(a, b, x, Policy());
|
||||
} // beta cdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const complemented2_type<beta_distribution<RealType, Policy>, RealType>& c)
|
||||
{ // Complemented Cumulative Distribution Function beta.
|
||||
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::cdf(beta_distribution<%1%> const&, %1%)";
|
||||
|
||||
RealType const& x = c.param;
|
||||
beta_distribution<RealType, Policy> const& dist = c.dist;
|
||||
RealType a = dist.alpha();
|
||||
RealType b = dist.beta();
|
||||
|
||||
// Argument checks:
|
||||
RealType result = 0;
|
||||
if(false == beta_detail::check_dist_and_x(
|
||||
function,
|
||||
a, b, x,
|
||||
&result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if (x == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if (x == 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
// Calculate cdf beta using the incomplete beta function.
|
||||
// Use of ibeta here prevents cancellation errors in calculating
|
||||
// 1 - x if x is very small, perhaps smaller than machine epsilon.
|
||||
return ibetac(a, b, x, Policy());
|
||||
} // beta cdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const beta_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
{ // Quantile or Percent Point beta function or
|
||||
// Inverse Cumulative probability distribution function CDF.
|
||||
// Return x (0 <= x <= 1),
|
||||
// for a given probability p (0 <= p <= 1).
|
||||
// These functions take a probability as an argument
|
||||
// and return a value such that the probability that a random variable x
|
||||
// will be less than or equal to that value
|
||||
// is whatever probability you supplied as an argument.
|
||||
|
||||
static const char* function = "boost::math::quantile(beta_distribution<%1%> const&, %1%)";
|
||||
|
||||
RealType result = 0; // of argument checks:
|
||||
RealType a = dist.alpha();
|
||||
RealType b = dist.beta();
|
||||
if(false == beta_detail::check_dist_and_prob(
|
||||
function,
|
||||
a, b, p,
|
||||
&result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
// Special cases:
|
||||
if (p == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (p == 1)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return ibeta_inv(a, b, p, static_cast<RealType*>(0), Policy());
|
||||
} // quantile
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const complemented2_type<beta_distribution<RealType, Policy>, RealType>& c)
|
||||
{ // Complement Quantile or Percent Point beta function .
|
||||
// Return the number of expected x for a given
|
||||
// complement of the probability q.
|
||||
|
||||
static const char* function = "boost::math::quantile(beta_distribution<%1%> const&, %1%)";
|
||||
|
||||
//
|
||||
// Error checks:
|
||||
RealType q = c.param;
|
||||
const beta_distribution<RealType, Policy>& dist = c.dist;
|
||||
RealType result = 0;
|
||||
RealType a = dist.alpha();
|
||||
RealType b = dist.beta();
|
||||
if(false == beta_detail::check_dist_and_prob(
|
||||
function,
|
||||
a,
|
||||
b,
|
||||
q,
|
||||
&result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
// Special cases:
|
||||
if(q == 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if(q == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return ibetac_inv(a, b, q, static_cast<RealType*>(0), Policy());
|
||||
} // Quantile Complement
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
// This include must be at the end, *after* the accessors
|
||||
// for this distribution have been defined, in order to
|
||||
// keep compilers that support two-phase lookup happy.
|
||||
#include <boost/math/distributions/detail/derived_accessors.hpp>
|
||||
|
||||
#if defined (BOOST_MSVC)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // BOOST_MATH_DIST_BETA_HPP
|
||||
|
||||
|
||||
724
test/external/boost/math/distributions/binomial.hpp
vendored
Normal file
724
test/external/boost/math/distributions/binomial.hpp
vendored
Normal file
@@ -0,0 +1,724 @@
|
||||
// boost\math\distributions\binomial.hpp
|
||||
|
||||
// Copyright John Maddock 2006.
|
||||
// Copyright Paul A. Bristow 2007.
|
||||
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
// http://en.wikipedia.org/wiki/binomial_distribution
|
||||
|
||||
// Binomial distribution is the discrete probability distribution of
|
||||
// the number (k) of successes, in a sequence of
|
||||
// n independent (yes or no, success or failure) Bernoulli trials.
|
||||
|
||||
// It expresses the probability of a number of events occurring in a fixed time
|
||||
// if these events occur with a known average rate (probability of success),
|
||||
// and are independent of the time since the last event.
|
||||
|
||||
// The number of cars that pass through a certain point on a road during a given period of time.
|
||||
// The number of spelling mistakes a secretary makes while typing a single page.
|
||||
// The number of phone calls at a call center per minute.
|
||||
// The number of times a web server is accessed per minute.
|
||||
// The number of light bulbs that burn out in a certain amount of time.
|
||||
// The number of roadkill found per unit length of road
|
||||
|
||||
// http://en.wikipedia.org/wiki/binomial_distribution
|
||||
|
||||
// Given a sample of N measured values k[i],
|
||||
// we wish to estimate the value of the parameter x (mean)
|
||||
// of the binomial population from which the sample was drawn.
|
||||
// To calculate the maximum likelihood value = 1/N sum i = 1 to N of k[i]
|
||||
|
||||
// Also may want a function for EXACTLY k.
|
||||
|
||||
// And probability that there are EXACTLY k occurrences is
|
||||
// exp(-x) * pow(x, k) / factorial(k)
|
||||
// where x is expected occurrences (mean) during the given interval.
|
||||
// For example, if events occur, on average, every 4 min,
|
||||
// and we are interested in number of events occurring in 10 min,
|
||||
// then x = 10/4 = 2.5
|
||||
|
||||
// http://www.itl.nist.gov/div898/handbook/eda/section3/eda366i.htm
|
||||
|
||||
// The binomial distribution is used when there are
|
||||
// exactly two mutually exclusive outcomes of a trial.
|
||||
// These outcomes are appropriately labeled "success" and "failure".
|
||||
// The binomial distribution is used to obtain
|
||||
// the probability of observing x successes in N trials,
|
||||
// with the probability of success on a single trial denoted by p.
|
||||
// The binomial distribution assumes that p is fixed for all trials.
|
||||
|
||||
// P(x, p, n) = n!/(x! * (n-x)!) * p^x * (1-p)^(n-x)
|
||||
|
||||
// http://mathworld.wolfram.com/BinomialCoefficient.html
|
||||
|
||||
// The binomial coefficient (n; k) is the number of ways of picking
|
||||
// k unordered outcomes from n possibilities,
|
||||
// also known as a combination or combinatorial number.
|
||||
// The symbols _nC_k and (n; k) are used to denote a binomial coefficient,
|
||||
// and are sometimes read as "n choose k."
|
||||
// (n; k) therefore gives the number of k-subsets possible out of a set of n distinct items.
|
||||
|
||||
// For example:
|
||||
// The 2-subsets of {1,2,3,4} are the six pairs {1,2}, {1,3}, {1,4}, {2,3}, {2,4}, and {3,4}, so (4; 2)==6.
|
||||
|
||||
// http://functions.wolfram.com/GammaBetaErf/Binomial/ for evaluation.
|
||||
|
||||
// But note that the binomial distribution
|
||||
// (like others including the poisson, negative binomial & Bernoulli)
|
||||
// is strictly defined as a discrete function: only integral values of k are envisaged.
|
||||
// However because of the method of calculation using a continuous gamma function,
|
||||
// it is convenient to treat it as if a continous function,
|
||||
// and permit non-integral values of k.
|
||||
// To enforce the strict mathematical model, users should use floor or ceil functions
|
||||
// on k outside this function to ensure that k is integral.
|
||||
|
||||
#ifndef BOOST_MATH_SPECIAL_BINOMIAL_HPP
|
||||
#define BOOST_MATH_SPECIAL_BINOMIAL_HPP
|
||||
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#include <boost/math/special_functions/beta.hpp> // for incomplete beta.
|
||||
#include <boost/math/distributions/complement.hpp> // complements
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp> // error checks
|
||||
#include <boost/math/distributions/detail/inv_discrete_quantile.hpp> // error checks
|
||||
#include <boost/math/special_functions/fpclassify.hpp> // isnan.
|
||||
#include <boost/math/tools/roots.hpp> // for root finding.
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace math
|
||||
{
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class binomial_distribution;
|
||||
|
||||
namespace binomial_detail{
|
||||
// common error checking routines for binomial distribution functions:
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_N(const char* function, const RealType& N, RealType* result, const Policy& pol)
|
||||
{
|
||||
if((N < 0) || !(boost::math::isfinite)(N))
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Number of Trials argument is %1%, but must be >= 0 !", N, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_success_fraction(const char* function, const RealType& p, RealType* result, const Policy& pol)
|
||||
{
|
||||
if((p < 0) || (p > 1) || !(boost::math::isfinite)(p))
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Success fraction argument is %1%, but must be >= 0 and <= 1 !", p, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_dist(const char* function, const RealType& N, const RealType& p, RealType* result, const Policy& pol)
|
||||
{
|
||||
return check_success_fraction(
|
||||
function, p, result, pol)
|
||||
&& check_N(
|
||||
function, N, result, pol);
|
||||
}
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_dist_and_k(const char* function, const RealType& N, const RealType& p, RealType k, RealType* result, const Policy& pol)
|
||||
{
|
||||
if(check_dist(function, N, p, result, pol) == false)
|
||||
return false;
|
||||
if((k < 0) || !(boost::math::isfinite)(k))
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Number of Successes argument is %1%, but must be >= 0 !", k, pol);
|
||||
return false;
|
||||
}
|
||||
if(k > N)
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Number of Successes argument is %1%, but must be <= Number of Trials !", k, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_dist_and_prob(const char* function, const RealType& N, RealType p, RealType prob, RealType* result, const Policy& pol)
|
||||
{
|
||||
if(check_dist(function, N, p, result, pol) && detail::check_probability(function, prob, result, pol) == false)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T, class Policy>
|
||||
T inverse_binomial_cornish_fisher(T n, T sf, T p, T q, const Policy& pol)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
// mean:
|
||||
T m = n * sf;
|
||||
// standard deviation:
|
||||
T sigma = sqrt(n * sf * (1 - sf));
|
||||
// skewness
|
||||
T sk = (1 - 2 * sf) / sigma;
|
||||
// kurtosis:
|
||||
// T k = (1 - 6 * sf * (1 - sf) ) / (n * sf * (1 - sf));
|
||||
// Get the inverse of a std normal distribution:
|
||||
T x = boost::math::erfc_inv(p > q ? 2 * q : 2 * p, pol) * constants::root_two<T>();
|
||||
// Set the sign:
|
||||
if(p < 0.5)
|
||||
x = -x;
|
||||
T x2 = x * x;
|
||||
// w is correction term due to skewness
|
||||
T w = x + sk * (x2 - 1) / 6;
|
||||
/*
|
||||
// Add on correction due to kurtosis.
|
||||
// Disabled for now, seems to make things worse?
|
||||
//
|
||||
if(n >= 10)
|
||||
w += k * x * (x2 - 3) / 24 + sk * sk * x * (2 * x2 - 5) / -36;
|
||||
*/
|
||||
w = m + sigma * w;
|
||||
if(w < tools::min_value<T>())
|
||||
return sqrt(tools::min_value<T>());
|
||||
if(w > n)
|
||||
return n;
|
||||
return w;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
RealType quantile_imp(const binomial_distribution<RealType, Policy>& dist, const RealType& p, const RealType& q)
|
||||
{ // Quantile or Percent Point Binomial function.
|
||||
// Return the number of expected successes k,
|
||||
// for a given probability p.
|
||||
//
|
||||
// Error checks:
|
||||
BOOST_MATH_STD_USING // ADL of std names
|
||||
RealType result = 0;
|
||||
RealType trials = dist.trials();
|
||||
RealType success_fraction = dist.success_fraction();
|
||||
if(false == binomial_detail::check_dist_and_prob(
|
||||
"boost::math::quantile(binomial_distribution<%1%> const&, %1%)",
|
||||
trials,
|
||||
success_fraction,
|
||||
p,
|
||||
&result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
// Special cases:
|
||||
//
|
||||
if(p == 0)
|
||||
{ // There may actually be no answer to this question,
|
||||
// since the probability of zero successes may be non-zero,
|
||||
// but zero is the best we can do:
|
||||
return 0;
|
||||
}
|
||||
if(p == 1)
|
||||
{ // Probability of n or fewer successes is always one,
|
||||
// so n is the most sensible answer here:
|
||||
return trials;
|
||||
}
|
||||
if (p <= pow(1 - success_fraction, trials))
|
||||
{ // p <= pdf(dist, 0) == cdf(dist, 0)
|
||||
return 0; // So the only reasonable result is zero.
|
||||
} // And root finder would fail otherwise.
|
||||
|
||||
// Solve for quantile numerically:
|
||||
//
|
||||
RealType guess = binomial_detail::inverse_binomial_cornish_fisher(trials, success_fraction, p, q, Policy());
|
||||
RealType factor = 8;
|
||||
if(trials > 100)
|
||||
factor = 1.01f; // guess is pretty accurate
|
||||
else if((trials > 10) && (trials - 1 > guess) && (guess > 3))
|
||||
factor = 1.15f; // less accurate but OK.
|
||||
else if(trials < 10)
|
||||
{
|
||||
// pretty inaccurate guess in this area:
|
||||
if(guess > trials / 64)
|
||||
{
|
||||
guess = trials / 4;
|
||||
factor = 2;
|
||||
}
|
||||
else
|
||||
guess = trials / 1024;
|
||||
}
|
||||
else
|
||||
factor = 2; // trials largish, but in far tails.
|
||||
|
||||
typedef typename Policy::discrete_quantile_type discrete_quantile_type;
|
||||
boost::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
|
||||
return detail::inverse_discrete_quantile(
|
||||
dist,
|
||||
p,
|
||||
q,
|
||||
guess,
|
||||
factor,
|
||||
RealType(1),
|
||||
discrete_quantile_type(),
|
||||
max_iter);
|
||||
} // quantile
|
||||
|
||||
}
|
||||
|
||||
template <class RealType = double, class Policy = policies::policy<> >
|
||||
class binomial_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
|
||||
binomial_distribution(RealType n = 1, RealType p = 0.5) : m_n(n), m_p(p)
|
||||
{ // Default n = 1 is the Bernoulli distribution
|
||||
// with equal probability of 'heads' or 'tails.
|
||||
RealType r;
|
||||
binomial_detail::check_dist(
|
||||
"boost::math::binomial_distribution<%1%>::binomial_distribution",
|
||||
m_n,
|
||||
m_p,
|
||||
&r, Policy());
|
||||
} // binomial_distribution constructor.
|
||||
|
||||
RealType success_fraction() const
|
||||
{ // Probability.
|
||||
return m_p;
|
||||
}
|
||||
RealType trials() const
|
||||
{ // Total number of trials.
|
||||
return m_n;
|
||||
}
|
||||
|
||||
enum interval_type{
|
||||
clopper_pearson_exact_interval,
|
||||
jeffreys_prior_interval
|
||||
};
|
||||
|
||||
//
|
||||
// Estimation of the success fraction parameter.
|
||||
// The best estimate is actually simply successes/trials,
|
||||
// these functions are used
|
||||
// to obtain confidence intervals for the success fraction.
|
||||
//
|
||||
static RealType find_lower_bound_on_p(
|
||||
RealType trials,
|
||||
RealType successes,
|
||||
RealType probability,
|
||||
interval_type t = clopper_pearson_exact_interval)
|
||||
{
|
||||
static const char* function = "boost::math::binomial_distribution<%1%>::find_lower_bound_on_p";
|
||||
// Error checks:
|
||||
RealType result = 0;
|
||||
if(false == binomial_detail::check_dist_and_k(
|
||||
function, trials, RealType(0), successes, &result, Policy())
|
||||
&&
|
||||
binomial_detail::check_dist_and_prob(
|
||||
function, trials, RealType(0), probability, &result, Policy()))
|
||||
{ return result; }
|
||||
|
||||
if(successes == 0)
|
||||
return 0;
|
||||
|
||||
// NOTE!!! The Clopper Pearson formula uses "successes" not
|
||||
// "successes+1" as usual to get the lower bound,
|
||||
// see http://www.itl.nist.gov/div898/handbook/prc/section2/prc241.htm
|
||||
return (t == clopper_pearson_exact_interval) ? ibeta_inv(successes, trials - successes + 1, probability, static_cast<RealType*>(0), Policy())
|
||||
: ibeta_inv(successes + 0.5f, trials - successes + 0.5f, probability, static_cast<RealType*>(0), Policy());
|
||||
}
|
||||
static RealType find_upper_bound_on_p(
|
||||
RealType trials,
|
||||
RealType successes,
|
||||
RealType probability,
|
||||
interval_type t = clopper_pearson_exact_interval)
|
||||
{
|
||||
static const char* function = "boost::math::binomial_distribution<%1%>::find_upper_bound_on_p";
|
||||
// Error checks:
|
||||
RealType result = 0;
|
||||
if(false == binomial_detail::check_dist_and_k(
|
||||
function, trials, RealType(0), successes, &result, Policy())
|
||||
&&
|
||||
binomial_detail::check_dist_and_prob(
|
||||
function, trials, RealType(0), probability, &result, Policy()))
|
||||
{ return result; }
|
||||
|
||||
if(trials == successes)
|
||||
return 1;
|
||||
|
||||
return (t == clopper_pearson_exact_interval) ? ibetac_inv(successes + 1, trials - successes, probability, static_cast<RealType*>(0), Policy())
|
||||
: ibetac_inv(successes + 0.5f, trials - successes + 0.5f, probability, static_cast<RealType*>(0), Policy());
|
||||
}
|
||||
// Estimate number of trials parameter:
|
||||
//
|
||||
// "How many trials do I need to be P% sure of seeing k events?"
|
||||
// or
|
||||
// "How many trials can I have to be P% sure of seeing fewer than k events?"
|
||||
//
|
||||
static RealType find_minimum_number_of_trials(
|
||||
RealType k, // number of events
|
||||
RealType p, // success fraction
|
||||
RealType alpha) // risk level
|
||||
{
|
||||
static const char* function = "boost::math::binomial_distribution<%1%>::find_minimum_number_of_trials";
|
||||
// Error checks:
|
||||
RealType result = 0;
|
||||
if(false == binomial_detail::check_dist_and_k(
|
||||
function, k, p, k, &result, Policy())
|
||||
&&
|
||||
binomial_detail::check_dist_and_prob(
|
||||
function, k, p, alpha, &result, Policy()))
|
||||
{ return result; }
|
||||
|
||||
result = ibetac_invb(k + 1, p, alpha, Policy()); // returns n - k
|
||||
return result + k;
|
||||
}
|
||||
|
||||
static RealType find_maximum_number_of_trials(
|
||||
RealType k, // number of events
|
||||
RealType p, // success fraction
|
||||
RealType alpha) // risk level
|
||||
{
|
||||
static const char* function = "boost::math::binomial_distribution<%1%>::find_maximum_number_of_trials";
|
||||
// Error checks:
|
||||
RealType result = 0;
|
||||
if(false == binomial_detail::check_dist_and_k(
|
||||
function, k, p, k, &result, Policy())
|
||||
&&
|
||||
binomial_detail::check_dist_and_prob(
|
||||
function, k, p, alpha, &result, Policy()))
|
||||
{ return result; }
|
||||
|
||||
result = ibeta_invb(k + 1, p, alpha, Policy()); // returns n - k
|
||||
return result + k;
|
||||
}
|
||||
|
||||
private:
|
||||
RealType m_n; // Not sure if this shouldn't be an int?
|
||||
RealType m_p; // success_fraction
|
||||
}; // template <class RealType, class Policy> class binomial_distribution
|
||||
|
||||
typedef binomial_distribution<> binomial;
|
||||
// typedef binomial_distribution<double> binomial;
|
||||
// IS now included since no longer a name clash with function binomial.
|
||||
//typedef binomial_distribution<double> binomial; // Reserved name of type double.
|
||||
|
||||
template <class RealType, class Policy>
|
||||
const std::pair<RealType, RealType> range(const binomial_distribution<RealType, Policy>& dist)
|
||||
{ // Range of permissible values for random variable k.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(static_cast<RealType>(0), dist.trials());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
const std::pair<RealType, RealType> support(const binomial_distribution<RealType, Policy>& dist)
|
||||
{ // Range of supported values for random variable k.
|
||||
// This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
|
||||
return std::pair<RealType, RealType>(static_cast<RealType>(0), dist.trials());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mean(const binomial_distribution<RealType, Policy>& dist)
|
||||
{ // Mean of Binomial distribution = np.
|
||||
return dist.trials() * dist.success_fraction();
|
||||
} // mean
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType variance(const binomial_distribution<RealType, Policy>& dist)
|
||||
{ // Variance of Binomial distribution = np(1-p).
|
||||
return dist.trials() * dist.success_fraction() * (1 - dist.success_fraction());
|
||||
} // variance
|
||||
|
||||
template <class RealType, class Policy>
|
||||
RealType pdf(const binomial_distribution<RealType, Policy>& dist, const RealType& k)
|
||||
{ // Probability Density/Mass Function.
|
||||
BOOST_FPU_EXCEPTION_GUARD
|
||||
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
RealType n = dist.trials();
|
||||
|
||||
// Error check:
|
||||
RealType result = 0; // initialization silences some compiler warnings
|
||||
if(false == binomial_detail::check_dist_and_k(
|
||||
"boost::math::pdf(binomial_distribution<%1%> const&, %1%)",
|
||||
n,
|
||||
dist.success_fraction(),
|
||||
k,
|
||||
&result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
// Special cases of success_fraction, regardless of k successes and regardless of n trials.
|
||||
if (dist.success_fraction() == 0)
|
||||
{ // probability of zero successes is 1:
|
||||
return static_cast<RealType>(k == 0 ? 1 : 0);
|
||||
}
|
||||
if (dist.success_fraction() == 1)
|
||||
{ // probability of n successes is 1:
|
||||
return static_cast<RealType>(k == n ? 1 : 0);
|
||||
}
|
||||
// k argument may be integral, signed, or unsigned, or floating point.
|
||||
// If necessary, it has already been promoted from an integral type.
|
||||
if (n == 0)
|
||||
{
|
||||
return 1; // Probability = 1 = certainty.
|
||||
}
|
||||
if (k == 0)
|
||||
{ // binomial coeffic (n 0) = 1,
|
||||
// n ^ 0 = 1
|
||||
return pow(1 - dist.success_fraction(), n);
|
||||
}
|
||||
if (k == n)
|
||||
{ // binomial coeffic (n n) = 1,
|
||||
// n ^ 0 = 1
|
||||
return pow(dist.success_fraction(), k); // * pow((1 - dist.success_fraction()), (n - k)) = 1
|
||||
}
|
||||
|
||||
// Probability of getting exactly k successes
|
||||
// if C(n, k) is the binomial coefficient then:
|
||||
//
|
||||
// f(k; n,p) = C(n, k) * p^k * (1-p)^(n-k)
|
||||
// = (n!/(k!(n-k)!)) * p^k * (1-p)^(n-k)
|
||||
// = (tgamma(n+1) / (tgamma(k+1)*tgamma(n-k+1))) * p^k * (1-p)^(n-k)
|
||||
// = p^k (1-p)^(n-k) / (beta(k+1, n-k+1) * (n+1))
|
||||
// = ibeta_derivative(k+1, n-k+1, p) / (n+1)
|
||||
//
|
||||
using boost::math::ibeta_derivative; // a, b, x
|
||||
return ibeta_derivative(k+1, n-k+1, dist.success_fraction(), Policy()) / (n+1);
|
||||
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const binomial_distribution<RealType, Policy>& dist, const RealType& k)
|
||||
{ // Cumulative Distribution Function Binomial.
|
||||
// The random variate k is the number of successes in n trials.
|
||||
// k argument may be integral, signed, or unsigned, or floating point.
|
||||
// If necessary, it has already been promoted from an integral type.
|
||||
|
||||
// Returns the sum of the terms 0 through k of the Binomial Probability Density/Mass:
|
||||
//
|
||||
// i=k
|
||||
// -- ( n ) i n-i
|
||||
// > | | p (1-p)
|
||||
// -- ( i )
|
||||
// i=0
|
||||
|
||||
// The terms are not summed directly instead
|
||||
// the incomplete beta integral is employed,
|
||||
// according to the formula:
|
||||
// P = I[1-p]( n-k, k+1).
|
||||
// = 1 - I[p](k + 1, n - k)
|
||||
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
RealType n = dist.trials();
|
||||
RealType p = dist.success_fraction();
|
||||
|
||||
// Error check:
|
||||
RealType result = 0;
|
||||
if(false == binomial_detail::check_dist_and_k(
|
||||
"boost::math::cdf(binomial_distribution<%1%> const&, %1%)",
|
||||
n,
|
||||
p,
|
||||
k,
|
||||
&result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if (k == n)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Special cases, regardless of k.
|
||||
if (p == 0)
|
||||
{ // This need explanation:
|
||||
// the pdf is zero for all cases except when k == 0.
|
||||
// For zero p the probability of zero successes is one.
|
||||
// Therefore the cdf is always 1:
|
||||
// the probability of k or *fewer* successes is always 1
|
||||
// if there are never any successes!
|
||||
return 1;
|
||||
}
|
||||
if (p == 1)
|
||||
{ // This is correct but needs explanation:
|
||||
// when k = 1
|
||||
// all the cdf and pdf values are zero *except* when k == n,
|
||||
// and that case has been handled above already.
|
||||
return 0;
|
||||
}
|
||||
//
|
||||
// P = I[1-p](n - k, k + 1)
|
||||
// = 1 - I[p](k + 1, n - k)
|
||||
// Use of ibetac here prevents cancellation errors in calculating
|
||||
// 1-p if p is very small, perhaps smaller than machine epsilon.
|
||||
//
|
||||
// Note that we do not use a finite sum here, since the incomplete
|
||||
// beta uses a finite sum internally for integer arguments, so
|
||||
// we'll just let it take care of the necessary logic.
|
||||
//
|
||||
return ibetac(k + 1, n - k, p, Policy());
|
||||
} // binomial cdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const complemented2_type<binomial_distribution<RealType, Policy>, RealType>& c)
|
||||
{ // Complemented Cumulative Distribution Function Binomial.
|
||||
// The random variate k is the number of successes in n trials.
|
||||
// k argument may be integral, signed, or unsigned, or floating point.
|
||||
// If necessary, it has already been promoted from an integral type.
|
||||
|
||||
// Returns the sum of the terms k+1 through n of the Binomial Probability Density/Mass:
|
||||
//
|
||||
// i=n
|
||||
// -- ( n ) i n-i
|
||||
// > | | p (1-p)
|
||||
// -- ( i )
|
||||
// i=k+1
|
||||
|
||||
// The terms are not summed directly instead
|
||||
// the incomplete beta integral is employed,
|
||||
// according to the formula:
|
||||
// Q = 1 -I[1-p]( n-k, k+1).
|
||||
// = I[p](k + 1, n - k)
|
||||
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
RealType const& k = c.param;
|
||||
binomial_distribution<RealType, Policy> const& dist = c.dist;
|
||||
RealType n = dist.trials();
|
||||
RealType p = dist.success_fraction();
|
||||
|
||||
// Error checks:
|
||||
RealType result = 0;
|
||||
if(false == binomial_detail::check_dist_and_k(
|
||||
"boost::math::cdf(binomial_distribution<%1%> const&, %1%)",
|
||||
n,
|
||||
p,
|
||||
k,
|
||||
&result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (k == n)
|
||||
{ // Probability of greater than n successes is necessarily zero:
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Special cases, regardless of k.
|
||||
if (p == 0)
|
||||
{
|
||||
// This need explanation: the pdf is zero for all
|
||||
// cases except when k == 0. For zero p the probability
|
||||
// of zero successes is one. Therefore the cdf is always
|
||||
// 1: the probability of *more than* k successes is always 0
|
||||
// if there are never any successes!
|
||||
return 0;
|
||||
}
|
||||
if (p == 1)
|
||||
{
|
||||
// This needs explanation, when p = 1
|
||||
// we always have n successes, so the probability
|
||||
// of more than k successes is 1 as long as k < n.
|
||||
// The k == n case has already been handled above.
|
||||
return 1;
|
||||
}
|
||||
//
|
||||
// Calculate cdf binomial using the incomplete beta function.
|
||||
// Q = 1 -I[1-p](n - k, k + 1)
|
||||
// = I[p](k + 1, n - k)
|
||||
// Use of ibeta here prevents cancellation errors in calculating
|
||||
// 1-p if p is very small, perhaps smaller than machine epsilon.
|
||||
//
|
||||
// Note that we do not use a finite sum here, since the incomplete
|
||||
// beta uses a finite sum internally for integer arguments, so
|
||||
// we'll just let it take care of the necessary logic.
|
||||
//
|
||||
return ibeta(k + 1, n - k, p, Policy());
|
||||
} // binomial cdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const binomial_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
{
|
||||
return binomial_detail::quantile_imp(dist, p, RealType(1-p));
|
||||
} // quantile
|
||||
|
||||
template <class RealType, class Policy>
|
||||
RealType quantile(const complemented2_type<binomial_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
return binomial_detail::quantile_imp(c.dist, RealType(1-c.param), c.param);
|
||||
} // quantile
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mode(const binomial_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING // ADL of std functions.
|
||||
RealType p = dist.success_fraction();
|
||||
RealType n = dist.trials();
|
||||
return floor(p * (n + 1));
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType median(const binomial_distribution<RealType, Policy>& dist)
|
||||
{ // Bounds for the median of the negative binomial distribution
|
||||
// VAN DE VEN R. ; WEBER N. C. ;
|
||||
// Univ. Sydney, school mathematics statistics, Sydney N.S.W. 2006, AUSTRALIE
|
||||
// Metrika (Metrika) ISSN 0026-1335 CODEN MTRKA8
|
||||
// 1993, vol. 40, no3-4, pp. 185-189 (4 ref.)
|
||||
|
||||
// Bounds for median and 50 percetage point of binomial and negative binomial distribution
|
||||
// Metrika, ISSN 0026-1335 (Print) 1435-926X (Online)
|
||||
// Volume 41, Number 1 / December, 1994, DOI 10.1007/BF01895303
|
||||
BOOST_MATH_STD_USING // ADL of std functions.
|
||||
RealType p = dist.success_fraction();
|
||||
RealType n = dist.trials();
|
||||
// Wikipedia says one of floor(np) -1, floor (np), floor(np) +1
|
||||
return floor(p * n); // Chose the middle value.
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType skewness(const binomial_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING // ADL of std functions.
|
||||
RealType p = dist.success_fraction();
|
||||
RealType n = dist.trials();
|
||||
return (1 - 2 * p) / sqrt(n * p * (1 - p));
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis(const binomial_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType p = dist.success_fraction();
|
||||
RealType n = dist.trials();
|
||||
return 3 - 6 / n + 1 / (n * p * (1 - p));
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis_excess(const binomial_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType p = dist.success_fraction();
|
||||
RealType q = 1 - p;
|
||||
RealType n = dist.trials();
|
||||
return (1 - 6 * p * q) / (n * p * q);
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
// This include must be at the end, *after* the accessors
|
||||
// for this distribution have been defined, in order to
|
||||
// keep compilers that support two-phase lookup happy.
|
||||
#include <boost/math/distributions/detail/derived_accessors.hpp>
|
||||
|
||||
#endif // BOOST_MATH_SPECIAL_BINOMIAL_HPP
|
||||
|
||||
|
||||
347
test/external/boost/math/distributions/cauchy.hpp
vendored
Normal file
347
test/external/boost/math/distributions/cauchy.hpp
vendored
Normal file
@@ -0,0 +1,347 @@
|
||||
// Copyright John Maddock 2006, 2007.
|
||||
// Copyright Paul A. Bristow 2007.
|
||||
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_STATS_CAUCHY_HPP
|
||||
#define BOOST_STATS_CAUCHY_HPP
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4127) // conditional expression is constant
|
||||
#endif
|
||||
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#include <boost/math/constants/constants.hpp>
|
||||
#include <boost/math/distributions/complement.hpp>
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp>
|
||||
#include <boost/config/no_tr1/cmath.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace boost{ namespace math
|
||||
{
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class cauchy_distribution;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <class RealType, class Policy>
|
||||
RealType cdf_imp(const cauchy_distribution<RealType, Policy>& dist, const RealType& x, bool complement)
|
||||
{
|
||||
//
|
||||
// This calculates the cdf of the Cauchy distribution and/or its complement.
|
||||
//
|
||||
// The usual formula for the Cauchy cdf is:
|
||||
//
|
||||
// cdf = 0.5 + atan(x)/pi
|
||||
//
|
||||
// But that suffers from cancellation error as x -> -INF.
|
||||
//
|
||||
// Recall that for x < 0:
|
||||
//
|
||||
// atan(x) = -pi/2 - atan(1/x)
|
||||
//
|
||||
// Substituting into the above we get:
|
||||
//
|
||||
// CDF = -atan(1/x) ; x < 0
|
||||
//
|
||||
// So the proceedure is to calculate the cdf for -fabs(x)
|
||||
// using the above formula, and then subtract from 1 when required
|
||||
// to get the result.
|
||||
//
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
static const char* function = "boost::math::cdf(cauchy<%1%>&, %1%)";
|
||||
RealType result = 0;
|
||||
RealType location = dist.location();
|
||||
RealType scale = dist.scale();
|
||||
if(false == detail::check_location(function, location, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(false == detail::check_scale(function, scale, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(std::numeric_limits<RealType>::has_infinity && x == std::numeric_limits<RealType>::infinity())
|
||||
{ // cdf +infinity is unity.
|
||||
return static_cast<RealType>((complement) ? 0 : 1);
|
||||
}
|
||||
if(std::numeric_limits<RealType>::has_infinity && x == -std::numeric_limits<RealType>::infinity())
|
||||
{ // cdf -infinity is zero.
|
||||
return static_cast<RealType>((complement) ? 1 : 0);
|
||||
}
|
||||
if(false == detail::check_x(function, x, &result, Policy()))
|
||||
{ // Catches x == NaN
|
||||
return result;
|
||||
}
|
||||
RealType mx = -fabs((x - location) / scale); // scale is > 0
|
||||
if(mx > -tools::epsilon<RealType>() / 8)
|
||||
{ // special case first: x extremely close to location.
|
||||
return 0.5;
|
||||
}
|
||||
result = -atan(1 / mx) / constants::pi<RealType>();
|
||||
return (((x > location) != complement) ? 1 - result : result);
|
||||
} // cdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
RealType quantile_imp(
|
||||
const cauchy_distribution<RealType, Policy>& dist,
|
||||
const RealType& p,
|
||||
bool complement)
|
||||
{
|
||||
// This routine implements the quantile for the Cauchy distribution,
|
||||
// the value p may be the probability, or its complement if complement=true.
|
||||
//
|
||||
// The procedure first performs argument reduction on p to avoid error
|
||||
// when calculating the tangent, then calulates the distance from the
|
||||
// mid-point of the distribution. This is either added or subtracted
|
||||
// from the location parameter depending on whether `complement` is true.
|
||||
//
|
||||
static const char* function = "boost::math::quantile(cauchy<%1%>&, %1%)";
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
RealType result = 0;
|
||||
RealType location = dist.location();
|
||||
RealType scale = dist.scale();
|
||||
if(false == detail::check_location(function, location, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(false == detail::check_scale(function, scale, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(false == detail::check_probability(function, p, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
// Special cases:
|
||||
if(p == 1)
|
||||
{
|
||||
return (complement ? -1 : 1) * policies::raise_overflow_error<RealType>(function, 0, Policy());
|
||||
}
|
||||
if(p == 0)
|
||||
{
|
||||
return (complement ? 1 : -1) * policies::raise_overflow_error<RealType>(function, 0, Policy());
|
||||
}
|
||||
|
||||
RealType P = p - floor(p); // argument reduction of p:
|
||||
if(P > 0.5)
|
||||
{
|
||||
P = P - 1;
|
||||
}
|
||||
if(P == 0.5) // special case:
|
||||
{
|
||||
return location;
|
||||
}
|
||||
result = -scale / tan(constants::pi<RealType>() * P);
|
||||
return complement ? RealType(location - result) : RealType(location + result);
|
||||
} // quantile
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class RealType = double, class Policy = policies::policy<> >
|
||||
class cauchy_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
|
||||
cauchy_distribution(RealType location = 0, RealType scale = 1)
|
||||
: m_a(location), m_hg(scale)
|
||||
{
|
||||
static const char* function = "boost::math::cauchy_distribution<%1%>::cauchy_distribution";
|
||||
RealType result;
|
||||
detail::check_location(function, location, &result, Policy());
|
||||
detail::check_scale(function, scale, &result, Policy());
|
||||
} // cauchy_distribution
|
||||
|
||||
RealType location()const
|
||||
{
|
||||
return m_a;
|
||||
}
|
||||
RealType scale()const
|
||||
{
|
||||
return m_hg;
|
||||
}
|
||||
|
||||
private:
|
||||
RealType m_a; // The location, this is the median of the distribution.
|
||||
RealType m_hg; // The scale )or shape), this is the half width at half height.
|
||||
};
|
||||
|
||||
typedef cauchy_distribution<double> cauchy;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const cauchy_distribution<RealType, Policy>&)
|
||||
{ // Range of permissible values for random variable x.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(-max_value<RealType>(), max_value<RealType>()); // - to + infinity.
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> support(const cauchy_distribution<RealType, Policy>& )
|
||||
{ // Range of supported values for random variable x.
|
||||
// This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
|
||||
return std::pair<RealType, RealType>(-tools::max_value<RealType>(), tools::max_value<RealType>()); // - to + infinity.
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType pdf(const cauchy_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::pdf(cauchy<%1%>&, %1%)";
|
||||
RealType result = 0;
|
||||
RealType location = dist.location();
|
||||
RealType scale = dist.scale();
|
||||
if(false == detail::check_scale("boost::math::pdf(cauchy<%1%>&, %1%)", scale, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(false == detail::check_location("boost::math::pdf(cauchy<%1%>&, %1%)", location, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if((boost::math::isinf)(x))
|
||||
{
|
||||
return 0; // pdf + and - infinity is zero.
|
||||
}
|
||||
// These produce MSVC 4127 warnings, so the above used instead.
|
||||
//if(std::numeric_limits<RealType>::has_infinity && abs(x) == std::numeric_limits<RealType>::infinity())
|
||||
//{ // pdf + and - infinity is zero.
|
||||
// return 0;
|
||||
//}
|
||||
|
||||
if(false == detail::check_x(function, x, &result, Policy()))
|
||||
{ // Catches x = NaN
|
||||
return result;
|
||||
}
|
||||
|
||||
RealType xs = (x - location) / scale;
|
||||
result = 1 / (constants::pi<RealType>() * scale * (1 + xs * xs));
|
||||
return result;
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const cauchy_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
return detail::cdf_imp(dist, x, false);
|
||||
} // cdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const cauchy_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
{
|
||||
return detail::quantile_imp(dist, p, false);
|
||||
} // quantile
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const complemented2_type<cauchy_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
return detail::cdf_imp(c.dist, c.param, true);
|
||||
} // cdf complement
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const complemented2_type<cauchy_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
return detail::quantile_imp(c.dist, c.param, true);
|
||||
} // quantile complement
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mean(const cauchy_distribution<RealType, Policy>&)
|
||||
{ // There is no mean:
|
||||
typedef typename Policy::assert_undefined_type assert_type;
|
||||
BOOST_STATIC_ASSERT(assert_type::value == 0);
|
||||
|
||||
return policies::raise_domain_error<RealType>(
|
||||
"boost::math::mean(cauchy<%1%>&)",
|
||||
"The Cauchy distribution does not have a mean: "
|
||||
"the only possible return value is %1%.",
|
||||
std::numeric_limits<RealType>::quiet_NaN(), Policy());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType variance(const cauchy_distribution<RealType, Policy>& /*dist*/)
|
||||
{
|
||||
// There is no variance:
|
||||
typedef typename Policy::assert_undefined_type assert_type;
|
||||
BOOST_STATIC_ASSERT(assert_type::value == 0);
|
||||
|
||||
return policies::raise_domain_error<RealType>(
|
||||
"boost::math::variance(cauchy<%1%>&)",
|
||||
"The Cauchy distribution does not have a variance: "
|
||||
"the only possible return value is %1%.",
|
||||
std::numeric_limits<RealType>::quiet_NaN(), Policy());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mode(const cauchy_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
return dist.location();
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType median(const cauchy_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
return dist.location();
|
||||
}
|
||||
template <class RealType, class Policy>
|
||||
inline RealType skewness(const cauchy_distribution<RealType, Policy>& /*dist*/)
|
||||
{
|
||||
// There is no skewness:
|
||||
typedef typename Policy::assert_undefined_type assert_type;
|
||||
BOOST_STATIC_ASSERT(assert_type::value == 0);
|
||||
|
||||
return policies::raise_domain_error<RealType>(
|
||||
"boost::math::skewness(cauchy<%1%>&)",
|
||||
"The Cauchy distribution does not have a skewness: "
|
||||
"the only possible return value is %1%.",
|
||||
std::numeric_limits<RealType>::quiet_NaN(), Policy()); // infinity?
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis(const cauchy_distribution<RealType, Policy>& /*dist*/)
|
||||
{
|
||||
// There is no kurtosis:
|
||||
typedef typename Policy::assert_undefined_type assert_type;
|
||||
BOOST_STATIC_ASSERT(assert_type::value == 0);
|
||||
|
||||
return policies::raise_domain_error<RealType>(
|
||||
"boost::math::kurtosis(cauchy<%1%>&)",
|
||||
"The Cauchy distribution does not have a kurtosis: "
|
||||
"the only possible return value is %1%.",
|
||||
std::numeric_limits<RealType>::quiet_NaN(), Policy());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis_excess(const cauchy_distribution<RealType, Policy>& /*dist*/)
|
||||
{
|
||||
// There is no kurtosis excess:
|
||||
typedef typename Policy::assert_undefined_type assert_type;
|
||||
BOOST_STATIC_ASSERT(assert_type::value == 0);
|
||||
|
||||
return policies::raise_domain_error<RealType>(
|
||||
"boost::math::kurtosis_excess(cauchy<%1%>&)",
|
||||
"The Cauchy distribution does not have a kurtosis: "
|
||||
"the only possible return value is %1%.",
|
||||
std::numeric_limits<RealType>::quiet_NaN(), Policy());
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
// This include must be at the end, *after* the accessors
|
||||
// for this distribution have been defined, in order to
|
||||
// keep compilers that support two-phase lookup happy.
|
||||
#include <boost/math/distributions/detail/derived_accessors.hpp>
|
||||
|
||||
#endif // BOOST_STATS_CAUCHY_HPP
|
||||
347
test/external/boost/math/distributions/chi_squared.hpp
vendored
Normal file
347
test/external/boost/math/distributions/chi_squared.hpp
vendored
Normal file
@@ -0,0 +1,347 @@
|
||||
// Copyright John Maddock 2006, 2007.
|
||||
// Copyright Paul A. Bristow 2008, 2010.
|
||||
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_MATH_DISTRIBUTIONS_CHI_SQUARED_HPP
|
||||
#define BOOST_MATH_DISTRIBUTIONS_CHI_SQUARED_HPP
|
||||
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#include <boost/math/special_functions/gamma.hpp> // for incomplete beta.
|
||||
#include <boost/math/distributions/complement.hpp> // complements
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp> // error checks
|
||||
#include <boost/math/special_functions/fpclassify.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace boost{ namespace math{
|
||||
|
||||
template <class RealType = double, class Policy = policies::policy<> >
|
||||
class chi_squared_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
|
||||
chi_squared_distribution(RealType i) : m_df(i)
|
||||
{
|
||||
RealType result;
|
||||
detail::check_df(
|
||||
"boost::math::chi_squared_distribution<%1%>::chi_squared_distribution", m_df, &result, Policy());
|
||||
} // chi_squared_distribution
|
||||
|
||||
RealType degrees_of_freedom()const
|
||||
{
|
||||
return m_df;
|
||||
}
|
||||
|
||||
// Parameter estimation:
|
||||
static RealType find_degrees_of_freedom(
|
||||
RealType difference_from_variance,
|
||||
RealType alpha,
|
||||
RealType beta,
|
||||
RealType variance,
|
||||
RealType hint = 100);
|
||||
|
||||
private:
|
||||
//
|
||||
// Data member:
|
||||
//
|
||||
RealType m_df; // degrees of freedom are a real number.
|
||||
}; // class chi_squared_distribution
|
||||
|
||||
typedef chi_squared_distribution<double> chi_squared;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const chi_squared_distribution<RealType, Policy>& /*dist*/)
|
||||
{ // Range of permissible values for random variable x.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>()); // 0 to + infinity.
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> support(const chi_squared_distribution<RealType, Policy>& /*dist*/)
|
||||
{ // Range of supported values for random variable x.
|
||||
// This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
|
||||
return std::pair<RealType, RealType>(static_cast<RealType>(0), tools::max_value<RealType>()); // 0 to + infinity.
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
RealType pdf(const chi_squared_distribution<RealType, Policy>& dist, const RealType& chi_square)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
RealType degrees_of_freedom = dist.degrees_of_freedom();
|
||||
// Error check:
|
||||
RealType error_result;
|
||||
|
||||
static const char* function = "boost::math::pdf(const chi_squared_distribution<%1%>&, %1%)";
|
||||
|
||||
if(false == detail::check_df(
|
||||
function, degrees_of_freedom, &error_result, Policy()))
|
||||
return error_result;
|
||||
|
||||
if((chi_square < 0) || !(boost::math::isfinite)(chi_square))
|
||||
{
|
||||
return policies::raise_domain_error<RealType>(
|
||||
function, "Chi Square parameter was %1%, but must be > 0 !", chi_square, Policy());
|
||||
}
|
||||
|
||||
if(chi_square == 0)
|
||||
{
|
||||
// Handle special cases:
|
||||
if(degrees_of_freedom < 2)
|
||||
{
|
||||
return policies::raise_overflow_error<RealType>(
|
||||
function, 0, Policy());
|
||||
}
|
||||
else if(degrees_of_freedom == 2)
|
||||
{
|
||||
return 0.5f;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return gamma_p_derivative(degrees_of_freedom / 2, chi_square / 2, Policy()) / 2;
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const chi_squared_distribution<RealType, Policy>& dist, const RealType& chi_square)
|
||||
{
|
||||
RealType degrees_of_freedom = dist.degrees_of_freedom();
|
||||
// Error check:
|
||||
RealType error_result;
|
||||
static const char* function = "boost::math::cdf(const chi_squared_distribution<%1%>&, %1%)";
|
||||
|
||||
if(false == detail::check_df(
|
||||
function, degrees_of_freedom, &error_result, Policy()))
|
||||
return error_result;
|
||||
|
||||
if((chi_square < 0) || !(boost::math::isfinite)(chi_square))
|
||||
{
|
||||
return policies::raise_domain_error<RealType>(
|
||||
function, "Chi Square parameter was %1%, but must be > 0 !", chi_square, Policy());
|
||||
}
|
||||
|
||||
return boost::math::gamma_p(degrees_of_freedom / 2, chi_square / 2, Policy());
|
||||
} // cdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const chi_squared_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
{
|
||||
RealType degrees_of_freedom = dist.degrees_of_freedom();
|
||||
static const char* function = "boost::math::quantile(const chi_squared_distribution<%1%>&, %1%)";
|
||||
// Error check:
|
||||
RealType error_result;
|
||||
if(false == detail::check_df(
|
||||
function, degrees_of_freedom, &error_result, Policy())
|
||||
&& detail::check_probability(
|
||||
function, p, &error_result, Policy()))
|
||||
return error_result;
|
||||
|
||||
return 2 * boost::math::gamma_p_inv(degrees_of_freedom / 2, p, Policy());
|
||||
} // quantile
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const complemented2_type<chi_squared_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
RealType const& degrees_of_freedom = c.dist.degrees_of_freedom();
|
||||
RealType const& chi_square = c.param;
|
||||
static const char* function = "boost::math::cdf(const chi_squared_distribution<%1%>&, %1%)";
|
||||
// Error check:
|
||||
RealType error_result;
|
||||
if(false == detail::check_df(
|
||||
function, degrees_of_freedom, &error_result, Policy()))
|
||||
return error_result;
|
||||
|
||||
if((chi_square < 0) || !(boost::math::isfinite)(chi_square))
|
||||
{
|
||||
return policies::raise_domain_error<RealType>(
|
||||
function, "Chi Square parameter was %1%, but must be > 0 !", chi_square, Policy());
|
||||
}
|
||||
|
||||
return boost::math::gamma_q(degrees_of_freedom / 2, chi_square / 2, Policy());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const complemented2_type<chi_squared_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
RealType const& degrees_of_freedom = c.dist.degrees_of_freedom();
|
||||
RealType const& q = c.param;
|
||||
static const char* function = "boost::math::quantile(const chi_squared_distribution<%1%>&, %1%)";
|
||||
// Error check:
|
||||
RealType error_result;
|
||||
if(false == detail::check_df(
|
||||
function, degrees_of_freedom, &error_result, Policy())
|
||||
&& detail::check_probability(
|
||||
function, q, &error_result, Policy()))
|
||||
return error_result;
|
||||
|
||||
return 2 * boost::math::gamma_q_inv(degrees_of_freedom / 2, q, Policy());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mean(const chi_squared_distribution<RealType, Policy>& dist)
|
||||
{ // Mean of Chi-Squared distribution = v.
|
||||
return dist.degrees_of_freedom();
|
||||
} // mean
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType variance(const chi_squared_distribution<RealType, Policy>& dist)
|
||||
{ // Variance of Chi-Squared distribution = 2v.
|
||||
return 2 * dist.degrees_of_freedom();
|
||||
} // variance
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mode(const chi_squared_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType df = dist.degrees_of_freedom();
|
||||
static const char* function = "boost::math::mode(const chi_squared_distribution<%1%>&)";
|
||||
// Most sources only define mode for df >= 2,
|
||||
// but for 0 <= df <= 2, the pdf maximum actually occurs at random variate = 0;
|
||||
// So one could extend the definition of mode thus:
|
||||
//if(df < 0)
|
||||
//{
|
||||
// return policies::raise_domain_error<RealType>(
|
||||
// function,
|
||||
// "Chi-Squared distribution only has a mode for degrees of freedom >= 0, but got degrees of freedom = %1%.",
|
||||
// df, Policy());
|
||||
//}
|
||||
//return (df <= 2) ? 0 : df - 2;
|
||||
|
||||
if(df < 2)
|
||||
return policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Chi-Squared distribution only has a mode for degrees of freedom >= 2, but got degrees of freedom = %1%.",
|
||||
df, Policy());
|
||||
return df - 2;
|
||||
}
|
||||
|
||||
//template <class RealType, class Policy>
|
||||
//inline RealType median(const chi_squared_distribution<RealType, Policy>& dist)
|
||||
//{ // Median is given by Quantile[dist, 1/2]
|
||||
// RealType df = dist.degrees_of_freedom();
|
||||
// if(df <= 1)
|
||||
// return tools::domain_error<RealType>(
|
||||
// BOOST_CURRENT_FUNCTION,
|
||||
// "The Chi-Squared distribution only has a mode for degrees of freedom >= 2, but got degrees of freedom = %1%.",
|
||||
// df);
|
||||
// return df - RealType(2)/3;
|
||||
//}
|
||||
// Now implemented via quantile(half) in derived accessors.
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType skewness(const chi_squared_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING // For ADL
|
||||
RealType df = dist.degrees_of_freedom();
|
||||
return sqrt (8 / df); // == 2 * sqrt(2 / df);
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis(const chi_squared_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType df = dist.degrees_of_freedom();
|
||||
return 3 + 12 / df;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis_excess(const chi_squared_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType df = dist.degrees_of_freedom();
|
||||
return 12 / df;
|
||||
}
|
||||
|
||||
//
|
||||
// Parameter estimation comes last:
|
||||
//
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <class RealType, class Policy>
|
||||
struct df_estimator
|
||||
{
|
||||
df_estimator(RealType a, RealType b, RealType variance, RealType delta)
|
||||
: alpha(a), beta(b), ratio(delta/variance)
|
||||
{ // Constructor
|
||||
}
|
||||
|
||||
RealType operator()(const RealType& df)
|
||||
{
|
||||
if(df <= tools::min_value<RealType>())
|
||||
return 1;
|
||||
chi_squared_distribution<RealType, Policy> cs(df);
|
||||
|
||||
RealType result;
|
||||
if(ratio > 0)
|
||||
{
|
||||
RealType r = 1 + ratio;
|
||||
result = cdf(cs, quantile(complement(cs, alpha)) / r) - beta;
|
||||
}
|
||||
else
|
||||
{ // ratio <= 0
|
||||
RealType r = 1 + ratio;
|
||||
result = cdf(complement(cs, quantile(cs, alpha) / r)) - beta;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
private:
|
||||
RealType alpha;
|
||||
RealType beta;
|
||||
RealType ratio; // Difference from variance / variance, so fractional.
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class RealType, class Policy>
|
||||
RealType chi_squared_distribution<RealType, Policy>::find_degrees_of_freedom(
|
||||
RealType difference_from_variance,
|
||||
RealType alpha,
|
||||
RealType beta,
|
||||
RealType variance,
|
||||
RealType hint)
|
||||
{
|
||||
static const char* function = "boost::math::chi_squared_distribution<%1%>::find_degrees_of_freedom(%1%,%1%,%1%,%1%,%1%)";
|
||||
// Check for domain errors:
|
||||
RealType error_result;
|
||||
if(false ==
|
||||
detail::check_probability(function, alpha, &error_result, Policy())
|
||||
&& detail::check_probability(function, beta, &error_result, Policy()))
|
||||
{ // Either probability is outside 0 to 1.
|
||||
return error_result;
|
||||
}
|
||||
|
||||
if(hint <= 0)
|
||||
{ // No hint given, so guess df = 1.
|
||||
hint = 1;
|
||||
}
|
||||
|
||||
detail::df_estimator<RealType, Policy> f(alpha, beta, variance, difference_from_variance);
|
||||
tools::eps_tolerance<RealType> tol(policies::digits<RealType, Policy>());
|
||||
boost::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
|
||||
std::pair<RealType, RealType> r =
|
||||
tools::bracket_and_solve_root(f, hint, RealType(2), false, tol, max_iter, Policy());
|
||||
RealType result = r.first + (r.second - r.first) / 2;
|
||||
if(max_iter >= policies::get_max_root_iterations<Policy>())
|
||||
{
|
||||
policies::raise_evaluation_error<RealType>(function, "Unable to locate solution in a reasonable time:"
|
||||
" either there is no answer to how many degrees of freedom are required"
|
||||
" or the answer is infinite. Current best guess is %1%", result, Policy());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
// This include must be at the end, *after* the accessors
|
||||
// for this distribution have been defined, in order to
|
||||
// keep compilers that support two-phase lookup happy.
|
||||
#include <boost/math/distributions/detail/derived_accessors.hpp>
|
||||
|
||||
#endif // BOOST_MATH_DISTRIBUTIONS_CHI_SQUARED_HPP
|
||||
195
test/external/boost/math/distributions/complement.hpp
vendored
Normal file
195
test/external/boost/math/distributions/complement.hpp
vendored
Normal file
@@ -0,0 +1,195 @@
|
||||
// (C) Copyright John Maddock 2006.
|
||||
// (C) Copyright Paul A. Bristow 2006.
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_STATS_COMPLEMENT_HPP
|
||||
#define BOOST_STATS_COMPLEMENT_HPP
|
||||
|
||||
//
|
||||
// This code really defines our own tuple type.
|
||||
// It would be nice to reuse boost::math::tuple
|
||||
// while retaining our own type safety, but it's
|
||||
// not clear if that's possible. In any case this
|
||||
// code is *very* lightweight.
|
||||
//
|
||||
namespace boost{ namespace math{
|
||||
|
||||
template <class Dist, class RealType>
|
||||
struct complemented2_type
|
||||
{
|
||||
complemented2_type(
|
||||
const Dist& d,
|
||||
const RealType& p1)
|
||||
: dist(d),
|
||||
param(p1) {}
|
||||
|
||||
const Dist& dist;
|
||||
const RealType& param;
|
||||
|
||||
private:
|
||||
complemented2_type& operator=(const complemented2_type&);
|
||||
};
|
||||
|
||||
template <class Dist, class RealType1, class RealType2>
|
||||
struct complemented3_type
|
||||
{
|
||||
complemented3_type(
|
||||
const Dist& d,
|
||||
const RealType1& p1,
|
||||
const RealType2& p2)
|
||||
: dist(d),
|
||||
param1(p1),
|
||||
param2(p2) {}
|
||||
|
||||
const Dist& dist;
|
||||
const RealType1& param1;
|
||||
const RealType2& param2;
|
||||
private:
|
||||
complemented3_type& operator=(const complemented3_type&);
|
||||
};
|
||||
|
||||
template <class Dist, class RealType1, class RealType2, class RealType3>
|
||||
struct complemented4_type
|
||||
{
|
||||
complemented4_type(
|
||||
const Dist& d,
|
||||
const RealType1& p1,
|
||||
const RealType2& p2,
|
||||
const RealType3& p3)
|
||||
: dist(d),
|
||||
param1(p1),
|
||||
param2(p2),
|
||||
param3(p3) {}
|
||||
|
||||
const Dist& dist;
|
||||
const RealType1& param1;
|
||||
const RealType2& param2;
|
||||
const RealType3& param3;
|
||||
private:
|
||||
complemented4_type& operator=(const complemented4_type&);
|
||||
};
|
||||
|
||||
template <class Dist, class RealType1, class RealType2, class RealType3, class RealType4>
|
||||
struct complemented5_type
|
||||
{
|
||||
complemented5_type(
|
||||
const Dist& d,
|
||||
const RealType1& p1,
|
||||
const RealType2& p2,
|
||||
const RealType3& p3,
|
||||
const RealType4& p4)
|
||||
: dist(d),
|
||||
param1(p1),
|
||||
param2(p2),
|
||||
param3(p3),
|
||||
param4(p4) {}
|
||||
|
||||
const Dist& dist;
|
||||
const RealType1& param1;
|
||||
const RealType2& param2;
|
||||
const RealType3& param3;
|
||||
const RealType4& param4;
|
||||
private:
|
||||
complemented5_type& operator=(const complemented5_type&);
|
||||
};
|
||||
|
||||
template <class Dist, class RealType1, class RealType2, class RealType3, class RealType4, class RealType5>
|
||||
struct complemented6_type
|
||||
{
|
||||
complemented6_type(
|
||||
const Dist& d,
|
||||
const RealType1& p1,
|
||||
const RealType2& p2,
|
||||
const RealType3& p3,
|
||||
const RealType4& p4,
|
||||
const RealType5& p5)
|
||||
: dist(d),
|
||||
param1(p1),
|
||||
param2(p2),
|
||||
param3(p3),
|
||||
param4(p4),
|
||||
param5(p5) {}
|
||||
|
||||
const Dist& dist;
|
||||
const RealType1& param1;
|
||||
const RealType2& param2;
|
||||
const RealType3& param3;
|
||||
const RealType4& param4;
|
||||
const RealType5& param5;
|
||||
private:
|
||||
complemented6_type& operator=(const complemented6_type&);
|
||||
};
|
||||
|
||||
template <class Dist, class RealType1, class RealType2, class RealType3, class RealType4, class RealType5, class RealType6>
|
||||
struct complemented7_type
|
||||
{
|
||||
complemented7_type(
|
||||
const Dist& d,
|
||||
const RealType1& p1,
|
||||
const RealType2& p2,
|
||||
const RealType3& p3,
|
||||
const RealType4& p4,
|
||||
const RealType5& p5,
|
||||
const RealType6& p6)
|
||||
: dist(d),
|
||||
param1(p1),
|
||||
param2(p2),
|
||||
param3(p3),
|
||||
param4(p4),
|
||||
param5(p5),
|
||||
param6(p6) {}
|
||||
|
||||
const Dist& dist;
|
||||
const RealType1& param1;
|
||||
const RealType2& param2;
|
||||
const RealType3& param3;
|
||||
const RealType4& param4;
|
||||
const RealType5& param5;
|
||||
const RealType6& param6;
|
||||
private:
|
||||
complemented7_type& operator=(const complemented7_type&);
|
||||
};
|
||||
|
||||
template <class Dist, class RealType>
|
||||
inline complemented2_type<Dist, RealType> complement(const Dist& d, const RealType& r)
|
||||
{
|
||||
return complemented2_type<Dist, RealType>(d, r);
|
||||
}
|
||||
|
||||
template <class Dist, class RealType1, class RealType2>
|
||||
inline complemented3_type<Dist, RealType1, RealType2> complement(const Dist& d, const RealType1& r1, const RealType2& r2)
|
||||
{
|
||||
return complemented3_type<Dist, RealType1, RealType2>(d, r1, r2);
|
||||
}
|
||||
|
||||
template <class Dist, class RealType1, class RealType2, class RealType3>
|
||||
inline complemented4_type<Dist, RealType1, RealType2, RealType3> complement(const Dist& d, const RealType1& r1, const RealType2& r2, const RealType3& r3)
|
||||
{
|
||||
return complemented4_type<Dist, RealType1, RealType2, RealType3>(d, r1, r2, r3);
|
||||
}
|
||||
|
||||
template <class Dist, class RealType1, class RealType2, class RealType3, class RealType4>
|
||||
inline complemented5_type<Dist, RealType1, RealType2, RealType3, RealType4> complement(const Dist& d, const RealType1& r1, const RealType2& r2, const RealType3& r3, const RealType4& r4)
|
||||
{
|
||||
return complemented5_type<Dist, RealType1, RealType2, RealType3, RealType4>(d, r1, r2, r3, r4);
|
||||
}
|
||||
|
||||
template <class Dist, class RealType1, class RealType2, class RealType3, class RealType4, class RealType5>
|
||||
inline complemented6_type<Dist, RealType1, RealType2, RealType3, RealType4, RealType5> complement(const Dist& d, const RealType1& r1, const RealType2& r2, const RealType3& r3, const RealType4& r4, const RealType5& r5)
|
||||
{
|
||||
return complemented6_type<Dist, RealType1, RealType2, RealType3, RealType4, RealType5>(d, r1, r2, r3, r4, r5);
|
||||
}
|
||||
|
||||
template <class Dist, class RealType1, class RealType2, class RealType3, class RealType4, class RealType5, class RealType6>
|
||||
inline complemented7_type<Dist, RealType1, RealType2, RealType3, RealType4, RealType5, RealType6> complement(const Dist& d, const RealType1& r1, const RealType2& r2, const RealType3& r3, const RealType4& r4, const RealType5& r5, const RealType6& r6)
|
||||
{
|
||||
return complemented7_type<Dist, RealType1, RealType2, RealType3, RealType4, RealType5, RealType6>(d, r1, r2, r3, r4, r5, r6);
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_STATS_COMPLEMENT_HPP
|
||||
|
||||
178
test/external/boost/math/distributions/detail/common_error_handling.hpp
vendored
Normal file
178
test/external/boost/math/distributions/detail/common_error_handling.hpp
vendored
Normal file
@@ -0,0 +1,178 @@
|
||||
// Copyright John Maddock 2006, 2007.
|
||||
// Copyright Paul A. Bristow 2006, 2007.
|
||||
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_MATH_DISTRIBUTIONS_COMMON_ERROR_HANDLING_HPP
|
||||
#define BOOST_MATH_DISTRIBUTIONS_COMMON_ERROR_HANDLING_HPP
|
||||
|
||||
#include <boost/math/policies/error_handling.hpp>
|
||||
#include <boost/math/special_functions/fpclassify.hpp>
|
||||
// using boost::math::isfinite;
|
||||
|
||||
namespace boost{ namespace math{ namespace detail
|
||||
{
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_probability(const char* function, RealType const& prob, RealType* result, const Policy& pol)
|
||||
{
|
||||
if((prob < 0) || (prob > 1) || !(boost::math::isfinite)(prob))
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Probability argument is %1%, but must be >= 0 and <= 1 !", prob, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_df(const char* function, RealType const& df, RealType* result, const Policy& pol)
|
||||
{
|
||||
if((df <= 0) || !(boost::math::isfinite)(df))
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Degrees of freedom argument is %1%, but must be > 0 !", df, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_scale(
|
||||
const char* function,
|
||||
RealType scale,
|
||||
RealType* result,
|
||||
const Policy& pol)
|
||||
{
|
||||
if((scale <= 0) || !(boost::math::isfinite)(scale))
|
||||
{ // Assume scale == 0 is NOT valid for any distribution.
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Scale parameter is %1%, but must be > 0 !", scale, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_location(
|
||||
const char* function,
|
||||
RealType location,
|
||||
RealType* result,
|
||||
const Policy& pol)
|
||||
{
|
||||
if(!(boost::math::isfinite)(location))
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Location parameter is %1%, but must be finite!", location, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_x(
|
||||
const char* function,
|
||||
RealType x,
|
||||
RealType* result,
|
||||
const Policy& pol)
|
||||
{
|
||||
if(!(boost::math::isfinite)(x))
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Random variate x is %1%, but must be finite!", x, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
// Note that this test catches both infinity and NaN.
|
||||
// Some special cases permit x to be infinite, so these must be tested 1st,
|
||||
// leaving this test to catch any NaNs. see Normal and cauchy for example.
|
||||
} // bool check_x
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_x_gt0(
|
||||
const char* function,
|
||||
RealType x,
|
||||
RealType* result,
|
||||
const Policy& pol)
|
||||
{
|
||||
if(x <= 0)
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Random variate x is %1%, but must be > 0!", x, pol);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
// Note that this test catches both infinity and NaN.
|
||||
// Some special cases permit x to be infinite, so these must be tested 1st,
|
||||
// leaving this test to catch any NaNs. See Normal and cauchy for example.
|
||||
} // bool check_x_gt0
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_positive_x(
|
||||
const char* function,
|
||||
RealType x,
|
||||
RealType* result,
|
||||
const Policy& pol)
|
||||
{
|
||||
if(!(boost::math::isfinite)(x) || (x < 0))
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Random variate x is %1%, but must be finite and >= 0!", x, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
// Note that this test catches both infinity and NaN.
|
||||
// Some special cases permit x to be infinite, so these must be tested 1st,
|
||||
// leaving this test to catch any NaNs. see Normal and cauchy for example.
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_non_centrality(
|
||||
const char* function,
|
||||
RealType ncp,
|
||||
RealType* result,
|
||||
const Policy& pol)
|
||||
{
|
||||
if((ncp < 0) || !(boost::math::isfinite)(ncp))
|
||||
{ // Assume scale == 0 is NOT valid for any distribution.
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Non centrality parameter is %1%, but must be > 0 !", ncp, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_finite(
|
||||
const char* function,
|
||||
RealType x,
|
||||
RealType* result,
|
||||
const Policy& pol)
|
||||
{
|
||||
if(!(boost::math::isfinite)(x))
|
||||
{ // Assume scale == 0 is NOT valid for any distribution.
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Parameter is %1%, but must be finite !", x, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_MATH_DISTRIBUTIONS_COMMON_ERROR_HANDLING_HPP
|
||||
163
test/external/boost/math/distributions/detail/derived_accessors.hpp
vendored
Normal file
163
test/external/boost/math/distributions/detail/derived_accessors.hpp
vendored
Normal file
@@ -0,0 +1,163 @@
|
||||
// Copyright John Maddock 2006.
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_STATS_DERIVED_HPP
|
||||
#define BOOST_STATS_DERIVED_HPP
|
||||
|
||||
// This file implements various common properties of distributions
|
||||
// that can be implemented in terms of other properties:
|
||||
// variance OR standard deviation (see note below),
|
||||
// hazard, cumulative hazard (chf), coefficient_of_variation.
|
||||
//
|
||||
// Note that while both variance and standard_deviation are provided
|
||||
// here, each distribution MUST SPECIALIZE AT LEAST ONE OF THESE
|
||||
// otherwise these two versions will just call each other over and over
|
||||
// until stack space runs out ...
|
||||
|
||||
// Of course there may be more efficient means of implementing these
|
||||
// that are specific to a particular distribution, but these generic
|
||||
// versions give these properties "for free" with most distributions.
|
||||
//
|
||||
// In order to make use of this header, it must be included AT THE END
|
||||
// of the distribution header, AFTER the distribution and its core
|
||||
// property accessors have been defined: this is so that compilers
|
||||
// that implement 2-phase lookup and early-type-checking of templates
|
||||
// can find the definitions refered to herein.
|
||||
//
|
||||
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4723) // potential divide by 0
|
||||
// Suppressing spurious warning in coefficient_of_variation
|
||||
#endif
|
||||
|
||||
namespace boost{ namespace math{
|
||||
|
||||
template <class Distribution>
|
||||
typename Distribution::value_type variance(const Distribution& dist);
|
||||
|
||||
template <class Distribution>
|
||||
inline typename Distribution::value_type standard_deviation(const Distribution& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING // ADL of sqrt.
|
||||
return sqrt(variance(dist));
|
||||
}
|
||||
|
||||
template <class Distribution>
|
||||
inline typename Distribution::value_type variance(const Distribution& dist)
|
||||
{
|
||||
typename Distribution::value_type result = standard_deviation(dist);
|
||||
return result * result;
|
||||
}
|
||||
|
||||
template <class Distribution, class RealType>
|
||||
inline typename Distribution::value_type hazard(const Distribution& dist, const RealType& x)
|
||||
{ // hazard function
|
||||
// http://www.itl.nist.gov/div898/handbook/eda/section3/eda362.htm#HAZ
|
||||
typedef typename Distribution::value_type value_type;
|
||||
typedef typename Distribution::policy_type policy_type;
|
||||
value_type p = cdf(complement(dist, x));
|
||||
value_type d = pdf(dist, x);
|
||||
if(d > p * tools::max_value<value_type>())
|
||||
return policies::raise_overflow_error<value_type>(
|
||||
"boost::math::hazard(const Distribution&, %1%)", 0, policy_type());
|
||||
if(d == 0)
|
||||
{
|
||||
// This protects against 0/0, but is it the right thing to do?
|
||||
return 0;
|
||||
}
|
||||
return d / p;
|
||||
}
|
||||
|
||||
template <class Distribution, class RealType>
|
||||
inline typename Distribution::value_type chf(const Distribution& dist, const RealType& x)
|
||||
{ // cumulative hazard function.
|
||||
// http://www.itl.nist.gov/div898/handbook/eda/section3/eda362.htm#HAZ
|
||||
BOOST_MATH_STD_USING
|
||||
return -log(cdf(complement(dist, x)));
|
||||
}
|
||||
|
||||
template <class Distribution>
|
||||
inline typename Distribution::value_type coefficient_of_variation(const Distribution& dist)
|
||||
{
|
||||
typedef typename Distribution::value_type value_type;
|
||||
typedef typename Distribution::policy_type policy_type;
|
||||
|
||||
using std::abs;
|
||||
|
||||
value_type m = mean(dist);
|
||||
value_type d = standard_deviation(dist);
|
||||
if((abs(m) < 1) && (d > abs(m) * tools::max_value<value_type>()))
|
||||
{ // Checks too that m is not zero,
|
||||
return policies::raise_overflow_error<value_type>("boost::math::coefficient_of_variation(const Distribution&, %1%)", 0, policy_type());
|
||||
}
|
||||
return d / m; // so MSVC warning on zerodivide is spurious, and suppressed.
|
||||
}
|
||||
//
|
||||
// Next follow overloads of some of the standard accessors with mixed
|
||||
// argument types. We just use a typecast to forward on to the "real"
|
||||
// implementation with all arguments of the same type:
|
||||
//
|
||||
template <class Distribution, class RealType>
|
||||
inline typename Distribution::value_type pdf(const Distribution& dist, const RealType& x)
|
||||
{
|
||||
typedef typename Distribution::value_type value_type;
|
||||
return pdf(dist, static_cast<value_type>(x));
|
||||
}
|
||||
template <class Distribution, class RealType>
|
||||
inline typename Distribution::value_type cdf(const Distribution& dist, const RealType& x)
|
||||
{
|
||||
typedef typename Distribution::value_type value_type;
|
||||
return cdf(dist, static_cast<value_type>(x));
|
||||
}
|
||||
template <class Distribution, class RealType>
|
||||
inline typename Distribution::value_type quantile(const Distribution& dist, const RealType& x)
|
||||
{
|
||||
typedef typename Distribution::value_type value_type;
|
||||
return quantile(dist, static_cast<value_type>(x));
|
||||
}
|
||||
/*
|
||||
template <class Distribution, class RealType>
|
||||
inline typename Distribution::value_type chf(const Distribution& dist, const RealType& x)
|
||||
{
|
||||
typedef typename Distribution::value_type value_type;
|
||||
return chf(dist, static_cast<value_type>(x));
|
||||
}
|
||||
*/
|
||||
template <class Distribution, class RealType>
|
||||
inline typename Distribution::value_type cdf(const complemented2_type<Distribution, RealType>& c)
|
||||
{
|
||||
typedef typename Distribution::value_type value_type;
|
||||
return cdf(complement(c.dist, static_cast<value_type>(c.param)));
|
||||
}
|
||||
|
||||
template <class Distribution, class RealType>
|
||||
inline typename Distribution::value_type quantile(const complemented2_type<Distribution, RealType>& c)
|
||||
{
|
||||
typedef typename Distribution::value_type value_type;
|
||||
return quantile(complement(c.dist, static_cast<value_type>(c.param)));
|
||||
}
|
||||
|
||||
template <class Dist>
|
||||
inline typename Dist::value_type median(const Dist& d)
|
||||
{ // median - default definition for those distributions for which a
|
||||
// simple closed form is not known,
|
||||
// and for which a domain_error and/or NaN generating function is NOT defined.
|
||||
typedef typename Dist::value_type value_type;
|
||||
return quantile(d, static_cast<value_type>(0.5f));
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // BOOST_STATS_DERIVED_HPP
|
||||
149
test/external/boost/math/distributions/detail/generic_mode.hpp
vendored
Normal file
149
test/external/boost/math/distributions/detail/generic_mode.hpp
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
// Copyright John Maddock 2008.
|
||||
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_MATH_DISTRIBUTIONS_DETAIL_MODE_HPP
|
||||
#define BOOST_MATH_DISTRIBUTIONS_DETAIL_MODE_HPP
|
||||
|
||||
#include <boost/math/tools/minima.hpp> // function minimization for mode
|
||||
#include <boost/math/policies/error_handling.hpp>
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
|
||||
namespace boost{ namespace math{ namespace detail{
|
||||
|
||||
template <class Dist>
|
||||
struct pdf_minimizer
|
||||
{
|
||||
pdf_minimizer(const Dist& d)
|
||||
: dist(d) {}
|
||||
|
||||
typename Dist::value_type operator()(const typename Dist::value_type& x)
|
||||
{
|
||||
return -pdf(dist, x);
|
||||
}
|
||||
private:
|
||||
Dist dist;
|
||||
};
|
||||
|
||||
template <class Dist>
|
||||
typename Dist::value_type generic_find_mode(const Dist& dist, typename Dist::value_type guess, const char* function, typename Dist::value_type step = 0)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
typedef typename Dist::value_type value_type;
|
||||
typedef typename Dist::policy_type policy_type;
|
||||
//
|
||||
// Need to begin by bracketing the maxima of the PDF:
|
||||
//
|
||||
value_type maxval;
|
||||
value_type upper_bound = guess;
|
||||
value_type lower_bound;
|
||||
value_type v = pdf(dist, guess);
|
||||
if(v == 0)
|
||||
{
|
||||
//
|
||||
// Oops we don't know how to handle this, or even in which
|
||||
// direction we should move in, treat as an evaluation error:
|
||||
//
|
||||
policies::raise_evaluation_error(
|
||||
function,
|
||||
"Could not locate a starting location for the search for the mode, original guess was %1%", guess, policy_type());
|
||||
}
|
||||
do
|
||||
{
|
||||
maxval = v;
|
||||
if(step != 0)
|
||||
upper_bound += step;
|
||||
else
|
||||
upper_bound *= 2;
|
||||
v = pdf(dist, upper_bound);
|
||||
}while(maxval < v);
|
||||
|
||||
lower_bound = upper_bound;
|
||||
do
|
||||
{
|
||||
maxval = v;
|
||||
if(step != 0)
|
||||
lower_bound -= step;
|
||||
else
|
||||
lower_bound /= 2;
|
||||
v = pdf(dist, lower_bound);
|
||||
}while(maxval < v);
|
||||
|
||||
boost::uintmax_t max_iter = policies::get_max_root_iterations<policy_type>();
|
||||
|
||||
value_type result = tools::brent_find_minima(
|
||||
pdf_minimizer<Dist>(dist),
|
||||
lower_bound,
|
||||
upper_bound,
|
||||
policies::digits<value_type, policy_type>(),
|
||||
max_iter).first;
|
||||
if(max_iter >= policies::get_max_root_iterations<policy_type>())
|
||||
{
|
||||
return policies::raise_evaluation_error<value_type>(
|
||||
function,
|
||||
"Unable to locate solution in a reasonable time:"
|
||||
" either there is no answer to the mode of the distribution"
|
||||
" or the answer is infinite. Current best guess is %1%", result, policy_type());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
//
|
||||
// As above,but confined to the interval [0,1]:
|
||||
//
|
||||
template <class Dist>
|
||||
typename Dist::value_type generic_find_mode_01(const Dist& dist, typename Dist::value_type guess, const char* function)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
typedef typename Dist::value_type value_type;
|
||||
typedef typename Dist::policy_type policy_type;
|
||||
//
|
||||
// Need to begin by bracketing the maxima of the PDF:
|
||||
//
|
||||
value_type maxval;
|
||||
value_type upper_bound = guess;
|
||||
value_type lower_bound;
|
||||
value_type v = pdf(dist, guess);
|
||||
do
|
||||
{
|
||||
maxval = v;
|
||||
upper_bound = 1 - (1 - upper_bound) / 2;
|
||||
if(upper_bound == 1)
|
||||
return 1;
|
||||
v = pdf(dist, upper_bound);
|
||||
}while(maxval < v);
|
||||
|
||||
lower_bound = upper_bound;
|
||||
do
|
||||
{
|
||||
maxval = v;
|
||||
lower_bound /= 2;
|
||||
if(lower_bound < tools::min_value<value_type>())
|
||||
return 0;
|
||||
v = pdf(dist, lower_bound);
|
||||
}while(maxval < v);
|
||||
|
||||
boost::uintmax_t max_iter = policies::get_max_root_iterations<policy_type>();
|
||||
|
||||
value_type result = tools::brent_find_minima(
|
||||
pdf_minimizer<Dist>(dist),
|
||||
lower_bound,
|
||||
upper_bound,
|
||||
policies::digits<value_type, policy_type>(),
|
||||
max_iter).first;
|
||||
if(max_iter >= policies::get_max_root_iterations<policy_type>())
|
||||
{
|
||||
return policies::raise_evaluation_error<value_type>(
|
||||
function,
|
||||
"Unable to locate solution in a reasonable time:"
|
||||
" either there is no answer to the mode of the distribution"
|
||||
" or the answer is infinite. Current best guess is %1%", result, policy_type());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}}} // namespaces
|
||||
|
||||
#endif // BOOST_MATH_DISTRIBUTIONS_DETAIL_MODE_HPP
|
||||
91
test/external/boost/math/distributions/detail/generic_quantile.hpp
vendored
Normal file
91
test/external/boost/math/distributions/detail/generic_quantile.hpp
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
// Copyright John Maddock 2008.
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_MATH_DISTIBUTIONS_DETAIL_GENERIC_QUANTILE_HPP
|
||||
#define BOOST_MATH_DISTIBUTIONS_DETAIL_GENERIC_QUANTILE_HPP
|
||||
|
||||
namespace boost{ namespace math{ namespace detail{
|
||||
|
||||
template <class Dist>
|
||||
struct generic_quantile_finder
|
||||
{
|
||||
typedef typename Dist::value_type value_type;
|
||||
typedef typename Dist::policy_type policy_type;
|
||||
|
||||
generic_quantile_finder(const Dist& d, value_type t, bool c)
|
||||
: dist(d), target(t), comp(c) {}
|
||||
|
||||
value_type operator()(const value_type& x)
|
||||
{
|
||||
return comp ?
|
||||
value_type(target - cdf(complement(dist, x)))
|
||||
: value_type(cdf(dist, x) - target);
|
||||
}
|
||||
|
||||
private:
|
||||
Dist dist;
|
||||
value_type target;
|
||||
bool comp;
|
||||
};
|
||||
|
||||
template <class T, class Policy>
|
||||
inline T check_range_result(const T& x, const Policy& pol, const char* function)
|
||||
{
|
||||
if((x >= 0) && (x < tools::min_value<T>()))
|
||||
return policies::raise_underflow_error<T>(function, 0, pol);
|
||||
if(x <= -tools::max_value<T>())
|
||||
return -policies::raise_overflow_error<T>(function, 0, pol);
|
||||
if(x >= tools::max_value<T>())
|
||||
return policies::raise_overflow_error<T>(function, 0, pol);
|
||||
return x;
|
||||
}
|
||||
|
||||
template <class Dist>
|
||||
typename Dist::value_type generic_quantile(const Dist& dist, const typename Dist::value_type& p, const typename Dist::value_type& guess, bool comp, const char* function)
|
||||
{
|
||||
typedef typename Dist::value_type value_type;
|
||||
typedef typename Dist::policy_type policy_type;
|
||||
typedef typename policies::normalise<
|
||||
policy_type,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
policies::discrete_quantile<>,
|
||||
policies::assert_undefined<> >::type forwarding_policy;
|
||||
|
||||
//
|
||||
// Special cases first:
|
||||
//
|
||||
if(p == 0)
|
||||
{
|
||||
return comp
|
||||
? check_range_result(range(dist).second, forwarding_policy(), function)
|
||||
: check_range_result(range(dist).first, forwarding_policy(), function);
|
||||
}
|
||||
if(p == 1)
|
||||
{
|
||||
return !comp
|
||||
? check_range_result(range(dist).second, forwarding_policy(), function)
|
||||
: check_range_result(range(dist).first, forwarding_policy(), function);
|
||||
}
|
||||
|
||||
generic_quantile_finder<Dist> f(dist, p, comp);
|
||||
tools::eps_tolerance<value_type> tol(policies::digits<value_type, forwarding_policy>() - 3);
|
||||
boost::uintmax_t max_iter = policies::get_max_root_iterations<forwarding_policy>();
|
||||
std::pair<value_type, value_type> ir = tools::bracket_and_solve_root(
|
||||
f, guess, value_type(2), true, tol, max_iter, forwarding_policy());
|
||||
value_type result = ir.first + (ir.second - ir.first) / 2;
|
||||
if(max_iter >= policies::get_max_root_iterations<forwarding_policy>())
|
||||
{
|
||||
policies::raise_evaluation_error<value_type>(function, "Unable to locate solution in a reasonable time:"
|
||||
" either there is no answer to quantile"
|
||||
" or the answer is infinite. Current best guess is %1%", result, forwarding_policy());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}}} // namespaces
|
||||
|
||||
#endif // BOOST_MATH_DISTIBUTIONS_DETAIL_GENERIC_QUANTILE_HPP
|
||||
|
||||
100
test/external/boost/math/distributions/detail/hypergeometric_cdf.hpp
vendored
Normal file
100
test/external/boost/math/distributions/detail/hypergeometric_cdf.hpp
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
// Copyright 2008 John Maddock
|
||||
//
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_MATH_DISTRIBUTIONS_DETAIL_HG_CDF_HPP
|
||||
#define BOOST_MATH_DISTRIBUTIONS_DETAIL_HG_CDF_HPP
|
||||
|
||||
#include <boost/math/policies/error_handling.hpp>
|
||||
#include <boost/math/distributions/detail/hypergeometric_pdf.hpp>
|
||||
|
||||
namespace boost{ namespace math{ namespace detail{
|
||||
|
||||
template <class T, class Policy>
|
||||
T hypergeometric_cdf_imp(unsigned x, unsigned r, unsigned n, unsigned N, bool invert, const Policy& pol)
|
||||
{
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4267)
|
||||
#endif
|
||||
BOOST_MATH_STD_USING
|
||||
T result = 0;
|
||||
T mode = floor(T(r + 1) * T(n + 1) / (N + 2));
|
||||
if(x < mode)
|
||||
{
|
||||
result = hypergeometric_pdf<T>(x, r, n, N, pol);
|
||||
T diff = result;
|
||||
unsigned lower_limit = static_cast<unsigned>((std::max)(0, (int)(n + r) - (int)(N)));
|
||||
while(diff > (invert ? T(1) : result) * tools::epsilon<T>())
|
||||
{
|
||||
diff = T(x) * T((N + x) - n - r) * diff / (T(1 + n - x) * T(1 + r - x));
|
||||
result += diff;
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(x);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(diff);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(result);
|
||||
if(x == lower_limit)
|
||||
break;
|
||||
--x;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
invert = !invert;
|
||||
unsigned upper_limit = (std::min)(r, n);
|
||||
if(x != upper_limit)
|
||||
{
|
||||
++x;
|
||||
result = hypergeometric_pdf<T>(x, r, n, N, pol);
|
||||
T diff = result;
|
||||
while((x <= upper_limit) && (diff > (invert ? T(1) : result) * tools::epsilon<T>()))
|
||||
{
|
||||
diff = T(n - x) * T(r - x) * diff / (T(x + 1) * T((N + x + 1) - n - r));
|
||||
result += diff;
|
||||
++x;
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(x);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(diff);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(invert)
|
||||
result = 1 - result;
|
||||
return result;
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class T, class Policy>
|
||||
inline T hypergeometric_cdf(unsigned x, unsigned r, unsigned n, unsigned N, bool invert, const Policy&)
|
||||
{
|
||||
BOOST_FPU_EXCEPTION_GUARD
|
||||
typedef typename tools::promote_args<T>::type result_type;
|
||||
typedef typename policies::evaluation<result_type, Policy>::type value_type;
|
||||
typedef typename policies::normalise<
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
policies::discrete_quantile<>,
|
||||
policies::assert_undefined<> >::type forwarding_policy;
|
||||
|
||||
value_type result;
|
||||
result = detail::hypergeometric_cdf_imp<value_type>(x, r, n, N, invert, forwarding_policy());
|
||||
if(result > 1)
|
||||
{
|
||||
result = 1;
|
||||
}
|
||||
if(result < 0)
|
||||
{
|
||||
result = 0;
|
||||
}
|
||||
return policies::checked_narrowing_cast<result_type, forwarding_policy>(result, "boost::math::hypergeometric_cdf<%1%>(%1%,%1%,%1%,%1%)");
|
||||
}
|
||||
|
||||
}}} // namespaces
|
||||
|
||||
#endif
|
||||
|
||||
488
test/external/boost/math/distributions/detail/hypergeometric_pdf.hpp
vendored
Normal file
488
test/external/boost/math/distributions/detail/hypergeometric_pdf.hpp
vendored
Normal file
@@ -0,0 +1,488 @@
|
||||
// Copyright 2008 Gautam Sewani
|
||||
// Copyright 2008 John Maddock
|
||||
//
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_MATH_DISTRIBUTIONS_DETAIL_HG_PDF_HPP
|
||||
#define BOOST_MATH_DISTRIBUTIONS_DETAIL_HG_PDF_HPP
|
||||
|
||||
#include <boost/math/constants/constants.hpp>
|
||||
#include <boost/math/special_functions/lanczos.hpp>
|
||||
#include <boost/math/special_functions/gamma.hpp>
|
||||
#include <boost/math/special_functions/pow.hpp>
|
||||
#include <boost/math/special_functions/prime.hpp>
|
||||
#include <boost/math/policies/error_handling.hpp>
|
||||
|
||||
#ifdef BOOST_MATH_INSTRUMENT
|
||||
#include <typeinfo>
|
||||
#endif
|
||||
|
||||
namespace boost{ namespace math{ namespace detail{
|
||||
|
||||
template <class T, class Func>
|
||||
void bubble_down_one(T* first, T* last, Func f)
|
||||
{
|
||||
using std::swap;
|
||||
T* next = first;
|
||||
++next;
|
||||
while((next != last) && (!f(*first, *next)))
|
||||
{
|
||||
swap(*first, *next);
|
||||
++first;
|
||||
++next;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
struct sort_functor
|
||||
{
|
||||
sort_functor(const T* exponents) : m_exponents(exponents){}
|
||||
bool operator()(int i, int j)
|
||||
{
|
||||
return m_exponents[i] > m_exponents[j];
|
||||
}
|
||||
private:
|
||||
const T* m_exponents;
|
||||
};
|
||||
|
||||
template <class T, class Lanczos, class Policy>
|
||||
T hypergeometric_pdf_lanczos_imp(T /*dummy*/, unsigned x, unsigned r, unsigned n, unsigned N, const Lanczos&, const Policy&)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
|
||||
BOOST_MATH_INSTRUMENT_FPU
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(x);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(r);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(n);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(N);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(typeid(Lanczos).name());
|
||||
|
||||
T bases[9] = {
|
||||
T(n) + Lanczos::g() + 0.5f,
|
||||
T(r) + Lanczos::g() + 0.5f,
|
||||
T(N - n) + Lanczos::g() + 0.5f,
|
||||
T(N - r) + Lanczos::g() + 0.5f,
|
||||
1 / (T(N) + Lanczos::g() + 0.5f),
|
||||
1 / (T(x) + Lanczos::g() + 0.5f),
|
||||
1 / (T(n - x) + Lanczos::g() + 0.5f),
|
||||
1 / (T(r - x) + Lanczos::g() + 0.5f),
|
||||
1 / (T(N - n - r + x) + Lanczos::g() + 0.5f)
|
||||
};
|
||||
T exponents[9] = {
|
||||
n + T(0.5f),
|
||||
r + T(0.5f),
|
||||
N - n + T(0.5f),
|
||||
N - r + T(0.5f),
|
||||
N + T(0.5f),
|
||||
x + T(0.5f),
|
||||
n - x + T(0.5f),
|
||||
r - x + T(0.5f),
|
||||
N - n - r + x + T(0.5f)
|
||||
};
|
||||
int base_e_factors[9] = {
|
||||
-1, -1, -1, -1, 1, 1, 1, 1, 1
|
||||
};
|
||||
int sorted_indexes[9] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8
|
||||
};
|
||||
#ifdef BOOST_MATH_INSTRUMENT
|
||||
BOOST_MATH_INSTRUMENT_FPU
|
||||
for(unsigned i = 0; i < 9; ++i)
|
||||
{
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(i);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(bases[i]);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(exponents[i]);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(base_e_factors[i]);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(sorted_indexes[i]);
|
||||
}
|
||||
#endif
|
||||
std::sort(sorted_indexes, sorted_indexes + 9, sort_functor<T>(exponents));
|
||||
#ifdef BOOST_MATH_INSTRUMENT
|
||||
BOOST_MATH_INSTRUMENT_FPU
|
||||
for(unsigned i = 0; i < 9; ++i)
|
||||
{
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(i);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(bases[i]);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(exponents[i]);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(base_e_factors[i]);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(sorted_indexes[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
do{
|
||||
exponents[sorted_indexes[0]] -= exponents[sorted_indexes[1]];
|
||||
bases[sorted_indexes[1]] *= bases[sorted_indexes[0]];
|
||||
if((bases[sorted_indexes[1]] < tools::min_value<T>()) && (exponents[sorted_indexes[1]] != 0))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
base_e_factors[sorted_indexes[1]] += base_e_factors[sorted_indexes[0]];
|
||||
bubble_down_one(sorted_indexes, sorted_indexes + 9, sort_functor<T>(exponents));
|
||||
|
||||
#ifdef BOOST_MATH_INSTRUMENT
|
||||
for(unsigned i = 0; i < 9; ++i)
|
||||
{
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(i);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(bases[i]);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(exponents[i]);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(base_e_factors[i]);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(sorted_indexes[i]);
|
||||
}
|
||||
#endif
|
||||
}while(exponents[sorted_indexes[1]] > 1);
|
||||
|
||||
//
|
||||
// Combine equal powers:
|
||||
//
|
||||
int j = 8;
|
||||
while(exponents[sorted_indexes[j]] == 0) --j;
|
||||
while(j)
|
||||
{
|
||||
while(j && (exponents[sorted_indexes[j-1]] == exponents[sorted_indexes[j]]))
|
||||
{
|
||||
bases[sorted_indexes[j-1]] *= bases[sorted_indexes[j]];
|
||||
exponents[sorted_indexes[j]] = 0;
|
||||
base_e_factors[sorted_indexes[j-1]] += base_e_factors[sorted_indexes[j]];
|
||||
bubble_down_one(sorted_indexes + j, sorted_indexes + 9, sort_functor<T>(exponents));
|
||||
--j;
|
||||
}
|
||||
--j;
|
||||
|
||||
#ifdef BOOST_MATH_INSTRUMENT
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(j);
|
||||
for(unsigned i = 0; i < 9; ++i)
|
||||
{
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(i);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(bases[i]);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(exponents[i]);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(base_e_factors[i]);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(sorted_indexes[i]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef BOOST_MATH_INSTRUMENT
|
||||
BOOST_MATH_INSTRUMENT_FPU
|
||||
for(unsigned i = 0; i < 9; ++i)
|
||||
{
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(i);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(bases[i]);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(exponents[i]);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(base_e_factors[i]);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(sorted_indexes[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
T result;
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(bases[sorted_indexes[0]] * exp(static_cast<T>(base_e_factors[sorted_indexes[0]])));
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(exponents[sorted_indexes[0]]);
|
||||
{
|
||||
BOOST_FPU_EXCEPTION_GUARD
|
||||
result = pow(bases[sorted_indexes[0]] * exp(static_cast<T>(base_e_factors[sorted_indexes[0]])), exponents[sorted_indexes[0]]);
|
||||
}
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(result);
|
||||
for(unsigned i = 1; (i < 9) && (exponents[sorted_indexes[i]] > 0); ++i)
|
||||
{
|
||||
BOOST_FPU_EXCEPTION_GUARD
|
||||
if(result < tools::min_value<T>())
|
||||
return 0; // short circuit further evaluation
|
||||
if(exponents[sorted_indexes[i]] == 1)
|
||||
result *= bases[sorted_indexes[i]] * exp(static_cast<T>(base_e_factors[sorted_indexes[i]]));
|
||||
else if(exponents[sorted_indexes[i]] == 0.5f)
|
||||
result *= sqrt(bases[sorted_indexes[i]] * exp(static_cast<T>(base_e_factors[sorted_indexes[i]])));
|
||||
else
|
||||
result *= pow(bases[sorted_indexes[i]] * exp(static_cast<T>(base_e_factors[sorted_indexes[i]])), exponents[sorted_indexes[i]]);
|
||||
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(result);
|
||||
}
|
||||
|
||||
result *= Lanczos::lanczos_sum_expG_scaled(static_cast<T>(n + 1))
|
||||
* Lanczos::lanczos_sum_expG_scaled(static_cast<T>(r + 1))
|
||||
* Lanczos::lanczos_sum_expG_scaled(static_cast<T>(N - n + 1))
|
||||
* Lanczos::lanczos_sum_expG_scaled(static_cast<T>(N - r + 1))
|
||||
/
|
||||
( Lanczos::lanczos_sum_expG_scaled(static_cast<T>(N + 1))
|
||||
* Lanczos::lanczos_sum_expG_scaled(static_cast<T>(x + 1))
|
||||
* Lanczos::lanczos_sum_expG_scaled(static_cast<T>(n - x + 1))
|
||||
* Lanczos::lanczos_sum_expG_scaled(static_cast<T>(r - x + 1))
|
||||
* Lanczos::lanczos_sum_expG_scaled(static_cast<T>(N - n - r + x + 1)));
|
||||
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class T, class Policy>
|
||||
T hypergeometric_pdf_lanczos_imp(T /*dummy*/, unsigned x, unsigned r, unsigned n, unsigned N, const boost::math::lanczos::undefined_lanczos&, const Policy& pol)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
return exp(
|
||||
boost::math::lgamma(T(n + 1), pol)
|
||||
+ boost::math::lgamma(T(r + 1), pol)
|
||||
+ boost::math::lgamma(T(N - n + 1), pol)
|
||||
+ boost::math::lgamma(T(N - r + 1), pol)
|
||||
- boost::math::lgamma(T(N + 1), pol)
|
||||
- boost::math::lgamma(T(x + 1), pol)
|
||||
- boost::math::lgamma(T(n - x + 1), pol)
|
||||
- boost::math::lgamma(T(r - x + 1), pol)
|
||||
- boost::math::lgamma(T(N - n - r + x + 1), pol));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T integer_power(const T& x, int ex)
|
||||
{
|
||||
if(ex < 0)
|
||||
return 1 / integer_power(x, -ex);
|
||||
switch(ex)
|
||||
{
|
||||
case 0:
|
||||
return 1;
|
||||
case 1:
|
||||
return x;
|
||||
case 2:
|
||||
return x * x;
|
||||
case 3:
|
||||
return x * x * x;
|
||||
case 4:
|
||||
return boost::math::pow<4>(x);
|
||||
case 5:
|
||||
return boost::math::pow<5>(x);
|
||||
case 6:
|
||||
return boost::math::pow<6>(x);
|
||||
case 7:
|
||||
return boost::math::pow<7>(x);
|
||||
case 8:
|
||||
return boost::math::pow<8>(x);
|
||||
}
|
||||
BOOST_MATH_STD_USING
|
||||
#ifdef __SUNPRO_CC
|
||||
return pow(x, T(ex));
|
||||
#else
|
||||
return pow(x, ex);
|
||||
#endif
|
||||
}
|
||||
template <class T>
|
||||
struct hypergeometric_pdf_prime_loop_result_entry
|
||||
{
|
||||
T value;
|
||||
const hypergeometric_pdf_prime_loop_result_entry* next;
|
||||
};
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4510 4512 4610)
|
||||
#endif
|
||||
|
||||
struct hypergeometric_pdf_prime_loop_data
|
||||
{
|
||||
const unsigned x;
|
||||
const unsigned r;
|
||||
const unsigned n;
|
||||
const unsigned N;
|
||||
unsigned prime_index;
|
||||
unsigned current_prime;
|
||||
};
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
T hypergeometric_pdf_prime_loop_imp(hypergeometric_pdf_prime_loop_data& data, hypergeometric_pdf_prime_loop_result_entry<T>& result)
|
||||
{
|
||||
while(data.current_prime <= data.N)
|
||||
{
|
||||
unsigned base = data.current_prime;
|
||||
int prime_powers = 0;
|
||||
while(base <= data.N)
|
||||
{
|
||||
prime_powers += data.n / base;
|
||||
prime_powers += data.r / base;
|
||||
prime_powers += (data.N - data.n) / base;
|
||||
prime_powers += (data.N - data.r) / base;
|
||||
prime_powers -= data.N / base;
|
||||
prime_powers -= data.x / base;
|
||||
prime_powers -= (data.n - data.x) / base;
|
||||
prime_powers -= (data.r - data.x) / base;
|
||||
prime_powers -= (data.N - data.n - data.r + data.x) / base;
|
||||
base *= data.current_prime;
|
||||
}
|
||||
if(prime_powers)
|
||||
{
|
||||
T p = integer_power<T>(data.current_prime, prime_powers);
|
||||
if((p > 1) && (tools::max_value<T>() / p < result.value))
|
||||
{
|
||||
//
|
||||
// The next calculation would overflow, use recursion
|
||||
// to sidestep the issue:
|
||||
//
|
||||
hypergeometric_pdf_prime_loop_result_entry<T> t = { p, &result };
|
||||
data.current_prime = prime(++data.prime_index);
|
||||
return hypergeometric_pdf_prime_loop_imp<T>(data, t);
|
||||
}
|
||||
if((p < 1) && (tools::min_value<T>() / p > result.value))
|
||||
{
|
||||
//
|
||||
// The next calculation would underflow, use recursion
|
||||
// to sidestep the issue:
|
||||
//
|
||||
hypergeometric_pdf_prime_loop_result_entry<T> t = { p, &result };
|
||||
data.current_prime = prime(++data.prime_index);
|
||||
return hypergeometric_pdf_prime_loop_imp<T>(data, t);
|
||||
}
|
||||
result.value *= p;
|
||||
}
|
||||
data.current_prime = prime(++data.prime_index);
|
||||
}
|
||||
//
|
||||
// When we get to here we have run out of prime factors,
|
||||
// the overall result is the product of all the partial
|
||||
// results we have accumulated on the stack so far, these
|
||||
// are in a linked list starting with "data.head" and ending
|
||||
// with "result".
|
||||
//
|
||||
// All that remains is to multiply them together, taking
|
||||
// care not to overflow or underflow.
|
||||
//
|
||||
// Enumerate partial results >= 1 in variable i
|
||||
// and partial results < 1 in variable j:
|
||||
//
|
||||
hypergeometric_pdf_prime_loop_result_entry<T> const *i, *j;
|
||||
i = &result;
|
||||
while(i && i->value < 1)
|
||||
i = i->next;
|
||||
j = &result;
|
||||
while(j && j->value >= 1)
|
||||
j = j->next;
|
||||
|
||||
T prod = 1;
|
||||
|
||||
while(i || j)
|
||||
{
|
||||
while(i && ((prod <= 1) || (j == 0)))
|
||||
{
|
||||
prod *= i->value;
|
||||
i = i->next;
|
||||
while(i && i->value < 1)
|
||||
i = i->next;
|
||||
}
|
||||
while(j && ((prod >= 1) || (i == 0)))
|
||||
{
|
||||
prod *= j->value;
|
||||
j = j->next;
|
||||
while(j && j->value >= 1)
|
||||
j = j->next;
|
||||
}
|
||||
}
|
||||
|
||||
return prod;
|
||||
}
|
||||
|
||||
template <class T, class Policy>
|
||||
inline T hypergeometric_pdf_prime_imp(unsigned x, unsigned r, unsigned n, unsigned N, const Policy&)
|
||||
{
|
||||
hypergeometric_pdf_prime_loop_result_entry<T> result = { 1, 0 };
|
||||
hypergeometric_pdf_prime_loop_data data = { x, r, n, N, 0, prime(0) };
|
||||
return hypergeometric_pdf_prime_loop_imp<T>(data, result);
|
||||
}
|
||||
|
||||
template <class T, class Policy>
|
||||
T hypergeometric_pdf_factorial_imp(unsigned x, unsigned r, unsigned n, unsigned N, const Policy&)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
BOOST_ASSERT(N < boost::math::max_factorial<T>::value);
|
||||
T result = boost::math::unchecked_factorial<T>(n);
|
||||
T num[3] = {
|
||||
boost::math::unchecked_factorial<T>(r),
|
||||
boost::math::unchecked_factorial<T>(N - n),
|
||||
boost::math::unchecked_factorial<T>(N - r)
|
||||
};
|
||||
T denom[5] = {
|
||||
boost::math::unchecked_factorial<T>(N),
|
||||
boost::math::unchecked_factorial<T>(x),
|
||||
boost::math::unchecked_factorial<T>(n - x),
|
||||
boost::math::unchecked_factorial<T>(r - x),
|
||||
boost::math::unchecked_factorial<T>(N - n - r + x)
|
||||
};
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
while((i < 3) || (j < 5))
|
||||
{
|
||||
while((j < 5) && ((result >= 1) || (i >= 3)))
|
||||
{
|
||||
result /= denom[j];
|
||||
++j;
|
||||
}
|
||||
while((i < 3) && ((result <= 1) || (j >= 5)))
|
||||
{
|
||||
result *= num[i];
|
||||
++i;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
template <class T, class Policy>
|
||||
inline typename tools::promote_args<T>::type
|
||||
hypergeometric_pdf(unsigned x, unsigned r, unsigned n, unsigned N, const Policy&)
|
||||
{
|
||||
BOOST_FPU_EXCEPTION_GUARD
|
||||
typedef typename tools::promote_args<T>::type result_type;
|
||||
typedef typename policies::evaluation<result_type, Policy>::type value_type;
|
||||
typedef typename lanczos::lanczos<value_type, Policy>::type evaluation_type;
|
||||
typedef typename policies::normalise<
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
policies::discrete_quantile<>,
|
||||
policies::assert_undefined<> >::type forwarding_policy;
|
||||
|
||||
value_type result;
|
||||
if(N <= boost::math::max_factorial<value_type>::value)
|
||||
{
|
||||
//
|
||||
// If N is small enough then we can evaluate the PDF via the factorials
|
||||
// directly: table lookup of the factorials gives the best performance
|
||||
// of the methods available:
|
||||
//
|
||||
result = detail::hypergeometric_pdf_factorial_imp<value_type>(x, r, n, N, forwarding_policy());
|
||||
}
|
||||
else if(N <= boost::math::prime(boost::math::max_prime - 1))
|
||||
{
|
||||
//
|
||||
// If N is no larger than the largest prime number in our lookup table
|
||||
// (104729) then we can use prime factorisation to evaluate the PDF,
|
||||
// this is slow but accurate:
|
||||
//
|
||||
result = detail::hypergeometric_pdf_prime_imp<value_type>(x, r, n, N, forwarding_policy());
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Catch all case - use the lanczos approximation - where available -
|
||||
// to evaluate the ratio of factorials. This is reasonably fast
|
||||
// (almost as quick as using logarithmic evaluation in terms of lgamma)
|
||||
// but only a few digits better in accuracy than using lgamma:
|
||||
//
|
||||
result = detail::hypergeometric_pdf_lanczos_imp(value_type(), x, r, n, N, evaluation_type(), forwarding_policy());
|
||||
}
|
||||
|
||||
if(result > 1)
|
||||
{
|
||||
result = 1;
|
||||
}
|
||||
if(result < 0)
|
||||
{
|
||||
result = 0;
|
||||
}
|
||||
|
||||
return policies::checked_narrowing_cast<result_type, forwarding_policy>(result, "boost::math::hypergeometric_pdf<%1%>(%1%,%1%,%1%,%1%)");
|
||||
}
|
||||
|
||||
}}} // namespaces
|
||||
|
||||
#endif
|
||||
|
||||
199
test/external/boost/math/distributions/detail/hypergeometric_quantile.hpp
vendored
Normal file
199
test/external/boost/math/distributions/detail/hypergeometric_quantile.hpp
vendored
Normal file
@@ -0,0 +1,199 @@
|
||||
// Copyright 2008 John Maddock
|
||||
//
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_MATH_DISTRIBUTIONS_DETAIL_HG_QUANTILE_HPP
|
||||
#define BOOST_MATH_DISTRIBUTIONS_DETAIL_HG_QUANTILE_HPP
|
||||
|
||||
#include <boost/math/policies/error_handling.hpp>
|
||||
#include <boost/math/distributions/detail/hypergeometric_pdf.hpp>
|
||||
|
||||
namespace boost{ namespace math{ namespace detail{
|
||||
|
||||
template <class T>
|
||||
inline unsigned round_x_from_p(unsigned x, T p, T cum, T fudge_factor, unsigned lbound, unsigned /*ubound*/, const policies::discrete_quantile<policies::integer_round_down>&)
|
||||
{
|
||||
if((p < cum * fudge_factor) && (x != lbound))
|
||||
{
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(x-1);
|
||||
return --x;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline unsigned round_x_from_p(unsigned x, T p, T cum, T fudge_factor, unsigned /*lbound*/, unsigned ubound, const policies::discrete_quantile<policies::integer_round_up>&)
|
||||
{
|
||||
if((cum < p * fudge_factor) && (x != ubound))
|
||||
{
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(x+1);
|
||||
return ++x;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline unsigned round_x_from_p(unsigned x, T p, T cum, T fudge_factor, unsigned lbound, unsigned ubound, const policies::discrete_quantile<policies::integer_round_inwards>&)
|
||||
{
|
||||
if(p >= 0.5)
|
||||
return round_x_from_p(x, p, cum, fudge_factor, lbound, ubound, policies::discrete_quantile<policies::integer_round_down>());
|
||||
return round_x_from_p(x, p, cum, fudge_factor, lbound, ubound, policies::discrete_quantile<policies::integer_round_up>());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline unsigned round_x_from_p(unsigned x, T p, T cum, T fudge_factor, unsigned lbound, unsigned ubound, const policies::discrete_quantile<policies::integer_round_outwards>&)
|
||||
{
|
||||
if(p >= 0.5)
|
||||
return round_x_from_p(x, p, cum, fudge_factor, lbound, ubound, policies::discrete_quantile<policies::integer_round_up>());
|
||||
return round_x_from_p(x, p, cum, fudge_factor, lbound, ubound, policies::discrete_quantile<policies::integer_round_down>());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline unsigned round_x_from_p(unsigned x, T /*p*/, T /*cum*/, T /*fudge_factor*/, unsigned /*lbound*/, unsigned /*ubound*/, const policies::discrete_quantile<policies::integer_round_nearest>&)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline unsigned round_x_from_q(unsigned x, T q, T cum, T fudge_factor, unsigned lbound, unsigned /*ubound*/, const policies::discrete_quantile<policies::integer_round_down>&)
|
||||
{
|
||||
if((q * fudge_factor > cum) && (x != lbound))
|
||||
{
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(x-1);
|
||||
return --x;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline unsigned round_x_from_q(unsigned x, T q, T cum, T fudge_factor, unsigned /*lbound*/, unsigned ubound, const policies::discrete_quantile<policies::integer_round_up>&)
|
||||
{
|
||||
if((q < cum * fudge_factor) && (x != ubound))
|
||||
{
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(x+1);
|
||||
return ++x;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline unsigned round_x_from_q(unsigned x, T q, T cum, T fudge_factor, unsigned lbound, unsigned ubound, const policies::discrete_quantile<policies::integer_round_inwards>&)
|
||||
{
|
||||
if(q < 0.5)
|
||||
return round_x_from_q(x, q, cum, fudge_factor, lbound, ubound, policies::discrete_quantile<policies::integer_round_down>());
|
||||
return round_x_from_q(x, q, cum, fudge_factor, lbound, ubound, policies::discrete_quantile<policies::integer_round_up>());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline unsigned round_x_from_q(unsigned x, T q, T cum, T fudge_factor, unsigned lbound, unsigned ubound, const policies::discrete_quantile<policies::integer_round_outwards>&)
|
||||
{
|
||||
if(q >= 0.5)
|
||||
return round_x_from_q(x, q, cum, fudge_factor, lbound, ubound, policies::discrete_quantile<policies::integer_round_down>());
|
||||
return round_x_from_q(x, q, cum, fudge_factor, lbound, ubound, policies::discrete_quantile<policies::integer_round_up>());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline unsigned round_x_from_q(unsigned x, T /*q*/, T /*cum*/, T /*fudge_factor*/, unsigned /*lbound*/, unsigned /*ubound*/, const policies::discrete_quantile<policies::integer_round_nearest>&)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
template <class T, class Policy>
|
||||
unsigned hypergeometric_quantile_imp(T p, T q, unsigned r, unsigned n, unsigned N, const Policy& pol)
|
||||
{
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4267)
|
||||
#endif
|
||||
typedef typename Policy::discrete_quantile_type discrete_quantile_type;
|
||||
BOOST_MATH_STD_USING
|
||||
BOOST_FPU_EXCEPTION_GUARD
|
||||
T result;
|
||||
T fudge_factor = 1 + tools::epsilon<T>() * ((N <= boost::math::prime(boost::math::max_prime - 1)) ? 50 : 2 * N);
|
||||
unsigned base = static_cast<unsigned>((std::max)(0, (int)(n + r) - (int)(N)));
|
||||
unsigned lim = (std::min)(r, n);
|
||||
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(p);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(q);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(r);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(n);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(N);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(fudge_factor);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(base);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(lim);
|
||||
|
||||
if(p <= 0.5)
|
||||
{
|
||||
unsigned x = base;
|
||||
result = hypergeometric_pdf<T>(x, r, n, N, pol);
|
||||
T diff = result;
|
||||
while(result < p)
|
||||
{
|
||||
diff = (diff > tools::min_value<T>() * 8)
|
||||
? T(n - x) * T(r - x) * diff / (T(x + 1) * T(N + x + 1 - n - r))
|
||||
: hypergeometric_pdf<T>(x + 1, r, n, N, pol);
|
||||
if(result + diff / 2 > p)
|
||||
break;
|
||||
++x;
|
||||
result += diff;
|
||||
#ifdef BOOST_MATH_INSTRUMENT
|
||||
if(diff != 0)
|
||||
{
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(x);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(diff);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(result);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return round_x_from_p(x, p, result, fudge_factor, base, lim, discrete_quantile_type());
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned x = lim;
|
||||
result = 0;
|
||||
T diff = hypergeometric_pdf<T>(x, r, n, N, pol);
|
||||
while(result + diff / 2 < q)
|
||||
{
|
||||
result += diff;
|
||||
diff = (diff > tools::min_value<T>() * 8)
|
||||
? x * T(N + x - n - r) * diff / (T(1 + n - x) * T(1 + r - x))
|
||||
: hypergeometric_pdf<T>(x - 1, r, n, N, pol);
|
||||
--x;
|
||||
#ifdef BOOST_MATH_INSTRUMENT
|
||||
if(diff != 0)
|
||||
{
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(x);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(diff);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(result);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return round_x_from_q(x, q, result, fudge_factor, base, lim, discrete_quantile_type());
|
||||
}
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class T, class Policy>
|
||||
inline unsigned hypergeometric_quantile(T p, T q, unsigned r, unsigned n, unsigned N, const Policy&)
|
||||
{
|
||||
BOOST_FPU_EXCEPTION_GUARD
|
||||
typedef typename tools::promote_args<T>::type result_type;
|
||||
typedef typename policies::evaluation<result_type, Policy>::type value_type;
|
||||
typedef typename policies::normalise<
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
policies::assert_undefined<> >::type forwarding_policy;
|
||||
|
||||
return detail::hypergeometric_quantile_imp<value_type>(p, q, r, n, N, forwarding_policy());
|
||||
}
|
||||
|
||||
}}} // namespaces
|
||||
|
||||
#endif
|
||||
|
||||
481
test/external/boost/math/distributions/detail/inv_discrete_quantile.hpp
vendored
Normal file
481
test/external/boost/math/distributions/detail/inv_discrete_quantile.hpp
vendored
Normal file
@@ -0,0 +1,481 @@
|
||||
// Copyright John Maddock 2007.
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_MATH_DISTRIBUTIONS_DETAIL_INV_DISCRETE_QUANTILE
|
||||
#define BOOST_MATH_DISTRIBUTIONS_DETAIL_INV_DISCRETE_QUANTILE
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace boost{ namespace math{ namespace detail{
|
||||
|
||||
//
|
||||
// Functor for root finding algorithm:
|
||||
//
|
||||
template <class Dist>
|
||||
struct distribution_quantile_finder
|
||||
{
|
||||
typedef typename Dist::value_type value_type;
|
||||
typedef typename Dist::policy_type policy_type;
|
||||
|
||||
distribution_quantile_finder(const Dist d, value_type p, value_type q)
|
||||
: dist(d), target(p < q ? p : q), comp(p < q ? false : true) {}
|
||||
|
||||
value_type operator()(value_type const& x)
|
||||
{
|
||||
return comp ? value_type(target - cdf(complement(dist, x))) : value_type(cdf(dist, x) - target);
|
||||
}
|
||||
|
||||
private:
|
||||
Dist dist;
|
||||
value_type target;
|
||||
bool comp;
|
||||
};
|
||||
//
|
||||
// The purpose of adjust_bounds, is to toggle the last bit of the
|
||||
// range so that both ends round to the same integer, if possible.
|
||||
// If they do both round the same then we terminate the search
|
||||
// for the root *very* quickly when finding an integer result.
|
||||
// At the point that this function is called we know that "a" is
|
||||
// below the root and "b" above it, so this change can not result
|
||||
// in the root no longer being bracketed.
|
||||
//
|
||||
template <class Real, class Tol>
|
||||
void adjust_bounds(Real& /* a */, Real& /* b */, Tol const& /* tol */){}
|
||||
|
||||
template <class Real>
|
||||
void adjust_bounds(Real& /* a */, Real& b, tools::equal_floor const& /* tol */)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
b -= tools::epsilon<Real>() * b;
|
||||
}
|
||||
|
||||
template <class Real>
|
||||
void adjust_bounds(Real& a, Real& /* b */, tools::equal_ceil const& /* tol */)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
a += tools::epsilon<Real>() * a;
|
||||
}
|
||||
|
||||
template <class Real>
|
||||
void adjust_bounds(Real& a, Real& b, tools::equal_nearest_integer const& /* tol */)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
a += tools::epsilon<Real>() * a;
|
||||
b -= tools::epsilon<Real>() * b;
|
||||
}
|
||||
//
|
||||
// This is where all the work is done:
|
||||
//
|
||||
template <class Dist, class Tolerance>
|
||||
typename Dist::value_type
|
||||
do_inverse_discrete_quantile(
|
||||
const Dist& dist,
|
||||
const typename Dist::value_type& p,
|
||||
const typename Dist::value_type& q,
|
||||
typename Dist::value_type guess,
|
||||
const typename Dist::value_type& multiplier,
|
||||
typename Dist::value_type adder,
|
||||
const Tolerance& tol,
|
||||
boost::uintmax_t& max_iter)
|
||||
{
|
||||
typedef typename Dist::value_type value_type;
|
||||
typedef typename Dist::policy_type policy_type;
|
||||
|
||||
static const char* function = "boost::math::do_inverse_discrete_quantile<%1%>";
|
||||
|
||||
BOOST_MATH_STD_USING
|
||||
|
||||
distribution_quantile_finder<Dist> f(dist, p, q);
|
||||
//
|
||||
// Max bounds of the distribution:
|
||||
//
|
||||
value_type min_bound, max_bound;
|
||||
boost::math::tie(min_bound, max_bound) = support(dist);
|
||||
|
||||
if(guess > max_bound)
|
||||
guess = max_bound;
|
||||
if(guess < min_bound)
|
||||
guess = min_bound;
|
||||
|
||||
value_type fa = f(guess);
|
||||
boost::uintmax_t count = max_iter - 1;
|
||||
value_type fb(fa), a(guess), b =0; // Compiler warning C4701: potentially uninitialized local variable 'b' used
|
||||
|
||||
if(fa == 0)
|
||||
return guess;
|
||||
|
||||
//
|
||||
// For small expected results, just use a linear search:
|
||||
//
|
||||
if(guess < 10)
|
||||
{
|
||||
b = a;
|
||||
while((a < 10) && (fa * fb >= 0))
|
||||
{
|
||||
if(fb <= 0)
|
||||
{
|
||||
a = b;
|
||||
b = a + 1;
|
||||
if(b > max_bound)
|
||||
b = max_bound;
|
||||
fb = f(b);
|
||||
--count;
|
||||
if(fb == 0)
|
||||
return b;
|
||||
}
|
||||
else
|
||||
{
|
||||
b = a;
|
||||
a = (std::max)(value_type(b - 1), value_type(0));
|
||||
if(a < min_bound)
|
||||
a = min_bound;
|
||||
fa = f(a);
|
||||
--count;
|
||||
if(fa == 0)
|
||||
return a;
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// Try and bracket using a couple of additions first,
|
||||
// we're assuming that "guess" is likely to be accurate
|
||||
// to the nearest int or so:
|
||||
//
|
||||
else if(adder != 0)
|
||||
{
|
||||
//
|
||||
// If we're looking for a large result, then bump "adder" up
|
||||
// by a bit to increase our chances of bracketing the root:
|
||||
//
|
||||
//adder = (std::max)(adder, 0.001f * guess);
|
||||
if(fa < 0)
|
||||
{
|
||||
b = a + adder;
|
||||
if(b > max_bound)
|
||||
b = max_bound;
|
||||
}
|
||||
else
|
||||
{
|
||||
b = (std::max)(value_type(a - adder), value_type(0));
|
||||
if(b < min_bound)
|
||||
b = min_bound;
|
||||
}
|
||||
fb = f(b);
|
||||
--count;
|
||||
if(fb == 0)
|
||||
return b;
|
||||
if(count && (fa * fb >= 0))
|
||||
{
|
||||
//
|
||||
// We didn't bracket the root, try
|
||||
// once more:
|
||||
//
|
||||
a = b;
|
||||
fa = fb;
|
||||
if(fa < 0)
|
||||
{
|
||||
b = a + adder;
|
||||
if(b > max_bound)
|
||||
b = max_bound;
|
||||
}
|
||||
else
|
||||
{
|
||||
b = (std::max)(value_type(a - adder), value_type(0));
|
||||
if(b < min_bound)
|
||||
b = min_bound;
|
||||
}
|
||||
fb = f(b);
|
||||
--count;
|
||||
}
|
||||
if(a > b)
|
||||
{
|
||||
using std::swap;
|
||||
swap(a, b);
|
||||
swap(fa, fb);
|
||||
}
|
||||
}
|
||||
//
|
||||
// If the root hasn't been bracketed yet, try again
|
||||
// using the multiplier this time:
|
||||
//
|
||||
if((boost::math::sign)(fb) == (boost::math::sign)(fa))
|
||||
{
|
||||
if(fa < 0)
|
||||
{
|
||||
//
|
||||
// Zero is to the right of x2, so walk upwards
|
||||
// until we find it:
|
||||
//
|
||||
while((boost::math::sign)(fb) == (boost::math::sign)(fa))
|
||||
{
|
||||
if(count == 0)
|
||||
policies::raise_evaluation_error(function, "Unable to bracket root, last nearest value was %1%", b, policy_type());
|
||||
a = b;
|
||||
fa = fb;
|
||||
b *= multiplier;
|
||||
if(b > max_bound)
|
||||
b = max_bound;
|
||||
fb = f(b);
|
||||
--count;
|
||||
BOOST_MATH_INSTRUMENT_CODE("a = " << a << " b = " << b << " fa = " << fa << " fb = " << fb << " count = " << count);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Zero is to the left of a, so walk downwards
|
||||
// until we find it:
|
||||
//
|
||||
while((boost::math::sign)(fb) == (boost::math::sign)(fa))
|
||||
{
|
||||
if(fabs(a) < tools::min_value<value_type>())
|
||||
{
|
||||
// Escape route just in case the answer is zero!
|
||||
max_iter -= count;
|
||||
max_iter += 1;
|
||||
return 0;
|
||||
}
|
||||
if(count == 0)
|
||||
policies::raise_evaluation_error(function, "Unable to bracket root, last nearest value was %1%", a, policy_type());
|
||||
b = a;
|
||||
fb = fa;
|
||||
a /= multiplier;
|
||||
if(a < min_bound)
|
||||
a = min_bound;
|
||||
fa = f(a);
|
||||
--count;
|
||||
BOOST_MATH_INSTRUMENT_CODE("a = " << a << " b = " << b << " fa = " << fa << " fb = " << fb << " count = " << count);
|
||||
}
|
||||
}
|
||||
}
|
||||
max_iter -= count;
|
||||
if(fa == 0)
|
||||
return a;
|
||||
if(fb == 0)
|
||||
return b;
|
||||
//
|
||||
// Adjust bounds so that if we're looking for an integer
|
||||
// result, then both ends round the same way:
|
||||
//
|
||||
adjust_bounds(a, b, tol);
|
||||
//
|
||||
// We don't want zero or denorm lower bounds:
|
||||
//
|
||||
if(a < tools::min_value<value_type>())
|
||||
a = tools::min_value<value_type>();
|
||||
//
|
||||
// Go ahead and find the root:
|
||||
//
|
||||
std::pair<value_type, value_type> r = toms748_solve(f, a, b, fa, fb, tol, count, policy_type());
|
||||
max_iter += count;
|
||||
BOOST_MATH_INSTRUMENT_CODE("max_iter = " << max_iter << " count = " << count);
|
||||
return (r.first + r.second) / 2;
|
||||
}
|
||||
//
|
||||
// Now finally are the public API functions.
|
||||
// There is one overload for each policy,
|
||||
// each one is responsible for selecting the correct
|
||||
// termination condition, and rounding the result
|
||||
// to an int where required.
|
||||
//
|
||||
template <class Dist>
|
||||
inline typename Dist::value_type
|
||||
inverse_discrete_quantile(
|
||||
const Dist& dist,
|
||||
const typename Dist::value_type& p,
|
||||
const typename Dist::value_type& q,
|
||||
const typename Dist::value_type& guess,
|
||||
const typename Dist::value_type& multiplier,
|
||||
const typename Dist::value_type& adder,
|
||||
const policies::discrete_quantile<policies::real>&,
|
||||
boost::uintmax_t& max_iter)
|
||||
{
|
||||
if(p <= pdf(dist, 0))
|
||||
return 0;
|
||||
return do_inverse_discrete_quantile(
|
||||
dist,
|
||||
p,
|
||||
q,
|
||||
guess,
|
||||
multiplier,
|
||||
adder,
|
||||
tools::eps_tolerance<typename Dist::value_type>(policies::digits<typename Dist::value_type, typename Dist::policy_type>()),
|
||||
max_iter);
|
||||
}
|
||||
|
||||
template <class Dist>
|
||||
inline typename Dist::value_type
|
||||
inverse_discrete_quantile(
|
||||
const Dist& dist,
|
||||
const typename Dist::value_type& p,
|
||||
const typename Dist::value_type& q,
|
||||
const typename Dist::value_type& guess,
|
||||
const typename Dist::value_type& multiplier,
|
||||
const typename Dist::value_type& adder,
|
||||
const policies::discrete_quantile<policies::integer_round_outwards>&,
|
||||
boost::uintmax_t& max_iter)
|
||||
{
|
||||
typedef typename Dist::value_type value_type;
|
||||
BOOST_MATH_STD_USING
|
||||
if(p <= pdf(dist, 0))
|
||||
return 0;
|
||||
//
|
||||
// What happens next depends on whether we're looking for an
|
||||
// upper or lower quantile:
|
||||
//
|
||||
if(p < 0.5f)
|
||||
return floor(do_inverse_discrete_quantile(
|
||||
dist,
|
||||
p,
|
||||
q,
|
||||
(guess < 1 ? value_type(1) : (value_type)floor(guess)),
|
||||
multiplier,
|
||||
adder,
|
||||
tools::equal_floor(),
|
||||
max_iter));
|
||||
// else:
|
||||
return ceil(do_inverse_discrete_quantile(
|
||||
dist,
|
||||
p,
|
||||
q,
|
||||
(value_type)ceil(guess),
|
||||
multiplier,
|
||||
adder,
|
||||
tools::equal_ceil(),
|
||||
max_iter));
|
||||
}
|
||||
|
||||
template <class Dist>
|
||||
inline typename Dist::value_type
|
||||
inverse_discrete_quantile(
|
||||
const Dist& dist,
|
||||
const typename Dist::value_type& p,
|
||||
const typename Dist::value_type& q,
|
||||
const typename Dist::value_type& guess,
|
||||
const typename Dist::value_type& multiplier,
|
||||
const typename Dist::value_type& adder,
|
||||
const policies::discrete_quantile<policies::integer_round_inwards>&,
|
||||
boost::uintmax_t& max_iter)
|
||||
{
|
||||
typedef typename Dist::value_type value_type;
|
||||
BOOST_MATH_STD_USING
|
||||
if(p <= pdf(dist, 0))
|
||||
return 0;
|
||||
//
|
||||
// What happens next depends on whether we're looking for an
|
||||
// upper or lower quantile:
|
||||
//
|
||||
if(p < 0.5f)
|
||||
return ceil(do_inverse_discrete_quantile(
|
||||
dist,
|
||||
p,
|
||||
q,
|
||||
ceil(guess),
|
||||
multiplier,
|
||||
adder,
|
||||
tools::equal_ceil(),
|
||||
max_iter));
|
||||
// else:
|
||||
return floor(do_inverse_discrete_quantile(
|
||||
dist,
|
||||
p,
|
||||
q,
|
||||
(guess < 1 ? value_type(1) : floor(guess)),
|
||||
multiplier,
|
||||
adder,
|
||||
tools::equal_floor(),
|
||||
max_iter));
|
||||
}
|
||||
|
||||
template <class Dist>
|
||||
inline typename Dist::value_type
|
||||
inverse_discrete_quantile(
|
||||
const Dist& dist,
|
||||
const typename Dist::value_type& p,
|
||||
const typename Dist::value_type& q,
|
||||
const typename Dist::value_type& guess,
|
||||
const typename Dist::value_type& multiplier,
|
||||
const typename Dist::value_type& adder,
|
||||
const policies::discrete_quantile<policies::integer_round_down>&,
|
||||
boost::uintmax_t& max_iter)
|
||||
{
|
||||
typedef typename Dist::value_type value_type;
|
||||
BOOST_MATH_STD_USING
|
||||
if(p <= pdf(dist, 0))
|
||||
return 0;
|
||||
return floor(do_inverse_discrete_quantile(
|
||||
dist,
|
||||
p,
|
||||
q,
|
||||
(guess < 1 ? value_type(1) : floor(guess)),
|
||||
multiplier,
|
||||
adder,
|
||||
tools::equal_floor(),
|
||||
max_iter));
|
||||
}
|
||||
|
||||
template <class Dist>
|
||||
inline typename Dist::value_type
|
||||
inverse_discrete_quantile(
|
||||
const Dist& dist,
|
||||
const typename Dist::value_type& p,
|
||||
const typename Dist::value_type& q,
|
||||
const typename Dist::value_type& guess,
|
||||
const typename Dist::value_type& multiplier,
|
||||
const typename Dist::value_type& adder,
|
||||
const policies::discrete_quantile<policies::integer_round_up>&,
|
||||
boost::uintmax_t& max_iter)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
if(p <= pdf(dist, 0))
|
||||
return 0;
|
||||
return ceil(do_inverse_discrete_quantile(
|
||||
dist,
|
||||
p,
|
||||
q,
|
||||
ceil(guess),
|
||||
multiplier,
|
||||
adder,
|
||||
tools::equal_ceil(),
|
||||
max_iter));
|
||||
}
|
||||
|
||||
template <class Dist>
|
||||
inline typename Dist::value_type
|
||||
inverse_discrete_quantile(
|
||||
const Dist& dist,
|
||||
const typename Dist::value_type& p,
|
||||
const typename Dist::value_type& q,
|
||||
const typename Dist::value_type& guess,
|
||||
const typename Dist::value_type& multiplier,
|
||||
const typename Dist::value_type& adder,
|
||||
const policies::discrete_quantile<policies::integer_round_nearest>&,
|
||||
boost::uintmax_t& max_iter)
|
||||
{
|
||||
typedef typename Dist::value_type value_type;
|
||||
BOOST_MATH_STD_USING
|
||||
if(p <= pdf(dist, 0))
|
||||
return 0;
|
||||
//
|
||||
// Note that we adjust the guess to the nearest half-integer:
|
||||
// this increase the chances that we will bracket the root
|
||||
// with two results that both round to the same integer quickly.
|
||||
//
|
||||
return floor(do_inverse_discrete_quantile(
|
||||
dist,
|
||||
p,
|
||||
q,
|
||||
(guess < 0.5f ? value_type(1.5f) : floor(guess + 0.5f) + 0.5f),
|
||||
multiplier,
|
||||
adder,
|
||||
tools::equal_nearest_integer(),
|
||||
max_iter) + 0.5f);
|
||||
}
|
||||
|
||||
}}} // namespaces
|
||||
|
||||
#endif // BOOST_MATH_DISTRIBUTIONS_DETAIL_INV_DISCRETE_QUANTILE
|
||||
|
||||
|
||||
261
test/external/boost/math/distributions/exponential.hpp
vendored
Normal file
261
test/external/boost/math/distributions/exponential.hpp
vendored
Normal file
@@ -0,0 +1,261 @@
|
||||
// Copyright John Maddock 2006.
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_STATS_EXPONENTIAL_HPP
|
||||
#define BOOST_STATS_EXPONENTIAL_HPP
|
||||
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#include <boost/math/constants/constants.hpp>
|
||||
#include <boost/math/special_functions/log1p.hpp>
|
||||
#include <boost/math/special_functions/expm1.hpp>
|
||||
#include <boost/math/distributions/complement.hpp>
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp>
|
||||
#include <boost/config/no_tr1/cmath.hpp>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4702) // unreachable code (return after domain_error throw).
|
||||
#endif
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace boost{ namespace math{
|
||||
|
||||
namespace detail{
|
||||
//
|
||||
// Error check:
|
||||
//
|
||||
template <class RealType, class Policy>
|
||||
inline bool verify_lambda(const char* function, RealType l, RealType* presult, const Policy& pol)
|
||||
{
|
||||
if(l <= 0)
|
||||
{
|
||||
*presult = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"The scale parameter \"lambda\" must be > 0, but was: %1%.", l, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool verify_exp_x(const char* function, RealType x, RealType* presult, const Policy& pol)
|
||||
{
|
||||
if(x < 0)
|
||||
{
|
||||
*presult = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"The random variable must be >= 0, but was: %1%.", x, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class RealType = double, class Policy = policies::policy<> >
|
||||
class exponential_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
|
||||
exponential_distribution(RealType lambda = 1)
|
||||
: m_lambda(lambda)
|
||||
{
|
||||
RealType err;
|
||||
detail::verify_lambda("boost::math::exponential_distribution<%1%>::exponential_distribution", lambda, &err, Policy());
|
||||
} // exponential_distribution
|
||||
|
||||
RealType lambda()const { return m_lambda; }
|
||||
|
||||
private:
|
||||
RealType m_lambda;
|
||||
};
|
||||
|
||||
typedef exponential_distribution<double> exponential;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const exponential_distribution<RealType, Policy>& /*dist*/)
|
||||
{ // Range of permissible values for random variable x.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> support(const exponential_distribution<RealType, Policy>& /*dist*/)
|
||||
{ // Range of supported values for random variable x.
|
||||
// This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
|
||||
using boost::math::tools::max_value;
|
||||
using boost::math::tools::min_value;
|
||||
return std::pair<RealType, RealType>(min_value<RealType>(), max_value<RealType>());
|
||||
// min_value<RealType>() to avoid a discontinuity at x = 0.
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType pdf(const exponential_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::pdf(const exponential_distribution<%1%>&, %1%)";
|
||||
|
||||
RealType lambda = dist.lambda();
|
||||
RealType result = 0;
|
||||
if(0 == detail::verify_lambda(function, lambda, &result, Policy()))
|
||||
return result;
|
||||
if(0 == detail::verify_exp_x(function, x, &result, Policy()))
|
||||
return result;
|
||||
result = lambda * exp(-lambda * x);
|
||||
return result;
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const exponential_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::cdf(const exponential_distribution<%1%>&, %1%)";
|
||||
|
||||
RealType result = 0;
|
||||
RealType lambda = dist.lambda();
|
||||
if(0 == detail::verify_lambda(function, lambda, &result, Policy()))
|
||||
return result;
|
||||
if(0 == detail::verify_exp_x(function, x, &result, Policy()))
|
||||
return result;
|
||||
result = -boost::math::expm1(-x * lambda, Policy());
|
||||
|
||||
return result;
|
||||
} // cdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const exponential_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::quantile(const exponential_distribution<%1%>&, %1%)";
|
||||
|
||||
RealType result = 0;
|
||||
RealType lambda = dist.lambda();
|
||||
if(0 == detail::verify_lambda(function, lambda, &result, Policy()))
|
||||
return result;
|
||||
if(0 == detail::check_probability(function, p, &result, Policy()))
|
||||
return result;
|
||||
|
||||
if(p == 0)
|
||||
return 0;
|
||||
if(p == 1)
|
||||
return policies::raise_overflow_error<RealType>(function, 0, Policy());
|
||||
|
||||
result = -boost::math::log1p(-p, Policy()) / lambda;
|
||||
return result;
|
||||
} // quantile
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const complemented2_type<exponential_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::cdf(const exponential_distribution<%1%>&, %1%)";
|
||||
|
||||
RealType result = 0;
|
||||
RealType lambda = c.dist.lambda();
|
||||
if(0 == detail::verify_lambda(function, lambda, &result, Policy()))
|
||||
return result;
|
||||
if(0 == detail::verify_exp_x(function, c.param, &result, Policy()))
|
||||
return result;
|
||||
result = exp(-c.param * lambda);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const complemented2_type<exponential_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::quantile(const exponential_distribution<%1%>&, %1%)";
|
||||
|
||||
RealType result = 0;
|
||||
RealType lambda = c.dist.lambda();
|
||||
if(0 == detail::verify_lambda(function, lambda, &result, Policy()))
|
||||
return result;
|
||||
|
||||
RealType q = c.param;
|
||||
if(0 == detail::check_probability(function, q, &result, Policy()))
|
||||
return result;
|
||||
|
||||
if(q == 1)
|
||||
return 0;
|
||||
if(q == 0)
|
||||
return policies::raise_overflow_error<RealType>(function, 0, Policy());
|
||||
|
||||
result = -log(q) / lambda;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mean(const exponential_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType result = 0;
|
||||
RealType lambda = dist.lambda();
|
||||
if(0 == detail::verify_lambda("boost::math::mean(const exponential_distribution<%1%>&)", lambda, &result, Policy()))
|
||||
return result;
|
||||
return 1 / lambda;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType standard_deviation(const exponential_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType result = 0;
|
||||
RealType lambda = dist.lambda();
|
||||
if(0 == detail::verify_lambda("boost::math::standard_deviation(const exponential_distribution<%1%>&)", lambda, &result, Policy()))
|
||||
return result;
|
||||
return 1 / lambda;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mode(const exponential_distribution<RealType, Policy>& /*dist*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType median(const exponential_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
using boost::math::constants::ln_two;
|
||||
return ln_two<RealType>() / dist.lambda(); // ln(2) / lambda
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType skewness(const exponential_distribution<RealType, Policy>& /*dist*/)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis(const exponential_distribution<RealType, Policy>& /*dist*/)
|
||||
{
|
||||
return 9;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis_excess(const exponential_distribution<RealType, Policy>& /*dist*/)
|
||||
{
|
||||
return 6;
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
// This include must be at the end, *after* the accessors
|
||||
// for this distribution have been defined, in order to
|
||||
// keep compilers that support two-phase lookup happy.
|
||||
#include <boost/math/distributions/detail/derived_accessors.hpp>
|
||||
|
||||
#endif // BOOST_STATS_EXPONENTIAL_HPP
|
||||
260
test/external/boost/math/distributions/extreme_value.hpp
vendored
Normal file
260
test/external/boost/math/distributions/extreme_value.hpp
vendored
Normal file
@@ -0,0 +1,260 @@
|
||||
// Copyright John Maddock 2006.
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_STATS_EXTREME_VALUE_HPP
|
||||
#define BOOST_STATS_EXTREME_VALUE_HPP
|
||||
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#include <boost/math/constants/constants.hpp>
|
||||
#include <boost/math/special_functions/log1p.hpp>
|
||||
#include <boost/math/special_functions/expm1.hpp>
|
||||
#include <boost/math/distributions/complement.hpp>
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp>
|
||||
#include <boost/config/no_tr1/cmath.hpp>
|
||||
|
||||
//
|
||||
// This is the maximum extreme value distribution, see
|
||||
// http://www.itl.nist.gov/div898/handbook/eda/section3/eda366g.htm
|
||||
// and http://mathworld.wolfram.com/ExtremeValueDistribution.html
|
||||
// Also known as a Fisher-Tippett distribution, a log-Weibull
|
||||
// distribution or a Gumbel distribution.
|
||||
|
||||
#include <utility>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4702) // unreachable code (return after domain_error throw).
|
||||
#endif
|
||||
|
||||
namespace boost{ namespace math{
|
||||
|
||||
namespace detail{
|
||||
//
|
||||
// Error check:
|
||||
//
|
||||
template <class RealType, class Policy>
|
||||
inline bool verify_scale_b(const char* function, RealType b, RealType* presult, const Policy& pol)
|
||||
{
|
||||
if(b <= 0)
|
||||
{
|
||||
*presult = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"The scale parameter \"b\" must be > 0, but was: %1%.", b, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class RealType = double, class Policy = policies::policy<> >
|
||||
class extreme_value_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
|
||||
extreme_value_distribution(RealType a = 0, RealType b = 1)
|
||||
: m_a(a), m_b(b)
|
||||
{
|
||||
RealType err;
|
||||
detail::verify_scale_b("boost::math::extreme_value_distribution<%1%>::extreme_value_distribution", b, &err, Policy());
|
||||
} // extreme_value_distribution
|
||||
|
||||
RealType location()const { return m_a; }
|
||||
RealType scale()const { return m_b; }
|
||||
|
||||
private:
|
||||
RealType m_a, m_b;
|
||||
};
|
||||
|
||||
typedef extreme_value_distribution<double> extreme_value;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const extreme_value_distribution<RealType, Policy>& /*dist*/)
|
||||
{ // Range of permissible values for random variable x.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(-max_value<RealType>(), max_value<RealType>());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> support(const extreme_value_distribution<RealType, Policy>& /*dist*/)
|
||||
{ // Range of supported values for random variable x.
|
||||
// This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(-max_value<RealType>(), max_value<RealType>());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType pdf(const extreme_value_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
RealType a = dist.location();
|
||||
RealType b = dist.scale();
|
||||
RealType result = 0;
|
||||
if(0 == detail::verify_scale_b("boost::math::pdf(const extreme_value_distribution<%1%>&, %1%)", b, &result, Policy()))
|
||||
return result;
|
||||
result = exp((a-x)/b) * exp(-exp((a-x)/b)) / b;
|
||||
return result;
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const extreme_value_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
RealType a = dist.location();
|
||||
RealType b = dist.scale();
|
||||
RealType result = 0;
|
||||
if(0 == detail::verify_scale_b("boost::math::cdf(const extreme_value_distribution<%1%>&, %1%)", b, &result, Policy()))
|
||||
return result;
|
||||
|
||||
result = exp(-exp((a-x)/b));
|
||||
|
||||
return result;
|
||||
} // cdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
RealType quantile(const extreme_value_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::quantile(const extreme_value_distribution<%1%>&, %1%)";
|
||||
|
||||
RealType a = dist.location();
|
||||
RealType b = dist.scale();
|
||||
RealType result = 0;
|
||||
if(0 == detail::verify_scale_b(function, b, &result, Policy()))
|
||||
return result;
|
||||
if(0 == detail::check_probability(function, p, &result, Policy()))
|
||||
return result;
|
||||
|
||||
if(p == 0)
|
||||
return -policies::raise_overflow_error<RealType>(function, 0, Policy());
|
||||
if(p == 1)
|
||||
return policies::raise_overflow_error<RealType>(function, 0, Policy());
|
||||
|
||||
result = a - log(-log(p)) * b;
|
||||
|
||||
return result;
|
||||
} // quantile
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const complemented2_type<extreme_value_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
RealType a = c.dist.location();
|
||||
RealType b = c.dist.scale();
|
||||
RealType result = 0;
|
||||
if(0 == detail::verify_scale_b("boost::math::cdf(const extreme_value_distribution<%1%>&, %1%)", b, &result, Policy()))
|
||||
return result;
|
||||
|
||||
result = -boost::math::expm1(-exp((a-c.param)/b), Policy());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
RealType quantile(const complemented2_type<extreme_value_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::quantile(const extreme_value_distribution<%1%>&, %1%)";
|
||||
|
||||
RealType a = c.dist.location();
|
||||
RealType b = c.dist.scale();
|
||||
RealType q = c.param;
|
||||
RealType result = 0;
|
||||
if(0 == detail::verify_scale_b(function, b, &result, Policy()))
|
||||
return result;
|
||||
if(0 == detail::check_probability(function, q, &result, Policy()))
|
||||
return result;
|
||||
|
||||
if(q == 0)
|
||||
return policies::raise_overflow_error<RealType>(function, 0, Policy());
|
||||
if(q == 1)
|
||||
return -policies::raise_overflow_error<RealType>(function, 0, Policy());
|
||||
|
||||
result = a - log(-boost::math::log1p(-q, Policy())) * b;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mean(const extreme_value_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType a = dist.location();
|
||||
RealType b = dist.scale();
|
||||
RealType result = 0;
|
||||
if(0 == detail::verify_scale_b("boost::math::mean(const extreme_value_distribution<%1%>&)", b, &result, Policy()))
|
||||
return result;
|
||||
return a + constants::euler<RealType>() * b;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType standard_deviation(const extreme_value_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions.
|
||||
|
||||
RealType b = dist.scale();
|
||||
RealType result = 0;
|
||||
if(0 == detail::verify_scale_b("boost::math::standard_deviation(const extreme_value_distribution<%1%>&)", b, &result, Policy()))
|
||||
return result;
|
||||
return constants::pi<RealType>() * b / sqrt(static_cast<RealType>(6));
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mode(const extreme_value_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
return dist.location();
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType median(const extreme_value_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
using constants::ln_ln_two;
|
||||
return dist.location() - dist.scale() * ln_ln_two<RealType>();
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType skewness(const extreme_value_distribution<RealType, Policy>& /*dist*/)
|
||||
{
|
||||
//
|
||||
// This is 12 * sqrt(6) * zeta(3) / pi^3:
|
||||
// See http://mathworld.wolfram.com/ExtremeValueDistribution.html
|
||||
//
|
||||
return static_cast<RealType>(1.1395470994046486574927930193898461120875997958366L);
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis(const extreme_value_distribution<RealType, Policy>& /*dist*/)
|
||||
{
|
||||
// See http://mathworld.wolfram.com/ExtremeValueDistribution.html
|
||||
return RealType(27) / 5;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis_excess(const extreme_value_distribution<RealType, Policy>& /*dist*/)
|
||||
{
|
||||
// See http://mathworld.wolfram.com/ExtremeValueDistribution.html
|
||||
return RealType(12) / 5;
|
||||
}
|
||||
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
// This include must be at the end, *after* the accessors
|
||||
// for this distribution have been defined, in order to
|
||||
// keep compilers that support two-phase lookup happy.
|
||||
#include <boost/math/distributions/detail/derived_accessors.hpp>
|
||||
|
||||
#endif // BOOST_STATS_EXTREME_VALUE_HPP
|
||||
146
test/external/boost/math/distributions/find_location.hpp
vendored
Normal file
146
test/external/boost/math/distributions/find_location.hpp
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
// Copyright John Maddock 2007.
|
||||
// Copyright Paul A. Bristow 2007.
|
||||
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_STATS_FIND_LOCATION_HPP
|
||||
#define BOOST_STATS_FIND_LOCATION_HPP
|
||||
|
||||
#include <boost/math/distributions/fwd.hpp> // for all distribution signatures.
|
||||
#include <boost/math/distributions/complement.hpp>
|
||||
#include <boost/math/policies/policy.hpp>
|
||||
#include <boost/math/tools/traits.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/math/special_functions/fpclassify.hpp>
|
||||
#include <boost/math/policies/error_handling.hpp>
|
||||
// using boost::math::policies::policy;
|
||||
// using boost::math::complement; // will be needed by users who want complement,
|
||||
// but NOT placed here to avoid putting it in global scope.
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace math
|
||||
{
|
||||
// Function to find location of random variable z
|
||||
// to give probability p (given scale)
|
||||
// Applies to normal, lognormal, extreme value, Cauchy, (and symmetrical triangular),
|
||||
// enforced by BOOST_STATIC_ASSERT below.
|
||||
|
||||
template <class Dist, class Policy>
|
||||
inline
|
||||
typename Dist::value_type find_location( // For example, normal mean.
|
||||
typename Dist::value_type z, // location of random variable z to give probability, P(X > z) == p.
|
||||
// For example, a nominal minimum acceptable z, so that p * 100 % are > z
|
||||
typename Dist::value_type p, // probability value desired at x, say 0.95 for 95% > z.
|
||||
typename Dist::value_type scale, // scale parameter, for example, normal standard deviation.
|
||||
const Policy& pol
|
||||
)
|
||||
{
|
||||
#if !defined(BOOST_NO_SFINAE) && !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
|
||||
// Will fail to compile here if try to use with a distribution without scale & location,
|
||||
// for example pareto, and many others. These tests are disabled by the pp-logic
|
||||
// above if the compiler doesn't support the SFINAE tricks used in the traits class.
|
||||
BOOST_STATIC_ASSERT(::boost::math::tools::is_distribution<Dist>::value);
|
||||
BOOST_STATIC_ASSERT(::boost::math::tools::is_scaled_distribution<Dist>::value);
|
||||
#endif
|
||||
static const char* function = "boost::math::find_location<Dist, Policy>&, %1%)";
|
||||
|
||||
if(!(boost::math::isfinite)(p) || (p < 0) || (p > 1))
|
||||
{
|
||||
return policies::raise_domain_error<typename Dist::value_type>(
|
||||
function, "Probability parameter was %1%, but must be >= 0 and <= 1!", p, pol);
|
||||
}
|
||||
if(!(boost::math::isfinite)(z))
|
||||
{
|
||||
return policies::raise_domain_error<typename Dist::value_type>(
|
||||
function, "z parameter was %1%, but must be finite!", z, pol);
|
||||
}
|
||||
if(!(boost::math::isfinite)(scale))
|
||||
{
|
||||
return policies::raise_domain_error<typename Dist::value_type>(
|
||||
function, "scale parameter was %1%, but must be finite!", scale, pol);
|
||||
}
|
||||
|
||||
//cout << "z " << z << ", p " << p << ", quantile(Dist(), p) "
|
||||
// << quantile(Dist(), p) << ", quan * scale " << quantile(Dist(), p) * scale << endl;
|
||||
return z - (quantile(Dist(), p) * scale);
|
||||
} // find_location
|
||||
|
||||
template <class Dist>
|
||||
inline // with default policy.
|
||||
typename Dist::value_type find_location( // For example, normal mean.
|
||||
typename Dist::value_type z, // location of random variable z to give probability, P(X > z) == p.
|
||||
// For example, a nominal minimum acceptable z, so that p * 100 % are > z
|
||||
typename Dist::value_type p, // probability value desired at x, say 0.95 for 95% > z.
|
||||
typename Dist::value_type scale) // scale parameter, for example, normal standard deviation.
|
||||
{ // Forward to find_location with default policy.
|
||||
return (find_location<Dist>(z, p, scale, policies::policy<>()));
|
||||
} // find_location
|
||||
|
||||
// So the user can start from the complement q = (1 - p) of the probability p,
|
||||
// for example, l = find_location<normal>(complement(z, q, sd));
|
||||
|
||||
template <class Dist, class Real1, class Real2, class Real3>
|
||||
inline typename Dist::value_type find_location( // Default policy.
|
||||
complemented3_type<Real1, Real2, Real3> const& c)
|
||||
{
|
||||
static const char* function = "boost::math::find_location<Dist, Policy>&, %1%)";
|
||||
|
||||
typename Dist::value_type p = c.param1;
|
||||
if(!(boost::math::isfinite)(p) || (p < 0) || (p > 1))
|
||||
{
|
||||
return policies::raise_domain_error<typename Dist::value_type>(
|
||||
function, "Probability parameter was %1%, but must be >= 0 and <= 1!", p, policies::policy<>());
|
||||
}
|
||||
typename Dist::value_type z = c.dist;
|
||||
if(!(boost::math::isfinite)(z))
|
||||
{
|
||||
return policies::raise_domain_error<typename Dist::value_type>(
|
||||
function, "z parameter was %1%, but must be finite!", z, policies::policy<>());
|
||||
}
|
||||
typename Dist::value_type scale = c.param2;
|
||||
if(!(boost::math::isfinite)(scale))
|
||||
{
|
||||
return policies::raise_domain_error<typename Dist::value_type>(
|
||||
function, "scale parameter was %1%, but must be finite!", scale, policies::policy<>());
|
||||
}
|
||||
// cout << "z " << c.dist << ", quantile (Dist(), " << c.param1 << ") * scale " << c.param2 << endl;
|
||||
return z - quantile(Dist(), p) * scale;
|
||||
} // find_location complement
|
||||
|
||||
|
||||
template <class Dist, class Real1, class Real2, class Real3, class Real4>
|
||||
inline typename Dist::value_type find_location( // Explicit policy.
|
||||
complemented4_type<Real1, Real2, Real3, Real4> const& c)
|
||||
{
|
||||
static const char* function = "boost::math::find_location<Dist, Policy>&, %1%)";
|
||||
|
||||
typename Dist::value_type p = c.param1;
|
||||
if(!(boost::math::isfinite)(p) || (p < 0) || (p > 1))
|
||||
{
|
||||
return policies::raise_domain_error<typename Dist::value_type>(
|
||||
function, "Probability parameter was %1%, but must be >= 0 and <= 1!", p, c.param3);
|
||||
}
|
||||
typename Dist::value_type z = c.dist;
|
||||
if(!(boost::math::isfinite)(z))
|
||||
{
|
||||
return policies::raise_domain_error<typename Dist::value_type>(
|
||||
function, "z parameter was %1%, but must be finite!", z, c.param3);
|
||||
}
|
||||
typename Dist::value_type scale = c.param2;
|
||||
if(!(boost::math::isfinite)(scale))
|
||||
{
|
||||
return policies::raise_domain_error<typename Dist::value_type>(
|
||||
function, "scale parameter was %1%, but must be finite!", scale, c.param3);
|
||||
}
|
||||
// cout << "z " << c.dist << ", quantile (Dist(), " << c.param1 << ") * scale " << c.param2 << endl;
|
||||
return z - quantile(Dist(), p) * scale;
|
||||
} // find_location complement
|
||||
|
||||
} // namespace boost
|
||||
} // namespace math
|
||||
|
||||
#endif // BOOST_STATS_FIND_LOCATION_HPP
|
||||
|
||||
211
test/external/boost/math/distributions/find_scale.hpp
vendored
Normal file
211
test/external/boost/math/distributions/find_scale.hpp
vendored
Normal file
@@ -0,0 +1,211 @@
|
||||
// Copyright John Maddock 2007.
|
||||
// Copyright Paul A. Bristow 2007.
|
||||
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_STATS_FIND_SCALE_HPP
|
||||
#define BOOST_STATS_FIND_SCALE_HPP
|
||||
|
||||
#include <boost/math/distributions/fwd.hpp> // for all distribution signatures.
|
||||
#include <boost/math/distributions/complement.hpp>
|
||||
#include <boost/math/policies/policy.hpp>
|
||||
// using boost::math::policies::policy;
|
||||
#include <boost/math/tools/traits.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/math/special_functions/fpclassify.hpp>
|
||||
#include <boost/math/policies/error_handling.hpp>
|
||||
// using boost::math::complement; // will be needed by users who want complement,
|
||||
// but NOT placed here to avoid putting it in global scope.
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace math
|
||||
{
|
||||
// Function to find location of random variable z
|
||||
// to give probability p (given scale)
|
||||
// Applies to normal, lognormal, extreme value, Cauchy, (and symmetrical triangular),
|
||||
// distributions that have scale.
|
||||
// BOOST_STATIC_ASSERTs, see below, are used to enforce this.
|
||||
|
||||
template <class Dist, class Policy>
|
||||
inline
|
||||
typename Dist::value_type find_scale( // For example, normal mean.
|
||||
typename Dist::value_type z, // location of random variable z to give probability, P(X > z) == p.
|
||||
// For example, a nominal minimum acceptable weight z, so that p * 100 % are > z
|
||||
typename Dist::value_type p, // probability value desired at x, say 0.95 for 95% > z.
|
||||
typename Dist::value_type location, // location parameter, for example, normal distribution mean.
|
||||
const Policy& pol
|
||||
)
|
||||
{
|
||||
#if !defined(BOOST_NO_SFINAE) && !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
|
||||
BOOST_STATIC_ASSERT(::boost::math::tools::is_distribution<Dist>::value);
|
||||
BOOST_STATIC_ASSERT(::boost::math::tools::is_scaled_distribution<Dist>::value);
|
||||
#endif
|
||||
static const char* function = "boost::math::find_scale<Dist, Policy>(%1%, %1%, %1%, Policy)";
|
||||
|
||||
if(!(boost::math::isfinite)(p) || (p < 0) || (p > 1))
|
||||
{
|
||||
return policies::raise_domain_error<typename Dist::value_type>(
|
||||
function, "Probability parameter was %1%, but must be >= 0 and <= 1!", p, pol);
|
||||
}
|
||||
if(!(boost::math::isfinite)(z))
|
||||
{
|
||||
return policies::raise_domain_error<typename Dist::value_type>(
|
||||
function, "find_scale z parameter was %1%, but must be finite!", z, pol);
|
||||
}
|
||||
if(!(boost::math::isfinite)(location))
|
||||
{
|
||||
return policies::raise_domain_error<typename Dist::value_type>(
|
||||
function, "find_scale location parameter was %1%, but must be finite!", location, pol);
|
||||
}
|
||||
|
||||
//cout << "z " << z << ", p " << p << ", quantile(Dist(), p) "
|
||||
//<< quantile(Dist(), p) << ", z - mean " << z - location
|
||||
//<<", sd " << (z - location) / quantile(Dist(), p) << endl;
|
||||
|
||||
//quantile(N01, 0.001) -3.09023
|
||||
//quantile(N01, 0.01) -2.32635
|
||||
//quantile(N01, 0.05) -1.64485
|
||||
//quantile(N01, 0.333333) -0.430728
|
||||
//quantile(N01, 0.5) 0
|
||||
//quantile(N01, 0.666667) 0.430728
|
||||
//quantile(N01, 0.9) 1.28155
|
||||
//quantile(N01, 0.95) 1.64485
|
||||
//quantile(N01, 0.99) 2.32635
|
||||
//quantile(N01, 0.999) 3.09023
|
||||
|
||||
typename Dist::value_type result =
|
||||
(z - location) // difference between desired x and current location.
|
||||
/ quantile(Dist(), p); // standard distribution.
|
||||
|
||||
if (result <= 0)
|
||||
{ // If policy isn't to throw, return the scale <= 0.
|
||||
policies::raise_evaluation_error<typename Dist::value_type>(function,
|
||||
"Computed scale (%1%) is <= 0!" " Was the complement intended?",
|
||||
result, Policy());
|
||||
}
|
||||
return result;
|
||||
} // template <class Dist, class Policy> find_scale
|
||||
|
||||
template <class Dist>
|
||||
inline // with default policy.
|
||||
typename Dist::value_type find_scale( // For example, normal mean.
|
||||
typename Dist::value_type z, // location of random variable z to give probability, P(X > z) == p.
|
||||
// For example, a nominal minimum acceptable z, so that p * 100 % are > z
|
||||
typename Dist::value_type p, // probability value desired at x, say 0.95 for 95% > z.
|
||||
typename Dist::value_type location) // location parameter, for example, mean.
|
||||
{ // Forward to find_scale using the default policy.
|
||||
return (find_scale<Dist>(z, p, location, policies::policy<>()));
|
||||
} // find_scale
|
||||
|
||||
template <class Dist, class Real1, class Real2, class Real3, class Policy>
|
||||
inline typename Dist::value_type find_scale(
|
||||
complemented4_type<Real1, Real2, Real3, Policy> const& c)
|
||||
{
|
||||
//cout << "cparam1 q " << c.param1 // q
|
||||
// << ", c.dist z " << c.dist // z
|
||||
// << ", c.param2 l " << c.param2 // l
|
||||
// << ", quantile (Dist(), c.param1 = q) "
|
||||
// << quantile(Dist(), c.param1) //q
|
||||
// << endl;
|
||||
|
||||
#if !defined(BOOST_NO_SFINAE) && !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
|
||||
BOOST_STATIC_ASSERT(::boost::math::tools::is_distribution<Dist>::value);
|
||||
BOOST_STATIC_ASSERT(::boost::math::tools::is_scaled_distribution<Dist>::value);
|
||||
#endif
|
||||
static const char* function = "boost::math::find_scale<Dist, Policy>(complement(%1%, %1%, %1%, Policy))";
|
||||
|
||||
// Checks on arguments, as not complemented version,
|
||||
// Explicit policy.
|
||||
typename Dist::value_type q = c.param1;
|
||||
if(!(boost::math::isfinite)(q) || (q < 0) || (q > 1))
|
||||
{
|
||||
return policies::raise_domain_error<typename Dist::value_type>(
|
||||
function, "Probability parameter was %1%, but must be >= 0 and <= 1!", q, c.param3);
|
||||
}
|
||||
typename Dist::value_type z = c.dist;
|
||||
if(!(boost::math::isfinite)(z))
|
||||
{
|
||||
return policies::raise_domain_error<typename Dist::value_type>(
|
||||
function, "find_scale z parameter was %1%, but must be finite!", z, c.param3);
|
||||
}
|
||||
typename Dist::value_type location = c.param2;
|
||||
if(!(boost::math::isfinite)(location))
|
||||
{
|
||||
return policies::raise_domain_error<typename Dist::value_type>(
|
||||
function, "find_scale location parameter was %1%, but must be finite!", location, c.param3);
|
||||
}
|
||||
|
||||
typename Dist::value_type result =
|
||||
(c.dist - c.param2) // difference between desired x and current location.
|
||||
/ quantile(complement(Dist(), c.param1));
|
||||
// ( z - location) / (quantile(complement(Dist(), q))
|
||||
if (result <= 0)
|
||||
{ // If policy isn't to throw, return the scale <= 0.
|
||||
policies::raise_evaluation_error<typename Dist::value_type>(function,
|
||||
"Computed scale (%1%) is <= 0!" " Was the complement intended?",
|
||||
result, Policy());
|
||||
}
|
||||
return result;
|
||||
} // template <class Dist, class Policy, class Real1, class Real2, class Real3> typename Dist::value_type find_scale
|
||||
|
||||
// So the user can start from the complement q = (1 - p) of the probability p,
|
||||
// for example, s = find_scale<normal>(complement(z, q, l));
|
||||
|
||||
template <class Dist, class Real1, class Real2, class Real3>
|
||||
inline typename Dist::value_type find_scale(
|
||||
complemented3_type<Real1, Real2, Real3> const& c)
|
||||
{
|
||||
//cout << "cparam1 q " << c.param1 // q
|
||||
// << ", c.dist z " << c.dist // z
|
||||
// << ", c.param2 l " << c.param2 // l
|
||||
// << ", quantile (Dist(), c.param1 = q) "
|
||||
// << quantile(Dist(), c.param1) //q
|
||||
// << endl;
|
||||
|
||||
#if !defined(BOOST_NO_SFINAE) && !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
|
||||
BOOST_STATIC_ASSERT(::boost::math::tools::is_distribution<Dist>::value);
|
||||
BOOST_STATIC_ASSERT(::boost::math::tools::is_scaled_distribution<Dist>::value);
|
||||
#endif
|
||||
static const char* function = "boost::math::find_scale<Dist, Policy>(complement(%1%, %1%, %1%, Policy))";
|
||||
|
||||
// Checks on arguments, as not complemented version,
|
||||
// default policy policies::policy<>().
|
||||
typename Dist::value_type q = c.param1;
|
||||
if(!(boost::math::isfinite)(q) || (q < 0) || (q > 1))
|
||||
{
|
||||
return policies::raise_domain_error<typename Dist::value_type>(
|
||||
function, "Probability parameter was %1%, but must be >= 0 and <= 1!", q, policies::policy<>());
|
||||
}
|
||||
typename Dist::value_type z = c.dist;
|
||||
if(!(boost::math::isfinite)(z))
|
||||
{
|
||||
return policies::raise_domain_error<typename Dist::value_type>(
|
||||
function, "find_scale z parameter was %1%, but must be finite!", z, policies::policy<>());
|
||||
}
|
||||
typename Dist::value_type location = c.param2;
|
||||
if(!(boost::math::isfinite)(location))
|
||||
{
|
||||
return policies::raise_domain_error<typename Dist::value_type>(
|
||||
function, "find_scale location parameter was %1%, but must be finite!", location, policies::policy<>());
|
||||
}
|
||||
|
||||
typename Dist::value_type result =
|
||||
(z - location) // difference between desired x and current location.
|
||||
/ quantile(complement(Dist(), q));
|
||||
// ( z - location) / (quantile(complement(Dist(), q))
|
||||
if (result <= 0)
|
||||
{ // If policy isn't to throw, return the scale <= 0.
|
||||
policies::raise_evaluation_error<typename Dist::value_type>(function,
|
||||
"Computed scale (%1%) is <= 0!" " Was the complement intended?",
|
||||
result, policies::policy<>()); // This is only the default policy - also Want a version with Policy here.
|
||||
}
|
||||
return result;
|
||||
} // template <class Dist, class Real1, class Real2, class Real3> typename Dist::value_type find_scale
|
||||
|
||||
} // namespace boost
|
||||
} // namespace math
|
||||
|
||||
#endif // BOOST_STATS_FIND_SCALE_HPP
|
||||
387
test/external/boost/math/distributions/fisher_f.hpp
vendored
Normal file
387
test/external/boost/math/distributions/fisher_f.hpp
vendored
Normal file
@@ -0,0 +1,387 @@
|
||||
// Copyright John Maddock 2006.
|
||||
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_MATH_DISTRIBUTIONS_FISHER_F_HPP
|
||||
#define BOOST_MATH_DISTRIBUTIONS_FISHER_F_HPP
|
||||
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#include <boost/math/special_functions/beta.hpp> // for incomplete beta.
|
||||
#include <boost/math/distributions/complement.hpp> // complements
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp> // error checks
|
||||
#include <boost/math/special_functions/fpclassify.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace boost{ namespace math{
|
||||
|
||||
template <class RealType = double, class Policy = policies::policy<> >
|
||||
class fisher_f_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
|
||||
fisher_f_distribution(const RealType& i, const RealType& j) : m_df1(i), m_df2(j)
|
||||
{
|
||||
static const char* function = "fisher_f_distribution<%1%>::fisher_f_distribution";
|
||||
RealType result;
|
||||
detail::check_df(
|
||||
function, m_df1, &result, Policy());
|
||||
detail::check_df(
|
||||
function, m_df2, &result, Policy());
|
||||
} // fisher_f_distribution
|
||||
|
||||
RealType degrees_of_freedom1()const
|
||||
{
|
||||
return m_df1;
|
||||
}
|
||||
RealType degrees_of_freedom2()const
|
||||
{
|
||||
return m_df2;
|
||||
}
|
||||
|
||||
private:
|
||||
//
|
||||
// Data members:
|
||||
//
|
||||
RealType m_df1; // degrees of freedom are a real number.
|
||||
RealType m_df2; // degrees of freedom are a real number.
|
||||
};
|
||||
|
||||
typedef fisher_f_distribution<double> fisher_f;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const fisher_f_distribution<RealType, Policy>& /*dist*/)
|
||||
{ // Range of permissible values for random variable x.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> support(const fisher_f_distribution<RealType, Policy>& /*dist*/)
|
||||
{ // Range of supported values for random variable x.
|
||||
// This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
RealType pdf(const fisher_f_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
RealType df1 = dist.degrees_of_freedom1();
|
||||
RealType df2 = dist.degrees_of_freedom2();
|
||||
// Error check:
|
||||
RealType error_result = 0;
|
||||
static const char* function = "boost::math::pdf(fisher_f_distribution<%1%> const&, %1%)";
|
||||
if(false == detail::check_df(
|
||||
function, df1, &error_result, Policy())
|
||||
&& detail::check_df(
|
||||
function, df2, &error_result, Policy()))
|
||||
return error_result;
|
||||
|
||||
if((x < 0) || !(boost::math::isfinite)(x))
|
||||
{
|
||||
return policies::raise_domain_error<RealType>(
|
||||
function, "Random variable parameter was %1%, but must be > 0 !", x, Policy());
|
||||
}
|
||||
|
||||
if(x == 0)
|
||||
{
|
||||
// special cases:
|
||||
if(df1 < 2)
|
||||
return policies::raise_overflow_error<RealType>(
|
||||
function, 0, Policy());
|
||||
else if(df1 == 2)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// You reach this formula by direct differentiation of the
|
||||
// cdf expressed in terms of the incomplete beta.
|
||||
//
|
||||
// There are two versions so we don't pass a value of z
|
||||
// that is very close to 1 to ibeta_derivative: for some values
|
||||
// of df1 and df2, all the change takes place in this area.
|
||||
//
|
||||
RealType v1x = df1 * x;
|
||||
RealType result;
|
||||
if(v1x > df2)
|
||||
{
|
||||
result = (df2 * df1) / ((df2 + v1x) * (df2 + v1x));
|
||||
result *= ibeta_derivative(df2 / 2, df1 / 2, df2 / (df2 + v1x), Policy());
|
||||
}
|
||||
else
|
||||
{
|
||||
result = df2 + df1 * x;
|
||||
result = (result * df1 - x * df1 * df1) / (result * result);
|
||||
result *= ibeta_derivative(df1 / 2, df2 / 2, v1x / (df2 + v1x), Policy());
|
||||
}
|
||||
return result;
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const fisher_f_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
static const char* function = "boost::math::cdf(fisher_f_distribution<%1%> const&, %1%)";
|
||||
RealType df1 = dist.degrees_of_freedom1();
|
||||
RealType df2 = dist.degrees_of_freedom2();
|
||||
// Error check:
|
||||
RealType error_result = 0;
|
||||
if(false == detail::check_df(
|
||||
function, df1, &error_result, Policy())
|
||||
&& detail::check_df(
|
||||
function, df2, &error_result, Policy()))
|
||||
return error_result;
|
||||
|
||||
if((x < 0) || !(boost::math::isfinite)(x))
|
||||
{
|
||||
return policies::raise_domain_error<RealType>(
|
||||
function, "Random Variable parameter was %1%, but must be > 0 !", x, Policy());
|
||||
}
|
||||
|
||||
RealType v1x = df1 * x;
|
||||
//
|
||||
// There are two equivalent formulas used here, the aim is
|
||||
// to prevent the final argument to the incomplete beta
|
||||
// from being too close to 1: for some values of df1 and df2
|
||||
// the rate of change can be arbitrarily large in this area,
|
||||
// whilst the value we're passing will have lost information
|
||||
// content as a result of being 0.999999something. Better
|
||||
// to switch things around so we're passing 1-z instead.
|
||||
//
|
||||
return v1x > df2
|
||||
? boost::math::ibetac(df2 / 2, df1 / 2, df2 / (df2 + v1x), Policy())
|
||||
: boost::math::ibeta(df1 / 2, df2 / 2, v1x / (df2 + v1x), Policy());
|
||||
} // cdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const fisher_f_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
{
|
||||
static const char* function = "boost::math::quantile(fisher_f_distribution<%1%> const&, %1%)";
|
||||
RealType df1 = dist.degrees_of_freedom1();
|
||||
RealType df2 = dist.degrees_of_freedom2();
|
||||
// Error check:
|
||||
RealType error_result = 0;
|
||||
if(false == detail::check_df(
|
||||
function, df1, &error_result, Policy())
|
||||
&& detail::check_df(
|
||||
function, df2, &error_result, Policy())
|
||||
&& detail::check_probability(
|
||||
function, p, &error_result, Policy()))
|
||||
return error_result;
|
||||
|
||||
// With optimizations turned on, gcc wrongly warns about y being used
|
||||
// uninitializated unless we initialize it to something:
|
||||
RealType x, y(0);
|
||||
|
||||
x = boost::math::ibeta_inv(df1 / 2, df2 / 2, p, &y, Policy());
|
||||
|
||||
return df2 * x / (df1 * y);
|
||||
} // quantile
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const complemented2_type<fisher_f_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
static const char* function = "boost::math::cdf(fisher_f_distribution<%1%> const&, %1%)";
|
||||
RealType df1 = c.dist.degrees_of_freedom1();
|
||||
RealType df2 = c.dist.degrees_of_freedom2();
|
||||
RealType x = c.param;
|
||||
// Error check:
|
||||
RealType error_result = 0;
|
||||
if(false == detail::check_df(
|
||||
function, df1, &error_result, Policy())
|
||||
&& detail::check_df(
|
||||
function, df2, &error_result, Policy()))
|
||||
return error_result;
|
||||
|
||||
if((x < 0) || !(boost::math::isfinite)(x))
|
||||
{
|
||||
return policies::raise_domain_error<RealType>(
|
||||
function, "Random Variable parameter was %1%, but must be > 0 !", x, Policy());
|
||||
}
|
||||
|
||||
RealType v1x = df1 * x;
|
||||
//
|
||||
// There are two equivalent formulas used here, the aim is
|
||||
// to prevent the final argument to the incomplete beta
|
||||
// from being too close to 1: for some values of df1 and df2
|
||||
// the rate of change can be arbitrarily large in this area,
|
||||
// whilst the value we're passing will have lost information
|
||||
// content as a result of being 0.999999something. Better
|
||||
// to switch things around so we're passing 1-z instead.
|
||||
//
|
||||
return v1x > df2
|
||||
? boost::math::ibeta(df2 / 2, df1 / 2, df2 / (df2 + v1x), Policy())
|
||||
: boost::math::ibetac(df1 / 2, df2 / 2, v1x / (df2 + v1x), Policy());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const complemented2_type<fisher_f_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
static const char* function = "boost::math::quantile(fisher_f_distribution<%1%> const&, %1%)";
|
||||
RealType df1 = c.dist.degrees_of_freedom1();
|
||||
RealType df2 = c.dist.degrees_of_freedom2();
|
||||
RealType p = c.param;
|
||||
// Error check:
|
||||
RealType error_result = 0;
|
||||
if(false == detail::check_df(
|
||||
function, df1, &error_result, Policy())
|
||||
&& detail::check_df(
|
||||
function, df2, &error_result, Policy())
|
||||
&& detail::check_probability(
|
||||
function, p, &error_result, Policy()))
|
||||
return error_result;
|
||||
|
||||
RealType x, y;
|
||||
|
||||
x = boost::math::ibetac_inv(df1 / 2, df2 / 2, p, &y, Policy());
|
||||
|
||||
return df2 * x / (df1 * y);
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mean(const fisher_f_distribution<RealType, Policy>& dist)
|
||||
{ // Mean of F distribution = v.
|
||||
static const char* function = "boost::math::mean(fisher_f_distribution<%1%> const&)";
|
||||
RealType df1 = dist.degrees_of_freedom1();
|
||||
RealType df2 = dist.degrees_of_freedom2();
|
||||
// Error check:
|
||||
RealType error_result = 0;
|
||||
if(false == detail::check_df(
|
||||
function, df1, &error_result, Policy())
|
||||
&& detail::check_df(
|
||||
function, df2, &error_result, Policy()))
|
||||
return error_result;
|
||||
if(df2 <= 2)
|
||||
{
|
||||
return policies::raise_domain_error<RealType>(
|
||||
function, "Second degree of freedom was %1% but must be > 2 in order for the distribution to have a mean.", df2, Policy());
|
||||
}
|
||||
return df2 / (df2 - 2);
|
||||
} // mean
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType variance(const fisher_f_distribution<RealType, Policy>& dist)
|
||||
{ // Variance of F distribution.
|
||||
static const char* function = "boost::math::variance(fisher_f_distribution<%1%> const&)";
|
||||
RealType df1 = dist.degrees_of_freedom1();
|
||||
RealType df2 = dist.degrees_of_freedom2();
|
||||
// Error check:
|
||||
RealType error_result = 0;
|
||||
if(false == detail::check_df(
|
||||
function, df1, &error_result, Policy())
|
||||
&& detail::check_df(
|
||||
function, df2, &error_result, Policy()))
|
||||
return error_result;
|
||||
if(df2 <= 4)
|
||||
{
|
||||
return policies::raise_domain_error<RealType>(
|
||||
function, "Second degree of freedom was %1% but must be > 4 in order for the distribution to have a valid variance.", df2, Policy());
|
||||
}
|
||||
return 2 * df2 * df2 * (df1 + df2 - 2) / (df1 * (df2 - 2) * (df2 - 2) * (df2 - 4));
|
||||
} // variance
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mode(const fisher_f_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
static const char* function = "boost::math::mode(fisher_f_distribution<%1%> const&)";
|
||||
RealType df1 = dist.degrees_of_freedom1();
|
||||
RealType df2 = dist.degrees_of_freedom2();
|
||||
// Error check:
|
||||
RealType error_result = 0;
|
||||
if(false == detail::check_df(
|
||||
function, df1, &error_result, Policy())
|
||||
&& detail::check_df(
|
||||
function, df2, &error_result, Policy()))
|
||||
return error_result;
|
||||
if(df2 <= 2)
|
||||
{
|
||||
return policies::raise_domain_error<RealType>(
|
||||
function, "Second degree of freedom was %1% but must be > 2 in order for the distribution to have a mode.", df2, Policy());
|
||||
}
|
||||
return df2 * (df1 - 2) / (df1 * (df2 + 2));
|
||||
}
|
||||
|
||||
//template <class RealType, class Policy>
|
||||
//inline RealType median(const fisher_f_distribution<RealType, Policy>& dist)
|
||||
//{ // Median of Fisher F distribution is not defined.
|
||||
// return tools::domain_error<RealType>(BOOST_CURRENT_FUNCTION, "Median is not implemented, result is %1%!", std::numeric_limits<RealType>::quiet_NaN());
|
||||
// } // median
|
||||
|
||||
// Now implemented via quantile(half) in derived accessors.
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType skewness(const fisher_f_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
static const char* function = "boost::math::skewness(fisher_f_distribution<%1%> const&)";
|
||||
BOOST_MATH_STD_USING // ADL of std names
|
||||
// See http://mathworld.wolfram.com/F-Distribution.html
|
||||
RealType df1 = dist.degrees_of_freedom1();
|
||||
RealType df2 = dist.degrees_of_freedom2();
|
||||
// Error check:
|
||||
RealType error_result = 0;
|
||||
if(false == detail::check_df(
|
||||
function, df1, &error_result, Policy())
|
||||
&& detail::check_df(
|
||||
function, df2, &error_result, Policy()))
|
||||
return error_result;
|
||||
if(df2 <= 6)
|
||||
{
|
||||
return policies::raise_domain_error<RealType>(
|
||||
function, "Second degree of freedom was %1% but must be > 6 in order for the distribution to have a skewness.", df2, Policy());
|
||||
}
|
||||
return 2 * (df2 + 2 * df1 - 2) * sqrt((2 * df2 - 8) / (df1 * (df2 + df1 - 2))) / (df2 - 6);
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
RealType kurtosis_excess(const fisher_f_distribution<RealType, Policy>& dist);
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis(const fisher_f_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
return 3 + kurtosis_excess(dist);
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis_excess(const fisher_f_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
static const char* function = "boost::math::kurtosis_excess(fisher_f_distribution<%1%> const&)";
|
||||
// See http://mathworld.wolfram.com/F-Distribution.html
|
||||
RealType df1 = dist.degrees_of_freedom1();
|
||||
RealType df2 = dist.degrees_of_freedom2();
|
||||
// Error check:
|
||||
RealType error_result = 0;
|
||||
if(false == detail::check_df(
|
||||
function, df1, &error_result, Policy())
|
||||
&& detail::check_df(
|
||||
function, df2, &error_result, Policy()))
|
||||
return error_result;
|
||||
if(df2 <= 8)
|
||||
{
|
||||
return policies::raise_domain_error<RealType>(
|
||||
function, "Second degree of freedom was %1% but must be > 8 in order for the distribution to have a kutosis.", df2, Policy());
|
||||
}
|
||||
RealType df2_2 = df2 * df2;
|
||||
RealType df1_2 = df1 * df1;
|
||||
RealType n = -16 + 20 * df2 - 8 * df2_2 + df2_2 * df2 + 44 * df1 - 32 * df2 * df1 + 5 * df2_2 * df1 - 22 * df1_2 + 5 * df2 * df1_2;
|
||||
n *= 12;
|
||||
RealType d = df1 * (df2 - 6) * (df2 - 8) * (df1 + df2 - 2);
|
||||
return n / d;
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
// This include must be at the end, *after* the accessors
|
||||
// for this distribution have been defined, in order to
|
||||
// keep compilers that support two-phase lookup happy.
|
||||
#include <boost/math/distributions/detail/derived_accessors.hpp>
|
||||
|
||||
#endif // BOOST_MATH_DISTRIBUTIONS_FISHER_F_HPP
|
||||
144
test/external/boost/math/distributions/fwd.hpp
vendored
Normal file
144
test/external/boost/math/distributions/fwd.hpp
vendored
Normal file
@@ -0,0 +1,144 @@
|
||||
// fwd.hpp Forward declarations of Boost.Math distributions.
|
||||
|
||||
// Copyright Paul A. Bristow 2007, 2010.
|
||||
// Copyright John Maddock 2007.
|
||||
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_MATH_DISTRIBUTIONS_FWD_HPP
|
||||
#define BOOST_MATH_DISTRIBUTIONS_FWD_HPP
|
||||
|
||||
namespace boost{ namespace math{
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class bernoulli_distribution;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class beta_distribution;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class binomial_distribution;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class cauchy_distribution;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class chi_squared_distribution;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class exponential_distribution;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class extreme_value_distribution;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class fisher_f_distribution;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class gamma_distribution;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class geometric_distribution;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class hypergeometric_distribution;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class inverse_chi_squared_distribution;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class inverse_gamma_distribution;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class inverse_gaussian_distribution;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class inverse_uniform_distribution;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class laplace_distribution;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class logistic_distribution;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class lognormal_distribution;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class negative_binomial_distribution;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class non_central_chi_squared_distribution;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class non_central_beta_distribution;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class non_central_f_distribution;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class non_central_t_distribution;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class normal_distribution;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class pareto_distribution;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class poisson_distribution;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class rayleigh_distribution;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class students_t_distribution;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class triangular_distribution;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class uniform_distribution;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class weibull_distribution;
|
||||
|
||||
}} // namespaces
|
||||
|
||||
#define BOOST_MATH_DECLARE_DISTRIBUTIONS(Type, Policy)\
|
||||
typedef boost::math::bernoulli_distribution<Type, Policy> bernoulli;\
|
||||
typedef boost::math::beta_distribution<Type, Policy> beta;\
|
||||
typedef boost::math::binomial_distribution<Type, Policy> binomial;\
|
||||
typedef boost::math::cauchy_distribution<Type, Policy> cauchy;\
|
||||
typedef boost::math::chi_squared_distribution<Type, Policy> chi_squared;\
|
||||
typedef boost::math::exponential_distribution<Type, Policy> exponential;\
|
||||
typedef boost::math::extreme_value_distribution<Type, Policy> extreme_value;\
|
||||
typedef boost::math::fisher_f_distribution<Type, Policy> fisher_f;\
|
||||
typedef boost::math::gamma_distribution<Type, Policy> gamma;\
|
||||
typedef boost::math::laplace_distribution<Type, Policy> laplace;\
|
||||
typedef boost::math::logistic_distribution<Type, Policy> logistic;\
|
||||
typedef boost::math::lognormal_distribution<Type, Policy> lognormal;\
|
||||
typedef boost::math::negative_binomial_distribution<Type, Policy> negative_binomial;\
|
||||
typedef boost::math::normal_distribution<Type, Policy> normal;\
|
||||
typedef boost::math::pareto_distribution<Type, Policy> pareto;\
|
||||
typedef boost::math::poisson_distribution<Type, Policy> poisson;\
|
||||
typedef boost::math::rayleigh_distribution<Type, Policy> rayleigh;\
|
||||
typedef boost::math::students_t_distribution<Type, Policy> students_t;\
|
||||
typedef boost::math::triangular_distribution<Type, Policy> triangular;\
|
||||
typedef boost::math::uniform_distribution<Type, Policy> uniform;\
|
||||
typedef boost::math::weibull_distribution<Type, Policy> weibull;\
|
||||
typedef boost::math::non_central_chi_squared_distribution<Type, Policy> non_central_chi_squared;\
|
||||
typedef boost::math::non_central_beta_distribution<Type, Policy> non_central_beta;\
|
||||
typedef boost::math::non_central_f_distribution<Type, Policy> non_central_f;\
|
||||
typedef boost::math::non_central_t_distribution<Type, Policy> non_central_t;\
|
||||
typedef boost::math::hypergeometric_distribution<Type, Policy> hypergeometric;\
|
||||
typedef boost::math::inverse_uniform_distribution<Type, Policy> inverse_uniform;\
|
||||
typedef boost::math::geometric_distribution<Type, Policy> geometric;\
|
||||
typedef boost::math::inverse_chi_squared_distribution<Type, Policy> inverse_chi_squared;\
|
||||
typedef boost::math::inverse_gamma_distribution<Type, Policy> inverse_gamma;\
|
||||
typedef boost::math::inverse_gaussian_distribution<Type, Policy> inverse_gaussian;\
|
||||
|
||||
#endif // BOOST_MATH_DISTRIBUTIONS_FWD_HPP
|
||||
349
test/external/boost/math/distributions/gamma.hpp
vendored
Normal file
349
test/external/boost/math/distributions/gamma.hpp
vendored
Normal file
@@ -0,0 +1,349 @@
|
||||
// Copyright John Maddock 2006.
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_STATS_GAMMA_HPP
|
||||
#define BOOST_STATS_GAMMA_HPP
|
||||
|
||||
// http://www.itl.nist.gov/div898/handbook/eda/section3/eda366b.htm
|
||||
// http://mathworld.wolfram.com/GammaDistribution.html
|
||||
// http://en.wikipedia.org/wiki/Gamma_distribution
|
||||
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#include <boost/math/special_functions/gamma.hpp>
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp>
|
||||
#include <boost/math/distributions/complement.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace boost{ namespace math
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_gamma_shape(
|
||||
const char* function,
|
||||
RealType shape,
|
||||
RealType* result, const Policy& pol)
|
||||
{
|
||||
if((shape <= 0) || !(boost::math::isfinite)(shape))
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Shape parameter is %1%, but must be > 0 !", shape, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_gamma_x(
|
||||
const char* function,
|
||||
RealType const& x,
|
||||
RealType* result, const Policy& pol)
|
||||
{
|
||||
if((x < 0) || !(boost::math::isfinite)(x))
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Random variate is %1% but must be >= 0 !", x, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_gamma(
|
||||
const char* function,
|
||||
RealType scale,
|
||||
RealType shape,
|
||||
RealType* result, const Policy& pol)
|
||||
{
|
||||
return check_scale(function, scale, result, pol) && check_gamma_shape(function, shape, result, pol);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class RealType = double, class Policy = policies::policy<> >
|
||||
class gamma_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
|
||||
gamma_distribution(RealType shape, RealType scale = 1)
|
||||
: m_shape(shape), m_scale(scale)
|
||||
{
|
||||
RealType result;
|
||||
detail::check_gamma("boost::math::gamma_distribution<%1%>::gamma_distribution", scale, shape, &result, Policy());
|
||||
}
|
||||
|
||||
RealType shape()const
|
||||
{
|
||||
return m_shape;
|
||||
}
|
||||
|
||||
RealType scale()const
|
||||
{
|
||||
return m_scale;
|
||||
}
|
||||
private:
|
||||
//
|
||||
// Data members:
|
||||
//
|
||||
RealType m_shape; // distribution shape
|
||||
RealType m_scale; // distribution scale
|
||||
};
|
||||
|
||||
// NO typedef because of clash with name of gamma function.
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const gamma_distribution<RealType, Policy>& /* dist */)
|
||||
{ // Range of permissible values for random variable x.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> support(const gamma_distribution<RealType, Policy>& /* dist */)
|
||||
{ // Range of supported values for random variable x.
|
||||
// This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
|
||||
using boost::math::tools::max_value;
|
||||
using boost::math::tools::min_value;
|
||||
return std::pair<RealType, RealType>(min_value<RealType>(), max_value<RealType>());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType pdf(const gamma_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::pdf(const gamma_distribution<%1%>&, %1%)";
|
||||
|
||||
RealType shape = dist.shape();
|
||||
RealType scale = dist.scale();
|
||||
|
||||
RealType result = 0;
|
||||
if(false == detail::check_gamma(function, scale, shape, &result, Policy()))
|
||||
return result;
|
||||
if(false == detail::check_gamma_x(function, x, &result, Policy()))
|
||||
return result;
|
||||
|
||||
if(x == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
result = gamma_p_derivative(shape, x / scale, Policy()) / scale;
|
||||
return result;
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const gamma_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::cdf(const gamma_distribution<%1%>&, %1%)";
|
||||
|
||||
RealType shape = dist.shape();
|
||||
RealType scale = dist.scale();
|
||||
|
||||
RealType result = 0;
|
||||
if(false == detail::check_gamma(function, scale, shape, &result, Policy()))
|
||||
return result;
|
||||
if(false == detail::check_gamma_x(function, x, &result, Policy()))
|
||||
return result;
|
||||
|
||||
result = boost::math::gamma_p(shape, x / scale, Policy());
|
||||
return result;
|
||||
} // cdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const gamma_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::quantile(const gamma_distribution<%1%>&, %1%)";
|
||||
|
||||
RealType shape = dist.shape();
|
||||
RealType scale = dist.scale();
|
||||
|
||||
RealType result = 0;
|
||||
if(false == detail::check_gamma(function, scale, shape, &result, Policy()))
|
||||
return result;
|
||||
if(false == detail::check_probability(function, p, &result, Policy()))
|
||||
return result;
|
||||
|
||||
if(p == 1)
|
||||
return policies::raise_overflow_error<RealType>(function, 0, Policy());
|
||||
|
||||
result = gamma_p_inv(shape, p, Policy()) * scale;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const complemented2_type<gamma_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::quantile(const gamma_distribution<%1%>&, %1%)";
|
||||
|
||||
RealType shape = c.dist.shape();
|
||||
RealType scale = c.dist.scale();
|
||||
|
||||
RealType result = 0;
|
||||
if(false == detail::check_gamma(function, scale, shape, &result, Policy()))
|
||||
return result;
|
||||
if(false == detail::check_gamma_x(function, c.param, &result, Policy()))
|
||||
return result;
|
||||
|
||||
result = gamma_q(shape, c.param / scale, Policy());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const complemented2_type<gamma_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::quantile(const gamma_distribution<%1%>&, %1%)";
|
||||
|
||||
RealType shape = c.dist.shape();
|
||||
RealType scale = c.dist.scale();
|
||||
RealType q = c.param;
|
||||
|
||||
RealType result = 0;
|
||||
if(false == detail::check_gamma(function, scale, shape, &result, Policy()))
|
||||
return result;
|
||||
if(false == detail::check_probability(function, q, &result, Policy()))
|
||||
return result;
|
||||
|
||||
if(q == 0)
|
||||
return policies::raise_overflow_error<RealType>(function, 0, Policy());
|
||||
|
||||
result = gamma_q_inv(shape, q, Policy()) * scale;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mean(const gamma_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::mean(const gamma_distribution<%1%>&)";
|
||||
|
||||
RealType shape = dist.shape();
|
||||
RealType scale = dist.scale();
|
||||
|
||||
RealType result = 0;
|
||||
if(false == detail::check_gamma(function, scale, shape, &result, Policy()))
|
||||
return result;
|
||||
|
||||
result = shape * scale;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType variance(const gamma_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::variance(const gamma_distribution<%1%>&)";
|
||||
|
||||
RealType shape = dist.shape();
|
||||
RealType scale = dist.scale();
|
||||
|
||||
RealType result = 0;
|
||||
if(false == detail::check_gamma(function, scale, shape, &result, Policy()))
|
||||
return result;
|
||||
|
||||
result = shape * scale * scale;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mode(const gamma_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::mode(const gamma_distribution<%1%>&)";
|
||||
|
||||
RealType shape = dist.shape();
|
||||
RealType scale = dist.scale();
|
||||
|
||||
RealType result = 0;
|
||||
if(false == detail::check_gamma(function, scale, shape, &result, Policy()))
|
||||
return result;
|
||||
|
||||
if(shape < 1)
|
||||
return policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"The mode of the gamma distribution is only defined for values of the shape parameter >= 1, but got %1%.",
|
||||
shape, Policy());
|
||||
|
||||
result = (shape - 1) * scale;
|
||||
return result;
|
||||
}
|
||||
|
||||
//template <class RealType, class Policy>
|
||||
//inline RealType median(const gamma_distribution<RealType, Policy>& dist)
|
||||
//{ // Rely on default definition in derived accessors.
|
||||
//}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType skewness(const gamma_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::skewness(const gamma_distribution<%1%>&)";
|
||||
|
||||
RealType shape = dist.shape();
|
||||
RealType scale = dist.scale();
|
||||
|
||||
RealType result = 0;
|
||||
if(false == detail::check_gamma(function, scale, shape, &result, Policy()))
|
||||
return result;
|
||||
|
||||
result = 2 / sqrt(shape);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis_excess(const gamma_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::kurtosis_excess(const gamma_distribution<%1%>&)";
|
||||
|
||||
RealType shape = dist.shape();
|
||||
RealType scale = dist.scale();
|
||||
|
||||
RealType result = 0;
|
||||
if(false == detail::check_gamma(function, scale, shape, &result, Policy()))
|
||||
return result;
|
||||
|
||||
result = 6 / shape;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis(const gamma_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
return kurtosis_excess(dist) + 3;
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
// This include must be at the end, *after* the accessors
|
||||
// for this distribution have been defined, in order to
|
||||
// keep compilers that support two-phase lookup happy.
|
||||
#include <boost/math/distributions/detail/derived_accessors.hpp>
|
||||
|
||||
#endif // BOOST_STATS_GAMMA_HPP
|
||||
|
||||
|
||||
516
test/external/boost/math/distributions/geometric.hpp
vendored
Normal file
516
test/external/boost/math/distributions/geometric.hpp
vendored
Normal file
@@ -0,0 +1,516 @@
|
||||
// boost\math\distributions\geometric.hpp
|
||||
|
||||
// Copyright John Maddock 2010.
|
||||
// Copyright Paul A. Bristow 2010.
|
||||
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
// geometric distribution is a discrete probability distribution.
|
||||
// It expresses the probability distribution of the number (k) of
|
||||
// events, occurrences, failures or arrivals before the first success.
|
||||
// supported on the set {0, 1, 2, 3...}
|
||||
|
||||
// Note that the set includes zero (unlike some definitions that start at one).
|
||||
|
||||
// The random variate k is the number of events, occurrences or arrivals.
|
||||
// k argument may be integral, signed, or unsigned, or floating point.
|
||||
// If necessary, it has already been promoted from an integral type.
|
||||
|
||||
// Note that the geometric distribution
|
||||
// (like others including the binomial, geometric & Bernoulli)
|
||||
// is strictly defined as a discrete function:
|
||||
// only integral values of k are envisaged.
|
||||
// However because the method of calculation uses a continuous gamma function,
|
||||
// it is convenient to treat it as if a continous function,
|
||||
// and permit non-integral values of k.
|
||||
// To enforce the strict mathematical model, users should use floor or ceil functions
|
||||
// on k outside this function to ensure that k is integral.
|
||||
|
||||
// See http://en.wikipedia.org/wiki/geometric_distribution
|
||||
// http://documents.wolfram.com/v5/Add-onsLinks/StandardPackages/Statistics/DiscreteDistributions.html
|
||||
// http://mathworld.wolfram.com/GeometricDistribution.html
|
||||
|
||||
#ifndef BOOST_MATH_SPECIAL_GEOMETRIC_HPP
|
||||
#define BOOST_MATH_SPECIAL_GEOMETRIC_HPP
|
||||
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#include <boost/math/special_functions/beta.hpp> // for ibeta(a, b, x) == Ix(a, b).
|
||||
#include <boost/math/distributions/complement.hpp> // complement.
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp> // error checks domain_error & logic_error.
|
||||
#include <boost/math/special_functions/fpclassify.hpp> // isnan.
|
||||
#include <boost/math/tools/roots.hpp> // for root finding.
|
||||
#include <boost/math/distributions/detail/inv_discrete_quantile.hpp>
|
||||
|
||||
#include <boost/type_traits/is_floating_point.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
|
||||
#include <limits> // using std::numeric_limits;
|
||||
#include <utility>
|
||||
|
||||
#if defined (BOOST_MSVC)
|
||||
# pragma warning(push)
|
||||
// This believed not now necessary, so commented out.
|
||||
//# pragma warning(disable: 4702) // unreachable code.
|
||||
// in domain_error_imp in error_handling.
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace math
|
||||
{
|
||||
namespace geometric_detail
|
||||
{
|
||||
// Common error checking routines for geometric distribution function:
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_success_fraction(const char* function, const RealType& p, RealType* result, const Policy& pol)
|
||||
{
|
||||
if( !(boost::math::isfinite)(p) || (p < 0) || (p > 1) )
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Success fraction argument is %1%, but must be >= 0 and <= 1 !", p, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_dist(const char* function, const RealType& p, RealType* result, const Policy& pol)
|
||||
{
|
||||
return check_success_fraction(function, p, result, pol);
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_dist_and_k(const char* function, const RealType& p, RealType k, RealType* result, const Policy& pol)
|
||||
{
|
||||
if(check_dist(function, p, result, pol) == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if( !(boost::math::isfinite)(k) || (k < 0) )
|
||||
{ // Check k failures.
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Number of failures argument is %1%, but must be >= 0 !", k, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // Check_dist_and_k
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_dist_and_prob(const char* function, RealType p, RealType prob, RealType* result, const Policy& pol)
|
||||
{
|
||||
if(check_dist(function, p, result, pol) && detail::check_probability(function, prob, result, pol) == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // check_dist_and_prob
|
||||
} // namespace geometric_detail
|
||||
|
||||
template <class RealType = double, class Policy = policies::policy<> >
|
||||
class geometric_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
|
||||
geometric_distribution(RealType p) : m_p(p)
|
||||
{ // Constructor stores success_fraction p.
|
||||
RealType result;
|
||||
geometric_detail::check_dist(
|
||||
"geometric_distribution<%1%>::geometric_distribution",
|
||||
m_p, // Check success_fraction 0 <= p <= 1.
|
||||
&result, Policy());
|
||||
} // geometric_distribution constructor.
|
||||
|
||||
// Private data getter class member functions.
|
||||
RealType success_fraction() const
|
||||
{ // Probability of success as fraction in range 0 to 1.
|
||||
return m_p;
|
||||
}
|
||||
RealType successes() const
|
||||
{ // Total number of successes r = 1 (for compatibility with negative binomial?).
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Parameter estimation.
|
||||
// (These are copies of negative_binomial distribution with successes = 1).
|
||||
static RealType find_lower_bound_on_p(
|
||||
RealType trials,
|
||||
RealType alpha) // alpha 0.05 equivalent to 95% for one-sided test.
|
||||
{
|
||||
static const char* function = "boost::math::geometric<%1%>::find_lower_bound_on_p";
|
||||
RealType result = 0; // of error checks.
|
||||
RealType successes = 1;
|
||||
RealType failures = trials - successes;
|
||||
if(false == detail::check_probability(function, alpha, &result, Policy())
|
||||
&& geometric_detail::check_dist_and_k(
|
||||
function, RealType(0), failures, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
// Use complement ibeta_inv function for lower bound.
|
||||
// This is adapted from the corresponding binomial formula
|
||||
// here: http://www.itl.nist.gov/div898/handbook/prc/section2/prc241.htm
|
||||
// This is a Clopper-Pearson interval, and may be overly conservative,
|
||||
// see also "A Simple Improved Inferential Method for Some
|
||||
// Discrete Distributions" Yong CAI and K. KRISHNAMOORTHY
|
||||
// http://www.ucs.louisiana.edu/~kxk4695/Discrete_new.pdf
|
||||
//
|
||||
return ibeta_inv(successes, failures + 1, alpha, static_cast<RealType*>(0), Policy());
|
||||
} // find_lower_bound_on_p
|
||||
|
||||
static RealType find_upper_bound_on_p(
|
||||
RealType trials,
|
||||
RealType alpha) // alpha 0.05 equivalent to 95% for one-sided test.
|
||||
{
|
||||
static const char* function = "boost::math::geometric<%1%>::find_upper_bound_on_p";
|
||||
RealType result = 0; // of error checks.
|
||||
RealType successes = 1;
|
||||
RealType failures = trials - successes;
|
||||
if(false == geometric_detail::check_dist_and_k(
|
||||
function, RealType(0), failures, &result, Policy())
|
||||
&& detail::check_probability(function, alpha, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(failures == 0)
|
||||
{
|
||||
return 1;
|
||||
}// Use complement ibetac_inv function for upper bound.
|
||||
// Note adjusted failures value: *not* failures+1 as usual.
|
||||
// This is adapted from the corresponding binomial formula
|
||||
// here: http://www.itl.nist.gov/div898/handbook/prc/section2/prc241.htm
|
||||
// This is a Clopper-Pearson interval, and may be overly conservative,
|
||||
// see also "A Simple Improved Inferential Method for Some
|
||||
// Discrete Distributions" Yong CAI and K. Krishnamoorthy
|
||||
// http://www.ucs.louisiana.edu/~kxk4695/Discrete_new.pdf
|
||||
//
|
||||
return ibetac_inv(successes, failures, alpha, static_cast<RealType*>(0), Policy());
|
||||
} // find_upper_bound_on_p
|
||||
|
||||
// Estimate number of trials :
|
||||
// "How many trials do I need to be P% sure of seeing k or fewer failures?"
|
||||
|
||||
static RealType find_minimum_number_of_trials(
|
||||
RealType k, // number of failures (k >= 0).
|
||||
RealType p, // success fraction 0 <= p <= 1.
|
||||
RealType alpha) // risk level threshold 0 <= alpha <= 1.
|
||||
{
|
||||
static const char* function = "boost::math::geometric<%1%>::find_minimum_number_of_trials";
|
||||
// Error checks:
|
||||
RealType result = 0;
|
||||
if(false == geometric_detail::check_dist_and_k(
|
||||
function, p, k, &result, Policy())
|
||||
&& detail::check_probability(function, alpha, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
result = ibeta_inva(k + 1, p, alpha, Policy()); // returns n - k
|
||||
return result + k;
|
||||
} // RealType find_number_of_failures
|
||||
|
||||
static RealType find_maximum_number_of_trials(
|
||||
RealType k, // number of failures (k >= 0).
|
||||
RealType p, // success fraction 0 <= p <= 1.
|
||||
RealType alpha) // risk level threshold 0 <= alpha <= 1.
|
||||
{
|
||||
static const char* function = "boost::math::geometric<%1%>::find_maximum_number_of_trials";
|
||||
// Error checks:
|
||||
RealType result = 0;
|
||||
if(false == geometric_detail::check_dist_and_k(
|
||||
function, p, k, &result, Policy())
|
||||
&& detail::check_probability(function, alpha, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
result = ibetac_inva(k + 1, p, alpha, Policy()); // returns n - k
|
||||
return result + k;
|
||||
} // RealType find_number_of_trials complemented
|
||||
|
||||
private:
|
||||
//RealType m_r; // successes fixed at unity.
|
||||
RealType m_p; // success_fraction
|
||||
}; // template <class RealType, class Policy> class geometric_distribution
|
||||
|
||||
typedef geometric_distribution<double> geometric; // Reserved name of type double.
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const geometric_distribution<RealType, Policy>& /* dist */)
|
||||
{ // Range of permissible values for random variable k.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>()); // max_integer?
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> support(const geometric_distribution<RealType, Policy>& /* dist */)
|
||||
{ // Range of supported values for random variable k.
|
||||
// This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>()); // max_integer?
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mean(const geometric_distribution<RealType, Policy>& dist)
|
||||
{ // Mean of geometric distribution = (1-p)/p.
|
||||
return (1 - dist.success_fraction() ) / dist.success_fraction();
|
||||
} // mean
|
||||
|
||||
// median implemented via quantile(half) in derived accessors.
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mode(const geometric_distribution<RealType, Policy>&)
|
||||
{ // Mode of geometric distribution = zero.
|
||||
BOOST_MATH_STD_USING // ADL of std functions.
|
||||
return 0;
|
||||
} // mode
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType variance(const geometric_distribution<RealType, Policy>& dist)
|
||||
{ // Variance of Binomial distribution = (1-p) / p^2.
|
||||
return (1 - dist.success_fraction())
|
||||
/ (dist.success_fraction() * dist.success_fraction());
|
||||
} // variance
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType skewness(const geometric_distribution<RealType, Policy>& dist)
|
||||
{ // skewness of geometric distribution = 2-p / (sqrt(r(1-p))
|
||||
BOOST_MATH_STD_USING // ADL of std functions.
|
||||
RealType p = dist.success_fraction();
|
||||
return (2 - p) / sqrt(1 - p);
|
||||
} // skewness
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis(const geometric_distribution<RealType, Policy>& dist)
|
||||
{ // kurtosis of geometric distribution
|
||||
// http://en.wikipedia.org/wiki/geometric is kurtosis_excess so add 3
|
||||
RealType p = dist.success_fraction();
|
||||
return 3 + (p*p - 6*p + 6) / (1 - p);
|
||||
} // kurtosis
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis_excess(const geometric_distribution<RealType, Policy>& dist)
|
||||
{ // kurtosis excess of geometric distribution
|
||||
// http://mathworld.wolfram.com/Kurtosis.html table of kurtosis_excess
|
||||
RealType p = dist.success_fraction();
|
||||
return (p*p - 6*p + 6) / (1 - p);
|
||||
} // kurtosis_excess
|
||||
|
||||
// RealType standard_deviation(const geometric_distribution<RealType, Policy>& dist)
|
||||
// standard_deviation provided by derived accessors.
|
||||
// RealType hazard(const geometric_distribution<RealType, Policy>& dist)
|
||||
// hazard of geometric distribution provided by derived accessors.
|
||||
// RealType chf(const geometric_distribution<RealType, Policy>& dist)
|
||||
// chf of geometric distribution provided by derived accessors.
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType pdf(const geometric_distribution<RealType, Policy>& dist, const RealType& k)
|
||||
{ // Probability Density/Mass Function.
|
||||
BOOST_FPU_EXCEPTION_GUARD
|
||||
BOOST_MATH_STD_USING // For ADL of math functions.
|
||||
static const char* function = "boost::math::pdf(const geometric_distribution<%1%>&, %1%)";
|
||||
|
||||
RealType p = dist.success_fraction();
|
||||
RealType result = 0;
|
||||
if(false == geometric_detail::check_dist_and_k(
|
||||
function,
|
||||
p,
|
||||
k,
|
||||
&result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if (k == 0)
|
||||
{
|
||||
return p; // success_fraction
|
||||
}
|
||||
RealType q = 1 - p; // Inaccurate for small p?
|
||||
// So try to avoid inaccuracy for large or small p.
|
||||
// but has little effect > last significant bit.
|
||||
//cout << "p * pow(q, k) " << result << endl; // seems best whatever p
|
||||
//cout << "exp(p * k * log1p(-p)) " << p * exp(k * log1p(-p)) << endl;
|
||||
//if (p < 0.5)
|
||||
//{
|
||||
// result = p * pow(q, k);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// result = p * exp(k * log1p(-p));
|
||||
//}
|
||||
result = p * pow(q, k);
|
||||
return result;
|
||||
} // geometric_pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const geometric_distribution<RealType, Policy>& dist, const RealType& k)
|
||||
{ // Cumulative Distribution Function of geometric.
|
||||
static const char* function = "boost::math::cdf(const geometric_distribution<%1%>&, %1%)";
|
||||
|
||||
// k argument may be integral, signed, or unsigned, or floating point.
|
||||
// If necessary, it has already been promoted from an integral type.
|
||||
RealType p = dist.success_fraction();
|
||||
// Error check:
|
||||
RealType result = 0;
|
||||
if(false == geometric_detail::check_dist_and_k(
|
||||
function,
|
||||
p,
|
||||
k,
|
||||
&result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(k == 0)
|
||||
{
|
||||
return p; // success_fraction
|
||||
}
|
||||
//RealType q = 1 - p; // Bad for small p
|
||||
//RealType probability = 1 - std::pow(q, k+1);
|
||||
|
||||
RealType z = boost::math::log1p(-p) * (k+1);
|
||||
RealType probability = -boost::math::expm1(z);
|
||||
|
||||
return probability;
|
||||
} // cdf Cumulative Distribution Function geometric.
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const complemented2_type<geometric_distribution<RealType, Policy>, RealType>& c)
|
||||
{ // Complemented Cumulative Distribution Function geometric.
|
||||
BOOST_MATH_STD_USING
|
||||
static const char* function = "boost::math::cdf(const geometric_distribution<%1%>&, %1%)";
|
||||
// k argument may be integral, signed, or unsigned, or floating point.
|
||||
// If necessary, it has already been promoted from an integral type.
|
||||
RealType const& k = c.param;
|
||||
geometric_distribution<RealType, Policy> const& dist = c.dist;
|
||||
RealType p = dist.success_fraction();
|
||||
// Error check:
|
||||
RealType result = 0;
|
||||
if(false == geometric_detail::check_dist_and_k(
|
||||
function,
|
||||
p,
|
||||
k,
|
||||
&result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
RealType z = boost::math::log1p(-p) * (k+1);
|
||||
RealType probability = exp(z);
|
||||
return probability;
|
||||
} // cdf Complemented Cumulative Distribution Function geometric.
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const geometric_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{ // Quantile, percentile/100 or Percent Point geometric function.
|
||||
// Return the number of expected failures k for a given probability p.
|
||||
|
||||
// Inverse cumulative Distribution Function or Quantile (percentile / 100) of geometric Probability.
|
||||
// k argument may be integral, signed, or unsigned, or floating point.
|
||||
|
||||
static const char* function = "boost::math::quantile(const geometric_distribution<%1%>&, %1%)";
|
||||
BOOST_MATH_STD_USING // ADL of std functions.
|
||||
|
||||
RealType success_fraction = dist.success_fraction();
|
||||
// Check dist and x.
|
||||
RealType result = 0;
|
||||
if(false == geometric_detail::check_dist_and_prob
|
||||
(function, success_fraction, x, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
// Special cases.
|
||||
if (x == 1)
|
||||
{ // Would need +infinity failures for total confidence.
|
||||
result = policies::raise_overflow_error<RealType>(
|
||||
function,
|
||||
"Probability argument is 1, which implies infinite failures !", Policy());
|
||||
return result;
|
||||
// usually means return +std::numeric_limits<RealType>::infinity();
|
||||
// unless #define BOOST_MATH_THROW_ON_OVERFLOW_ERROR
|
||||
}
|
||||
if (x == 0)
|
||||
{ // No failures are expected if P = 0.
|
||||
return 0; // Total trials will be just dist.successes.
|
||||
}
|
||||
// if (P <= pow(dist.success_fraction(), 1))
|
||||
if (x <= success_fraction)
|
||||
{ // p <= pdf(dist, 0) == cdf(dist, 0)
|
||||
return 0;
|
||||
}
|
||||
if (x == 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// log(1-x) /log(1-success_fraction) -1; but use log1p in case success_fraction is small
|
||||
result = boost::math::log1p(-x) / boost::math::log1p(-success_fraction) -1;
|
||||
// Subtract a few epsilons here too?
|
||||
// to make sure it doesn't slip over, so ceil would be one too many.
|
||||
return result;
|
||||
} // RealType quantile(const geometric_distribution dist, p)
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const complemented2_type<geometric_distribution<RealType, Policy>, RealType>& c)
|
||||
{ // Quantile or Percent Point Binomial function.
|
||||
// Return the number of expected failures k for a given
|
||||
// complement of the probability Q = 1 - P.
|
||||
static const char* function = "boost::math::quantile(const geometric_distribution<%1%>&, %1%)";
|
||||
BOOST_MATH_STD_USING
|
||||
// Error checks:
|
||||
RealType x = c.param;
|
||||
const geometric_distribution<RealType, Policy>& dist = c.dist;
|
||||
RealType success_fraction = dist.success_fraction();
|
||||
RealType result = 0;
|
||||
if(false == geometric_detail::check_dist_and_prob(
|
||||
function,
|
||||
success_fraction,
|
||||
x,
|
||||
&result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
// Special cases:
|
||||
if(x == 1)
|
||||
{ // There may actually be no answer to this question,
|
||||
// since the probability of zero failures may be non-zero,
|
||||
return 0; // but zero is the best we can do:
|
||||
}
|
||||
if (-x <= boost::math::powm1(dist.success_fraction(), dist.successes(), Policy()))
|
||||
{ // q <= cdf(complement(dist, 0)) == pdf(dist, 0)
|
||||
return 0; //
|
||||
}
|
||||
if(x == 0)
|
||||
{ // Probability 1 - Q == 1 so infinite failures to achieve certainty.
|
||||
// Would need +infinity failures for total confidence.
|
||||
result = policies::raise_overflow_error<RealType>(
|
||||
function,
|
||||
"Probability argument complement is 0, which implies infinite failures !", Policy());
|
||||
return result;
|
||||
// usually means return +std::numeric_limits<RealType>::infinity();
|
||||
// unless #define BOOST_MATH_THROW_ON_OVERFLOW_ERROR
|
||||
}
|
||||
// log(x) /log(1-success_fraction) -1; but use log1p in case success_fraction is small
|
||||
result = log(x) / boost::math::log1p(-success_fraction) -1;
|
||||
return result;
|
||||
|
||||
} // quantile complement
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
// This include must be at the end, *after* the accessors
|
||||
// for this distribution have been defined, in order to
|
||||
// keep compilers that support two-phase lookup happy.
|
||||
#include <boost/math/distributions/detail/derived_accessors.hpp>
|
||||
|
||||
#if defined (BOOST_MSVC)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // BOOST_MATH_SPECIAL_GEOMETRIC_HPP
|
||||
293
test/external/boost/math/distributions/hypergeometric.hpp
vendored
Normal file
293
test/external/boost/math/distributions/hypergeometric.hpp
vendored
Normal file
@@ -0,0 +1,293 @@
|
||||
// Copyright 2008 Gautam Sewani
|
||||
// Copyright 2008 John Maddock
|
||||
//
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_MATH_DISTRIBUTIONS_HYPERGEOMETRIC_HPP
|
||||
#define BOOST_MATH_DISTRIBUTIONS_HYPERGEOMETRIC_HPP
|
||||
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp>
|
||||
#include <boost/math/distributions/complement.hpp>
|
||||
#include <boost/math/distributions/detail/hypergeometric_pdf.hpp>
|
||||
#include <boost/math/distributions/detail/hypergeometric_cdf.hpp>
|
||||
#include <boost/math/distributions/detail/hypergeometric_quantile.hpp>
|
||||
#include <boost/math/special_functions/fpclassify.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace math {
|
||||
|
||||
template <class RealType = double, class Policy = policies::policy<> >
|
||||
class hypergeometric_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
|
||||
hypergeometric_distribution(unsigned r, unsigned n, unsigned N) // Constructor.
|
||||
: m_n(n), m_N(N), m_r(r)
|
||||
{
|
||||
static const char* function = "boost::math::hypergeometric_distribution<%1%>::hypergeometric_distribution";
|
||||
RealType ret;
|
||||
check_params(function, &ret);
|
||||
}
|
||||
// Accessor functions.
|
||||
unsigned total()const
|
||||
{
|
||||
return m_N;
|
||||
}
|
||||
|
||||
unsigned defective()const
|
||||
{
|
||||
return m_n;
|
||||
}
|
||||
|
||||
unsigned sample_count()const
|
||||
{
|
||||
return m_r;
|
||||
}
|
||||
|
||||
bool check_params(const char* function, RealType* result)const
|
||||
{
|
||||
if(m_r > m_N)
|
||||
{
|
||||
*result = boost::math::policies::raise_domain_error<RealType>(
|
||||
function, "Parameter r out of range: must be <= N but got %1%", static_cast<RealType>(m_r), Policy());
|
||||
return false;
|
||||
}
|
||||
if(m_n > m_N)
|
||||
{
|
||||
*result = boost::math::policies::raise_domain_error<RealType>(
|
||||
function, "Parameter n out of range: must be <= N but got %1%", static_cast<RealType>(m_n), Policy());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool check_x(unsigned x, const char* function, RealType* result)const
|
||||
{
|
||||
if(x < static_cast<unsigned>((std::max)(0, (int)(m_n + m_r) - (int)(m_N))))
|
||||
{
|
||||
*result = boost::math::policies::raise_domain_error<RealType>(
|
||||
function, "Random variable out of range: must be > 0 and > m + r - N but got %1%", static_cast<RealType>(x), Policy());
|
||||
return false;
|
||||
}
|
||||
if(x > (std::min)(m_r, m_n))
|
||||
{
|
||||
*result = boost::math::policies::raise_domain_error<RealType>(
|
||||
function, "Random variable out of range: must be less than both n and r but got %1%", static_cast<RealType>(x), Policy());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
// Data members:
|
||||
unsigned m_n; // number of "defective" items
|
||||
unsigned m_N; // number of "total" items
|
||||
unsigned m_r; // number of items picked
|
||||
|
||||
}; // class hypergeometric_distribution
|
||||
|
||||
typedef hypergeometric_distribution<double> hypergeometric;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<unsigned, unsigned> range(const hypergeometric_distribution<RealType, Policy>& dist)
|
||||
{ // Range of permissible values for random variable x.
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4267)
|
||||
#endif
|
||||
unsigned r = dist.sample_count();
|
||||
unsigned n = dist.defective();
|
||||
unsigned N = dist.total();
|
||||
unsigned l = static_cast<unsigned>((std::max)(0, (int)(n + r) - (int)(N)));
|
||||
unsigned u = (std::min)(r, n);
|
||||
return std::pair<unsigned, unsigned>(l, u);
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<unsigned, unsigned> support(const hypergeometric_distribution<RealType, Policy>& d)
|
||||
{
|
||||
return range(d);
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType pdf(const hypergeometric_distribution<RealType, Policy>& dist, const unsigned& x)
|
||||
{
|
||||
static const char* function = "boost::math::pdf(const hypergeometric_distribution<%1%>&, const %1%&)";
|
||||
RealType result = 0;
|
||||
if(!dist.check_params(function, &result))
|
||||
return result;
|
||||
if(!dist.check_x(x, function, &result))
|
||||
return result;
|
||||
|
||||
return boost::math::detail::hypergeometric_pdf<RealType>(
|
||||
x, dist.sample_count(), dist.defective(), dist.total(), Policy());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy, class U>
|
||||
inline RealType pdf(const hypergeometric_distribution<RealType, Policy>& dist, const U& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
static const char* function = "boost::math::pdf(const hypergeometric_distribution<%1%>&, const %1%&)";
|
||||
RealType r = static_cast<RealType>(x);
|
||||
unsigned u = itrunc(r);
|
||||
if(u != r)
|
||||
{
|
||||
return boost::math::policies::raise_domain_error<RealType>(
|
||||
function, "Random variable out of range: must be an integer but got %1%", r, Policy());
|
||||
}
|
||||
return pdf(dist, u);
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const hypergeometric_distribution<RealType, Policy>& dist, const unsigned& x)
|
||||
{
|
||||
static const char* function = "boost::math::cdf(const hypergeometric_distribution<%1%>&, const %1%&)";
|
||||
RealType result = 0;
|
||||
if(!dist.check_params(function, &result))
|
||||
return result;
|
||||
if(!dist.check_x(x, function, &result))
|
||||
return result;
|
||||
|
||||
return boost::math::detail::hypergeometric_cdf<RealType>(
|
||||
x, dist.sample_count(), dist.defective(), dist.total(), false, Policy());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy, class U>
|
||||
inline RealType cdf(const hypergeometric_distribution<RealType, Policy>& dist, const U& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
static const char* function = "boost::math::cdf(const hypergeometric_distribution<%1%>&, const %1%&)";
|
||||
RealType r = static_cast<RealType>(x);
|
||||
unsigned u = itrunc(r);
|
||||
if(u != r)
|
||||
{
|
||||
return boost::math::policies::raise_domain_error<RealType>(
|
||||
function, "Random variable out of range: must be an integer but got %1%", r, Policy());
|
||||
}
|
||||
return cdf(dist, u);
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const complemented2_type<hypergeometric_distribution<RealType, Policy>, unsigned>& c)
|
||||
{
|
||||
static const char* function = "boost::math::cdf(const hypergeometric_distribution<%1%>&, const %1%&)";
|
||||
RealType result = 0;
|
||||
if(!c.dist.check_params(function, &result))
|
||||
return result;
|
||||
if(!c.dist.check_x(c.param, function, &result))
|
||||
return result;
|
||||
|
||||
return boost::math::detail::hypergeometric_cdf<RealType>(
|
||||
c.param, c.dist.sample_count(), c.dist.defective(), c.dist.total(), true, Policy());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy, class U>
|
||||
inline RealType cdf(const complemented2_type<hypergeometric_distribution<RealType, Policy>, U>& c)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
static const char* function = "boost::math::cdf(const hypergeometric_distribution<%1%>&, const %1%&)";
|
||||
RealType r = static_cast<RealType>(c.param);
|
||||
unsigned u = itrunc(r);
|
||||
if(u != r)
|
||||
{
|
||||
return boost::math::policies::raise_domain_error<RealType>(
|
||||
function, "Random variable out of range: must be an integer but got %1%", r, Policy());
|
||||
}
|
||||
return cdf(complement(c.dist, u));
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const hypergeometric_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
// Checking function argument
|
||||
RealType result = 0;
|
||||
const char* function = "boost::math::quantile(const hypergeometric_distribution<%1%>&, %1%)";
|
||||
if (false == dist.check_params(function, &result)) return result;
|
||||
if(false == detail::check_probability(function, p, &result, Policy())) return result;
|
||||
|
||||
return static_cast<RealType>(detail::hypergeometric_quantile(p, RealType(1 - p), dist.sample_count(), dist.defective(), dist.total(), Policy()));
|
||||
} // quantile
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const complemented2_type<hypergeometric_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
// Checking function argument
|
||||
RealType result = 0;
|
||||
const char* function = "quantile(const complemented2_type<hypergeometric_distribution<%1%>, %1%>&)";
|
||||
if (false == c.dist.check_params(function, &result)) return result;
|
||||
if(false == detail::check_probability(function, c.param, &result, Policy())) return result;
|
||||
|
||||
return static_cast<RealType>(detail::hypergeometric_quantile(RealType(1 - c.param), c.param, c.dist.sample_count(), c.dist.defective(), c.dist.total(), Policy()));
|
||||
} // quantile
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mean(const hypergeometric_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
return static_cast<RealType>(dist.sample_count() * dist.defective()) / dist.total();
|
||||
} // RealType mean(const hypergeometric_distribution<RealType, Policy>& dist)
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType variance(const hypergeometric_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType r = static_cast<RealType>(dist.sample_count());
|
||||
RealType n = static_cast<RealType>(dist.defective());
|
||||
RealType N = static_cast<RealType>(dist.total());
|
||||
return r * (n / N) * (1 - n / N) * (N - r) / (N - 1);
|
||||
} // RealType variance(const hypergeometric_distribution<RealType, Policy>& dist)
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mode(const hypergeometric_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
RealType r = static_cast<RealType>(dist.sample_count());
|
||||
RealType n = static_cast<RealType>(dist.defective());
|
||||
RealType N = static_cast<RealType>(dist.total());
|
||||
return floor((r + 1) * (n + 1) / (N + 2));
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType skewness(const hypergeometric_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
RealType r = static_cast<RealType>(dist.sample_count());
|
||||
RealType n = static_cast<RealType>(dist.defective());
|
||||
RealType N = static_cast<RealType>(dist.total());
|
||||
return (N - 2 * n) * sqrt(N - 1) * (N - 2 * r) / (sqrt(n * r * (N - n) * (N - r)) * (N - 2));
|
||||
} // RealType skewness(const hypergeometric_distribution<RealType, Policy>& dist)
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis_excess(const hypergeometric_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType r = static_cast<RealType>(dist.sample_count());
|
||||
RealType n = static_cast<RealType>(dist.defective());
|
||||
RealType N = static_cast<RealType>(dist.total());
|
||||
RealType t1 = N * N * (N - 1) / (r * (N - 2) * (N - 3) * (N - r));
|
||||
RealType t2 = (N * (N + 1) - 6 * N * (N - r)) / (n * (N - n))
|
||||
+ 3 * r * (N - r) * (N + 6) / (N * N) - 6;
|
||||
return t1 * t2;
|
||||
} // RealType kurtosis_excess(const hypergeometric_distribution<RealType, Policy>& dist)
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis(const hypergeometric_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
return kurtosis_excess(dist) + 3;
|
||||
} // RealType kurtosis_excess(const hypergeometric_distribution<RealType, Policy>& dist)
|
||||
}} // namespaces
|
||||
|
||||
// This include must be at the end, *after* the accessors
|
||||
// for this distribution have been defined, in order to
|
||||
// keep compilers that support two-phase lookup happy.
|
||||
#include <boost/math/distributions/detail/derived_accessors.hpp>
|
||||
|
||||
#endif // include guard
|
||||
391
test/external/boost/math/distributions/inverse_chi_squared.hpp
vendored
Normal file
391
test/external/boost/math/distributions/inverse_chi_squared.hpp
vendored
Normal file
@@ -0,0 +1,391 @@
|
||||
// Copyright John Maddock 2010.
|
||||
// Copyright Paul A. Bristow 2010.
|
||||
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_MATH_DISTRIBUTIONS_INVERSE_CHI_SQUARED_HPP
|
||||
#define BOOST_MATH_DISTRIBUTIONS_INVERSE_CHI_SQUARED_HPP
|
||||
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#include <boost/math/special_functions/gamma.hpp> // for incomplete beta.
|
||||
#include <boost/math/distributions/complement.hpp> // for complements.
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp> // for error checks.
|
||||
#include <boost/math/special_functions/fpclassify.hpp> // for isfinite
|
||||
|
||||
// See http://en.wikipedia.org/wiki/Scaled-inverse-chi-square_distribution
|
||||
// for definitions of this scaled version.
|
||||
// See http://en.wikipedia.org/wiki/Inverse-chi-square_distribution
|
||||
// for unscaled version.
|
||||
|
||||
// http://reference.wolfram.com/mathematica/ref/InverseChiSquareDistribution.html
|
||||
// Weisstein, Eric W. "Inverse Chi-Squared Distribution." From MathWorld--A Wolfram Web Resource.
|
||||
// http://mathworld.wolfram.com/InverseChi-SquaredDistribution.html
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace boost{ namespace math{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_inverse_chi_squared( // Check both distribution parameters.
|
||||
const char* function,
|
||||
RealType degrees_of_freedom, // degrees_of_freedom (aka nu).
|
||||
RealType scale, // scale (aka sigma^2)
|
||||
RealType* result,
|
||||
const Policy& pol)
|
||||
{
|
||||
return check_scale(function, scale, result, pol)
|
||||
&& check_df(function, degrees_of_freedom,
|
||||
result, pol);
|
||||
} // bool check_inverse_chi_squared
|
||||
} // namespace detail
|
||||
|
||||
template <class RealType = double, class Policy = policies::policy<> >
|
||||
class inverse_chi_squared_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
|
||||
inverse_chi_squared_distribution(RealType df, RealType scale) : m_df(df), m_scale (scale)
|
||||
{
|
||||
RealType result;
|
||||
detail::check_df(
|
||||
"boost::math::inverse_chi_squared_distribution<%1%>::inverse_chi_squared_distribution",
|
||||
m_df, &result, Policy())
|
||||
&& detail::check_scale(
|
||||
"boost::math::inverse_chi_squared_distribution<%1%>::inverse_chi_squared_distribution",
|
||||
m_scale, &result, Policy());
|
||||
} // inverse_chi_squared_distribution constructor
|
||||
|
||||
inverse_chi_squared_distribution(RealType df = 1) : m_df(df)
|
||||
{
|
||||
RealType result;
|
||||
m_scale = 1 / m_df ; // Default scale = 1 / degrees of freedom (Wikipedia definition 1).
|
||||
detail::check_df(
|
||||
"boost::math::inverse_chi_squared_distribution<%1%>::inverse_chi_squared_distribution",
|
||||
m_df, &result, Policy());
|
||||
} // inverse_chi_squared_distribution
|
||||
|
||||
RealType degrees_of_freedom()const
|
||||
{
|
||||
return m_df; // aka nu
|
||||
}
|
||||
RealType scale()const
|
||||
{
|
||||
return m_scale; // aka xi
|
||||
}
|
||||
|
||||
// Parameter estimation: NOT implemented yet.
|
||||
//static RealType find_degrees_of_freedom(
|
||||
// RealType difference_from_variance,
|
||||
// RealType alpha,
|
||||
// RealType beta,
|
||||
// RealType variance,
|
||||
// RealType hint = 100);
|
||||
|
||||
private:
|
||||
// Data members:
|
||||
RealType m_df; // degrees of freedom are treated as a real number.
|
||||
RealType m_scale; // distribution scale.
|
||||
|
||||
}; // class chi_squared_distribution
|
||||
|
||||
typedef inverse_chi_squared_distribution<double> inverse_chi_squared;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const inverse_chi_squared_distribution<RealType, Policy>& /*dist*/)
|
||||
{ // Range of permissible values for random variable x.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>()); // 0 to + infinity.
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> support(const inverse_chi_squared_distribution<RealType, Policy>& /*dist*/)
|
||||
{ // Range of supported values for random variable x.
|
||||
// This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
|
||||
return std::pair<RealType, RealType>(static_cast<RealType>(0), tools::max_value<RealType>()); // 0 to + infinity.
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
RealType pdf(const inverse_chi_squared_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions.
|
||||
RealType df = dist.degrees_of_freedom();
|
||||
RealType scale = dist.scale();
|
||||
RealType error_result;
|
||||
|
||||
static const char* function = "boost::math::pdf(const inverse_chi_squared_distribution<%1%>&, %1%)";
|
||||
|
||||
if(false == detail::check_inverse_chi_squared
|
||||
(function, df, scale, &error_result, Policy())
|
||||
)
|
||||
{ // Bad distribution.
|
||||
return error_result;
|
||||
}
|
||||
if((x < 0) || !(boost::math::isfinite)(x))
|
||||
{ // Bad x.
|
||||
return policies::raise_domain_error<RealType>(
|
||||
function, "inverse Chi Square parameter was %1%, but must be >= 0 !", x, Policy());
|
||||
}
|
||||
|
||||
if(x == 0)
|
||||
{ // Treat as special case.
|
||||
return 0;
|
||||
}
|
||||
// Wikipedia scaled inverse chi sq (df, scale) related to inv gamma (df/2, df * scale /2)
|
||||
// so use inverse gamma pdf with shape = df/2, scale df * scale /2
|
||||
// RealType shape = df /2; // inv_gamma shape
|
||||
// RealType scale = df * scale/2; // inv_gamma scale
|
||||
// RealType result = gamma_p_derivative(shape, scale / x, Policy()) * scale / (x * x);
|
||||
RealType result = df * scale/2 / x;
|
||||
if(result < tools::min_value<RealType>())
|
||||
return 0; // Random variable is near enough infinite.
|
||||
result = gamma_p_derivative(df/2, result, Policy()) * df * scale/2;
|
||||
if(result != 0) // prevent 0 / 0, gamma_p_derivative -> 0 faster than x^2
|
||||
result /= (x * x);
|
||||
return result;
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const inverse_chi_squared_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
static const char* function = "boost::math::cdf(const inverse_chi_squared_distribution<%1%>&, %1%)";
|
||||
RealType df = dist.degrees_of_freedom();
|
||||
RealType scale = dist.scale();
|
||||
RealType error_result;
|
||||
|
||||
if(false ==
|
||||
detail::check_inverse_chi_squared(function, df, scale, &error_result, Policy())
|
||||
)
|
||||
{ // Bad distribution.
|
||||
return error_result;
|
||||
}
|
||||
if((x < 0) || !(boost::math::isfinite)(x))
|
||||
{ // Bad x.
|
||||
return policies::raise_domain_error<RealType>(
|
||||
function, "inverse Chi Square parameter was %1%, but must be >= 0 !", x, Policy());
|
||||
}
|
||||
if (x == 0)
|
||||
{ // Treat zero as a special case.
|
||||
return 0;
|
||||
}
|
||||
// RealType shape = df /2; // inv_gamma shape,
|
||||
// RealType scale = df * scale/2; // inv_gamma scale,
|
||||
// result = boost::math::gamma_q(shape, scale / x, Policy()); // inverse_gamma code.
|
||||
return boost::math::gamma_q(df / 2, (df * (scale / 2)) / x, Policy());
|
||||
} // cdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const inverse_chi_squared_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
{
|
||||
using boost::math::gamma_q_inv;
|
||||
RealType df = dist.degrees_of_freedom();
|
||||
RealType scale = dist.scale();
|
||||
|
||||
static const char* function = "boost::math::quantile(const inverse_chi_squared_distribution<%1%>&, %1%)";
|
||||
// Error check:
|
||||
RealType error_result;
|
||||
if(false == detail::check_df(
|
||||
function, df, &error_result, Policy())
|
||||
&& detail::check_probability(
|
||||
function, p, &error_result, Policy()))
|
||||
{
|
||||
return error_result;
|
||||
}
|
||||
if(false == detail::check_probability(
|
||||
function, p, &error_result, Policy()))
|
||||
{
|
||||
return error_result;
|
||||
}
|
||||
// RealType shape = df /2; // inv_gamma shape,
|
||||
// RealType scale = df * scale/2; // inv_gamma scale,
|
||||
// result = scale / gamma_q_inv(shape, p, Policy());
|
||||
RealType result = gamma_q_inv(df /2, p, Policy());
|
||||
if(result == 0)
|
||||
return policies::raise_overflow_error<RealType, Policy>(function, "Random variable is infinite.", Policy());
|
||||
result = df * (scale / 2) / result;
|
||||
return result;
|
||||
} // quantile
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const complemented2_type<inverse_chi_squared_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
using boost::math::gamma_q_inv;
|
||||
RealType const& df = c.dist.degrees_of_freedom();
|
||||
RealType const& scale = c.dist.scale();
|
||||
RealType const& x = c.param;
|
||||
static const char* function = "boost::math::cdf(const inverse_chi_squared_distribution<%1%>&, %1%)";
|
||||
// Error check:
|
||||
RealType error_result;
|
||||
if(false == detail::check_df(
|
||||
function, df, &error_result, Policy()))
|
||||
{
|
||||
return error_result;
|
||||
}
|
||||
if (x == 0)
|
||||
{ // Treat zero as a special case.
|
||||
return 1;
|
||||
}
|
||||
if((x < 0) || !(boost::math::isfinite)(x))
|
||||
{
|
||||
return policies::raise_domain_error<RealType>(
|
||||
function, "inverse Chi Square parameter was %1%, but must be > 0 !", x, Policy());
|
||||
}
|
||||
// RealType shape = df /2; // inv_gamma shape,
|
||||
// RealType scale = df * scale/2; // inv_gamma scale,
|
||||
// result = gamma_p(shape, scale/c.param, Policy()); use inv_gamma.
|
||||
|
||||
return gamma_p(df / 2, (df * scale/2) / x, Policy()); // OK
|
||||
} // cdf(complemented
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const complemented2_type<inverse_chi_squared_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
using boost::math::gamma_q_inv;
|
||||
|
||||
RealType const& df = c.dist.degrees_of_freedom();
|
||||
RealType const& scale = c.dist.scale();
|
||||
RealType const& q = c.param;
|
||||
static const char* function = "boost::math::quantile(const inverse_chi_squared_distribution<%1%>&, %1%)";
|
||||
// Error check:
|
||||
RealType error_result;
|
||||
if(false == detail::check_df(function, df, &error_result, Policy()))
|
||||
{
|
||||
return error_result;
|
||||
}
|
||||
if(false == detail::check_probability(function, q, &error_result, Policy()))
|
||||
{
|
||||
return error_result;
|
||||
}
|
||||
// RealType shape = df /2; // inv_gamma shape,
|
||||
// RealType scale = df * scale/2; // inv_gamma scale,
|
||||
// result = scale / gamma_p_inv(shape, q, Policy()); // using inv_gamma.
|
||||
RealType result = gamma_p_inv(df/2, q, Policy());
|
||||
if(result == 0)
|
||||
return policies::raise_overflow_error<RealType, Policy>(function, "Random variable is infinite.", Policy());
|
||||
result = (df * scale / 2) / result;
|
||||
return result;
|
||||
} // quantile(const complement
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mean(const inverse_chi_squared_distribution<RealType, Policy>& dist)
|
||||
{ // Mean of inverse Chi-Squared distribution.
|
||||
RealType df = dist.degrees_of_freedom();
|
||||
RealType scale = dist.scale();
|
||||
|
||||
static const char* function = "boost::math::mean(const inverse_chi_squared_distribution<%1%>&)";
|
||||
if(df <= 2)
|
||||
return policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"inverse Chi-Squared distribution only has a mode for degrees of freedom > 2, but got degrees of freedom = %1%.",
|
||||
df, Policy());
|
||||
return (df * scale) / (df - 2);
|
||||
} // mean
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType variance(const inverse_chi_squared_distribution<RealType, Policy>& dist)
|
||||
{ // Variance of inverse Chi-Squared distribution.
|
||||
RealType df = dist.degrees_of_freedom();
|
||||
RealType scale = dist.scale();
|
||||
static const char* function = "boost::math::variance(const inverse_chi_squared_distribution<%1%>&)";
|
||||
if(df <= 4)
|
||||
{
|
||||
return policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"inverse Chi-Squared distribution only has a variance for degrees of freedom > 4, but got degrees of freedom = %1%.",
|
||||
df, Policy());
|
||||
}
|
||||
return 2 * df * df * scale * scale / ((df - 2)*(df - 2) * (df - 4));
|
||||
} // variance
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mode(const inverse_chi_squared_distribution<RealType, Policy>& dist)
|
||||
{ // mode is not defined in Mathematica.
|
||||
// See Discussion section http://en.wikipedia.org/wiki/Talk:Scaled-inverse-chi-square_distribution
|
||||
// for origin of the formula used below.
|
||||
|
||||
RealType df = dist.degrees_of_freedom();
|
||||
RealType scale = dist.scale();
|
||||
static const char* function = "boost::math::mode(const inverse_chi_squared_distribution<%1%>&)";
|
||||
if(df < 0)
|
||||
return policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"inverse Chi-Squared distribution only has a mode for degrees of freedom >= 0, but got degrees of freedom = %1%.",
|
||||
df, Policy());
|
||||
return (df * scale) / (df + 2);
|
||||
}
|
||||
|
||||
//template <class RealType, class Policy>
|
||||
//inline RealType median(const inverse_chi_squared_distribution<RealType, Policy>& dist)
|
||||
//{ // Median is given by Quantile[dist, 1/2]
|
||||
// RealType df = dist.degrees_of_freedom();
|
||||
// if(df <= 1)
|
||||
// return tools::domain_error<RealType>(
|
||||
// BOOST_CURRENT_FUNCTION,
|
||||
// "The inverse_Chi-Squared distribution only has a median for degrees of freedom >= 0, but got degrees of freedom = %1%.",
|
||||
// df);
|
||||
// return df;
|
||||
//}
|
||||
// Now implemented via quantile(half) in derived accessors.
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType skewness(const inverse_chi_squared_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING // For ADL
|
||||
RealType df = dist.degrees_of_freedom();
|
||||
static const char* function = "boost::math::skewness(const inverse_chi_squared_distribution<%1%>&)";
|
||||
if(df <= 6)
|
||||
return policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"inverse Chi-Squared distribution only has a skewness for degrees of freedom > 6, but got degrees of freedom = %1%.",
|
||||
df, Policy());
|
||||
|
||||
return 4 * sqrt (2 * (df - 4)) / (df - 6); // Not a function of scale.
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis(const inverse_chi_squared_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType df = dist.degrees_of_freedom();
|
||||
static const char* function = "boost::math::kurtosis(const inverse_chi_squared_distribution<%1%>&)";
|
||||
if(df <= 8)
|
||||
return policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"inverse Chi-Squared distribution only has a kurtosis for degrees of freedom > 8, but got degrees of freedom = %1%.",
|
||||
df, Policy());
|
||||
|
||||
return kurtosis_excess(dist) + 3;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis_excess(const inverse_chi_squared_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType df = dist.degrees_of_freedom();
|
||||
static const char* function = "boost::math::kurtosis(const inverse_chi_squared_distribution<%1%>&)";
|
||||
if(df <= 8)
|
||||
return policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"inverse Chi-Squared distribution only has a kurtosis excess for degrees of freedom > 8, but got degrees of freedom = %1%.",
|
||||
df, Policy());
|
||||
|
||||
return 12 * (5 * df - 22) / ((df - 6 )*(df - 8)); // Not a function of scale.
|
||||
}
|
||||
|
||||
//
|
||||
// Parameter estimation comes last:
|
||||
//
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
// This include must be at the end, *after* the accessors
|
||||
// for this distribution have been defined, in order to
|
||||
// keep compilers that support two-phase lookup happy.
|
||||
#include <boost/math/distributions/detail/derived_accessors.hpp>
|
||||
|
||||
#endif // BOOST_MATH_DISTRIBUTIONS_INVERSE_CHI_SQUARED_HPP
|
||||
458
test/external/boost/math/distributions/inverse_gamma.hpp
vendored
Normal file
458
test/external/boost/math/distributions/inverse_gamma.hpp
vendored
Normal file
@@ -0,0 +1,458 @@
|
||||
// inverse_gamma.hpp
|
||||
|
||||
// Copyright Paul A. Bristow 2010.
|
||||
// Copyright John Maddock 2010.
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_STATS_INVERSE_GAMMA_HPP
|
||||
#define BOOST_STATS_INVERSE_GAMMA_HPP
|
||||
|
||||
// Inverse Gamma Distribution is a two-parameter family
|
||||
// of continuous probability distributions
|
||||
// on the positive real line, which is the distribution of
|
||||
// the reciprocal of a variable distributed according to the gamma distribution.
|
||||
|
||||
// http://en.wikipedia.org/wiki/Inverse-gamma_distribution
|
||||
// http://rss.acs.unt.edu/Rdoc/library/pscl/html/igamma.html
|
||||
|
||||
// See also gamma distribution at gamma.hpp:
|
||||
// http://www.itl.nist.gov/div898/handbook/eda/section3/eda366b.htm
|
||||
// http://mathworld.wolfram.com/GammaDistribution.html
|
||||
// http://en.wikipedia.org/wiki/Gamma_distribution
|
||||
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#include <boost/math/special_functions/gamma.hpp>
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp>
|
||||
#include <boost/math/distributions/complement.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace boost{ namespace math
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_inverse_gamma_shape(
|
||||
const char* function, // inverse_gamma
|
||||
RealType shape, // shape aka alpha
|
||||
RealType* result, // to update, perhaps with NaN
|
||||
const Policy& pol)
|
||||
{ // Sources say shape argument must be > 0
|
||||
// but seems logical to allow shape zero as special case,
|
||||
// returning pdf and cdf zero (but not < 0).
|
||||
// (Functions like mean, variance with other limits on shape are checked
|
||||
// in version including an operator & limit below).
|
||||
if((shape < 0) || !(boost::math::isfinite)(shape))
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Shape parameter is %1%, but must be >= 0 !", shape, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} //bool check_inverse_gamma_shape
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_inverse_gamma_x(
|
||||
const char* function,
|
||||
RealType const& x,
|
||||
RealType* result, const Policy& pol)
|
||||
{
|
||||
if((x < 0) || !(boost::math::isfinite)(x))
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Random variate is %1% but must be >= 0 !", x, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_inverse_gamma(
|
||||
const char* function, // TODO swap these over, so shape is first.
|
||||
RealType scale, // scale aka beta
|
||||
RealType shape, // shape aka alpha
|
||||
RealType* result, const Policy& pol)
|
||||
{
|
||||
return check_scale(function, scale, result, pol)
|
||||
&& check_inverse_gamma_shape(function, shape, result, pol);
|
||||
} // bool check_inverse_gamma
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class RealType = double, class Policy = policies::policy<> >
|
||||
class inverse_gamma_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
|
||||
inverse_gamma_distribution(RealType shape = 1, RealType scale = 1)
|
||||
: m_shape(shape), m_scale(scale)
|
||||
{
|
||||
RealType result;
|
||||
detail::check_inverse_gamma(
|
||||
"boost::math::inverse_gamma_distribution<%1%>::inverse_gamma_distribution",
|
||||
scale, shape, &result, Policy());
|
||||
}
|
||||
|
||||
RealType shape()const
|
||||
{
|
||||
return m_shape;
|
||||
}
|
||||
|
||||
RealType scale()const
|
||||
{
|
||||
return m_scale;
|
||||
}
|
||||
private:
|
||||
//
|
||||
// Data members:
|
||||
//
|
||||
RealType m_shape; // distribution shape
|
||||
RealType m_scale; // distribution scale
|
||||
};
|
||||
|
||||
typedef inverse_gamma_distribution<double> inverse_gamma;
|
||||
// typedef - but potential clash with name of inverse gamma *function*.
|
||||
// but there is a typedef for gamma
|
||||
// typedef boost::math::gamma_distribution<Type, Policy> gamma;
|
||||
|
||||
// Allow random variable x to be zero, treated as a special case (unlike some definitions).
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const inverse_gamma_distribution<RealType, Policy>& /* dist */)
|
||||
{ // Range of permissible values for random variable x.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> support(const inverse_gamma_distribution<RealType, Policy>& /* dist */)
|
||||
{ // Range of supported values for random variable x.
|
||||
// This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
|
||||
using boost::math::tools::max_value;
|
||||
using boost::math::tools::min_value;
|
||||
return std::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType pdf(const inverse_gamma_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::pdf(const inverse_gamma_distribution<%1%>&, %1%)";
|
||||
|
||||
RealType shape = dist.shape();
|
||||
RealType scale = dist.scale();
|
||||
|
||||
RealType result = 0;
|
||||
if(false == detail::check_inverse_gamma(function, scale, shape, &result, Policy()))
|
||||
{ // distribution parameters bad.
|
||||
return result;
|
||||
}
|
||||
if(x == 0)
|
||||
{ // Treat random variate zero as a special case.
|
||||
return 0;
|
||||
}
|
||||
else if(false == detail::check_inverse_gamma_x(function, x, &result, Policy()))
|
||||
{ // x bad.
|
||||
return result;
|
||||
}
|
||||
result = scale / x;
|
||||
if(result < tools::min_value<RealType>())
|
||||
return 0; // random variable is infinite or so close as to make no difference.
|
||||
result = gamma_p_derivative(shape, result, Policy()) * scale;
|
||||
if(0 != result)
|
||||
{
|
||||
if(x < 0)
|
||||
{
|
||||
// x * x may under or overflow, likewise our result,
|
||||
// so be extra careful about the arithmetic:
|
||||
RealType lim = tools::max_value<RealType>() * x;
|
||||
if(lim < result)
|
||||
return policies::raise_overflow_error<RealType, Policy>(function, "PDF is infinite.", Policy());
|
||||
result /= x;
|
||||
if(lim < result)
|
||||
return policies::raise_overflow_error<RealType, Policy>(function, "PDF is infinite.", Policy());
|
||||
result /= x;
|
||||
}
|
||||
result /= (x * x);
|
||||
}
|
||||
// better than naive
|
||||
// result = (pow(scale, shape) * pow(x, (-shape -1)) * exp(-scale/x) ) / tgamma(shape);
|
||||
return result;
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const inverse_gamma_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::cdf(const inverse_gamma_distribution<%1%>&, %1%)";
|
||||
|
||||
RealType shape = dist.shape();
|
||||
RealType scale = dist.scale();
|
||||
|
||||
RealType result = 0;
|
||||
if(false == detail::check_inverse_gamma(function, scale, shape, &result, Policy()))
|
||||
{ // distribution parameters bad.
|
||||
return result;
|
||||
}
|
||||
if (x == 0)
|
||||
{ // Treat zero as a special case.
|
||||
return 0;
|
||||
}
|
||||
else if(false == detail::check_inverse_gamma_x(function, x, &result, Policy()))
|
||||
{ // x bad
|
||||
return result;
|
||||
}
|
||||
result = boost::math::gamma_q(shape, scale / x, Policy());
|
||||
// result = tgamma(shape, scale / x) / tgamma(shape); // naive using tgamma
|
||||
return result;
|
||||
} // cdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const inverse_gamma_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
using boost::math::gamma_q_inv;
|
||||
|
||||
static const char* function = "boost::math::quantile(const inverse_gamma_distribution<%1%>&, %1%)";
|
||||
|
||||
RealType shape = dist.shape();
|
||||
RealType scale = dist.scale();
|
||||
|
||||
RealType result = 0;
|
||||
if(false == detail::check_inverse_gamma(function, scale, shape, &result, Policy()))
|
||||
return result;
|
||||
if(false == detail::check_probability(function, p, &result, Policy()))
|
||||
return result;
|
||||
if(p == 1)
|
||||
{
|
||||
return policies::raise_overflow_error<RealType>(function, 0, Policy());
|
||||
}
|
||||
result = gamma_q_inv(shape, p, Policy());
|
||||
if((result < 1) && (result * tools::max_value<RealType>() < scale))
|
||||
return policies::raise_overflow_error<RealType, Policy>(function, "Value of random variable in inverse gamma distribution quantile is infinite.", Policy());
|
||||
result = scale / result;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const complemented2_type<inverse_gamma_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::quantile(const gamma_distribution<%1%>&, %1%)";
|
||||
|
||||
RealType shape = c.dist.shape();
|
||||
RealType scale = c.dist.scale();
|
||||
|
||||
RealType result = 0;
|
||||
if(false == detail::check_inverse_gamma(function, scale, shape, &result, Policy()))
|
||||
return result;
|
||||
if(false == detail::check_inverse_gamma_x(function, c.param, &result, Policy()))
|
||||
return result;
|
||||
|
||||
//result = 1. - gamma_q(shape, c.param / scale, Policy());
|
||||
result = gamma_p(shape, scale/c.param, Policy());
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const complemented2_type<inverse_gamma_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::quantile(const inverse_gamma_distribution<%1%>&, %1%)";
|
||||
|
||||
RealType shape = c.dist.shape();
|
||||
RealType scale = c.dist.scale();
|
||||
RealType q = c.param;
|
||||
|
||||
RealType result = 0;
|
||||
if(false == detail::check_inverse_gamma(function, scale, shape, &result, Policy()))
|
||||
return result;
|
||||
if(false == detail::check_probability(function, q, &result, Policy()))
|
||||
return result;
|
||||
|
||||
if(q == 0)
|
||||
{
|
||||
return policies::raise_overflow_error<RealType>(function, 0, Policy());
|
||||
}
|
||||
result = gamma_p_inv(shape, q, Policy());
|
||||
if((result < 1) && (result * tools::max_value<RealType>() < scale))
|
||||
return policies::raise_overflow_error<RealType, Policy>(function, "Value of random variable in inverse gamma distribution quantile is infinite.", Policy());
|
||||
result = scale / result;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mean(const inverse_gamma_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::mean(const inverse_gamma_distribution<%1%>&)";
|
||||
|
||||
RealType shape = dist.shape();
|
||||
RealType scale = dist.scale();
|
||||
|
||||
RealType result = 0;
|
||||
|
||||
if(false == detail::check_scale(function, scale, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if((shape <= 1) || !(boost::math::isfinite)(shape))
|
||||
{
|
||||
result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Shape parameter is %1%, but for a defined mean it must be > 1", shape, Policy());
|
||||
return result;
|
||||
}
|
||||
result = scale / (shape - 1);
|
||||
return result;
|
||||
} // mean
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType variance(const inverse_gamma_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::variance(const inverse_gamma_distribution<%1%>&)";
|
||||
|
||||
RealType shape = dist.shape();
|
||||
RealType scale = dist.scale();
|
||||
|
||||
RealType result = 0;
|
||||
if(false == detail::check_scale(function, scale, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if((shape <= 2) || !(boost::math::isfinite)(shape))
|
||||
{
|
||||
result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Shape parameter is %1%, but for a defined variance it must be > 2", shape, Policy());
|
||||
return result;
|
||||
}
|
||||
result = (scale * scale) / ((shape - 1) * (shape -1) * (shape -2));
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mode(const inverse_gamma_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::mode(const inverse_gamma_distribution<%1%>&)";
|
||||
|
||||
RealType shape = dist.shape();
|
||||
RealType scale = dist.scale();
|
||||
|
||||
RealType result = 0;
|
||||
if(false == detail::check_inverse_gamma(function, scale, shape, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
// Only defined for shape >= 0, but is checked by check_inverse_gamma.
|
||||
result = scale / (shape + 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
//template <class RealType, class Policy>
|
||||
//inline RealType median(const gamma_distribution<RealType, Policy>& dist)
|
||||
//{ // Wikipedia does not define median,
|
||||
// so rely on default definition quantile(0.5) in derived accessors.
|
||||
// return result.
|
||||
//}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType skewness(const inverse_gamma_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::skewness(const inverse_gamma_distribution<%1%>&)";
|
||||
|
||||
RealType shape = dist.shape();
|
||||
RealType scale = dist.scale();
|
||||
RealType result = 0;
|
||||
|
||||
if(false == detail::check_scale(function, scale, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if((shape <= 3) || !(boost::math::isfinite)(shape))
|
||||
{
|
||||
result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Shape parameter is %1%, but for a defined skewness it must be > 3", shape, Policy());
|
||||
return result;
|
||||
}
|
||||
result = (4 * sqrt(shape - 2) ) / (shape - 3);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis_excess(const inverse_gamma_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::kurtosis_excess(const inverse_gamma_distribution<%1%>&)";
|
||||
|
||||
RealType shape = dist.shape();
|
||||
RealType scale = dist.scale();
|
||||
|
||||
RealType result = 0;
|
||||
if(false == detail::check_scale(function, scale, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if((shape <= 4) || !(boost::math::isfinite)(shape))
|
||||
{
|
||||
result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Shape parameter is %1%, but for a defined kurtosis excess it must be > 4", shape, Policy());
|
||||
return result;
|
||||
}
|
||||
result = (30 * shape - 66) / ((shape - 3) * (shape - 4));
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis(const inverse_gamma_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
static const char* function = "boost::math::kurtosis(const inverse_gamma_distribution<%1%>&)";
|
||||
RealType shape = dist.shape();
|
||||
RealType scale = dist.scale();
|
||||
|
||||
RealType result = 0;
|
||||
|
||||
if(false == detail::check_scale(function, scale, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if((shape <= 4) || !(boost::math::isfinite)(shape))
|
||||
{
|
||||
result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Shape parameter is %1%, but for a defined kurtosis it must be > 4", shape, Policy());
|
||||
return result;
|
||||
}
|
||||
return kurtosis_excess(dist) + 3;
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
// This include must be at the end, *after* the accessors
|
||||
// for this distribution have been defined, in order to
|
||||
// keep compilers that support two-phase lookup happy.
|
||||
#include <boost/math/distributions/detail/derived_accessors.hpp>
|
||||
|
||||
#endif // BOOST_STATS_INVERSE_GAMMA_HPP
|
||||
512
test/external/boost/math/distributions/inverse_gaussian.hpp
vendored
Normal file
512
test/external/boost/math/distributions/inverse_gaussian.hpp
vendored
Normal file
@@ -0,0 +1,512 @@
|
||||
// Copyright John Maddock 2010.
|
||||
// Copyright Paul A. Bristow 2010.
|
||||
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_STATS_INVERSE_GAUSSIAN_HPP
|
||||
#define BOOST_STATS_INVERSE_GAUSSIAN_HPP
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable: 4512) // assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
// http://en.wikipedia.org/wiki/Normal-inverse_Gaussian_distribution
|
||||
// http://mathworld.wolfram.com/InverseGaussianDistribution.html
|
||||
|
||||
// The normal-inverse Gaussian distribution
|
||||
// also called the Wald distribution (some sources limit this to when mean = 1).
|
||||
|
||||
// It is the continuous probability distribution
|
||||
// that is defined as the normal variance-mean mixture where the mixing density is the
|
||||
// inverse Gaussian distribution. The tails of the distribution decrease more slowly
|
||||
// than the normal distribution. It is therefore suitable to model phenomena
|
||||
// where numerically large values are more probable than is the case for the normal distribution.
|
||||
|
||||
// The Inverse Gaussian distribution was first studied in relationship to Brownian motion.
|
||||
// In 1956 M.C.K. Tweedie used the name 'Inverse Gaussian' because there is an inverse
|
||||
// relationship between the time to cover a unit distance and distance covered in unit time.
|
||||
|
||||
// Examples are returns from financial assets and turbulent wind speeds.
|
||||
// The normal-inverse Gaussian distributions form
|
||||
// a subclass of the generalised hyperbolic distributions.
|
||||
|
||||
// See also
|
||||
|
||||
// http://en.wikipedia.org/wiki/Normal_distribution
|
||||
// http://www.itl.nist.gov/div898/handbook/eda/section3/eda3661.htm
|
||||
// Also:
|
||||
// Weisstein, Eric W. "Normal Distribution."
|
||||
// From MathWorld--A Wolfram Web Resource.
|
||||
// http://mathworld.wolfram.com/NormalDistribution.html
|
||||
|
||||
// http://www.jstatsoft.org/v26/i04/paper General class of inverse Gaussian distributions.
|
||||
// ig package - withdrawn but at http://cran.r-project.org/src/contrib/Archive/ig/
|
||||
|
||||
// http://www.stat.ucl.ac.be/ISdidactique/Rhelp/library/SuppDists/html/inverse_gaussian.html
|
||||
// R package for dinverse_gaussian, ...
|
||||
|
||||
// http://www.statsci.org/s/inverse_gaussian.s and http://www.statsci.org/s/inverse_gaussian.html
|
||||
|
||||
//#include <boost/math/distributions/fwd.hpp>
|
||||
#include <boost/math/special_functions/erf.hpp> // for erf/erfc.
|
||||
#include <boost/math/distributions/complement.hpp>
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp>
|
||||
#include <boost/math/distributions/normal.hpp>
|
||||
#include <boost/math/distributions/gamma.hpp> // for gamma function
|
||||
// using boost::math::gamma_p;
|
||||
|
||||
#include <boost/math/tools/tuple.hpp>
|
||||
//using std::tr1::tuple;
|
||||
//using std::tr1::make_tuple;
|
||||
#include <boost/math/tools/roots.hpp>
|
||||
//using boost::math::tools::newton_raphson_iterate;
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace boost{ namespace math{
|
||||
|
||||
template <class RealType = double, class Policy = policies::policy<> >
|
||||
class inverse_gaussian_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
|
||||
inverse_gaussian_distribution(RealType mean = 1, RealType scale = 1)
|
||||
: m_mean(mean), m_scale(scale)
|
||||
{ // Default is a 1,1 inverse_gaussian distribution.
|
||||
static const char* function = "boost::math::inverse_gaussian_distribution<%1%>::inverse_gaussian_distribution";
|
||||
|
||||
RealType result;
|
||||
detail::check_scale(function, scale, &result, Policy());
|
||||
detail::check_location(function, mean, &result, Policy());
|
||||
}
|
||||
|
||||
RealType mean()const
|
||||
{ // alias for location.
|
||||
return m_mean; // aka mu
|
||||
}
|
||||
|
||||
// Synonyms, provided to allow generic use of find_location and find_scale.
|
||||
RealType location()const
|
||||
{ // location, aka mu.
|
||||
return m_mean;
|
||||
}
|
||||
RealType scale()const
|
||||
{ // scale, aka lambda.
|
||||
return m_scale;
|
||||
}
|
||||
|
||||
RealType shape()const
|
||||
{ // shape, aka phi = lambda/mu.
|
||||
return m_scale / m_mean;
|
||||
}
|
||||
|
||||
private:
|
||||
//
|
||||
// Data members:
|
||||
//
|
||||
RealType m_mean; // distribution mean or location, aka mu.
|
||||
RealType m_scale; // distribution standard deviation or scale, aka lambda.
|
||||
}; // class normal_distribution
|
||||
|
||||
typedef inverse_gaussian_distribution<double> inverse_gaussian;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const inverse_gaussian_distribution<RealType, Policy>& /*dist*/)
|
||||
{ // Range of permissible values for random variable x, zero to max.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(static_cast<RealType>(0.), max_value<RealType>()); // - to + max value.
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> support(const inverse_gaussian_distribution<RealType, Policy>& /*dist*/)
|
||||
{ // Range of supported values for random variable x, zero to max.
|
||||
// This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(static_cast<RealType>(0.), max_value<RealType>()); // - to + max value.
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType pdf(const inverse_gaussian_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{ // Probability Density Function
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
RealType scale = dist.scale();
|
||||
RealType mean = dist.mean();
|
||||
RealType result = 0;
|
||||
static const char* function = "boost::math::pdf(const inverse_gaussian_distribution<%1%>&, %1%)";
|
||||
if(false == detail::check_scale(function, scale, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(false == detail::check_location(function, mean, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(false == detail::check_positive_x(function, x, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (x == 0)
|
||||
{
|
||||
return 0; // Convenient, even if not defined mathematically.
|
||||
}
|
||||
|
||||
result =
|
||||
sqrt(scale / (constants::two_pi<RealType>() * x * x * x))
|
||||
* exp(-scale * (x - mean) * (x - mean) / (2 * x * mean * mean));
|
||||
return result;
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const inverse_gaussian_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{ // Cumulative Density Function.
|
||||
BOOST_MATH_STD_USING // for ADL of std functions.
|
||||
|
||||
RealType scale = dist.scale();
|
||||
RealType mean = dist.mean();
|
||||
static const char* function = "boost::math::cdf(const inverse_gaussian_distribution<%1%>&, %1%)";
|
||||
RealType result = 0;
|
||||
if(false == detail::check_scale(function, scale, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(false == detail::check_location(function, mean, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(false == detail::check_positive_x(function, x, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if (x == 0)
|
||||
{
|
||||
return 0; // Convenient, even if not defined mathematically.
|
||||
}
|
||||
// Problem with this formula for large scale > 1000 or small x,
|
||||
//result = 0.5 * (erf(sqrt(scale / x) * ((x / mean) - 1) / constants::root_two<RealType>(), Policy()) + 1)
|
||||
// + exp(2 * scale / mean) / 2
|
||||
// * (1 - erf(sqrt(scale / x) * (x / mean + 1) / constants::root_two<RealType>(), Policy()));
|
||||
// so use normal distribution version:
|
||||
// Wikipedia CDF equation http://en.wikipedia.org/wiki/Inverse_Gaussian_distribution.
|
||||
|
||||
normal_distribution<RealType> n01;
|
||||
|
||||
RealType n0 = sqrt(scale / x);
|
||||
n0 *= ((x / mean) -1);
|
||||
RealType n1 = cdf(n01, n0);
|
||||
RealType expfactor = exp(2 * scale / mean);
|
||||
RealType n3 = - sqrt(scale / x);
|
||||
n3 *= (x / mean) + 1;
|
||||
RealType n4 = cdf(n01, n3);
|
||||
result = n1 + expfactor * n4;
|
||||
return result;
|
||||
} // cdf
|
||||
|
||||
template <class RealType>
|
||||
struct inverse_gaussian_quantile_functor
|
||||
{
|
||||
|
||||
inverse_gaussian_quantile_functor(const boost::math::inverse_gaussian_distribution<RealType> dist, RealType const& p)
|
||||
: distribution(dist), prob(p)
|
||||
{
|
||||
}
|
||||
boost::math::tuple<RealType, RealType> operator()(RealType const& x)
|
||||
{
|
||||
RealType c = cdf(distribution, x);
|
||||
RealType fx = c - prob; // Difference cdf - value - to minimize.
|
||||
RealType dx = pdf(distribution, x); // pdf is 1st derivative.
|
||||
// return both function evaluation difference f(x) and 1st derivative f'(x).
|
||||
return boost::math::make_tuple(fx, dx);
|
||||
}
|
||||
private:
|
||||
const boost::math::inverse_gaussian_distribution<RealType> distribution;
|
||||
RealType prob;
|
||||
};
|
||||
|
||||
template <class RealType>
|
||||
struct inverse_gaussian_quantile_complement_functor
|
||||
{
|
||||
inverse_gaussian_quantile_complement_functor(const boost::math::inverse_gaussian_distribution<RealType> dist, RealType const& p)
|
||||
: distribution(dist), prob(p)
|
||||
{
|
||||
}
|
||||
boost::math::tuple<RealType, RealType> operator()(RealType const& x)
|
||||
{
|
||||
RealType c = cdf(complement(distribution, x));
|
||||
RealType fx = c - prob; // Difference cdf - value - to minimize.
|
||||
RealType dx = -pdf(distribution, x); // pdf is 1st derivative.
|
||||
// return both function evaluation difference f(x) and 1st derivative f'(x).
|
||||
//return std::tr1::make_tuple(fx, dx); if available.
|
||||
return boost::math::make_tuple(fx, dx);
|
||||
}
|
||||
private:
|
||||
const boost::math::inverse_gaussian_distribution<RealType> distribution;
|
||||
RealType prob;
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class RealType>
|
||||
inline RealType guess_ig(RealType p, RealType mu = 1, RealType lambda = 1)
|
||||
{ // guess at random variate value x for inverse gaussian quantile.
|
||||
BOOST_MATH_STD_USING
|
||||
using boost::math::policies::policy;
|
||||
// Error type.
|
||||
using boost::math::policies::overflow_error;
|
||||
// Action.
|
||||
using boost::math::policies::ignore_error;
|
||||
|
||||
typedef policy<
|
||||
overflow_error<ignore_error> // Ignore overflow (return infinity)
|
||||
> no_overthrow_policy;
|
||||
|
||||
RealType x; // result is guess at random variate value x.
|
||||
RealType phi = lambda / mu;
|
||||
if (phi > 2.)
|
||||
{ // Big phi, so starting to look like normal Gaussian distribution.
|
||||
// x=(qnorm(p,0,1,true,false) - 0.5 * sqrt(mu/lambda)) / sqrt(lambda/mu);
|
||||
// Whitmore, G.A. and Yalovsky, M.
|
||||
// A normalising logarithmic transformation for inverse Gaussian random variables,
|
||||
// Technometrics 20-2, 207-208 (1978), but using expression from
|
||||
// V Seshadri, Inverse Gaussian distribution (1998) ISBN 0387 98618 9, page 6.
|
||||
|
||||
normal_distribution<RealType, no_overthrow_policy> n01;
|
||||
x = mu * exp(quantile(n01, p) / sqrt(phi) - 1/(2 * phi));
|
||||
}
|
||||
else
|
||||
{ // phi < 2 so much less symmetrical with long tail,
|
||||
// so use gamma distribution as an approximation.
|
||||
using boost::math::gamma_distribution;
|
||||
|
||||
// Define the distribution, using gamma_nooverflow:
|
||||
typedef gamma_distribution<RealType, no_overthrow_policy> gamma_nooverflow;
|
||||
|
||||
gamma_distribution<RealType, no_overthrow_policy> g(static_cast<RealType>(0.5), static_cast<RealType>(1.));
|
||||
|
||||
// gamma_nooverflow g(static_cast<RealType>(0.5), static_cast<RealType>(1.));
|
||||
// R qgamma(0.2, 0.5, 1) 0.0320923
|
||||
RealType qg = quantile(complement(g, p));
|
||||
//RealType qg1 = qgamma(1.- p, 0.5, 1.0, true, false);
|
||||
x = lambda / (qg * 2);
|
||||
//
|
||||
if (x > mu/2) // x > mu /2?
|
||||
{ // x too large for the gamma approximation to work well.
|
||||
//x = qgamma(p, 0.5, 1.0); // qgamma(0.270614, 0.5, 1) = 0.05983807
|
||||
RealType q = quantile(g, p);
|
||||
// x = mu * exp(q * static_cast<RealType>(0.1)); // Said to improve at high p
|
||||
// x = mu * x; // Improves at high p?
|
||||
x = mu * exp(q / sqrt(phi) - 1/(2 * phi));
|
||||
}
|
||||
}
|
||||
return x;
|
||||
} // guess_ig
|
||||
} // namespace detail
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const inverse_gaussian_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions.
|
||||
// No closed form exists so guess and use Newton Raphson iteration.
|
||||
|
||||
RealType mean = dist.mean();
|
||||
RealType scale = dist.scale();
|
||||
static const char* function = "boost::math::quantile(const inverse_gaussian_distribution<%1%>&, %1%)";
|
||||
|
||||
RealType result = 0;
|
||||
if(false == detail::check_scale(function, scale, &result, Policy()))
|
||||
return result;
|
||||
if(false == detail::check_location(function, mean, &result, Policy()))
|
||||
return result;
|
||||
if(false == detail::check_probability(function, p, &result, Policy()))
|
||||
return result;
|
||||
if (p == 0)
|
||||
{
|
||||
return 0; // Convenient, even if not defined mathematically?
|
||||
}
|
||||
if (p == 1)
|
||||
{ // overflow
|
||||
result = policies::raise_overflow_error<RealType>(function,
|
||||
"probability parameter is 1, but must be < 1!", Policy());
|
||||
return result; // std::numeric_limits<RealType>::infinity();
|
||||
}
|
||||
|
||||
RealType guess = detail::guess_ig(p, dist.mean(), dist.scale());
|
||||
using boost::math::tools::max_value;
|
||||
|
||||
RealType min = 0.; // Minimum possible value is bottom of range of distribution.
|
||||
RealType max = max_value<RealType>();// Maximum possible value is top of range.
|
||||
// int digits = std::numeric_limits<RealType>::digits; // Maximum possible binary digits accuracy for type T.
|
||||
// digits used to control how accurate to try to make the result.
|
||||
// To allow user to control accuracy versus speed,
|
||||
int get_digits = policies::digits<RealType, Policy>();// get digits from policy,
|
||||
boost::uintmax_t m = policies::get_max_root_iterations<Policy>(); // and max iterations.
|
||||
using boost::math::tools::newton_raphson_iterate;
|
||||
result =
|
||||
newton_raphson_iterate(inverse_gaussian_quantile_functor<RealType>(dist, p), guess, min, max, get_digits, m);
|
||||
return result;
|
||||
} // quantile
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const complemented2_type<inverse_gaussian_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions.
|
||||
|
||||
RealType scale = c.dist.scale();
|
||||
RealType mean = c.dist.mean();
|
||||
RealType x = c.param;
|
||||
static const char* function = "boost::math::cdf(const complement(inverse_gaussian_distribution<%1%>&), %1%)";
|
||||
// infinite arguments not supported.
|
||||
//if((boost::math::isinf)(x))
|
||||
//{
|
||||
// if(x < 0) return 1; // cdf complement -infinity is unity.
|
||||
// return 0; // cdf complement +infinity is zero
|
||||
//}
|
||||
// These produce MSVC 4127 warnings, so the above used instead.
|
||||
//if(std::numeric_limits<RealType>::has_infinity && x == std::numeric_limits<RealType>::infinity())
|
||||
//{ // cdf complement +infinity is zero.
|
||||
// return 0;
|
||||
//}
|
||||
//if(std::numeric_limits<RealType>::has_infinity && x == -std::numeric_limits<RealType>::infinity())
|
||||
//{ // cdf complement -infinity is unity.
|
||||
// return 1;
|
||||
//}
|
||||
RealType result = 0;
|
||||
if(false == detail::check_scale(function, scale, &result, Policy()))
|
||||
return result;
|
||||
if(false == detail::check_location(function, mean, &result, Policy()))
|
||||
return result;
|
||||
if(false == detail::check_x(function, x, &result, Policy()))
|
||||
return result;
|
||||
|
||||
normal_distribution<RealType> n01;
|
||||
RealType n0 = sqrt(scale / x);
|
||||
n0 *= ((x / mean) -1);
|
||||
RealType cdf_1 = cdf(complement(n01, n0));
|
||||
|
||||
RealType expfactor = exp(2 * scale / mean);
|
||||
RealType n3 = - sqrt(scale / x);
|
||||
n3 *= (x / mean) + 1;
|
||||
|
||||
//RealType n5 = +sqrt(scale/x) * ((x /mean) + 1); // note now positive sign.
|
||||
RealType n6 = cdf(complement(n01, +sqrt(scale/x) * ((x /mean) + 1)));
|
||||
// RealType n4 = cdf(n01, n3); // =
|
||||
result = cdf_1 - expfactor * n6;
|
||||
return result;
|
||||
} // cdf complement
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const complemented2_type<inverse_gaussian_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
RealType scale = c.dist.scale();
|
||||
RealType mean = c.dist.mean();
|
||||
static const char* function = "boost::math::quantile(const complement(inverse_gaussian_distribution<%1%>&), %1%)";
|
||||
RealType result = 0;
|
||||
if(false == detail::check_scale(function, scale, &result, Policy()))
|
||||
return result;
|
||||
if(false == detail::check_location(function, mean, &result, Policy()))
|
||||
return result;
|
||||
RealType q = c.param;
|
||||
if(false == detail::check_probability(function, q, &result, Policy()))
|
||||
return result;
|
||||
|
||||
RealType guess = detail::guess_ig(q, mean, scale);
|
||||
// Complement.
|
||||
using boost::math::tools::max_value;
|
||||
|
||||
RealType min = 0.; // Minimum possible value is bottom of range of distribution.
|
||||
RealType max = max_value<RealType>();// Maximum possible value is top of range.
|
||||
// int digits = std::numeric_limits<RealType>::digits; // Maximum possible binary digits accuracy for type T.
|
||||
// digits used to control how accurate to try to make the result.
|
||||
int get_digits = policies::digits<RealType, Policy>();
|
||||
boost::uintmax_t m = policies::get_max_root_iterations<Policy>();
|
||||
using boost::math::tools::newton_raphson_iterate;
|
||||
result =
|
||||
newton_raphson_iterate(inverse_gaussian_quantile_complement_functor<RealType>(c.dist, q), guess, min, max, get_digits, m);
|
||||
return result;
|
||||
} // quantile
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mean(const inverse_gaussian_distribution<RealType, Policy>& dist)
|
||||
{ // aka mu
|
||||
return dist.mean();
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType scale(const inverse_gaussian_distribution<RealType, Policy>& dist)
|
||||
{ // aka lambda
|
||||
return dist.scale();
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType shape(const inverse_gaussian_distribution<RealType, Policy>& dist)
|
||||
{ // aka phi
|
||||
return dist.shape();
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType standard_deviation(const inverse_gaussian_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
RealType scale = dist.scale();
|
||||
RealType mean = dist.mean();
|
||||
RealType result = sqrt(mean * mean * mean / scale);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mode(const inverse_gaussian_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
RealType scale = dist.scale();
|
||||
RealType mean = dist.mean();
|
||||
RealType result = mean * (sqrt(1 + (9 * mean * mean)/(4 * scale * scale))
|
||||
- 3 * mean / (2 * scale));
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType skewness(const inverse_gaussian_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
RealType scale = dist.scale();
|
||||
RealType mean = dist.mean();
|
||||
RealType result = 3 * sqrt(mean/scale);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis(const inverse_gaussian_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType scale = dist.scale();
|
||||
RealType mean = dist.mean();
|
||||
RealType result = 15 * mean / scale -3;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis_excess(const inverse_gaussian_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType scale = dist.scale();
|
||||
RealType mean = dist.mean();
|
||||
RealType result = 15 * mean / scale;
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
// This include must be at the end, *after* the accessors
|
||||
// for this distribution have been defined, in order to
|
||||
// keep compilers that support two-phase lookup happy.
|
||||
#include <boost/math/distributions/detail/derived_accessors.hpp>
|
||||
|
||||
#endif // BOOST_STATS_INVERSE_GAUSSIAN_HPP
|
||||
|
||||
|
||||
306
test/external/boost/math/distributions/laplace.hpp
vendored
Normal file
306
test/external/boost/math/distributions/laplace.hpp
vendored
Normal file
@@ -0,0 +1,306 @@
|
||||
// Copyright Thijs van den Berg, 2008.
|
||||
// Copyright John Maddock 2008.
|
||||
// Copyright Paul A. Bristow 2008.
|
||||
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
// This module implements the Laplace distribution.
|
||||
// Weisstein, Eric W. "Laplace Distribution." From MathWorld--A Wolfram Web Resource.
|
||||
// http://mathworld.wolfram.com/LaplaceDistribution.html
|
||||
// http://en.wikipedia.org/wiki/Laplace_distribution
|
||||
//
|
||||
// Abramowitz and Stegun 1972, p 930
|
||||
// http://www.math.sfu.ca/~cbm/aands/page_930.htm
|
||||
|
||||
#ifndef BOOST_STATS_LAPLACE_HPP
|
||||
#define BOOST_STATS_LAPLACE_HPP
|
||||
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp>
|
||||
#include <boost/math/distributions/complement.hpp>
|
||||
#include <boost/math/constants/constants.hpp>
|
||||
#include <limits>
|
||||
|
||||
namespace boost{ namespace math{
|
||||
|
||||
template <class RealType = double, class Policy = policies::policy<> >
|
||||
class laplace_distribution
|
||||
{
|
||||
public:
|
||||
// ----------------------------------
|
||||
// public Types
|
||||
// ----------------------------------
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
|
||||
// ----------------------------------
|
||||
// Constructor(s)
|
||||
// ----------------------------------
|
||||
laplace_distribution(RealType location = 0, RealType scale = 1)
|
||||
: m_location(location), m_scale(scale)
|
||||
{
|
||||
RealType result;
|
||||
check_parameters("boost::math::laplace_distribution<%1%>::laplace_distribution()", &result);
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------
|
||||
// Public functions
|
||||
// ----------------------------------
|
||||
|
||||
RealType location() const
|
||||
{
|
||||
return m_location;
|
||||
}
|
||||
|
||||
RealType scale() const
|
||||
{
|
||||
return m_scale;
|
||||
}
|
||||
|
||||
bool check_parameters(const char* function, RealType* result) const
|
||||
{
|
||||
if(false == detail::check_scale(function, m_scale, result, Policy())) return false;
|
||||
if(false == detail::check_location(function, m_location, result, Policy())) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
RealType m_location;
|
||||
RealType m_scale;
|
||||
}; // class laplace_distribution
|
||||
|
||||
//
|
||||
// Convenient type synonym for double
|
||||
typedef laplace_distribution<double> laplace;
|
||||
|
||||
//
|
||||
// Non member functions
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const laplace_distribution<RealType, Policy>&)
|
||||
{
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(-max_value<RealType>(), max_value<RealType>());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> support(const laplace_distribution<RealType, Policy>&)
|
||||
{
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(-max_value<RealType>(), max_value<RealType>());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType pdf(const laplace_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
// Checking function argument
|
||||
RealType result = 0;
|
||||
const char* function = "boost::math::pdf(const laplace_distribution<%1%>&, %1%))";
|
||||
if (false == dist.check_parameters(function, &result)) return result;
|
||||
if (false == detail::check_x(function, x, &result, Policy())) return result;
|
||||
|
||||
// Special pdf values
|
||||
if((boost::math::isinf)(x))
|
||||
return 0; // pdf + and - infinity is zero.
|
||||
|
||||
// General case
|
||||
RealType scale( dist.scale() );
|
||||
RealType location( dist.location() );
|
||||
|
||||
RealType exponent = x - location;
|
||||
if (exponent>0) exponent = -exponent;
|
||||
exponent /= scale;
|
||||
|
||||
result = exp(exponent);
|
||||
result /= 2 * scale;
|
||||
|
||||
return result;
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const laplace_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
// Checking function argument
|
||||
RealType result = 0;
|
||||
const char* function = "boost::math::cdf(const laplace_distribution<%1%>&, %1%)";
|
||||
if (false == dist.check_parameters(function, &result)) return result;
|
||||
if (false == detail::check_x(function, x, &result, Policy())) return result;
|
||||
|
||||
// Special cdf values:
|
||||
if((boost::math::isinf)(x))
|
||||
{
|
||||
if(x < 0) return 0; // -infinity
|
||||
return 1; // + infinity
|
||||
}
|
||||
|
||||
// General cdf values
|
||||
RealType scale( dist.scale() );
|
||||
RealType location( dist.location() );
|
||||
|
||||
if (x < location)
|
||||
result = exp( (x-location)/scale )/2;
|
||||
else
|
||||
result = 1 - exp( (location-x)/scale )/2;
|
||||
|
||||
return result;
|
||||
} // cdf
|
||||
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const laplace_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions.
|
||||
|
||||
// Checking function argument
|
||||
RealType result = 0;
|
||||
const char* function = "boost::math::quantile(const laplace_distribution<%1%>&, %1%)";
|
||||
if (false == dist.check_parameters(function, &result)) return result;
|
||||
if(false == detail::check_probability(function, p, &result, Policy())) return result;
|
||||
|
||||
// Extreme values of p:
|
||||
if(p == 0)
|
||||
{
|
||||
result = policies::raise_overflow_error<RealType>(function,
|
||||
"probability parameter is 0, but must be > 0!", Policy());
|
||||
return -result; // -std::numeric_limits<RealType>::infinity();
|
||||
}
|
||||
|
||||
if(p == 1)
|
||||
{
|
||||
result = policies::raise_overflow_error<RealType>(function,
|
||||
"probability parameter is 1, but must be < 1!", Policy());
|
||||
return result; // std::numeric_limits<RealType>::infinity();
|
||||
}
|
||||
// Calculate Quantile
|
||||
RealType scale( dist.scale() );
|
||||
RealType location( dist.location() );
|
||||
|
||||
if (p - 0.5 < 0.0)
|
||||
result = location + scale*log( static_cast<RealType>(p*2) );
|
||||
else
|
||||
result = location - scale*log( static_cast<RealType>(-p*2 + 2) );
|
||||
|
||||
return result;
|
||||
} // quantile
|
||||
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const complemented2_type<laplace_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
RealType scale = c.dist.scale();
|
||||
RealType location = c.dist.location();
|
||||
RealType x = c.param;
|
||||
|
||||
// Checking function argument
|
||||
RealType result = 0;
|
||||
const char* function = "boost::math::cdf(const complemented2_type<laplace_distribution<%1%>, %1%>&)";
|
||||
if(false == detail::check_x(function, x, &result, Policy()))return result;
|
||||
|
||||
// Calculate cdf
|
||||
|
||||
// Special cdf value
|
||||
if((boost::math::isinf)(x))
|
||||
{
|
||||
if(x < 0) return 1; // cdf complement -infinity is unity.
|
||||
return 0; // cdf complement +infinity is zero
|
||||
}
|
||||
|
||||
// Cdf interval value
|
||||
if (-x < location)
|
||||
result = exp( (-x-location)/scale )/2;
|
||||
else
|
||||
result = 1 - exp( (location+x)/scale )/2;
|
||||
|
||||
return result;
|
||||
} // cdf complement
|
||||
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const complemented2_type<laplace_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
// Calculate quantile
|
||||
RealType scale = c.dist.scale();
|
||||
RealType location = c.dist.location();
|
||||
RealType q = c.param;
|
||||
|
||||
// Checking function argument
|
||||
RealType result = 0;
|
||||
const char* function = "quantile(const complemented2_type<laplace_distribution<%1%>, %1%>&)";
|
||||
if(false == detail::check_probability(function, q, &result, Policy())) return result;
|
||||
|
||||
|
||||
// extreme values
|
||||
if(q == 0) return std::numeric_limits<RealType>::infinity();
|
||||
if(q == 1) return -std::numeric_limits<RealType>::infinity();
|
||||
|
||||
if (0.5 - q < 0.0)
|
||||
result = location + scale*log( static_cast<RealType>(-q*2 + 2) );
|
||||
else
|
||||
result = location - scale*log( static_cast<RealType>(q*2) );
|
||||
|
||||
|
||||
return result;
|
||||
} // quantile
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mean(const laplace_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
return dist.location();
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType standard_deviation(const laplace_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
return constants::root_two<RealType>() * dist.scale();
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mode(const laplace_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
return dist.location();
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType median(const laplace_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
return dist.location();
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType skewness(const laplace_distribution<RealType, Policy>& /*dist*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis(const laplace_distribution<RealType, Policy>& /*dist*/)
|
||||
{
|
||||
return 6;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis_excess(const laplace_distribution<RealType, Policy>& /*dist*/)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
// This include must be at the end, *after* the accessors
|
||||
// for this distribution have been defined, in order to
|
||||
// keep compilers that support two-phase lookup happy.
|
||||
#include <boost/math/distributions/detail/derived_accessors.hpp>
|
||||
|
||||
#endif // BOOST_STATS_LAPLACE_HPP
|
||||
|
||||
|
||||
287
test/external/boost/math/distributions/logistic.hpp
vendored
Normal file
287
test/external/boost/math/distributions/logistic.hpp
vendored
Normal file
@@ -0,0 +1,287 @@
|
||||
// Copyright 2008 Gautam Sewani
|
||||
//
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp>
|
||||
#include <boost/math/distributions/complement.hpp>
|
||||
#include <boost/math/special_functions/log1p.hpp>
|
||||
#include <boost/math/constants/constants.hpp>
|
||||
#include <utility>
|
||||
|
||||
namespace boost { namespace math {
|
||||
|
||||
template <class RealType = double, class Policy = policies::policy<> >
|
||||
class logistic_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
|
||||
logistic_distribution(RealType location=0, RealType scale=1) // Constructor.
|
||||
: m_location(location), m_scale(scale)
|
||||
{
|
||||
static const char* function = "boost::math::logistic_distribution<%1%>::logistic_distribution";
|
||||
|
||||
RealType result;
|
||||
detail::check_scale(function, scale, &result, Policy());
|
||||
detail::check_location(function, location, &result, Policy());
|
||||
}
|
||||
// Accessor functions.
|
||||
RealType scale()const
|
||||
{
|
||||
return m_scale;
|
||||
}
|
||||
|
||||
RealType location()const
|
||||
{
|
||||
return m_location;
|
||||
}
|
||||
private:
|
||||
// Data members:
|
||||
RealType m_location; // distribution location aka mu.
|
||||
RealType m_scale; // distribution scale aka s.
|
||||
}; // class logistic_distribution
|
||||
|
||||
|
||||
typedef logistic_distribution<double> logistic;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const logistic_distribution<RealType, Policy>& /* dist */)
|
||||
{ // Range of permissible values for random variable x.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(-max_value<RealType>(), max_value<RealType>()); // - to + infinity
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> support(const logistic_distribution<RealType, Policy>& /* dist */)
|
||||
{ // Range of supported values for random variable x.
|
||||
// This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(-max_value<RealType>(), max_value<RealType>()); // - to + infinity
|
||||
}
|
||||
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType pdf(const logistic_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
RealType scale = dist.scale();
|
||||
RealType location = dist.location();
|
||||
|
||||
static const char* function = "boost::math::pdf(const logistic_distribution<%1%>&, %1%)";
|
||||
if((boost::math::isinf)(x))
|
||||
{
|
||||
return 0; // pdf + and - infinity is zero.
|
||||
}
|
||||
|
||||
RealType result = 0;
|
||||
if(false == detail::check_scale(function, scale , &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(false == detail::check_location(function, location, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(false == detail::check_x(function, x, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOST_MATH_STD_USING
|
||||
RealType exp_term = (location - x) / scale;
|
||||
if(fabs(exp_term) > tools::log_max_value<RealType>())
|
||||
return 0;
|
||||
exp_term = exp(exp_term);
|
||||
if((exp_term * scale > 1) && (exp_term > tools::max_value<RealType>() / (scale * exp_term)))
|
||||
return 1 / (scale * exp_term);
|
||||
return (exp_term) / (scale * (1 + exp_term) * (1 + exp_term));
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const logistic_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
RealType scale = dist.scale();
|
||||
RealType location = dist.location();
|
||||
RealType result = 0; // of checks.
|
||||
static const char* function = "boost::math::cdf(const logistic_distribution<%1%>&, %1%)";
|
||||
if(false == detail::check_scale(function, scale, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(false == detail::check_location(function, location, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if((boost::math::isinf)(x))
|
||||
{
|
||||
if(x < 0) return 0; // -infinity
|
||||
return 1; // + infinity
|
||||
}
|
||||
|
||||
if(false == detail::check_x(function, x, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
BOOST_MATH_STD_USING
|
||||
RealType power = (location - x) / scale;
|
||||
if(power > tools::log_max_value<RealType>())
|
||||
return 0;
|
||||
if(power < -tools::log_max_value<RealType>())
|
||||
return 1;
|
||||
return 1 / (1 + exp(power));
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const logistic_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
RealType location = dist.location();
|
||||
RealType scale = dist.scale();
|
||||
|
||||
static const char* function = "boost::math::quantile(const logistic_distribution<%1%>&, %1%)";
|
||||
|
||||
RealType result = 0;
|
||||
if(false == detail::check_scale(function, scale, &result, Policy()))
|
||||
return result;
|
||||
if(false == detail::check_location(function, location, &result, Policy()))
|
||||
return result;
|
||||
if(false == detail::check_probability(function, p, &result, Policy()))
|
||||
return result;
|
||||
|
||||
if(p == 0)
|
||||
{
|
||||
return -policies::raise_overflow_error<RealType>(function,"probability argument is 0, must be >0 and <1",Policy());
|
||||
}
|
||||
if(p == 1)
|
||||
{
|
||||
return policies::raise_overflow_error<RealType>(function,"probability argument is 1, must be >0 and <1",Policy());
|
||||
}
|
||||
//Expressions to try
|
||||
//return location+scale*log(p/(1-p));
|
||||
//return location+scale*log1p((2*p-1)/(1-p));
|
||||
|
||||
//return location - scale*log( (1-p)/p);
|
||||
//return location - scale*log1p((1-2*p)/p);
|
||||
|
||||
//return -scale*log(1/p-1) + location;
|
||||
return location - scale * log((1 - p) / p);
|
||||
} // RealType quantile(const logistic_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const complemented2_type<logistic_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
RealType location = c.dist.location();
|
||||
RealType scale = c.dist.scale();
|
||||
RealType x = c.param;
|
||||
static const char* function = "boost::math::cdf(const complement(logistic_distribution<%1%>&), %1%)";
|
||||
|
||||
if((boost::math::isinf)(x))
|
||||
{
|
||||
if(x < 0) return 1; // cdf complement -infinity is unity.
|
||||
return 0; // cdf complement +infinity is zero
|
||||
}
|
||||
RealType result = 0;
|
||||
if(false == detail::check_scale(function, scale, &result, Policy()))
|
||||
return result;
|
||||
if(false == detail::check_location(function, location, &result, Policy()))
|
||||
return result;
|
||||
if(false == detail::check_x(function, x, &result, Policy()))
|
||||
return result;
|
||||
RealType power = (x - location) / scale;
|
||||
if(power > tools::log_max_value<RealType>())
|
||||
return 0;
|
||||
if(power < -tools::log_max_value<RealType>())
|
||||
return 1;
|
||||
return 1 / (1 + exp(power));
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const complemented2_type<logistic_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
RealType scale = c.dist.scale();
|
||||
RealType location = c.dist.location();
|
||||
static const char* function = "boost::math::quantile(const complement(logistic_distribution<%1%>&), %1%)";
|
||||
RealType result = 0;
|
||||
if(false == detail::check_scale(function, scale, &result, Policy()))
|
||||
return result;
|
||||
if(false == detail::check_location(function, location, &result, Policy()))
|
||||
return result;
|
||||
RealType q = c.param;
|
||||
if(false == detail::check_probability(function, q, &result, Policy()))
|
||||
return result;
|
||||
using boost::math::tools::max_value;
|
||||
|
||||
if(q == 1)
|
||||
{
|
||||
return -policies::raise_overflow_error<RealType>(function,"probability argument is 1, but must be >0 and <1",Policy());
|
||||
}
|
||||
if(q == 0)
|
||||
{
|
||||
return policies::raise_overflow_error<RealType>(function,"probability argument is 0, but must be >0 and <1",Policy());
|
||||
}
|
||||
//Expressions to try
|
||||
//return location+scale*log((1-q)/q);
|
||||
return location + scale * log((1 - q) / q);
|
||||
|
||||
//return location-scale*log(q/(1-q));
|
||||
//return location-scale*log1p((2*q-1)/(1-q));
|
||||
|
||||
//return location+scale*log(1/q-1);
|
||||
//return location+scale*log1p(1/q-2);
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mean(const logistic_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
return dist.location();
|
||||
} // RealType mean(const logistic_distribution<RealType, Policy>& dist)
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType variance(const logistic_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
RealType scale = dist.scale();
|
||||
return boost::math::constants::pi<RealType>()*boost::math::constants::pi<RealType>()*scale*scale/3;
|
||||
} // RealType variance(const logistic_distribution<RealType, Policy>& dist)
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mode(const logistic_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
return dist.location();
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType median(const logistic_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
return dist.location();
|
||||
}
|
||||
template <class RealType, class Policy>
|
||||
inline RealType skewness(const logistic_distribution<RealType, Policy>& /*dist*/)
|
||||
{
|
||||
return 0;
|
||||
} // RealType skewness(const logistic_distribution<RealType, Policy>& dist)
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis_excess(const logistic_distribution<RealType, Policy>& /*dist*/)
|
||||
{
|
||||
return static_cast<RealType>(6)/5;
|
||||
} // RealType kurtosis_excess(const logistic_distribution<RealType, Policy>& dist)
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis(const logistic_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
return kurtosis_excess(dist) + 3;
|
||||
} // RealType kurtosis_excess(const logistic_distribution<RealType, Policy>& dist)
|
||||
}}
|
||||
|
||||
|
||||
// Must come at the end:
|
||||
#include <boost/math/distributions/detail/derived_accessors.hpp>
|
||||
|
||||
310
test/external/boost/math/distributions/lognormal.hpp
vendored
Normal file
310
test/external/boost/math/distributions/lognormal.hpp
vendored
Normal file
@@ -0,0 +1,310 @@
|
||||
// Copyright John Maddock 2006.
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_STATS_LOGNORMAL_HPP
|
||||
#define BOOST_STATS_LOGNORMAL_HPP
|
||||
|
||||
// http://www.itl.nist.gov/div898/handbook/eda/section3/eda3669.htm
|
||||
// http://mathworld.wolfram.com/LogNormalDistribution.html
|
||||
// http://en.wikipedia.org/wiki/Lognormal_distribution
|
||||
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#include <boost/math/distributions/normal.hpp>
|
||||
#include <boost/math/special_functions/expm1.hpp>
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace boost{ namespace math
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_lognormal_x(
|
||||
const char* function,
|
||||
RealType const& x,
|
||||
RealType* result, const Policy& pol)
|
||||
{
|
||||
if((x < 0) || !(boost::math::isfinite)(x))
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Random variate is %1% but must be >= 0 !", x, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
template <class RealType = double, class Policy = policies::policy<> >
|
||||
class lognormal_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
|
||||
lognormal_distribution(RealType location = 0, RealType scale = 1)
|
||||
: m_location(location), m_scale(scale)
|
||||
{
|
||||
RealType result;
|
||||
detail::check_scale("boost::math::lognormal_distribution<%1%>::lognormal_distribution", scale, &result, Policy());
|
||||
}
|
||||
|
||||
RealType location()const
|
||||
{
|
||||
return m_location;
|
||||
}
|
||||
|
||||
RealType scale()const
|
||||
{
|
||||
return m_scale;
|
||||
}
|
||||
private:
|
||||
//
|
||||
// Data members:
|
||||
//
|
||||
RealType m_location; // distribution location.
|
||||
RealType m_scale; // distribution scale.
|
||||
};
|
||||
|
||||
typedef lognormal_distribution<double> lognormal;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const lognormal_distribution<RealType, Policy>& /*dist*/)
|
||||
{ // Range of permissible values for random variable x is >0 to +infinity.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> support(const lognormal_distribution<RealType, Policy>& /*dist*/)
|
||||
{ // Range of supported values for random variable x.
|
||||
// This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
RealType pdf(const lognormal_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
RealType mu = dist.location();
|
||||
RealType sigma = dist.scale();
|
||||
|
||||
static const char* function = "boost::math::pdf(const lognormal_distribution<%1%>&, %1%)";
|
||||
|
||||
RealType result = 0;
|
||||
if(0 == detail::check_scale(function, sigma, &result, Policy()))
|
||||
return result;
|
||||
if(0 == detail::check_lognormal_x(function, x, &result, Policy()))
|
||||
return result;
|
||||
|
||||
if(x == 0)
|
||||
return 0;
|
||||
|
||||
RealType exponent = log(x) - mu;
|
||||
exponent *= -exponent;
|
||||
exponent /= 2 * sigma * sigma;
|
||||
|
||||
result = exp(exponent);
|
||||
result /= sigma * sqrt(2 * constants::pi<RealType>()) * x;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const lognormal_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::cdf(const lognormal_distribution<%1%>&, %1%)";
|
||||
|
||||
RealType result = 0;
|
||||
if(0 == detail::check_lognormal_x(function, x, &result, Policy()))
|
||||
return result;
|
||||
|
||||
if(x == 0)
|
||||
return 0;
|
||||
|
||||
normal_distribution<RealType, Policy> norm(dist.location(), dist.scale());
|
||||
return cdf(norm, log(x));
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const lognormal_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::quantile(const lognormal_distribution<%1%>&, %1%)";
|
||||
|
||||
RealType result = 0;
|
||||
if(0 == detail::check_probability(function, p, &result, Policy()))
|
||||
return result;
|
||||
|
||||
if(p == 0)
|
||||
return 0;
|
||||
if(p == 1)
|
||||
return policies::raise_overflow_error<RealType>(function, 0, Policy());
|
||||
|
||||
normal_distribution<RealType, Policy> norm(dist.location(), dist.scale());
|
||||
return exp(quantile(norm, p));
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const complemented2_type<lognormal_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::cdf(const lognormal_distribution<%1%>&, %1%)";
|
||||
|
||||
RealType result = 0;
|
||||
if(0 == detail::check_lognormal_x(function, c.param, &result, Policy()))
|
||||
return result;
|
||||
|
||||
if(c.param == 0)
|
||||
return 1;
|
||||
|
||||
normal_distribution<RealType, Policy> norm(c.dist.location(), c.dist.scale());
|
||||
return cdf(complement(norm, log(c.param)));
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const complemented2_type<lognormal_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::quantile(const lognormal_distribution<%1%>&, %1%)";
|
||||
|
||||
RealType result = 0;
|
||||
if(0 == detail::check_probability(function, c.param, &result, Policy()))
|
||||
return result;
|
||||
|
||||
if(c.param == 1)
|
||||
return 0;
|
||||
if(c.param == 0)
|
||||
return policies::raise_overflow_error<RealType>(function, 0, Policy());
|
||||
|
||||
normal_distribution<RealType, Policy> norm(c.dist.location(), c.dist.scale());
|
||||
return exp(quantile(complement(norm, c.param)));
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mean(const lognormal_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
RealType mu = dist.location();
|
||||
RealType sigma = dist.scale();
|
||||
|
||||
RealType result = 0;
|
||||
if(0 == detail::check_scale("boost::math::mean(const lognormal_distribution<%1%>&)", sigma, &result, Policy()))
|
||||
return result;
|
||||
|
||||
return exp(mu + sigma * sigma / 2);
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType variance(const lognormal_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
RealType mu = dist.location();
|
||||
RealType sigma = dist.scale();
|
||||
|
||||
RealType result = 0;
|
||||
if(0 == detail::check_scale("boost::math::variance(const lognormal_distribution<%1%>&)", sigma, &result, Policy()))
|
||||
return result;
|
||||
|
||||
return boost::math::expm1(sigma * sigma, Policy()) * exp(2 * mu + sigma * sigma);
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mode(const lognormal_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
RealType mu = dist.location();
|
||||
RealType sigma = dist.scale();
|
||||
|
||||
RealType result = 0;
|
||||
if(0 == detail::check_scale("boost::math::mode(const lognormal_distribution<%1%>&)", sigma, &result, Policy()))
|
||||
return result;
|
||||
|
||||
return exp(mu - sigma * sigma);
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType median(const lognormal_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
RealType mu = dist.location();
|
||||
return exp(mu); // e^mu
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType skewness(const lognormal_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
//RealType mu = dist.location();
|
||||
RealType sigma = dist.scale();
|
||||
|
||||
RealType ss = sigma * sigma;
|
||||
RealType ess = exp(ss);
|
||||
|
||||
RealType result = 0;
|
||||
if(0 == detail::check_scale("boost::math::skewness(const lognormal_distribution<%1%>&)", sigma, &result, Policy()))
|
||||
return result;
|
||||
|
||||
return (ess + 2) * sqrt(boost::math::expm1(ss, Policy()));
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis(const lognormal_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
//RealType mu = dist.location();
|
||||
RealType sigma = dist.scale();
|
||||
RealType ss = sigma * sigma;
|
||||
|
||||
RealType result = 0;
|
||||
if(0 == detail::check_scale("boost::math::kurtosis(const lognormal_distribution<%1%>&)", sigma, &result, Policy()))
|
||||
return result;
|
||||
|
||||
return exp(4 * ss) + 2 * exp(3 * ss) + 3 * exp(2 * ss) - 3;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis_excess(const lognormal_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
// RealType mu = dist.location();
|
||||
RealType sigma = dist.scale();
|
||||
RealType ss = sigma * sigma;
|
||||
|
||||
RealType result = 0;
|
||||
if(0 == detail::check_scale("boost::math::kurtosis_excess(const lognormal_distribution<%1%>&)", sigma, &result, Policy()))
|
||||
return result;
|
||||
|
||||
return exp(4 * ss) + 2 * exp(3 * ss) + 3 * exp(2 * ss) - 6;
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
// This include must be at the end, *after* the accessors
|
||||
// for this distribution have been defined, in order to
|
||||
// keep compilers that support two-phase lookup happy.
|
||||
#include <boost/math/distributions/detail/derived_accessors.hpp>
|
||||
|
||||
#endif // BOOST_STATS_STUDENTS_T_HPP
|
||||
|
||||
|
||||
588
test/external/boost/math/distributions/negative_binomial.hpp
vendored
Normal file
588
test/external/boost/math/distributions/negative_binomial.hpp
vendored
Normal file
@@ -0,0 +1,588 @@
|
||||
// boost\math\special_functions\negative_binomial.hpp
|
||||
|
||||
// Copyright Paul A. Bristow 2007.
|
||||
// Copyright John Maddock 2007.
|
||||
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
// http://en.wikipedia.org/wiki/negative_binomial_distribution
|
||||
// http://mathworld.wolfram.com/NegativeBinomialDistribution.html
|
||||
// http://documents.wolfram.com/teachersedition/Teacher/Statistics/DiscreteDistributions.html
|
||||
|
||||
// The negative binomial distribution NegativeBinomialDistribution[n, p]
|
||||
// is the distribution of the number (k) of failures that occur in a sequence of trials before
|
||||
// r successes have occurred, where the probability of success in each trial is p.
|
||||
|
||||
// In a sequence of Bernoulli trials or events
|
||||
// (independent, yes or no, succeed or fail) with success_fraction probability p,
|
||||
// negative_binomial is the probability that k or fewer failures
|
||||
// preceed the r th trial's success.
|
||||
// random variable k is the number of failures (NOT the probability).
|
||||
|
||||
// Negative_binomial distribution is a discrete probability distribution.
|
||||
// But note that the negative binomial distribution
|
||||
// (like others including the binomial, Poisson & Bernoulli)
|
||||
// is strictly defined as a discrete function: only integral values of k are envisaged.
|
||||
// However because of the method of calculation using a continuous gamma function,
|
||||
// it is convenient to treat it as if a continous function,
|
||||
// and permit non-integral values of k.
|
||||
|
||||
// However, by default the policy is to use discrete_quantile_policy.
|
||||
|
||||
// To enforce the strict mathematical model, users should use conversion
|
||||
// on k outside this function to ensure that k is integral.
|
||||
|
||||
// MATHCAD cumulative negative binomial pnbinom(k, n, p)
|
||||
|
||||
// Implementation note: much greater speed, and perhaps greater accuracy,
|
||||
// might be achieved for extreme values by using a normal approximation.
|
||||
// This is NOT been tested or implemented.
|
||||
|
||||
#ifndef BOOST_MATH_SPECIAL_NEGATIVE_BINOMIAL_HPP
|
||||
#define BOOST_MATH_SPECIAL_NEGATIVE_BINOMIAL_HPP
|
||||
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#include <boost/math/special_functions/beta.hpp> // for ibeta(a, b, x) == Ix(a, b).
|
||||
#include <boost/math/distributions/complement.hpp> // complement.
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp> // error checks domain_error & logic_error.
|
||||
#include <boost/math/special_functions/fpclassify.hpp> // isnan.
|
||||
#include <boost/math/tools/roots.hpp> // for root finding.
|
||||
#include <boost/math/distributions/detail/inv_discrete_quantile.hpp>
|
||||
|
||||
#include <boost/type_traits/is_floating_point.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
|
||||
#include <limits> // using std::numeric_limits;
|
||||
#include <utility>
|
||||
|
||||
#if defined (BOOST_MSVC)
|
||||
# pragma warning(push)
|
||||
// This believed not now necessary, so commented out.
|
||||
//# pragma warning(disable: 4702) // unreachable code.
|
||||
// in domain_error_imp in error_handling.
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace math
|
||||
{
|
||||
namespace negative_binomial_detail
|
||||
{
|
||||
// Common error checking routines for negative binomial distribution functions:
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_successes(const char* function, const RealType& r, RealType* result, const Policy& pol)
|
||||
{
|
||||
if( !(boost::math::isfinite)(r) || (r <= 0) )
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Number of successes argument is %1%, but must be > 0 !", r, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_success_fraction(const char* function, const RealType& p, RealType* result, const Policy& pol)
|
||||
{
|
||||
if( !(boost::math::isfinite)(p) || (p < 0) || (p > 1) )
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Success fraction argument is %1%, but must be >= 0 and <= 1 !", p, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_dist(const char* function, const RealType& r, const RealType& p, RealType* result, const Policy& pol)
|
||||
{
|
||||
return check_success_fraction(function, p, result, pol)
|
||||
&& check_successes(function, r, result, pol);
|
||||
}
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_dist_and_k(const char* function, const RealType& r, const RealType& p, RealType k, RealType* result, const Policy& pol)
|
||||
{
|
||||
if(check_dist(function, r, p, result, pol) == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if( !(boost::math::isfinite)(k) || (k < 0) )
|
||||
{ // Check k failures.
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Number of failures argument is %1%, but must be >= 0 !", k, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // Check_dist_and_k
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_dist_and_prob(const char* function, const RealType& r, RealType p, RealType prob, RealType* result, const Policy& pol)
|
||||
{
|
||||
if(check_dist(function, r, p, result, pol) && detail::check_probability(function, prob, result, pol) == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // check_dist_and_prob
|
||||
} // namespace negative_binomial_detail
|
||||
|
||||
template <class RealType = double, class Policy = policies::policy<> >
|
||||
class negative_binomial_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
|
||||
negative_binomial_distribution(RealType r, RealType p) : m_r(r), m_p(p)
|
||||
{ // Constructor.
|
||||
RealType result;
|
||||
negative_binomial_detail::check_dist(
|
||||
"negative_binomial_distribution<%1%>::negative_binomial_distribution",
|
||||
m_r, // Check successes r > 0.
|
||||
m_p, // Check success_fraction 0 <= p <= 1.
|
||||
&result, Policy());
|
||||
} // negative_binomial_distribution constructor.
|
||||
|
||||
// Private data getter class member functions.
|
||||
RealType success_fraction() const
|
||||
{ // Probability of success as fraction in range 0 to 1.
|
||||
return m_p;
|
||||
}
|
||||
RealType successes() const
|
||||
{ // Total number of successes r.
|
||||
return m_r;
|
||||
}
|
||||
|
||||
static RealType find_lower_bound_on_p(
|
||||
RealType trials,
|
||||
RealType successes,
|
||||
RealType alpha) // alpha 0.05 equivalent to 95% for one-sided test.
|
||||
{
|
||||
static const char* function = "boost::math::negative_binomial<%1%>::find_lower_bound_on_p";
|
||||
RealType result = 0; // of error checks.
|
||||
RealType failures = trials - successes;
|
||||
if(false == detail::check_probability(function, alpha, &result, Policy())
|
||||
&& negative_binomial_detail::check_dist_and_k(
|
||||
function, successes, RealType(0), failures, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
// Use complement ibeta_inv function for lower bound.
|
||||
// This is adapted from the corresponding binomial formula
|
||||
// here: http://www.itl.nist.gov/div898/handbook/prc/section2/prc241.htm
|
||||
// This is a Clopper-Pearson interval, and may be overly conservative,
|
||||
// see also "A Simple Improved Inferential Method for Some
|
||||
// Discrete Distributions" Yong CAI and K. KRISHNAMOORTHY
|
||||
// http://www.ucs.louisiana.edu/~kxk4695/Discrete_new.pdf
|
||||
//
|
||||
return ibeta_inv(successes, failures + 1, alpha, static_cast<RealType*>(0), Policy());
|
||||
} // find_lower_bound_on_p
|
||||
|
||||
static RealType find_upper_bound_on_p(
|
||||
RealType trials,
|
||||
RealType successes,
|
||||
RealType alpha) // alpha 0.05 equivalent to 95% for one-sided test.
|
||||
{
|
||||
static const char* function = "boost::math::negative_binomial<%1%>::find_upper_bound_on_p";
|
||||
RealType result = 0; // of error checks.
|
||||
RealType failures = trials - successes;
|
||||
if(false == negative_binomial_detail::check_dist_and_k(
|
||||
function, successes, RealType(0), failures, &result, Policy())
|
||||
&& detail::check_probability(function, alpha, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(failures == 0)
|
||||
return 1;
|
||||
// Use complement ibetac_inv function for upper bound.
|
||||
// Note adjusted failures value: *not* failures+1 as usual.
|
||||
// This is adapted from the corresponding binomial formula
|
||||
// here: http://www.itl.nist.gov/div898/handbook/prc/section2/prc241.htm
|
||||
// This is a Clopper-Pearson interval, and may be overly conservative,
|
||||
// see also "A Simple Improved Inferential Method for Some
|
||||
// Discrete Distributions" Yong CAI and K. KRISHNAMOORTHY
|
||||
// http://www.ucs.louisiana.edu/~kxk4695/Discrete_new.pdf
|
||||
//
|
||||
return ibetac_inv(successes, failures, alpha, static_cast<RealType*>(0), Policy());
|
||||
} // find_upper_bound_on_p
|
||||
|
||||
// Estimate number of trials :
|
||||
// "How many trials do I need to be P% sure of seeing k or fewer failures?"
|
||||
|
||||
static RealType find_minimum_number_of_trials(
|
||||
RealType k, // number of failures (k >= 0).
|
||||
RealType p, // success fraction 0 <= p <= 1.
|
||||
RealType alpha) // risk level threshold 0 <= alpha <= 1.
|
||||
{
|
||||
static const char* function = "boost::math::negative_binomial<%1%>::find_minimum_number_of_trials";
|
||||
// Error checks:
|
||||
RealType result = 0;
|
||||
if(false == negative_binomial_detail::check_dist_and_k(
|
||||
function, RealType(1), p, k, &result, Policy())
|
||||
&& detail::check_probability(function, alpha, &result, Policy()))
|
||||
{ return result; }
|
||||
|
||||
result = ibeta_inva(k + 1, p, alpha, Policy()); // returns n - k
|
||||
return result + k;
|
||||
} // RealType find_number_of_failures
|
||||
|
||||
static RealType find_maximum_number_of_trials(
|
||||
RealType k, // number of failures (k >= 0).
|
||||
RealType p, // success fraction 0 <= p <= 1.
|
||||
RealType alpha) // risk level threshold 0 <= alpha <= 1.
|
||||
{
|
||||
static const char* function = "boost::math::negative_binomial<%1%>::find_maximum_number_of_trials";
|
||||
// Error checks:
|
||||
RealType result = 0;
|
||||
if(false == negative_binomial_detail::check_dist_and_k(
|
||||
function, RealType(1), p, k, &result, Policy())
|
||||
&& detail::check_probability(function, alpha, &result, Policy()))
|
||||
{ return result; }
|
||||
|
||||
result = ibetac_inva(k + 1, p, alpha, Policy()); // returns n - k
|
||||
return result + k;
|
||||
} // RealType find_number_of_trials complemented
|
||||
|
||||
private:
|
||||
RealType m_r; // successes.
|
||||
RealType m_p; // success_fraction
|
||||
}; // template <class RealType, class Policy> class negative_binomial_distribution
|
||||
|
||||
typedef negative_binomial_distribution<double> negative_binomial; // Reserved name of type double.
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const negative_binomial_distribution<RealType, Policy>& /* dist */)
|
||||
{ // Range of permissible values for random variable k.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>()); // max_integer?
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> support(const negative_binomial_distribution<RealType, Policy>& /* dist */)
|
||||
{ // Range of supported values for random variable k.
|
||||
// This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>()); // max_integer?
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mean(const negative_binomial_distribution<RealType, Policy>& dist)
|
||||
{ // Mean of Negative Binomial distribution = r(1-p)/p.
|
||||
return dist.successes() * (1 - dist.success_fraction() ) / dist.success_fraction();
|
||||
} // mean
|
||||
|
||||
//template <class RealType, class Policy>
|
||||
//inline RealType median(const negative_binomial_distribution<RealType, Policy>& dist)
|
||||
//{ // Median of negative_binomial_distribution is not defined.
|
||||
// return policies::raise_domain_error<RealType>(BOOST_CURRENT_FUNCTION, "Median is not implemented, result is %1%!", std::numeric_limits<RealType>::quiet_NaN());
|
||||
//} // median
|
||||
// Now implemented via quantile(half) in derived accessors.
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mode(const negative_binomial_distribution<RealType, Policy>& dist)
|
||||
{ // Mode of Negative Binomial distribution = floor[(r-1) * (1 - p)/p]
|
||||
BOOST_MATH_STD_USING // ADL of std functions.
|
||||
return floor((dist.successes() -1) * (1 - dist.success_fraction()) / dist.success_fraction());
|
||||
} // mode
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType skewness(const negative_binomial_distribution<RealType, Policy>& dist)
|
||||
{ // skewness of Negative Binomial distribution = 2-p / (sqrt(r(1-p))
|
||||
BOOST_MATH_STD_USING // ADL of std functions.
|
||||
RealType p = dist.success_fraction();
|
||||
RealType r = dist.successes();
|
||||
|
||||
return (2 - p) /
|
||||
sqrt(r * (1 - p));
|
||||
} // skewness
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis(const negative_binomial_distribution<RealType, Policy>& dist)
|
||||
{ // kurtosis of Negative Binomial distribution
|
||||
// http://en.wikipedia.org/wiki/Negative_binomial is kurtosis_excess so add 3
|
||||
RealType p = dist.success_fraction();
|
||||
RealType r = dist.successes();
|
||||
return 3 + (6 / r) + ((p * p) / (r * (1 - p)));
|
||||
} // kurtosis
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis_excess(const negative_binomial_distribution<RealType, Policy>& dist)
|
||||
{ // kurtosis excess of Negative Binomial distribution
|
||||
// http://mathworld.wolfram.com/Kurtosis.html table of kurtosis_excess
|
||||
RealType p = dist.success_fraction();
|
||||
RealType r = dist.successes();
|
||||
return (6 - p * (6-p)) / (r * (1-p));
|
||||
} // kurtosis_excess
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType variance(const negative_binomial_distribution<RealType, Policy>& dist)
|
||||
{ // Variance of Binomial distribution = r (1-p) / p^2.
|
||||
return dist.successes() * (1 - dist.success_fraction())
|
||||
/ (dist.success_fraction() * dist.success_fraction());
|
||||
} // variance
|
||||
|
||||
// RealType standard_deviation(const negative_binomial_distribution<RealType, Policy>& dist)
|
||||
// standard_deviation provided by derived accessors.
|
||||
// RealType hazard(const negative_binomial_distribution<RealType, Policy>& dist)
|
||||
// hazard of Negative Binomial distribution provided by derived accessors.
|
||||
// RealType chf(const negative_binomial_distribution<RealType, Policy>& dist)
|
||||
// chf of Negative Binomial distribution provided by derived accessors.
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType pdf(const negative_binomial_distribution<RealType, Policy>& dist, const RealType& k)
|
||||
{ // Probability Density/Mass Function.
|
||||
BOOST_FPU_EXCEPTION_GUARD
|
||||
|
||||
static const char* function = "boost::math::pdf(const negative_binomial_distribution<%1%>&, %1%)";
|
||||
|
||||
RealType r = dist.successes();
|
||||
RealType p = dist.success_fraction();
|
||||
RealType result = 0;
|
||||
if(false == negative_binomial_detail::check_dist_and_k(
|
||||
function,
|
||||
r,
|
||||
dist.success_fraction(),
|
||||
k,
|
||||
&result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
result = (p/(r + k)) * ibeta_derivative(r, static_cast<RealType>(k+1), p, Policy());
|
||||
// Equivalent to:
|
||||
// return exp(lgamma(r + k) - lgamma(r) - lgamma(k+1)) * pow(p, r) * pow((1-p), k);
|
||||
return result;
|
||||
} // negative_binomial_pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const negative_binomial_distribution<RealType, Policy>& dist, const RealType& k)
|
||||
{ // Cumulative Distribution Function of Negative Binomial.
|
||||
static const char* function = "boost::math::cdf(const negative_binomial_distribution<%1%>&, %1%)";
|
||||
using boost::math::ibeta; // Regularized incomplete beta function.
|
||||
// k argument may be integral, signed, or unsigned, or floating point.
|
||||
// If necessary, it has already been promoted from an integral type.
|
||||
RealType p = dist.success_fraction();
|
||||
RealType r = dist.successes();
|
||||
// Error check:
|
||||
RealType result = 0;
|
||||
if(false == negative_binomial_detail::check_dist_and_k(
|
||||
function,
|
||||
r,
|
||||
dist.success_fraction(),
|
||||
k,
|
||||
&result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
RealType probability = ibeta(r, static_cast<RealType>(k+1), p, Policy());
|
||||
// Ip(r, k+1) = ibeta(r, k+1, p)
|
||||
return probability;
|
||||
} // cdf Cumulative Distribution Function Negative Binomial.
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const complemented2_type<negative_binomial_distribution<RealType, Policy>, RealType>& c)
|
||||
{ // Complemented Cumulative Distribution Function Negative Binomial.
|
||||
|
||||
static const char* function = "boost::math::cdf(const negative_binomial_distribution<%1%>&, %1%)";
|
||||
using boost::math::ibetac; // Regularized incomplete beta function complement.
|
||||
// k argument may be integral, signed, or unsigned, or floating point.
|
||||
// If necessary, it has already been promoted from an integral type.
|
||||
RealType const& k = c.param;
|
||||
negative_binomial_distribution<RealType, Policy> const& dist = c.dist;
|
||||
RealType p = dist.success_fraction();
|
||||
RealType r = dist.successes();
|
||||
// Error check:
|
||||
RealType result = 0;
|
||||
if(false == negative_binomial_detail::check_dist_and_k(
|
||||
function,
|
||||
r,
|
||||
p,
|
||||
k,
|
||||
&result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
// Calculate cdf negative binomial using the incomplete beta function.
|
||||
// Use of ibeta here prevents cancellation errors in calculating
|
||||
// 1-p if p is very small, perhaps smaller than machine epsilon.
|
||||
// Ip(k+1, r) = ibetac(r, k+1, p)
|
||||
// constrain_probability here?
|
||||
RealType probability = ibetac(r, static_cast<RealType>(k+1), p, Policy());
|
||||
// Numerical errors might cause probability to be slightly outside the range < 0 or > 1.
|
||||
// This might cause trouble downstream, so warn, possibly throw exception, but constrain to the limits.
|
||||
return probability;
|
||||
} // cdf Cumulative Distribution Function Negative Binomial.
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const negative_binomial_distribution<RealType, Policy>& dist, const RealType& P)
|
||||
{ // Quantile, percentile/100 or Percent Point Negative Binomial function.
|
||||
// Return the number of expected failures k for a given probability p.
|
||||
|
||||
// Inverse cumulative Distribution Function or Quantile (percentile / 100) of negative_binomial Probability.
|
||||
// MAthCAD pnbinom return smallest k such that negative_binomial(k, n, p) >= probability.
|
||||
// k argument may be integral, signed, or unsigned, or floating point.
|
||||
// BUT Cephes/CodeCogs says: finds argument p (0 to 1) such that cdf(k, n, p) = y
|
||||
static const char* function = "boost::math::quantile(const negative_binomial_distribution<%1%>&, %1%)";
|
||||
BOOST_MATH_STD_USING // ADL of std functions.
|
||||
|
||||
RealType p = dist.success_fraction();
|
||||
RealType r = dist.successes();
|
||||
// Check dist and P.
|
||||
RealType result = 0;
|
||||
if(false == negative_binomial_detail::check_dist_and_prob
|
||||
(function, r, p, P, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
// Special cases.
|
||||
if (P == 1)
|
||||
{ // Would need +infinity failures for total confidence.
|
||||
result = policies::raise_overflow_error<RealType>(
|
||||
function,
|
||||
"Probability argument is 1, which implies infinite failures !", Policy());
|
||||
return result;
|
||||
// usually means return +std::numeric_limits<RealType>::infinity();
|
||||
// unless #define BOOST_MATH_THROW_ON_OVERFLOW_ERROR
|
||||
}
|
||||
if (P == 0)
|
||||
{ // No failures are expected if P = 0.
|
||||
return 0; // Total trials will be just dist.successes.
|
||||
}
|
||||
if (P <= pow(dist.success_fraction(), dist.successes()))
|
||||
{ // p <= pdf(dist, 0) == cdf(dist, 0)
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
// Calculate quantile of negative_binomial using the inverse incomplete beta function.
|
||||
using boost::math::ibeta_invb;
|
||||
return ibeta_invb(r, p, P, Policy()) - 1; //
|
||||
*/
|
||||
RealType guess = 0;
|
||||
RealType factor = 5;
|
||||
if(r * r * r * P * p > 0.005)
|
||||
guess = detail::inverse_negative_binomial_cornish_fisher(r, p, RealType(1-p), P, RealType(1-P), Policy());
|
||||
|
||||
if(guess < 10)
|
||||
{
|
||||
//
|
||||
// Cornish-Fisher Negative binomial approximation not accurate in this area:
|
||||
//
|
||||
guess = (std::min)(RealType(r * 2), RealType(10));
|
||||
}
|
||||
else
|
||||
factor = (1-P < sqrt(tools::epsilon<RealType>())) ? 2 : (guess < 20 ? 1.2f : 1.1f);
|
||||
BOOST_MATH_INSTRUMENT_CODE("guess = " << guess);
|
||||
//
|
||||
// Max iterations permitted:
|
||||
//
|
||||
boost::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
|
||||
typedef typename Policy::discrete_quantile_type discrete_type;
|
||||
return detail::inverse_discrete_quantile(
|
||||
dist,
|
||||
P,
|
||||
1-P,
|
||||
guess,
|
||||
factor,
|
||||
RealType(1),
|
||||
discrete_type(),
|
||||
max_iter);
|
||||
} // RealType quantile(const negative_binomial_distribution dist, p)
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const complemented2_type<negative_binomial_distribution<RealType, Policy>, RealType>& c)
|
||||
{ // Quantile or Percent Point Binomial function.
|
||||
// Return the number of expected failures k for a given
|
||||
// complement of the probability Q = 1 - P.
|
||||
static const char* function = "boost::math::quantile(const negative_binomial_distribution<%1%>&, %1%)";
|
||||
BOOST_MATH_STD_USING
|
||||
|
||||
// Error checks:
|
||||
RealType Q = c.param;
|
||||
const negative_binomial_distribution<RealType, Policy>& dist = c.dist;
|
||||
RealType p = dist.success_fraction();
|
||||
RealType r = dist.successes();
|
||||
RealType result = 0;
|
||||
if(false == negative_binomial_detail::check_dist_and_prob(
|
||||
function,
|
||||
r,
|
||||
p,
|
||||
Q,
|
||||
&result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
// Special cases:
|
||||
//
|
||||
if(Q == 1)
|
||||
{ // There may actually be no answer to this question,
|
||||
// since the probability of zero failures may be non-zero,
|
||||
return 0; // but zero is the best we can do:
|
||||
}
|
||||
if (-Q <= boost::math::powm1(dist.success_fraction(), dist.successes(), Policy()))
|
||||
{ // q <= cdf(complement(dist, 0)) == pdf(dist, 0)
|
||||
return 0; //
|
||||
}
|
||||
if(Q == 0)
|
||||
{ // Probability 1 - Q == 1 so infinite failures to achieve certainty.
|
||||
// Would need +infinity failures for total confidence.
|
||||
result = policies::raise_overflow_error<RealType>(
|
||||
function,
|
||||
"Probability argument complement is 0, which implies infinite failures !", Policy());
|
||||
return result;
|
||||
// usually means return +std::numeric_limits<RealType>::infinity();
|
||||
// unless #define BOOST_MATH_THROW_ON_OVERFLOW_ERROR
|
||||
}
|
||||
//return ibetac_invb(r, p, Q, Policy()) -1;
|
||||
RealType guess = 0;
|
||||
RealType factor = 5;
|
||||
if(r * r * r * (1-Q) * p > 0.005)
|
||||
guess = detail::inverse_negative_binomial_cornish_fisher(r, p, RealType(1-p), RealType(1-Q), Q, Policy());
|
||||
|
||||
if(guess < 10)
|
||||
{
|
||||
//
|
||||
// Cornish-Fisher Negative binomial approximation not accurate in this area:
|
||||
//
|
||||
guess = (std::min)(RealType(r * 2), RealType(10));
|
||||
}
|
||||
else
|
||||
factor = (Q < sqrt(tools::epsilon<RealType>())) ? 2 : (guess < 20 ? 1.2f : 1.1f);
|
||||
BOOST_MATH_INSTRUMENT_CODE("guess = " << guess);
|
||||
//
|
||||
// Max iterations permitted:
|
||||
//
|
||||
boost::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
|
||||
typedef typename Policy::discrete_quantile_type discrete_type;
|
||||
return detail::inverse_discrete_quantile(
|
||||
dist,
|
||||
1-Q,
|
||||
Q,
|
||||
guess,
|
||||
factor,
|
||||
RealType(1),
|
||||
discrete_type(),
|
||||
max_iter);
|
||||
} // quantile complement
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
// This include must be at the end, *after* the accessors
|
||||
// for this distribution have been defined, in order to
|
||||
// keep compilers that support two-phase lookup happy.
|
||||
#include <boost/math/distributions/detail/derived_accessors.hpp>
|
||||
|
||||
#if defined (BOOST_MSVC)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // BOOST_MATH_SPECIAL_NEGATIVE_BINOMIAL_HPP
|
||||
934
test/external/boost/math/distributions/non_central_beta.hpp
vendored
Normal file
934
test/external/boost/math/distributions/non_central_beta.hpp
vendored
Normal file
@@ -0,0 +1,934 @@
|
||||
// boost\math\distributions\non_central_beta.hpp
|
||||
|
||||
// Copyright John Maddock 2008.
|
||||
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_MATH_SPECIAL_NON_CENTRAL_BETA_HPP
|
||||
#define BOOST_MATH_SPECIAL_NON_CENTRAL_BETA_HPP
|
||||
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#include <boost/math/special_functions/beta.hpp> // for incomplete gamma. gamma_q
|
||||
#include <boost/math/distributions/complement.hpp> // complements
|
||||
#include <boost/math/distributions/beta.hpp> // central distribution
|
||||
#include <boost/math/distributions/detail/generic_mode.hpp>
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp> // error checks
|
||||
#include <boost/math/special_functions/fpclassify.hpp> // isnan.
|
||||
#include <boost/math/tools/roots.hpp> // for root finding.
|
||||
#include <boost/math/tools/series.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace math
|
||||
{
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class non_central_beta_distribution;
|
||||
|
||||
namespace detail{
|
||||
|
||||
template <class T, class Policy>
|
||||
T non_central_beta_p(T a, T b, T lam, T x, T y, const Policy& pol, T init_val = 0)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
using namespace boost::math;
|
||||
//
|
||||
// Variables come first:
|
||||
//
|
||||
boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
|
||||
T errtol = boost::math::policies::get_epsilon<T, Policy>();
|
||||
T l2 = lam / 2;
|
||||
//
|
||||
// k is the starting point for iteration, and is the
|
||||
// maximum of the poisson weighting term,
|
||||
// note that unlike other similar code, we do not set
|
||||
// k to zero, when l2 is small, as forward iteration
|
||||
// is unstable:
|
||||
//
|
||||
int k = itrunc(l2);
|
||||
if(k == 0)
|
||||
k = 1;
|
||||
T pois;
|
||||
if(k == 0)
|
||||
{
|
||||
// Starting Poisson weight:
|
||||
pois = exp(-l2);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Starting Poisson weight:
|
||||
pois = gamma_p_derivative(T(k+1), l2, pol);
|
||||
}
|
||||
if(pois == 0)
|
||||
return init_val;
|
||||
// recurance term:
|
||||
T xterm;
|
||||
// Starting beta term:
|
||||
T beta = x < y
|
||||
? detail::ibeta_imp(T(a + k), b, x, pol, false, true, &xterm)
|
||||
: detail::ibeta_imp(b, T(a + k), y, pol, true, true, &xterm);
|
||||
|
||||
xterm *= y / (a + b + k - 1);
|
||||
T poisf(pois), betaf(beta), xtermf(xterm);
|
||||
T sum = init_val;
|
||||
|
||||
if((beta == 0) && (xterm == 0))
|
||||
return init_val;
|
||||
|
||||
//
|
||||
// Backwards recursion first, this is the stable
|
||||
// direction for recursion:
|
||||
//
|
||||
T last_term = 0;
|
||||
boost::uintmax_t count = k;
|
||||
for(int i = k; i >= 0; --i)
|
||||
{
|
||||
T term = beta * pois;
|
||||
sum += term;
|
||||
if(((fabs(term/sum) < errtol) && (last_term >= term)) || (term == 0))
|
||||
{
|
||||
count = k - i;
|
||||
break;
|
||||
}
|
||||
pois *= i / l2;
|
||||
beta += xterm;
|
||||
xterm *= (a + i - 1) / (x * (a + b + i - 2));
|
||||
last_term = term;
|
||||
}
|
||||
for(int i = k + 1; ; ++i)
|
||||
{
|
||||
poisf *= l2 / i;
|
||||
xtermf *= (x * (a + b + i - 2)) / (a + i - 1);
|
||||
betaf -= xtermf;
|
||||
|
||||
T term = poisf * betaf;
|
||||
sum += term;
|
||||
if((fabs(term/sum) < errtol) || (term == 0))
|
||||
{
|
||||
break;
|
||||
}
|
||||
if(static_cast<boost::uintmax_t>(count + i - k) > max_iter)
|
||||
{
|
||||
return policies::raise_evaluation_error(
|
||||
"cdf(non_central_beta_distribution<%1%>, %1%)",
|
||||
"Series did not converge, closest value was %1%", sum, pol);
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
template <class T, class Policy>
|
||||
T non_central_beta_q(T a, T b, T lam, T x, T y, const Policy& pol, T init_val = 0)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
using namespace boost::math;
|
||||
//
|
||||
// Variables come first:
|
||||
//
|
||||
boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
|
||||
T errtol = boost::math::policies::get_epsilon<T, Policy>();
|
||||
T l2 = lam / 2;
|
||||
//
|
||||
// k is the starting point for iteration, and is the
|
||||
// maximum of the poisson weighting term:
|
||||
//
|
||||
int k = itrunc(l2);
|
||||
T pois;
|
||||
if(k <= 30)
|
||||
{
|
||||
//
|
||||
// Might as well start at 0 since we'll likely have this number of terms anyway:
|
||||
//
|
||||
if(a + b > 1)
|
||||
k = 0;
|
||||
else if(k == 0)
|
||||
k = 1;
|
||||
}
|
||||
if(k == 0)
|
||||
{
|
||||
// Starting Poisson weight:
|
||||
pois = exp(-l2);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Starting Poisson weight:
|
||||
pois = gamma_p_derivative(T(k+1), l2, pol);
|
||||
}
|
||||
if(pois == 0)
|
||||
return init_val;
|
||||
// recurance term:
|
||||
T xterm;
|
||||
// Starting beta term:
|
||||
T beta = x < y
|
||||
? detail::ibeta_imp(T(a + k), b, x, pol, true, true, &xterm)
|
||||
: detail::ibeta_imp(b, T(a + k), y, pol, false, true, &xterm);
|
||||
|
||||
xterm *= y / (a + b + k - 1);
|
||||
T poisf(pois), betaf(beta), xtermf(xterm);
|
||||
T sum = init_val;
|
||||
if((beta == 0) && (xterm == 0))
|
||||
return init_val;
|
||||
//
|
||||
// Forwards recursion first, this is the stable
|
||||
// direction for recursion, and the location
|
||||
// of the bulk of the sum:
|
||||
//
|
||||
T last_term = 0;
|
||||
boost::uintmax_t count = 0;
|
||||
for(int i = k + 1; ; ++i)
|
||||
{
|
||||
poisf *= l2 / i;
|
||||
xtermf *= (x * (a + b + i - 2)) / (a + i - 1);
|
||||
betaf += xtermf;
|
||||
|
||||
T term = poisf * betaf;
|
||||
sum += term;
|
||||
if((fabs(term/sum) < errtol) && (last_term >= term))
|
||||
{
|
||||
count = i - k;
|
||||
break;
|
||||
}
|
||||
if(static_cast<boost::uintmax_t>(i - k) > max_iter)
|
||||
{
|
||||
return policies::raise_evaluation_error(
|
||||
"cdf(non_central_beta_distribution<%1%>, %1%)",
|
||||
"Series did not converge, closest value was %1%", sum, pol);
|
||||
}
|
||||
last_term = term;
|
||||
}
|
||||
for(int i = k; i >= 0; --i)
|
||||
{
|
||||
T term = beta * pois;
|
||||
sum += term;
|
||||
if(fabs(term/sum) < errtol)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if(static_cast<boost::uintmax_t>(count + k - i) > max_iter)
|
||||
{
|
||||
return policies::raise_evaluation_error(
|
||||
"cdf(non_central_beta_distribution<%1%>, %1%)",
|
||||
"Series did not converge, closest value was %1%", sum, pol);
|
||||
}
|
||||
pois *= i / l2;
|
||||
beta -= xterm;
|
||||
xterm *= (a + i - 1) / (x * (a + b + i - 2));
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType non_central_beta_cdf(RealType x, RealType y, RealType a, RealType b, RealType l, bool invert, const Policy&)
|
||||
{
|
||||
typedef typename policies::evaluation<RealType, Policy>::type value_type;
|
||||
typedef typename policies::normalise<
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
policies::discrete_quantile<>,
|
||||
policies::assert_undefined<> >::type forwarding_policy;
|
||||
|
||||
BOOST_MATH_STD_USING
|
||||
|
||||
if(x == 0)
|
||||
return invert ? 1.0f : 0.0f;
|
||||
if(y == 0)
|
||||
return invert ? 0.0f : 1.0f;
|
||||
value_type result;
|
||||
value_type c = a + b + l / 2;
|
||||
value_type cross = 1 - (b / c) * (1 + l / (2 * c * c));
|
||||
if(l == 0)
|
||||
result = cdf(boost::math::beta_distribution<RealType, Policy>(a, b), x);
|
||||
else if(x > cross)
|
||||
{
|
||||
// Complement is the smaller of the two:
|
||||
result = detail::non_central_beta_q(
|
||||
static_cast<value_type>(a),
|
||||
static_cast<value_type>(b),
|
||||
static_cast<value_type>(l),
|
||||
static_cast<value_type>(x),
|
||||
static_cast<value_type>(y),
|
||||
forwarding_policy(),
|
||||
static_cast<value_type>(invert ? 0 : -1));
|
||||
invert = !invert;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = detail::non_central_beta_p(
|
||||
static_cast<value_type>(a),
|
||||
static_cast<value_type>(b),
|
||||
static_cast<value_type>(l),
|
||||
static_cast<value_type>(x),
|
||||
static_cast<value_type>(y),
|
||||
forwarding_policy(),
|
||||
static_cast<value_type>(invert ? -1 : 0));
|
||||
}
|
||||
if(invert)
|
||||
result = -result;
|
||||
return policies::checked_narrowing_cast<RealType, forwarding_policy>(
|
||||
result,
|
||||
"boost::math::non_central_beta_cdf<%1%>(%1%, %1%, %1%)");
|
||||
}
|
||||
|
||||
template <class T, class Policy>
|
||||
struct nc_beta_quantile_functor
|
||||
{
|
||||
nc_beta_quantile_functor(const non_central_beta_distribution<T,Policy>& d, T t, bool c)
|
||||
: dist(d), target(t), comp(c) {}
|
||||
|
||||
T operator()(const T& x)
|
||||
{
|
||||
return comp ?
|
||||
T(target - cdf(complement(dist, x)))
|
||||
: T(cdf(dist, x) - target);
|
||||
}
|
||||
|
||||
private:
|
||||
non_central_beta_distribution<T,Policy> dist;
|
||||
T target;
|
||||
bool comp;
|
||||
};
|
||||
|
||||
//
|
||||
// This is more or less a copy of bracket_and_solve_root, but
|
||||
// modified to search only the interval [0,1] using similar
|
||||
// heuristics.
|
||||
//
|
||||
template <class F, class T, class Tol, class Policy>
|
||||
std::pair<T, T> bracket_and_solve_root_01(F f, const T& guess, T factor, bool rising, Tol tol, boost::uintmax_t& max_iter, const Policy& pol)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
static const char* function = "boost::math::tools::bracket_and_solve_root_01<%1%>";
|
||||
//
|
||||
// Set up inital brackets:
|
||||
//
|
||||
T a = guess;
|
||||
T b = a;
|
||||
T fa = f(a);
|
||||
T fb = fa;
|
||||
//
|
||||
// Set up invocation count:
|
||||
//
|
||||
boost::uintmax_t count = max_iter - 1;
|
||||
|
||||
if((fa < 0) == (guess < 0 ? !rising : rising))
|
||||
{
|
||||
//
|
||||
// Zero is to the right of b, so walk upwards
|
||||
// until we find it:
|
||||
//
|
||||
while((boost::math::sign)(fb) == (boost::math::sign)(fa))
|
||||
{
|
||||
if(count == 0)
|
||||
{
|
||||
b = policies::raise_evaluation_error(function, "Unable to bracket root, last nearest value was %1%", b, pol);
|
||||
return std::make_pair(a, b);
|
||||
}
|
||||
//
|
||||
// Heuristic: every 20 iterations we double the growth factor in case the
|
||||
// initial guess was *really* bad !
|
||||
//
|
||||
if((max_iter - count) % 20 == 0)
|
||||
factor *= 2;
|
||||
//
|
||||
// Now go ahead and move are guess by "factor",
|
||||
// we do this by reducing 1-guess by factor:
|
||||
//
|
||||
a = b;
|
||||
fa = fb;
|
||||
b = 1 - ((1 - b) / factor);
|
||||
fb = f(b);
|
||||
--count;
|
||||
BOOST_MATH_INSTRUMENT_CODE("a = " << a << " b = " << b << " fa = " << fa << " fb = " << fb << " count = " << count);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Zero is to the left of a, so walk downwards
|
||||
// until we find it:
|
||||
//
|
||||
while((boost::math::sign)(fb) == (boost::math::sign)(fa))
|
||||
{
|
||||
if(fabs(a) < tools::min_value<T>())
|
||||
{
|
||||
// Escape route just in case the answer is zero!
|
||||
max_iter -= count;
|
||||
max_iter += 1;
|
||||
return a > 0 ? std::make_pair(T(0), T(a)) : std::make_pair(T(a), T(0));
|
||||
}
|
||||
if(count == 0)
|
||||
{
|
||||
a = policies::raise_evaluation_error(function, "Unable to bracket root, last nearest value was %1%", a, pol);
|
||||
return std::make_pair(a, b);
|
||||
}
|
||||
//
|
||||
// Heuristic: every 20 iterations we double the growth factor in case the
|
||||
// initial guess was *really* bad !
|
||||
//
|
||||
if((max_iter - count) % 20 == 0)
|
||||
factor *= 2;
|
||||
//
|
||||
// Now go ahead and move are guess by "factor":
|
||||
//
|
||||
b = a;
|
||||
fb = fa;
|
||||
a /= factor;
|
||||
fa = f(a);
|
||||
--count;
|
||||
BOOST_MATH_INSTRUMENT_CODE("a = " << a << " b = " << b << " fa = " << fa << " fb = " << fb << " count = " << count);
|
||||
}
|
||||
}
|
||||
max_iter -= count;
|
||||
max_iter += 1;
|
||||
std::pair<T, T> r = toms748_solve(
|
||||
f,
|
||||
(a < 0 ? b : a),
|
||||
(a < 0 ? a : b),
|
||||
(a < 0 ? fb : fa),
|
||||
(a < 0 ? fa : fb),
|
||||
tol,
|
||||
count,
|
||||
pol);
|
||||
max_iter += count;
|
||||
BOOST_MATH_INSTRUMENT_CODE("max_iter = " << max_iter << " count = " << count);
|
||||
return r;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
RealType nc_beta_quantile(const non_central_beta_distribution<RealType, Policy>& dist, const RealType& p, bool comp)
|
||||
{
|
||||
static const char* function = "quantile(non_central_beta_distribution<%1%>, %1%)";
|
||||
typedef typename policies::evaluation<RealType, Policy>::type value_type;
|
||||
typedef typename policies::normalise<
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
policies::discrete_quantile<>,
|
||||
policies::assert_undefined<> >::type forwarding_policy;
|
||||
|
||||
value_type a = dist.alpha();
|
||||
value_type b = dist.beta();
|
||||
value_type l = dist.non_centrality();
|
||||
value_type r;
|
||||
if(!beta_detail::check_alpha(
|
||||
function,
|
||||
a, &r, Policy())
|
||||
||
|
||||
!beta_detail::check_beta(
|
||||
function,
|
||||
b, &r, Policy())
|
||||
||
|
||||
!detail::check_non_centrality(
|
||||
function,
|
||||
l,
|
||||
&r,
|
||||
Policy())
|
||||
||
|
||||
!detail::check_probability(
|
||||
function,
|
||||
static_cast<value_type>(p),
|
||||
&r,
|
||||
Policy()))
|
||||
return (RealType)r;
|
||||
//
|
||||
// Special cases first:
|
||||
//
|
||||
if(p == 0)
|
||||
return comp
|
||||
? 1.0f
|
||||
: 0.0f;
|
||||
if(p == 1)
|
||||
return !comp
|
||||
? 1.0f
|
||||
: 0.0f;
|
||||
|
||||
value_type c = a + b + l / 2;
|
||||
value_type mean = 1 - (b / c) * (1 + l / (2 * c * c));
|
||||
/*
|
||||
//
|
||||
// Calculate a normal approximation to the quantile,
|
||||
// uses mean and variance approximations from:
|
||||
// Algorithm AS 310:
|
||||
// Computing the Non-Central Beta Distribution Function
|
||||
// R. Chattamvelli; R. Shanmugam
|
||||
// Applied Statistics, Vol. 46, No. 1. (1997), pp. 146-156.
|
||||
//
|
||||
// Unfortunately, when this is wrong it tends to be *very*
|
||||
// wrong, so it's disabled for now, even though it often
|
||||
// gets the initial guess quite close. Probably we could
|
||||
// do much better by factoring in the skewness if only
|
||||
// we could calculate it....
|
||||
//
|
||||
value_type delta = l / 2;
|
||||
value_type delta2 = delta * delta;
|
||||
value_type delta3 = delta * delta2;
|
||||
value_type delta4 = delta2 * delta2;
|
||||
value_type G = c * (c + 1) + delta;
|
||||
value_type alpha = a + b;
|
||||
value_type alpha2 = alpha * alpha;
|
||||
value_type eta = (2 * alpha + 1) * (2 * alpha + 1) + 1;
|
||||
value_type H = 3 * alpha2 + 5 * alpha + 2;
|
||||
value_type F = alpha2 * (alpha + 1) + H * delta
|
||||
+ (2 * alpha + 4) * delta2 + delta3;
|
||||
value_type P = (3 * alpha + 1) * (9 * alpha + 17)
|
||||
+ 2 * alpha * (3 * alpha + 2) * (3 * alpha + 4) + 15;
|
||||
value_type Q = 54 * alpha2 + 162 * alpha + 130;
|
||||
value_type R = 6 * (6 * alpha + 11);
|
||||
value_type D = delta
|
||||
* (H * H + 2 * P * delta + Q * delta2 + R * delta3 + 9 * delta4);
|
||||
value_type variance = (b / G)
|
||||
* (1 + delta * (l * l + 3 * l + eta) / (G * G))
|
||||
- (b * b / F) * (1 + D / (F * F));
|
||||
value_type sd = sqrt(variance);
|
||||
|
||||
value_type guess = comp
|
||||
? quantile(complement(normal_distribution<RealType, Policy>(static_cast<RealType>(mean), static_cast<RealType>(sd)), p))
|
||||
: quantile(normal_distribution<RealType, Policy>(static_cast<RealType>(mean), static_cast<RealType>(sd)), p);
|
||||
|
||||
if(guess >= 1)
|
||||
guess = mean;
|
||||
if(guess <= tools::min_value<value_type>())
|
||||
guess = mean;
|
||||
*/
|
||||
value_type guess = mean;
|
||||
detail::nc_beta_quantile_functor<value_type, Policy>
|
||||
f(non_central_beta_distribution<value_type, Policy>(a, b, l), p, comp);
|
||||
tools::eps_tolerance<value_type> tol(policies::digits<RealType, Policy>());
|
||||
boost::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
|
||||
|
||||
std::pair<value_type, value_type> ir
|
||||
= bracket_and_solve_root_01(
|
||||
f, guess, value_type(2.5), true, tol,
|
||||
max_iter, Policy());
|
||||
value_type result = ir.first + (ir.second - ir.first) / 2;
|
||||
|
||||
if(max_iter >= policies::get_max_root_iterations<Policy>())
|
||||
{
|
||||
return policies::raise_evaluation_error<RealType>(function, "Unable to locate solution in a reasonable time:"
|
||||
" either there is no answer to quantile of the non central beta distribution"
|
||||
" or the answer is infinite. Current best guess is %1%",
|
||||
policies::checked_narrowing_cast<RealType, forwarding_policy>(
|
||||
result,
|
||||
function), Policy());
|
||||
}
|
||||
return policies::checked_narrowing_cast<RealType, forwarding_policy>(
|
||||
result,
|
||||
function);
|
||||
}
|
||||
|
||||
template <class T, class Policy>
|
||||
T non_central_beta_pdf(T a, T b, T lam, T x, T y, const Policy& pol)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
using namespace boost::math;
|
||||
//
|
||||
// Variables come first:
|
||||
//
|
||||
boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
|
||||
T errtol = boost::math::policies::get_epsilon<T, Policy>();
|
||||
T l2 = lam / 2;
|
||||
//
|
||||
// k is the starting point for iteration, and is the
|
||||
// maximum of the poisson weighting term:
|
||||
//
|
||||
int k = itrunc(l2);
|
||||
// Starting Poisson weight:
|
||||
T pois = gamma_p_derivative(T(k+1), l2, pol);
|
||||
// Starting beta term:
|
||||
T beta = x < y ?
|
||||
ibeta_derivative(a + k, b, x, pol)
|
||||
: ibeta_derivative(b, a + k, y, pol);
|
||||
T sum = 0;
|
||||
T poisf(pois);
|
||||
T betaf(beta);
|
||||
|
||||
//
|
||||
// Stable backwards recursion first:
|
||||
//
|
||||
boost::uintmax_t count = k;
|
||||
for(int i = k; i >= 0; --i)
|
||||
{
|
||||
T term = beta * pois;
|
||||
sum += term;
|
||||
if((fabs(term/sum) < errtol) || (term == 0))
|
||||
{
|
||||
count = k - i;
|
||||
break;
|
||||
}
|
||||
pois *= i / l2;
|
||||
beta *= (a + i - 1) / (x * (a + i + b - 1));
|
||||
}
|
||||
for(int i = k + 1; ; ++i)
|
||||
{
|
||||
poisf *= l2 / i;
|
||||
betaf *= x * (a + b + i - 1) / (a + i - 1);
|
||||
|
||||
T term = poisf * betaf;
|
||||
sum += term;
|
||||
if((fabs(term/sum) < errtol) || (term == 0))
|
||||
{
|
||||
break;
|
||||
}
|
||||
if(static_cast<boost::uintmax_t>(count + i - k) > max_iter)
|
||||
{
|
||||
return policies::raise_evaluation_error(
|
||||
"pdf(non_central_beta_distribution<%1%>, %1%)",
|
||||
"Series did not converge, closest value was %1%", sum, pol);
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
RealType nc_beta_pdf(const non_central_beta_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
static const char* function = "pdf(non_central_beta_distribution<%1%>, %1%)";
|
||||
typedef typename policies::evaluation<RealType, Policy>::type value_type;
|
||||
typedef typename policies::normalise<
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
policies::discrete_quantile<>,
|
||||
policies::assert_undefined<> >::type forwarding_policy;
|
||||
|
||||
value_type a = dist.alpha();
|
||||
value_type b = dist.beta();
|
||||
value_type l = dist.non_centrality();
|
||||
value_type r;
|
||||
if(!beta_detail::check_alpha(
|
||||
function,
|
||||
a, &r, Policy())
|
||||
||
|
||||
!beta_detail::check_beta(
|
||||
function,
|
||||
b, &r, Policy())
|
||||
||
|
||||
!detail::check_non_centrality(
|
||||
function,
|
||||
l,
|
||||
&r,
|
||||
Policy())
|
||||
||
|
||||
!beta_detail::check_x(
|
||||
function,
|
||||
static_cast<value_type>(x),
|
||||
&r,
|
||||
Policy()))
|
||||
return (RealType)r;
|
||||
|
||||
if(l == 0)
|
||||
return pdf(boost::math::beta_distribution<RealType, Policy>(dist.alpha(), dist.beta()), x);
|
||||
return policies::checked_narrowing_cast<RealType, forwarding_policy>(
|
||||
non_central_beta_pdf(a, b, l, static_cast<value_type>(x), value_type(1 - static_cast<value_type>(x)), forwarding_policy()),
|
||||
"function");
|
||||
}
|
||||
|
||||
template <class T>
|
||||
struct hypergeometric_2F2_sum
|
||||
{
|
||||
typedef T result_type;
|
||||
hypergeometric_2F2_sum(T a1_, T a2_, T b1_, T b2_, T z_) : a1(a1_), a2(a2_), b1(b1_), b2(b2_), z(z_), term(1), k(0) {}
|
||||
T operator()()
|
||||
{
|
||||
T result = term;
|
||||
term *= a1 * a2 / (b1 * b2);
|
||||
a1 += 1;
|
||||
a2 += 1;
|
||||
b1 += 1;
|
||||
b2 += 1;
|
||||
k += 1;
|
||||
term /= k;
|
||||
term *= z;
|
||||
return result;
|
||||
}
|
||||
T a1, a2, b1, b2, z, term, k;
|
||||
};
|
||||
|
||||
template <class T, class Policy>
|
||||
T hypergeometric_2F2(T a1, T a2, T b1, T b2, T z, const Policy& pol)
|
||||
{
|
||||
typedef typename policies::evaluation<T, Policy>::type value_type;
|
||||
|
||||
const char* function = "boost::math::detail::hypergeometric_2F2<%1%>(%1%,%1%,%1%,%1%,%1%)";
|
||||
|
||||
hypergeometric_2F2_sum<value_type> s(a1, a2, b1, b2, z);
|
||||
boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
|
||||
value_type zero = 0;
|
||||
value_type result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon<value_type, Policy>(), max_iter, zero);
|
||||
#else
|
||||
value_type result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon<value_type, Policy>(), max_iter);
|
||||
#endif
|
||||
policies::check_series_iterations<T>(function, max_iter, pol);
|
||||
return policies::checked_narrowing_cast<T, Policy>(result, function);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class RealType = double, class Policy = policies::policy<> >
|
||||
class non_central_beta_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
|
||||
non_central_beta_distribution(RealType a_, RealType b_, RealType lambda) : a(a_), b(b_), ncp(lambda)
|
||||
{
|
||||
const char* function = "boost::math::non_central_beta_distribution<%1%>::non_central_beta_distribution(%1%,%1%)";
|
||||
RealType r;
|
||||
beta_detail::check_alpha(
|
||||
function,
|
||||
a, &r, Policy());
|
||||
beta_detail::check_beta(
|
||||
function,
|
||||
b, &r, Policy());
|
||||
detail::check_non_centrality(
|
||||
function,
|
||||
lambda,
|
||||
&r,
|
||||
Policy());
|
||||
} // non_central_beta_distribution constructor.
|
||||
|
||||
RealType alpha() const
|
||||
{ // Private data getter function.
|
||||
return a;
|
||||
}
|
||||
RealType beta() const
|
||||
{ // Private data getter function.
|
||||
return b;
|
||||
}
|
||||
RealType non_centrality() const
|
||||
{ // Private data getter function.
|
||||
return ncp;
|
||||
}
|
||||
private:
|
||||
// Data member, initialized by constructor.
|
||||
RealType a; // alpha.
|
||||
RealType b; // beta.
|
||||
RealType ncp; // non-centrality parameter
|
||||
}; // template <class RealType, class Policy> class non_central_beta_distribution
|
||||
|
||||
typedef non_central_beta_distribution<double> non_central_beta; // Reserved name of type double.
|
||||
|
||||
// Non-member functions to give properties of the distribution.
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const non_central_beta_distribution<RealType, Policy>& /* dist */)
|
||||
{ // Range of permissible values for random variable k.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(static_cast<RealType>(0), static_cast<RealType>(1));
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> support(const non_central_beta_distribution<RealType, Policy>& /* dist */)
|
||||
{ // Range of supported values for random variable k.
|
||||
// This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(static_cast<RealType>(0), static_cast<RealType>(1));
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mode(const non_central_beta_distribution<RealType, Policy>& dist)
|
||||
{ // mode.
|
||||
static const char* function = "mode(non_central_beta_distribution<%1%> const&)";
|
||||
|
||||
RealType a = dist.alpha();
|
||||
RealType b = dist.beta();
|
||||
RealType l = dist.non_centrality();
|
||||
RealType r;
|
||||
if(!beta_detail::check_alpha(
|
||||
function,
|
||||
a, &r, Policy())
|
||||
||
|
||||
!beta_detail::check_beta(
|
||||
function,
|
||||
b, &r, Policy())
|
||||
||
|
||||
!detail::check_non_centrality(
|
||||
function,
|
||||
l,
|
||||
&r,
|
||||
Policy()))
|
||||
return (RealType)r;
|
||||
RealType c = a + b + l / 2;
|
||||
RealType mean = 1 - (b / c) * (1 + l / (2 * c * c));
|
||||
return detail::generic_find_mode_01(
|
||||
dist,
|
||||
mean,
|
||||
function);
|
||||
}
|
||||
|
||||
//
|
||||
// We don't have the necessary information to implement
|
||||
// these at present. These are just disabled for now,
|
||||
// prototypes retained so we can fill in the blanks
|
||||
// later:
|
||||
//
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mean(const non_central_beta_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
RealType a = dist.alpha();
|
||||
RealType b = dist.beta();
|
||||
RealType d = dist.non_centrality();
|
||||
RealType apb = a + b;
|
||||
return exp(-d / 2) * a * detail::hypergeometric_2F2<RealType, Policy>(1 + a, apb, a, 1 + apb, d / 2, Policy()) / apb;
|
||||
} // mean
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType variance(const non_central_beta_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
//
|
||||
// Relative error of this function may be arbitarily large... absolute
|
||||
// error will be small however... that's the best we can do for now.
|
||||
//
|
||||
BOOST_MATH_STD_USING
|
||||
RealType a = dist.alpha();
|
||||
RealType b = dist.beta();
|
||||
RealType d = dist.non_centrality();
|
||||
RealType apb = a + b;
|
||||
RealType result = detail::hypergeometric_2F2(RealType(1 + a), apb, a, RealType(1 + apb), RealType(d / 2), Policy());
|
||||
result *= result * -exp(-d) * a * a / (apb * apb);
|
||||
result += exp(-d / 2) * a * (1 + a) * detail::hypergeometric_2F2(RealType(2 + a), apb, a, RealType(2 + apb), RealType(d / 2), Policy()) / (apb * (1 + apb));
|
||||
return result;
|
||||
}
|
||||
|
||||
// RealType standard_deviation(const non_central_beta_distribution<RealType, Policy>& dist)
|
||||
// standard_deviation provided by derived accessors.
|
||||
template <class RealType, class Policy>
|
||||
inline RealType skewness(const non_central_beta_distribution<RealType, Policy>& /*dist*/)
|
||||
{ // skewness = sqrt(l).
|
||||
const char* function = "boost::math::non_central_beta_distribution<%1%>::skewness()";
|
||||
typedef typename Policy::assert_undefined_type assert_type;
|
||||
BOOST_STATIC_ASSERT(assert_type::value == 0);
|
||||
|
||||
return policies::raise_evaluation_error<RealType>(
|
||||
function,
|
||||
"This function is not yet implemented, the only sensible result is %1%.",
|
||||
std::numeric_limits<RealType>::quiet_NaN(), Policy()); // infinity?
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis_excess(const non_central_beta_distribution<RealType, Policy>& /*dist*/)
|
||||
{
|
||||
const char* function = "boost::math::non_central_beta_distribution<%1%>::kurtosis_excess()";
|
||||
typedef typename Policy::assert_undefined_type assert_type;
|
||||
BOOST_STATIC_ASSERT(assert_type::value == 0);
|
||||
|
||||
return policies::raise_evaluation_error<RealType>(
|
||||
function,
|
||||
"This function is not yet implemented, the only sensible result is %1%.",
|
||||
std::numeric_limits<RealType>::quiet_NaN(), Policy()); // infinity?
|
||||
} // kurtosis_excess
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis(const non_central_beta_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
return kurtosis_excess(dist) + 3;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType pdf(const non_central_beta_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{ // Probability Density/Mass Function.
|
||||
return detail::nc_beta_pdf(dist, x);
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
RealType cdf(const non_central_beta_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
const char* function = "boost::math::non_central_beta_distribution<%1%>::cdf(%1%)";
|
||||
RealType a = dist.alpha();
|
||||
RealType b = dist.beta();
|
||||
RealType l = dist.non_centrality();
|
||||
RealType r;
|
||||
if(!beta_detail::check_alpha(
|
||||
function,
|
||||
a, &r, Policy())
|
||||
||
|
||||
!beta_detail::check_beta(
|
||||
function,
|
||||
b, &r, Policy())
|
||||
||
|
||||
!detail::check_non_centrality(
|
||||
function,
|
||||
l,
|
||||
&r,
|
||||
Policy())
|
||||
||
|
||||
!beta_detail::check_x(
|
||||
function,
|
||||
x,
|
||||
&r,
|
||||
Policy()))
|
||||
return (RealType)r;
|
||||
|
||||
if(l == 0)
|
||||
return cdf(beta_distribution<RealType, Policy>(a, b), x);
|
||||
|
||||
return detail::non_central_beta_cdf(x, RealType(1 - x), a, b, l, false, Policy());
|
||||
} // cdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
RealType cdf(const complemented2_type<non_central_beta_distribution<RealType, Policy>, RealType>& c)
|
||||
{ // Complemented Cumulative Distribution Function
|
||||
const char* function = "boost::math::non_central_beta_distribution<%1%>::cdf(%1%)";
|
||||
non_central_beta_distribution<RealType, Policy> const& dist = c.dist;
|
||||
RealType a = dist.alpha();
|
||||
RealType b = dist.beta();
|
||||
RealType l = dist.non_centrality();
|
||||
RealType x = c.param;
|
||||
RealType r;
|
||||
if(!beta_detail::check_alpha(
|
||||
function,
|
||||
a, &r, Policy())
|
||||
||
|
||||
!beta_detail::check_beta(
|
||||
function,
|
||||
b, &r, Policy())
|
||||
||
|
||||
!detail::check_non_centrality(
|
||||
function,
|
||||
l,
|
||||
&r,
|
||||
Policy())
|
||||
||
|
||||
!beta_detail::check_x(
|
||||
function,
|
||||
x,
|
||||
&r,
|
||||
Policy()))
|
||||
return (RealType)r;
|
||||
|
||||
if(l == 0)
|
||||
return cdf(complement(beta_distribution<RealType, Policy>(a, b), x));
|
||||
|
||||
return detail::non_central_beta_cdf(x, RealType(1 - x), a, b, l, true, Policy());
|
||||
} // ccdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const non_central_beta_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
{ // Quantile (or Percent Point) function.
|
||||
return detail::nc_beta_quantile(dist, p, false);
|
||||
} // quantile
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const complemented2_type<non_central_beta_distribution<RealType, Policy>, RealType>& c)
|
||||
{ // Quantile (or Percent Point) function.
|
||||
return detail::nc_beta_quantile(c.dist, c.param, true);
|
||||
} // quantile complement.
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
// This include must be at the end, *after* the accessors
|
||||
// for this distribution have been defined, in order to
|
||||
// keep compilers that support two-phase lookup happy.
|
||||
#include <boost/math/distributions/detail/derived_accessors.hpp>
|
||||
|
||||
#endif // BOOST_MATH_SPECIAL_NON_CENTRAL_BETA_HPP
|
||||
|
||||
963
test/external/boost/math/distributions/non_central_chi_squared.hpp
vendored
Normal file
963
test/external/boost/math/distributions/non_central_chi_squared.hpp
vendored
Normal file
@@ -0,0 +1,963 @@
|
||||
// boost\math\distributions\non_central_chi_squared.hpp
|
||||
|
||||
// Copyright John Maddock 2008.
|
||||
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_MATH_SPECIAL_NON_CENTRAL_CHI_SQUARE_HPP
|
||||
#define BOOST_MATH_SPECIAL_NON_CENTRAL_CHI_SQUARE_HPP
|
||||
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#include <boost/math/special_functions/gamma.hpp> // for incomplete gamma. gamma_q
|
||||
#include <boost/math/special_functions/bessel.hpp> // for cyl_bessel_i
|
||||
#include <boost/math/special_functions/round.hpp> // for iround
|
||||
#include <boost/math/distributions/complement.hpp> // complements
|
||||
#include <boost/math/distributions/chi_squared.hpp> // central distribution
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp> // error checks
|
||||
#include <boost/math/special_functions/fpclassify.hpp> // isnan.
|
||||
#include <boost/math/tools/roots.hpp> // for root finding.
|
||||
#include <boost/math/distributions/detail/generic_mode.hpp>
|
||||
#include <boost/math/distributions/detail/generic_quantile.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace math
|
||||
{
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class non_central_chi_squared_distribution;
|
||||
|
||||
namespace detail{
|
||||
|
||||
template <class T, class Policy>
|
||||
T non_central_chi_square_q(T x, T f, T theta, const Policy& pol, T init_sum = 0)
|
||||
{
|
||||
//
|
||||
// Computes the complement of the Non-Central Chi-Square
|
||||
// Distribution CDF by summing a weighted sum of complements
|
||||
// of the central-distributions. The weighting factor is
|
||||
// a Poisson Distribution.
|
||||
//
|
||||
// This is an application of the technique described in:
|
||||
//
|
||||
// Computing discrete mixtures of continuous
|
||||
// distributions: noncentral chisquare, noncentral t
|
||||
// and the distribution of the square of the sample
|
||||
// multiple correlation coeficient.
|
||||
// D. Benton, K. Krishnamoorthy.
|
||||
// Computational Statistics & Data Analysis 43 (2003) 249 - 267
|
||||
//
|
||||
BOOST_MATH_STD_USING
|
||||
|
||||
// Special case:
|
||||
if(x == 0)
|
||||
return 1;
|
||||
|
||||
//
|
||||
// Initialize the variables we'll be using:
|
||||
//
|
||||
T lambda = theta / 2;
|
||||
T del = f / 2;
|
||||
T y = x / 2;
|
||||
boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
|
||||
T errtol = boost::math::policies::get_epsilon<T, Policy>();
|
||||
T sum = init_sum;
|
||||
//
|
||||
// k is the starting location for iteration, we'll
|
||||
// move both forwards and backwards from this point.
|
||||
// k is chosen as the peek of the Poisson weights, which
|
||||
// will occur *before* the largest term.
|
||||
//
|
||||
int k = iround(lambda, pol);
|
||||
// Forwards and backwards Poisson weights:
|
||||
T poisf = boost::math::gamma_p_derivative(1 + k, lambda, pol);
|
||||
T poisb = poisf * k / lambda;
|
||||
// Initial forwards central chi squared term:
|
||||
T gamf = boost::math::gamma_q(del + k, y, pol);
|
||||
// Forwards and backwards recursion terms on the central chi squared:
|
||||
T xtermf = boost::math::gamma_p_derivative(del + 1 + k, y, pol);
|
||||
T xtermb = xtermf * (del + k) / y;
|
||||
// Initial backwards central chi squared term:
|
||||
T gamb = gamf - xtermb;
|
||||
|
||||
//
|
||||
// Forwards iteration first, this is the
|
||||
// stable direction for the gamma function
|
||||
// recurrences:
|
||||
//
|
||||
int i;
|
||||
for(i = k; static_cast<boost::uintmax_t>(i-k) < max_iter; ++i)
|
||||
{
|
||||
T term = poisf * gamf;
|
||||
sum += term;
|
||||
poisf *= lambda / (i + 1);
|
||||
gamf += xtermf;
|
||||
xtermf *= y / (del + i + 1);
|
||||
if(((sum == 0) || (fabs(term / sum) < errtol)) && (term >= poisf * gamf))
|
||||
break;
|
||||
}
|
||||
//Error check:
|
||||
if(static_cast<boost::uintmax_t>(i-k) >= max_iter)
|
||||
policies::raise_evaluation_error(
|
||||
"cdf(non_central_chi_squared_distribution<%1%>, %1%)",
|
||||
"Series did not converge, closest value was %1%", sum, pol);
|
||||
//
|
||||
// Now backwards iteration: the gamma
|
||||
// function recurrences are unstable in this
|
||||
// direction, we rely on the terms deminishing in size
|
||||
// faster than we introduce cancellation errors.
|
||||
// For this reason it's very important that we start
|
||||
// *before* the largest term so that backwards iteration
|
||||
// is strictly converging.
|
||||
//
|
||||
for(i = k - 1; i >= 0; --i)
|
||||
{
|
||||
T term = poisb * gamb;
|
||||
sum += term;
|
||||
poisb *= i / lambda;
|
||||
xtermb *= (del + i) / y;
|
||||
gamb -= xtermb;
|
||||
if((sum == 0) || (fabs(term / sum) < errtol))
|
||||
break;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
template <class T, class Policy>
|
||||
T non_central_chi_square_p_ding(T x, T f, T theta, const Policy& pol, T init_sum = 0)
|
||||
{
|
||||
//
|
||||
// This is an implementation of:
|
||||
//
|
||||
// Algorithm AS 275:
|
||||
// Computing the Non-Central #2 Distribution Function
|
||||
// Cherng G. Ding
|
||||
// Applied Statistics, Vol. 41, No. 2. (1992), pp. 478-482.
|
||||
//
|
||||
// This uses a stable forward iteration to sum the
|
||||
// CDF, unfortunately this can not be used for large
|
||||
// values of the non-centrality parameter because:
|
||||
// * The first term may underfow to zero.
|
||||
// * We may need an extra-ordinary number of terms
|
||||
// before we reach the first *significant* term.
|
||||
//
|
||||
BOOST_MATH_STD_USING
|
||||
// Special case:
|
||||
if(x == 0)
|
||||
return 0;
|
||||
T tk = boost::math::gamma_p_derivative(f/2 + 1, x/2, pol);
|
||||
T lambda = theta / 2;
|
||||
T vk = exp(-lambda);
|
||||
T uk = vk;
|
||||
T sum = init_sum + tk * vk;
|
||||
if(sum == 0)
|
||||
return sum;
|
||||
|
||||
boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
|
||||
T errtol = boost::math::policies::get_epsilon<T, Policy>();
|
||||
|
||||
int i;
|
||||
T lterm(0), term(0);
|
||||
for(i = 1; static_cast<boost::uintmax_t>(i) < max_iter; ++i)
|
||||
{
|
||||
tk = tk * x / (f + 2 * i);
|
||||
uk = uk * lambda / i;
|
||||
vk = vk + uk;
|
||||
lterm = term;
|
||||
term = vk * tk;
|
||||
sum += term;
|
||||
if((fabs(term / sum) < errtol) && (term <= lterm))
|
||||
break;
|
||||
}
|
||||
//Error check:
|
||||
if(static_cast<boost::uintmax_t>(i) >= max_iter)
|
||||
policies::raise_evaluation_error(
|
||||
"cdf(non_central_chi_squared_distribution<%1%>, %1%)",
|
||||
"Series did not converge, closest value was %1%", sum, pol);
|
||||
return sum;
|
||||
}
|
||||
|
||||
|
||||
template <class T, class Policy>
|
||||
T non_central_chi_square_p(T y, T n, T lambda, const Policy& pol, T init_sum)
|
||||
{
|
||||
//
|
||||
// This is taken more or less directly from:
|
||||
//
|
||||
// Computing discrete mixtures of continuous
|
||||
// distributions: noncentral chisquare, noncentral t
|
||||
// and the distribution of the square of the sample
|
||||
// multiple correlation coeficient.
|
||||
// D. Benton, K. Krishnamoorthy.
|
||||
// Computational Statistics & Data Analysis 43 (2003) 249 - 267
|
||||
//
|
||||
// We're summing a Poisson weighting term multiplied by
|
||||
// a central chi squared distribution.
|
||||
//
|
||||
BOOST_MATH_STD_USING
|
||||
// Special case:
|
||||
if(y == 0)
|
||||
return 0;
|
||||
boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
|
||||
T errtol = boost::math::policies::get_epsilon<T, Policy>();
|
||||
T errorf(0), errorb(0);
|
||||
|
||||
T x = y / 2;
|
||||
T del = lambda / 2;
|
||||
//
|
||||
// Starting location for the iteration, we'll iterate
|
||||
// both forwards and backwards from this point. The
|
||||
// location chosen is the maximum of the Poisson weight
|
||||
// function, which ocurrs *after* the largest term in the
|
||||
// sum.
|
||||
//
|
||||
int k = iround(del, pol);
|
||||
T a = n / 2 + k;
|
||||
// Central chi squared term for forward iteration:
|
||||
T gamkf = boost::math::gamma_p(a, x, pol);
|
||||
|
||||
if(lambda == 0)
|
||||
return gamkf;
|
||||
// Central chi squared term for backward iteration:
|
||||
T gamkb = gamkf;
|
||||
// Forwards Poisson weight:
|
||||
T poiskf = gamma_p_derivative(k+1, del, pol);
|
||||
// Backwards Poisson weight:
|
||||
T poiskb = poiskf;
|
||||
// Forwards gamma function recursion term:
|
||||
T xtermf = boost::math::gamma_p_derivative(a, x, pol);
|
||||
// Backwards gamma function recursion term:
|
||||
T xtermb = xtermf * x / a;
|
||||
T sum = init_sum + poiskf * gamkf;
|
||||
if(sum == 0)
|
||||
return sum;
|
||||
int i = 1;
|
||||
//
|
||||
// Backwards recursion first, this is the stable
|
||||
// direction for gamma function recurrences:
|
||||
//
|
||||
while(i <= k)
|
||||
{
|
||||
xtermb *= (a - i + 1) / x;
|
||||
gamkb += xtermb;
|
||||
poiskb = poiskb * (k - i + 1) / del;
|
||||
errorf = errorb;
|
||||
errorb = gamkb * poiskb;
|
||||
sum += errorb;
|
||||
if((fabs(errorb / sum) < errtol) && (errorb <= errorf))
|
||||
break;
|
||||
++i;
|
||||
}
|
||||
i = 1;
|
||||
//
|
||||
// Now forwards recursion, the gamma function
|
||||
// recurrence relation is unstable in this direction,
|
||||
// so we rely on the magnitude of successive terms
|
||||
// decreasing faster than we introduce cancellation error.
|
||||
// For this reason it's vital that k is chosen to be *after*
|
||||
// the largest term, so that successive forward iterations
|
||||
// are strictly (and rapidly) converging.
|
||||
//
|
||||
do
|
||||
{
|
||||
xtermf = xtermf * x / (a + i - 1);
|
||||
gamkf = gamkf - xtermf;
|
||||
poiskf = poiskf * del / (k + i);
|
||||
errorf = poiskf * gamkf;
|
||||
sum += errorf;
|
||||
++i;
|
||||
}while((fabs(errorf / sum) > errtol) && (static_cast<boost::uintmax_t>(i) < max_iter));
|
||||
|
||||
//Error check:
|
||||
if(static_cast<boost::uintmax_t>(i) >= max_iter)
|
||||
policies::raise_evaluation_error(
|
||||
"cdf(non_central_chi_squared_distribution<%1%>, %1%)",
|
||||
"Series did not converge, closest value was %1%", sum, pol);
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
template <class T, class Policy>
|
||||
T non_central_chi_square_pdf(T x, T n, T lambda, const Policy& pol)
|
||||
{
|
||||
//
|
||||
// As above but for the PDF:
|
||||
//
|
||||
BOOST_MATH_STD_USING
|
||||
boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
|
||||
T errtol = boost::math::policies::get_epsilon<T, Policy>();
|
||||
T x2 = x / 2;
|
||||
T n2 = n / 2;
|
||||
T l2 = lambda / 2;
|
||||
T sum = 0;
|
||||
int k = itrunc(l2);
|
||||
T pois = gamma_p_derivative(k + 1, l2, pol) * gamma_p_derivative(n2 + k, x2);
|
||||
if(pois == 0)
|
||||
return 0;
|
||||
T poisb = pois;
|
||||
for(int i = k; ; ++i)
|
||||
{
|
||||
sum += pois;
|
||||
if(pois / sum < errtol)
|
||||
break;
|
||||
if(static_cast<boost::uintmax_t>(i - k) >= max_iter)
|
||||
return policies::raise_evaluation_error(
|
||||
"pdf(non_central_chi_squared_distribution<%1%>, %1%)",
|
||||
"Series did not converge, closest value was %1%", sum, pol);
|
||||
pois *= l2 * x2 / ((i + 1) * (n2 + i));
|
||||
}
|
||||
for(int i = k - 1; i >= 0; --i)
|
||||
{
|
||||
poisb *= (i + 1) * (n2 + i) / (l2 * x2);
|
||||
sum += poisb;
|
||||
if(poisb / sum < errtol)
|
||||
break;
|
||||
}
|
||||
return sum / 2;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType non_central_chi_squared_cdf(RealType x, RealType k, RealType l, bool invert, const Policy&)
|
||||
{
|
||||
typedef typename policies::evaluation<RealType, Policy>::type value_type;
|
||||
typedef typename policies::normalise<
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
policies::discrete_quantile<>,
|
||||
policies::assert_undefined<> >::type forwarding_policy;
|
||||
|
||||
BOOST_MATH_STD_USING
|
||||
value_type result;
|
||||
if(l == 0)
|
||||
result = cdf(boost::math::chi_squared_distribution<RealType, Policy>(k), x);
|
||||
else if(x > k + l)
|
||||
{
|
||||
// Complement is the smaller of the two:
|
||||
result = detail::non_central_chi_square_q(
|
||||
static_cast<value_type>(x),
|
||||
static_cast<value_type>(k),
|
||||
static_cast<value_type>(l),
|
||||
forwarding_policy(),
|
||||
static_cast<value_type>(invert ? 0 : -1));
|
||||
invert = !invert;
|
||||
}
|
||||
else if(l < 200)
|
||||
{
|
||||
// For small values of the non-centrality parameter
|
||||
// we can use Ding's method:
|
||||
result = detail::non_central_chi_square_p_ding(
|
||||
static_cast<value_type>(x),
|
||||
static_cast<value_type>(k),
|
||||
static_cast<value_type>(l),
|
||||
forwarding_policy(),
|
||||
static_cast<value_type>(invert ? -1 : 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
// For largers values of the non-centrality
|
||||
// parameter Ding's method will consume an
|
||||
// extra-ordinary number of terms, and worse
|
||||
// may return zero when the result is in fact
|
||||
// finite, use Krishnamoorthy's method instead:
|
||||
result = detail::non_central_chi_square_p(
|
||||
static_cast<value_type>(x),
|
||||
static_cast<value_type>(k),
|
||||
static_cast<value_type>(l),
|
||||
forwarding_policy(),
|
||||
static_cast<value_type>(invert ? -1 : 0));
|
||||
}
|
||||
if(invert)
|
||||
result = -result;
|
||||
return policies::checked_narrowing_cast<RealType, forwarding_policy>(
|
||||
result,
|
||||
"boost::math::non_central_chi_squared_cdf<%1%>(%1%, %1%, %1%)");
|
||||
}
|
||||
|
||||
template <class T, class Policy>
|
||||
struct nccs_quantile_functor
|
||||
{
|
||||
nccs_quantile_functor(const non_central_chi_squared_distribution<T,Policy>& d, T t, bool c)
|
||||
: dist(d), target(t), comp(c) {}
|
||||
|
||||
T operator()(const T& x)
|
||||
{
|
||||
return comp ?
|
||||
target - cdf(complement(dist, x))
|
||||
: cdf(dist, x) - target;
|
||||
}
|
||||
|
||||
private:
|
||||
non_central_chi_squared_distribution<T,Policy> dist;
|
||||
T target;
|
||||
bool comp;
|
||||
};
|
||||
|
||||
template <class RealType, class Policy>
|
||||
RealType nccs_quantile(const non_central_chi_squared_distribution<RealType, Policy>& dist, const RealType& p, bool comp)
|
||||
{
|
||||
static const char* function = "quantile(non_central_chi_squared_distribution<%1%>, %1%)";
|
||||
typedef typename policies::evaluation<RealType, Policy>::type value_type;
|
||||
typedef typename policies::normalise<
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
policies::discrete_quantile<>,
|
||||
policies::assert_undefined<> >::type forwarding_policy;
|
||||
|
||||
value_type k = dist.degrees_of_freedom();
|
||||
value_type l = dist.non_centrality();
|
||||
value_type r;
|
||||
if(!detail::check_df(
|
||||
function,
|
||||
k, &r, Policy())
|
||||
||
|
||||
!detail::check_non_centrality(
|
||||
function,
|
||||
l,
|
||||
&r,
|
||||
Policy())
|
||||
||
|
||||
!detail::check_probability(
|
||||
function,
|
||||
static_cast<value_type>(p),
|
||||
&r,
|
||||
Policy()))
|
||||
return (RealType)r;
|
||||
|
||||
value_type b = (l * l) / (k + 3 * l);
|
||||
value_type c = (k + 3 * l) / (k + 2 * l);
|
||||
value_type ff = (k + 2 * l) / (c * c);
|
||||
value_type guess;
|
||||
if(comp)
|
||||
guess = b + c * quantile(complement(chi_squared_distribution<value_type, forwarding_policy>(ff), p));
|
||||
else
|
||||
guess = b + c * quantile(chi_squared_distribution<value_type, forwarding_policy>(ff), p);
|
||||
|
||||
if(guess < 0)
|
||||
guess = tools::min_value<value_type>();
|
||||
|
||||
value_type result = detail::generic_quantile(
|
||||
non_central_chi_squared_distribution<value_type, forwarding_policy>(k, l),
|
||||
p,
|
||||
guess,
|
||||
comp,
|
||||
function);
|
||||
return policies::checked_narrowing_cast<RealType, forwarding_policy>(
|
||||
result,
|
||||
function);
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
RealType nccs_pdf(const non_central_chi_squared_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
static const char* function = "pdf(non_central_chi_squared_distribution<%1%>, %1%)";
|
||||
typedef typename policies::evaluation<RealType, Policy>::type value_type;
|
||||
typedef typename policies::normalise<
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
policies::discrete_quantile<>,
|
||||
policies::assert_undefined<> >::type forwarding_policy;
|
||||
|
||||
value_type k = dist.degrees_of_freedom();
|
||||
value_type l = dist.non_centrality();
|
||||
value_type r;
|
||||
if(!detail::check_df(
|
||||
function,
|
||||
k, &r, Policy())
|
||||
||
|
||||
!detail::check_non_centrality(
|
||||
function,
|
||||
l,
|
||||
&r,
|
||||
Policy())
|
||||
||
|
||||
!detail::check_positive_x(
|
||||
function,
|
||||
(value_type)x,
|
||||
&r,
|
||||
Policy()))
|
||||
return (RealType)r;
|
||||
|
||||
if(l == 0)
|
||||
return pdf(boost::math::chi_squared_distribution<RealType, forwarding_policy>(dist.degrees_of_freedom()), x);
|
||||
|
||||
// Special case:
|
||||
if(x == 0)
|
||||
return 0;
|
||||
if(l > 50)
|
||||
{
|
||||
r = non_central_chi_square_pdf(static_cast<value_type>(x), k, l, forwarding_policy());
|
||||
}
|
||||
else
|
||||
{
|
||||
r = log(x / l) * (k / 4 - 0.5f) - (x + l) / 2;
|
||||
if(fabs(r) >= tools::log_max_value<RealType>() / 4)
|
||||
{
|
||||
r = non_central_chi_square_pdf(static_cast<value_type>(x), k, l, forwarding_policy());
|
||||
}
|
||||
else
|
||||
{
|
||||
r = exp(r);
|
||||
r = 0.5f * r
|
||||
* boost::math::cyl_bessel_i(k/2 - 1, sqrt(l * x), forwarding_policy());
|
||||
}
|
||||
}
|
||||
return policies::checked_narrowing_cast<RealType, forwarding_policy>(
|
||||
r,
|
||||
function);
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
struct degrees_of_freedom_finder
|
||||
{
|
||||
degrees_of_freedom_finder(
|
||||
RealType lam_, RealType x_, RealType p_, bool c)
|
||||
: lam(lam_), x(x_), p(p_), comp(c) {}
|
||||
|
||||
RealType operator()(const RealType& v)
|
||||
{
|
||||
non_central_chi_squared_distribution<RealType, Policy> d(v, lam);
|
||||
return comp ?
|
||||
RealType(p - cdf(complement(d, x)))
|
||||
: RealType(cdf(d, x) - p);
|
||||
}
|
||||
private:
|
||||
RealType lam;
|
||||
RealType x;
|
||||
RealType p;
|
||||
bool comp;
|
||||
};
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType find_degrees_of_freedom(
|
||||
RealType lam, RealType x, RealType p, RealType q, const Policy& pol)
|
||||
{
|
||||
const char* function = "non_central_chi_squared<%1%>::find_degrees_of_freedom";
|
||||
if((p == 0) || (q == 0))
|
||||
{
|
||||
//
|
||||
// Can't a thing if one of p and q is zero:
|
||||
//
|
||||
return policies::raise_evaluation_error<RealType>(function,
|
||||
"Can't find degrees of freedom when the probability is 0 or 1, only possible answer is %1%",
|
||||
RealType(std::numeric_limits<RealType>::quiet_NaN()), Policy());
|
||||
}
|
||||
degrees_of_freedom_finder<RealType, Policy> f(lam, x, p < q ? p : q, p < q ? false : true);
|
||||
tools::eps_tolerance<RealType> tol(policies::digits<RealType, Policy>());
|
||||
boost::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
|
||||
//
|
||||
// Pick an initial guess that we know will give us a probability
|
||||
// right around 0.5.
|
||||
//
|
||||
RealType guess = x - lam;
|
||||
if(guess < 1)
|
||||
guess = 1;
|
||||
std::pair<RealType, RealType> ir = tools::bracket_and_solve_root(
|
||||
f, guess, RealType(2), false, tol, max_iter, pol);
|
||||
RealType result = ir.first + (ir.second - ir.first) / 2;
|
||||
if(max_iter >= policies::get_max_root_iterations<Policy>())
|
||||
{
|
||||
policies::raise_evaluation_error<RealType>(function, "Unable to locate solution in a reasonable time:"
|
||||
" or there is no answer to problem. Current best guess is %1%", result, Policy());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
struct non_centrality_finder
|
||||
{
|
||||
non_centrality_finder(
|
||||
RealType v_, RealType x_, RealType p_, bool c)
|
||||
: v(v_), x(x_), p(p_), comp(c) {}
|
||||
|
||||
RealType operator()(const RealType& lam)
|
||||
{
|
||||
non_central_chi_squared_distribution<RealType, Policy> d(v, lam);
|
||||
return comp ?
|
||||
RealType(p - cdf(complement(d, x)))
|
||||
: RealType(cdf(d, x) - p);
|
||||
}
|
||||
private:
|
||||
RealType v;
|
||||
RealType x;
|
||||
RealType p;
|
||||
bool comp;
|
||||
};
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType find_non_centrality(
|
||||
RealType v, RealType x, RealType p, RealType q, const Policy& pol)
|
||||
{
|
||||
const char* function = "non_central_chi_squared<%1%>::find_non_centrality";
|
||||
if((p == 0) || (q == 0))
|
||||
{
|
||||
//
|
||||
// Can't do a thing if one of p and q is zero:
|
||||
//
|
||||
return policies::raise_evaluation_error<RealType>(function,
|
||||
"Can't find non centrality parameter when the probability is 0 or 1, only possible answer is %1%",
|
||||
RealType(std::numeric_limits<RealType>::quiet_NaN()), Policy());
|
||||
}
|
||||
non_centrality_finder<RealType, Policy> f(v, x, p < q ? p : q, p < q ? false : true);
|
||||
tools::eps_tolerance<RealType> tol(policies::digits<RealType, Policy>());
|
||||
boost::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
|
||||
//
|
||||
// Pick an initial guess that we know will give us a probability
|
||||
// right around 0.5.
|
||||
//
|
||||
RealType guess = x - v;
|
||||
if(guess < 1)
|
||||
guess = 1;
|
||||
std::pair<RealType, RealType> ir = tools::bracket_and_solve_root(
|
||||
f, guess, RealType(2), false, tol, max_iter, pol);
|
||||
RealType result = ir.first + (ir.second - ir.first) / 2;
|
||||
if(max_iter >= policies::get_max_root_iterations<Policy>())
|
||||
{
|
||||
policies::raise_evaluation_error<RealType>(function, "Unable to locate solution in a reasonable time:"
|
||||
" or there is no answer to problem. Current best guess is %1%", result, Policy());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template <class RealType = double, class Policy = policies::policy<> >
|
||||
class non_central_chi_squared_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
|
||||
non_central_chi_squared_distribution(RealType df_, RealType lambda) : df(df_), ncp(lambda)
|
||||
{
|
||||
const char* function = "boost::math::non_central_chi_squared_distribution<%1%>::non_central_chi_squared_distribution(%1%,%1%)";
|
||||
RealType r;
|
||||
detail::check_df(
|
||||
function,
|
||||
df, &r, Policy());
|
||||
detail::check_non_centrality(
|
||||
function,
|
||||
ncp,
|
||||
&r,
|
||||
Policy());
|
||||
} // non_central_chi_squared_distribution constructor.
|
||||
|
||||
RealType degrees_of_freedom() const
|
||||
{ // Private data getter function.
|
||||
return df;
|
||||
}
|
||||
RealType non_centrality() const
|
||||
{ // Private data getter function.
|
||||
return ncp;
|
||||
}
|
||||
static RealType find_degrees_of_freedom(RealType lam, RealType x, RealType p)
|
||||
{
|
||||
const char* function = "non_central_chi_squared<%1%>::find_degrees_of_freedom";
|
||||
typedef typename policies::evaluation<RealType, Policy>::type value_type;
|
||||
typedef typename policies::normalise<
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
policies::discrete_quantile<>,
|
||||
policies::assert_undefined<> >::type forwarding_policy;
|
||||
value_type result = detail::find_degrees_of_freedom(
|
||||
static_cast<value_type>(lam),
|
||||
static_cast<value_type>(x),
|
||||
static_cast<value_type>(p),
|
||||
static_cast<value_type>(1-p),
|
||||
forwarding_policy());
|
||||
return policies::checked_narrowing_cast<RealType, forwarding_policy>(
|
||||
result,
|
||||
function);
|
||||
}
|
||||
template <class A, class B, class C>
|
||||
static RealType find_degrees_of_freedom(const complemented3_type<A,B,C>& c)
|
||||
{
|
||||
const char* function = "non_central_chi_squared<%1%>::find_degrees_of_freedom";
|
||||
typedef typename policies::evaluation<RealType, Policy>::type value_type;
|
||||
typedef typename policies::normalise<
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
policies::discrete_quantile<>,
|
||||
policies::assert_undefined<> >::type forwarding_policy;
|
||||
value_type result = detail::find_degrees_of_freedom(
|
||||
static_cast<value_type>(c.dist),
|
||||
static_cast<value_type>(c.param1),
|
||||
static_cast<value_type>(1-c.param2),
|
||||
static_cast<value_type>(c.param2),
|
||||
forwarding_policy());
|
||||
return policies::checked_narrowing_cast<RealType, forwarding_policy>(
|
||||
result,
|
||||
function);
|
||||
}
|
||||
static RealType find_non_centrality(RealType v, RealType x, RealType p)
|
||||
{
|
||||
const char* function = "non_central_chi_squared<%1%>::find_non_centrality";
|
||||
typedef typename policies::evaluation<RealType, Policy>::type value_type;
|
||||
typedef typename policies::normalise<
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
policies::discrete_quantile<>,
|
||||
policies::assert_undefined<> >::type forwarding_policy;
|
||||
value_type result = detail::find_non_centrality(
|
||||
static_cast<value_type>(v),
|
||||
static_cast<value_type>(x),
|
||||
static_cast<value_type>(p),
|
||||
static_cast<value_type>(1-p),
|
||||
forwarding_policy());
|
||||
return policies::checked_narrowing_cast<RealType, forwarding_policy>(
|
||||
result,
|
||||
function);
|
||||
}
|
||||
template <class A, class B, class C>
|
||||
static RealType find_non_centrality(const complemented3_type<A,B,C>& c)
|
||||
{
|
||||
const char* function = "non_central_chi_squared<%1%>::find_non_centrality";
|
||||
typedef typename policies::evaluation<RealType, Policy>::type value_type;
|
||||
typedef typename policies::normalise<
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
policies::discrete_quantile<>,
|
||||
policies::assert_undefined<> >::type forwarding_policy;
|
||||
value_type result = detail::find_non_centrality(
|
||||
static_cast<value_type>(c.dist),
|
||||
static_cast<value_type>(c.param1),
|
||||
static_cast<value_type>(1-c.param2),
|
||||
static_cast<value_type>(c.param2),
|
||||
forwarding_policy());
|
||||
return policies::checked_narrowing_cast<RealType, forwarding_policy>(
|
||||
result,
|
||||
function);
|
||||
}
|
||||
private:
|
||||
// Data member, initialized by constructor.
|
||||
RealType df; // degrees of freedom.
|
||||
RealType ncp; // non-centrality parameter
|
||||
}; // template <class RealType, class Policy> class non_central_chi_squared_distribution
|
||||
|
||||
typedef non_central_chi_squared_distribution<double> non_central_chi_squared; // Reserved name of type double.
|
||||
|
||||
// Non-member functions to give properties of the distribution.
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const non_central_chi_squared_distribution<RealType, Policy>& /* dist */)
|
||||
{ // Range of permissible values for random variable k.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>()); // Max integer?
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> support(const non_central_chi_squared_distribution<RealType, Policy>& /* dist */)
|
||||
{ // Range of supported values for random variable k.
|
||||
// This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mean(const non_central_chi_squared_distribution<RealType, Policy>& dist)
|
||||
{ // Mean of poisson distribution = lambda.
|
||||
const char* function = "boost::math::non_central_chi_squared_distribution<%1%>::mean()";
|
||||
RealType k = dist.degrees_of_freedom();
|
||||
RealType l = dist.non_centrality();
|
||||
RealType r;
|
||||
if(!detail::check_df(
|
||||
function,
|
||||
k, &r, Policy())
|
||||
||
|
||||
!detail::check_non_centrality(
|
||||
function,
|
||||
l,
|
||||
&r,
|
||||
Policy()))
|
||||
return r;
|
||||
return k + l;
|
||||
} // mean
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mode(const non_central_chi_squared_distribution<RealType, Policy>& dist)
|
||||
{ // mode.
|
||||
static const char* function = "mode(non_central_chi_squared_distribution<%1%> const&)";
|
||||
|
||||
RealType k = dist.degrees_of_freedom();
|
||||
RealType l = dist.non_centrality();
|
||||
RealType r;
|
||||
if(!detail::check_df(
|
||||
function,
|
||||
k, &r, Policy())
|
||||
||
|
||||
!detail::check_non_centrality(
|
||||
function,
|
||||
l,
|
||||
&r,
|
||||
Policy()))
|
||||
return (RealType)r;
|
||||
return detail::generic_find_mode(dist, 1 + k, function);
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType variance(const non_central_chi_squared_distribution<RealType, Policy>& dist)
|
||||
{ // variance.
|
||||
const char* function = "boost::math::non_central_chi_squared_distribution<%1%>::variance()";
|
||||
RealType k = dist.degrees_of_freedom();
|
||||
RealType l = dist.non_centrality();
|
||||
RealType r;
|
||||
if(!detail::check_df(
|
||||
function,
|
||||
k, &r, Policy())
|
||||
||
|
||||
!detail::check_non_centrality(
|
||||
function,
|
||||
l,
|
||||
&r,
|
||||
Policy()))
|
||||
return r;
|
||||
return 2 * (2 * l + k);
|
||||
}
|
||||
|
||||
// RealType standard_deviation(const non_central_chi_squared_distribution<RealType, Policy>& dist)
|
||||
// standard_deviation provided by derived accessors.
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType skewness(const non_central_chi_squared_distribution<RealType, Policy>& dist)
|
||||
{ // skewness = sqrt(l).
|
||||
const char* function = "boost::math::non_central_chi_squared_distribution<%1%>::skewness()";
|
||||
RealType k = dist.degrees_of_freedom();
|
||||
RealType l = dist.non_centrality();
|
||||
RealType r;
|
||||
if(!detail::check_df(
|
||||
function,
|
||||
k, &r, Policy())
|
||||
||
|
||||
!detail::check_non_centrality(
|
||||
function,
|
||||
l,
|
||||
&r,
|
||||
Policy()))
|
||||
return r;
|
||||
BOOST_MATH_STD_USING
|
||||
return pow(2 / (k + 2 * l), RealType(3)/2) * (k + 3 * l);
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis_excess(const non_central_chi_squared_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
const char* function = "boost::math::non_central_chi_squared_distribution<%1%>::kurtosis_excess()";
|
||||
RealType k = dist.degrees_of_freedom();
|
||||
RealType l = dist.non_centrality();
|
||||
RealType r;
|
||||
if(!detail::check_df(
|
||||
function,
|
||||
k, &r, Policy())
|
||||
||
|
||||
!detail::check_non_centrality(
|
||||
function,
|
||||
l,
|
||||
&r,
|
||||
Policy()))
|
||||
return r;
|
||||
return 12 * (k + 4 * l) / ((k + 2 * l) * (k + 2 * l));
|
||||
} // kurtosis_excess
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis(const non_central_chi_squared_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
return kurtosis_excess(dist) + 3;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType pdf(const non_central_chi_squared_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{ // Probability Density/Mass Function.
|
||||
return detail::nccs_pdf(dist, x);
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
RealType cdf(const non_central_chi_squared_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
const char* function = "boost::math::non_central_chi_squared_distribution<%1%>::cdf(%1%)";
|
||||
RealType k = dist.degrees_of_freedom();
|
||||
RealType l = dist.non_centrality();
|
||||
RealType r;
|
||||
if(!detail::check_df(
|
||||
function,
|
||||
k, &r, Policy())
|
||||
||
|
||||
!detail::check_non_centrality(
|
||||
function,
|
||||
l,
|
||||
&r,
|
||||
Policy())
|
||||
||
|
||||
!detail::check_positive_x(
|
||||
function,
|
||||
x,
|
||||
&r,
|
||||
Policy()))
|
||||
return r;
|
||||
|
||||
return detail::non_central_chi_squared_cdf(x, k, l, false, Policy());
|
||||
} // cdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
RealType cdf(const complemented2_type<non_central_chi_squared_distribution<RealType, Policy>, RealType>& c)
|
||||
{ // Complemented Cumulative Distribution Function
|
||||
const char* function = "boost::math::non_central_chi_squared_distribution<%1%>::cdf(%1%)";
|
||||
non_central_chi_squared_distribution<RealType, Policy> const& dist = c.dist;
|
||||
RealType x = c.param;
|
||||
RealType k = dist.degrees_of_freedom();
|
||||
RealType l = dist.non_centrality();
|
||||
RealType r;
|
||||
if(!detail::check_df(
|
||||
function,
|
||||
k, &r, Policy())
|
||||
||
|
||||
!detail::check_non_centrality(
|
||||
function,
|
||||
l,
|
||||
&r,
|
||||
Policy())
|
||||
||
|
||||
!detail::check_positive_x(
|
||||
function,
|
||||
x,
|
||||
&r,
|
||||
Policy()))
|
||||
return r;
|
||||
|
||||
return detail::non_central_chi_squared_cdf(x, k, l, true, Policy());
|
||||
} // ccdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const non_central_chi_squared_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
{ // Quantile (or Percent Point) function.
|
||||
return detail::nccs_quantile(dist, p, false);
|
||||
} // quantile
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const complemented2_type<non_central_chi_squared_distribution<RealType, Policy>, RealType>& c)
|
||||
{ // Quantile (or Percent Point) function.
|
||||
return detail::nccs_quantile(c.dist, c.param, true);
|
||||
} // quantile complement.
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
// This include must be at the end, *after* the accessors
|
||||
// for this distribution have been defined, in order to
|
||||
// keep compilers that support two-phase lookup happy.
|
||||
#include <boost/math/distributions/detail/derived_accessors.hpp>
|
||||
|
||||
#endif // BOOST_MATH_SPECIAL_NON_CENTRAL_CHI_SQUARE_HPP
|
||||
|
||||
|
||||
|
||||
409
test/external/boost/math/distributions/non_central_f.hpp
vendored
Normal file
409
test/external/boost/math/distributions/non_central_f.hpp
vendored
Normal file
@@ -0,0 +1,409 @@
|
||||
// boost\math\distributions\non_central_f.hpp
|
||||
|
||||
// Copyright John Maddock 2008.
|
||||
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_MATH_SPECIAL_NON_CENTRAL_F_HPP
|
||||
#define BOOST_MATH_SPECIAL_NON_CENTRAL_F_HPP
|
||||
|
||||
#include <boost/math/distributions/non_central_beta.hpp>
|
||||
#include <boost/math/distributions/detail/generic_mode.hpp>
|
||||
#include <boost/math/special_functions/pow.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace math
|
||||
{
|
||||
template <class RealType = double, class Policy = policies::policy<> >
|
||||
class non_central_f_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
|
||||
non_central_f_distribution(RealType v1_, RealType v2_, RealType lambda) : v1(v1_), v2(v2_), ncp(lambda)
|
||||
{
|
||||
const char* function = "boost::math::non_central_f_distribution<%1%>::non_central_f_distribution(%1%,%1%)";
|
||||
RealType r;
|
||||
detail::check_df(
|
||||
function,
|
||||
v1, &r, Policy());
|
||||
detail::check_df(
|
||||
function,
|
||||
v2, &r, Policy());
|
||||
detail::check_non_centrality(
|
||||
function,
|
||||
lambda,
|
||||
&r,
|
||||
Policy());
|
||||
} // non_central_f_distribution constructor.
|
||||
|
||||
RealType degrees_of_freedom1()const
|
||||
{
|
||||
return v1;
|
||||
}
|
||||
RealType degrees_of_freedom2()const
|
||||
{
|
||||
return v2;
|
||||
}
|
||||
RealType non_centrality() const
|
||||
{ // Private data getter function.
|
||||
return ncp;
|
||||
}
|
||||
private:
|
||||
// Data member, initialized by constructor.
|
||||
RealType v1; // alpha.
|
||||
RealType v2; // beta.
|
||||
RealType ncp; // non-centrality parameter
|
||||
}; // template <class RealType, class Policy> class non_central_f_distribution
|
||||
|
||||
typedef non_central_f_distribution<double> non_central_f; // Reserved name of type double.
|
||||
|
||||
// Non-member functions to give properties of the distribution.
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const non_central_f_distribution<RealType, Policy>& /* dist */)
|
||||
{ // Range of permissible values for random variable k.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> support(const non_central_f_distribution<RealType, Policy>& /* dist */)
|
||||
{ // Range of supported values for random variable k.
|
||||
// This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mean(const non_central_f_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
const char* function = "mean(non_central_f_distribution<%1%> const&)";
|
||||
RealType v1 = dist.degrees_of_freedom1();
|
||||
RealType v2 = dist.degrees_of_freedom2();
|
||||
RealType l = dist.non_centrality();
|
||||
RealType r;
|
||||
if(!detail::check_df(
|
||||
function,
|
||||
v1, &r, Policy())
|
||||
||
|
||||
!detail::check_df(
|
||||
function,
|
||||
v2, &r, Policy())
|
||||
||
|
||||
!detail::check_non_centrality(
|
||||
function,
|
||||
l,
|
||||
&r,
|
||||
Policy()))
|
||||
return r;
|
||||
if(v2 <= 2)
|
||||
return policies::raise_domain_error(
|
||||
function,
|
||||
"Second degrees of freedom parameter was %1%, but must be > 2 !",
|
||||
v2, Policy());
|
||||
return v2 * (v1 + l) / (v1 * (v2 - 2));
|
||||
} // mean
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mode(const non_central_f_distribution<RealType, Policy>& dist)
|
||||
{ // mode.
|
||||
static const char* function = "mode(non_central_chi_squared_distribution<%1%> const&)";
|
||||
|
||||
RealType n = dist.degrees_of_freedom1();
|
||||
RealType m = dist.degrees_of_freedom2();
|
||||
RealType l = dist.non_centrality();
|
||||
RealType r;
|
||||
if(!detail::check_df(
|
||||
function,
|
||||
n, &r, Policy())
|
||||
||
|
||||
!detail::check_df(
|
||||
function,
|
||||
m, &r, Policy())
|
||||
||
|
||||
!detail::check_non_centrality(
|
||||
function,
|
||||
l,
|
||||
&r,
|
||||
Policy()))
|
||||
return r;
|
||||
return detail::generic_find_mode(
|
||||
dist,
|
||||
m * (n + l) / (n * (m - 2)),
|
||||
function);
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType variance(const non_central_f_distribution<RealType, Policy>& dist)
|
||||
{ // variance.
|
||||
const char* function = "variance(non_central_f_distribution<%1%> const&)";
|
||||
RealType n = dist.degrees_of_freedom1();
|
||||
RealType m = dist.degrees_of_freedom2();
|
||||
RealType l = dist.non_centrality();
|
||||
RealType r;
|
||||
if(!detail::check_df(
|
||||
function,
|
||||
n, &r, Policy())
|
||||
||
|
||||
!detail::check_df(
|
||||
function,
|
||||
m, &r, Policy())
|
||||
||
|
||||
!detail::check_non_centrality(
|
||||
function,
|
||||
l,
|
||||
&r,
|
||||
Policy()))
|
||||
return r;
|
||||
if(m <= 4)
|
||||
return policies::raise_domain_error(
|
||||
function,
|
||||
"Second degrees of freedom parameter was %1%, but must be > 4 !",
|
||||
m, Policy());
|
||||
RealType result = 2 * m * m * ((n + l) * (n + l)
|
||||
+ (m - 2) * (n + 2 * l));
|
||||
result /= (m - 4) * (m - 2) * (m - 2) * n * n;
|
||||
return result;
|
||||
}
|
||||
|
||||
// RealType standard_deviation(const non_central_f_distribution<RealType, Policy>& dist)
|
||||
// standard_deviation provided by derived accessors.
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType skewness(const non_central_f_distribution<RealType, Policy>& dist)
|
||||
{ // skewness = sqrt(l).
|
||||
const char* function = "skewness(non_central_f_distribution<%1%> const&)";
|
||||
BOOST_MATH_STD_USING
|
||||
RealType n = dist.degrees_of_freedom1();
|
||||
RealType m = dist.degrees_of_freedom2();
|
||||
RealType l = dist.non_centrality();
|
||||
RealType r;
|
||||
if(!detail::check_df(
|
||||
function,
|
||||
n, &r, Policy())
|
||||
||
|
||||
!detail::check_df(
|
||||
function,
|
||||
m, &r, Policy())
|
||||
||
|
||||
!detail::check_non_centrality(
|
||||
function,
|
||||
l,
|
||||
&r,
|
||||
Policy()))
|
||||
return r;
|
||||
if(m <= 6)
|
||||
return policies::raise_domain_error(
|
||||
function,
|
||||
"Second degrees of freedom parameter was %1%, but must be > 6 !",
|
||||
m, Policy());
|
||||
RealType result = 2 * constants::root_two<RealType>();
|
||||
result *= sqrt(m - 4);
|
||||
result *= (n * (m + n - 2) *(m + 2 * n - 2)
|
||||
+ 3 * (m + n - 2) * (m + 2 * n - 2) * l
|
||||
+ 6 * (m + n - 2) * l * l + 2 * l * l * l);
|
||||
result /= (m - 6) * pow(n * (m + n - 2) + 2 * (m + n - 2) * l + l * l, RealType(1.5f));
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis_excess(const non_central_f_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
const char* function = "kurtosis_excess(non_central_f_distribution<%1%> const&)";
|
||||
BOOST_MATH_STD_USING
|
||||
RealType n = dist.degrees_of_freedom1();
|
||||
RealType m = dist.degrees_of_freedom2();
|
||||
RealType l = dist.non_centrality();
|
||||
RealType r;
|
||||
if(!detail::check_df(
|
||||
function,
|
||||
n, &r, Policy())
|
||||
||
|
||||
!detail::check_df(
|
||||
function,
|
||||
m, &r, Policy())
|
||||
||
|
||||
!detail::check_non_centrality(
|
||||
function,
|
||||
l,
|
||||
&r,
|
||||
Policy()))
|
||||
return r;
|
||||
if(m <= 8)
|
||||
return policies::raise_domain_error(
|
||||
function,
|
||||
"Second degrees of freedom parameter was %1%, but must be > 8 !",
|
||||
m, Policy());
|
||||
RealType l2 = l * l;
|
||||
RealType l3 = l2 * l;
|
||||
RealType l4 = l2 * l2;
|
||||
RealType result = (3 * (m - 4) * (n * (m + n - 2)
|
||||
* (4 * (m - 2) * (m - 2)
|
||||
+ (m - 2) * (m + 10) * n
|
||||
+ (10 + m) * n * n)
|
||||
+ 4 * (m + n - 2) * (4 * (m - 2) * (m - 2)
|
||||
+ (m - 2) * (10 + m) * n
|
||||
+ (10 + m) * n * n) * l + 2 * (10 + m)
|
||||
* (m + n - 2) * (2 * m + 3 * n - 4) * l2
|
||||
+ 4 * (10 + m) * (-2 + m + n) * l3
|
||||
+ (10 + m) * l4))
|
||||
/
|
||||
((-8 + m) * (-6 + m) * boost::math::pow<2>(n * (-2 + m + n)
|
||||
+ 2 * (-2 + m + n) * l + l2));
|
||||
return result;
|
||||
} // kurtosis_excess
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis(const non_central_f_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
return kurtosis_excess(dist) + 3;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType pdf(const non_central_f_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{ // Probability Density/Mass Function.
|
||||
typedef typename policies::evaluation<RealType, Policy>::type value_type;
|
||||
typedef typename policies::normalise<
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
policies::discrete_quantile<>,
|
||||
policies::assert_undefined<> >::type forwarding_policy;
|
||||
|
||||
value_type alpha = dist.degrees_of_freedom1() / 2;
|
||||
value_type beta = dist.degrees_of_freedom2() / 2;
|
||||
value_type y = x * alpha / beta;
|
||||
value_type r = pdf(boost::math::non_central_beta_distribution<value_type, forwarding_policy>(alpha, beta, dist.non_centrality()), y / (1 + y));
|
||||
return policies::checked_narrowing_cast<RealType, forwarding_policy>(
|
||||
r * (dist.degrees_of_freedom1() / dist.degrees_of_freedom2()) / ((1 + y) * (1 + y)),
|
||||
"pdf(non_central_f_distribution<%1%>, %1%)");
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
RealType cdf(const non_central_f_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
const char* function = "cdf(const non_central_f_distribution<%1%>&, %1%)";
|
||||
RealType r;
|
||||
if(!detail::check_df(
|
||||
function,
|
||||
dist.degrees_of_freedom1(), &r, Policy())
|
||||
||
|
||||
!detail::check_df(
|
||||
function,
|
||||
dist.degrees_of_freedom2(), &r, Policy())
|
||||
||
|
||||
!detail::check_non_centrality(
|
||||
function,
|
||||
dist.non_centrality(),
|
||||
&r,
|
||||
Policy()))
|
||||
return r;
|
||||
|
||||
if((x < 0) || !(boost::math::isfinite)(x))
|
||||
{
|
||||
return policies::raise_domain_error<RealType>(
|
||||
function, "Random Variable parameter was %1%, but must be > 0 !", x, Policy());
|
||||
}
|
||||
|
||||
RealType alpha = dist.degrees_of_freedom1() / 2;
|
||||
RealType beta = dist.degrees_of_freedom2() / 2;
|
||||
RealType y = x * alpha / beta;
|
||||
RealType c = y / (1 + y);
|
||||
RealType cp = 1 / (1 + y);
|
||||
//
|
||||
// To ensure accuracy, we pass both x and 1-x to the
|
||||
// non-central beta cdf routine, this ensures accuracy
|
||||
// even when we compute x to be ~ 1:
|
||||
//
|
||||
r = detail::non_central_beta_cdf(c, cp, alpha, beta,
|
||||
dist.non_centrality(), false, Policy());
|
||||
return r;
|
||||
} // cdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
RealType cdf(const complemented2_type<non_central_f_distribution<RealType, Policy>, RealType>& c)
|
||||
{ // Complemented Cumulative Distribution Function
|
||||
const char* function = "cdf(complement(const non_central_f_distribution<%1%>&, %1%))";
|
||||
RealType r;
|
||||
if(!detail::check_df(
|
||||
function,
|
||||
c.dist.degrees_of_freedom1(), &r, Policy())
|
||||
||
|
||||
!detail::check_df(
|
||||
function,
|
||||
c.dist.degrees_of_freedom2(), &r, Policy())
|
||||
||
|
||||
!detail::check_non_centrality(
|
||||
function,
|
||||
c.dist.non_centrality(),
|
||||
&r,
|
||||
Policy()))
|
||||
return r;
|
||||
|
||||
if((c.param < 0) || !(boost::math::isfinite)(c.param))
|
||||
{
|
||||
return policies::raise_domain_error<RealType>(
|
||||
function, "Random Variable parameter was %1%, but must be > 0 !", c.param, Policy());
|
||||
}
|
||||
|
||||
RealType alpha = c.dist.degrees_of_freedom1() / 2;
|
||||
RealType beta = c.dist.degrees_of_freedom2() / 2;
|
||||
RealType y = c.param * alpha / beta;
|
||||
RealType x = y / (1 + y);
|
||||
RealType cx = 1 / (1 + y);
|
||||
//
|
||||
// To ensure accuracy, we pass both x and 1-x to the
|
||||
// non-central beta cdf routine, this ensures accuracy
|
||||
// even when we compute x to be ~ 1:
|
||||
//
|
||||
r = detail::non_central_beta_cdf(x, cx, alpha, beta,
|
||||
c.dist.non_centrality(), true, Policy());
|
||||
return r;
|
||||
} // ccdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const non_central_f_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
{ // Quantile (or Percent Point) function.
|
||||
RealType alpha = dist.degrees_of_freedom1() / 2;
|
||||
RealType beta = dist.degrees_of_freedom2() / 2;
|
||||
RealType x = quantile(boost::math::non_central_beta_distribution<RealType, Policy>(alpha, beta, dist.non_centrality()), p);
|
||||
if(x == 1)
|
||||
return policies::raise_overflow_error<RealType>(
|
||||
"quantile(const non_central_f_distribution<%1%>&, %1%)",
|
||||
"Result of non central F quantile is too large to represent.",
|
||||
Policy());
|
||||
return (x / (1 - x)) * (dist.degrees_of_freedom2() / dist.degrees_of_freedom1());
|
||||
} // quantile
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const complemented2_type<non_central_f_distribution<RealType, Policy>, RealType>& c)
|
||||
{ // Quantile (or Percent Point) function.
|
||||
RealType alpha = c.dist.degrees_of_freedom1() / 2;
|
||||
RealType beta = c.dist.degrees_of_freedom2() / 2;
|
||||
RealType x = quantile(complement(boost::math::non_central_beta_distribution<RealType, Policy>(alpha, beta, c.dist.non_centrality()), c.param));
|
||||
if(x == 1)
|
||||
return policies::raise_overflow_error<RealType>(
|
||||
"quantile(complement(const non_central_f_distribution<%1%>&, %1%))",
|
||||
"Result of non central F quantile is too large to represent.",
|
||||
Policy());
|
||||
return (x / (1 - x)) * (c.dist.degrees_of_freedom2() / c.dist.degrees_of_freedom1());
|
||||
} // quantile complement.
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
// This include must be at the end, *after* the accessors
|
||||
// for this distribution have been defined, in order to
|
||||
// keep compilers that support two-phase lookup happy.
|
||||
#include <boost/math/distributions/detail/derived_accessors.hpp>
|
||||
|
||||
#endif // BOOST_MATH_SPECIAL_NON_CENTRAL_F_HPP
|
||||
|
||||
|
||||
|
||||
1126
test/external/boost/math/distributions/non_central_t.hpp
vendored
Normal file
1126
test/external/boost/math/distributions/non_central_t.hpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
308
test/external/boost/math/distributions/normal.hpp
vendored
Normal file
308
test/external/boost/math/distributions/normal.hpp
vendored
Normal file
@@ -0,0 +1,308 @@
|
||||
// Copyright John Maddock 2006, 2007.
|
||||
// Copyright Paul A. Bristow 2006, 2007.
|
||||
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_STATS_NORMAL_HPP
|
||||
#define BOOST_STATS_NORMAL_HPP
|
||||
|
||||
// http://en.wikipedia.org/wiki/Normal_distribution
|
||||
// http://www.itl.nist.gov/div898/handbook/eda/section3/eda3661.htm
|
||||
// Also:
|
||||
// Weisstein, Eric W. "Normal Distribution."
|
||||
// From MathWorld--A Wolfram Web Resource.
|
||||
// http://mathworld.wolfram.com/NormalDistribution.html
|
||||
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#include <boost/math/special_functions/erf.hpp> // for erf/erfc.
|
||||
#include <boost/math/distributions/complement.hpp>
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace boost{ namespace math{
|
||||
|
||||
template <class RealType = double, class Policy = policies::policy<> >
|
||||
class normal_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
|
||||
normal_distribution(RealType mean = 0, RealType sd = 1)
|
||||
: m_mean(mean), m_sd(sd)
|
||||
{ // Default is a 'standard' normal distribution N01.
|
||||
static const char* function = "boost::math::normal_distribution<%1%>::normal_distribution";
|
||||
|
||||
RealType result;
|
||||
detail::check_scale(function, sd, &result, Policy());
|
||||
detail::check_location(function, mean, &result, Policy());
|
||||
}
|
||||
|
||||
RealType mean()const
|
||||
{ // alias for location.
|
||||
return m_mean;
|
||||
}
|
||||
|
||||
RealType standard_deviation()const
|
||||
{ // alias for scale.
|
||||
return m_sd;
|
||||
}
|
||||
|
||||
// Synonyms, provided to allow generic use of find_location and find_scale.
|
||||
RealType location()const
|
||||
{ // location.
|
||||
return m_mean;
|
||||
}
|
||||
RealType scale()const
|
||||
{ // scale.
|
||||
return m_sd;
|
||||
}
|
||||
|
||||
private:
|
||||
//
|
||||
// Data members:
|
||||
//
|
||||
RealType m_mean; // distribution mean or location.
|
||||
RealType m_sd; // distribution standard deviation or scale.
|
||||
}; // class normal_distribution
|
||||
|
||||
typedef normal_distribution<double> normal;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const normal_distribution<RealType, Policy>& /*dist*/)
|
||||
{ // Range of permissible values for random variable x.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(-max_value<RealType>(), max_value<RealType>()); // - to + max value.
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> support(const normal_distribution<RealType, Policy>& /*dist*/)
|
||||
{ // Range of supported values for random variable x.
|
||||
// This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
|
||||
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(-max_value<RealType>(), max_value<RealType>()); // - to + max value.
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType pdf(const normal_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
RealType sd = dist.standard_deviation();
|
||||
RealType mean = dist.mean();
|
||||
|
||||
static const char* function = "boost::math::pdf(const normal_distribution<%1%>&, %1%)";
|
||||
if((boost::math::isinf)(x))
|
||||
{
|
||||
return 0; // pdf + and - infinity is zero.
|
||||
}
|
||||
// Below produces MSVC 4127 warnings, so the above used instead.
|
||||
//if(std::numeric_limits<RealType>::has_infinity && abs(x) == std::numeric_limits<RealType>::infinity())
|
||||
//{ // pdf + and - infinity is zero.
|
||||
// return 0;
|
||||
//}
|
||||
|
||||
RealType result = 0;
|
||||
if(false == detail::check_scale(function, sd, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(false == detail::check_location(function, mean, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(false == detail::check_x(function, x, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
RealType exponent = x - mean;
|
||||
exponent *= -exponent;
|
||||
exponent /= 2 * sd * sd;
|
||||
|
||||
result = exp(exponent);
|
||||
result /= sd * sqrt(2 * constants::pi<RealType>());
|
||||
|
||||
return result;
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const normal_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
RealType sd = dist.standard_deviation();
|
||||
RealType mean = dist.mean();
|
||||
static const char* function = "boost::math::cdf(const normal_distribution<%1%>&, %1%)";
|
||||
RealType result = 0;
|
||||
if(false == detail::check_scale(function, sd, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(false == detail::check_location(function, mean, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if((boost::math::isinf)(x))
|
||||
{
|
||||
if(x < 0) return 0; // -infinity
|
||||
return 1; // + infinity
|
||||
}
|
||||
// These produce MSVC 4127 warnings, so the above used instead.
|
||||
//if(std::numeric_limits<RealType>::has_infinity && x == std::numeric_limits<RealType>::infinity())
|
||||
//{ // cdf +infinity is unity.
|
||||
// return 1;
|
||||
//}
|
||||
//if(std::numeric_limits<RealType>::has_infinity && x == -std::numeric_limits<RealType>::infinity())
|
||||
//{ // cdf -infinity is zero.
|
||||
// return 0;
|
||||
//}
|
||||
if(false == detail::check_x(function, x, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
RealType diff = (x - mean) / (sd * constants::root_two<RealType>());
|
||||
result = boost::math::erfc(-diff, Policy()) / 2;
|
||||
return result;
|
||||
} // cdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const normal_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
RealType sd = dist.standard_deviation();
|
||||
RealType mean = dist.mean();
|
||||
static const char* function = "boost::math::quantile(const normal_distribution<%1%>&, %1%)";
|
||||
|
||||
RealType result = 0;
|
||||
if(false == detail::check_scale(function, sd, &result, Policy()))
|
||||
return result;
|
||||
if(false == detail::check_location(function, mean, &result, Policy()))
|
||||
return result;
|
||||
if(false == detail::check_probability(function, p, &result, Policy()))
|
||||
return result;
|
||||
|
||||
result= boost::math::erfc_inv(2 * p, Policy());
|
||||
result = -result;
|
||||
result *= sd * constants::root_two<RealType>();
|
||||
result += mean;
|
||||
return result;
|
||||
} // quantile
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const complemented2_type<normal_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
RealType sd = c.dist.standard_deviation();
|
||||
RealType mean = c.dist.mean();
|
||||
RealType x = c.param;
|
||||
static const char* function = "boost::math::cdf(const complement(normal_distribution<%1%>&), %1%)";
|
||||
|
||||
if((boost::math::isinf)(x))
|
||||
{
|
||||
if(x < 0) return 1; // cdf complement -infinity is unity.
|
||||
return 0; // cdf complement +infinity is zero
|
||||
}
|
||||
// These produce MSVC 4127 warnings, so the above used instead.
|
||||
//if(std::numeric_limits<RealType>::has_infinity && x == std::numeric_limits<RealType>::infinity())
|
||||
//{ // cdf complement +infinity is zero.
|
||||
// return 0;
|
||||
//}
|
||||
//if(std::numeric_limits<RealType>::has_infinity && x == -std::numeric_limits<RealType>::infinity())
|
||||
//{ // cdf complement -infinity is unity.
|
||||
// return 1;
|
||||
//}
|
||||
RealType result = 0;
|
||||
if(false == detail::check_scale(function, sd, &result, Policy()))
|
||||
return result;
|
||||
if(false == detail::check_location(function, mean, &result, Policy()))
|
||||
return result;
|
||||
if(false == detail::check_x(function, x, &result, Policy()))
|
||||
return result;
|
||||
|
||||
RealType diff = (x - mean) / (sd * constants::root_two<RealType>());
|
||||
result = boost::math::erfc(diff, Policy()) / 2;
|
||||
return result;
|
||||
} // cdf complement
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const complemented2_type<normal_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
RealType sd = c.dist.standard_deviation();
|
||||
RealType mean = c.dist.mean();
|
||||
static const char* function = "boost::math::quantile(const complement(normal_distribution<%1%>&), %1%)";
|
||||
RealType result = 0;
|
||||
if(false == detail::check_scale(function, sd, &result, Policy()))
|
||||
return result;
|
||||
if(false == detail::check_location(function, mean, &result, Policy()))
|
||||
return result;
|
||||
RealType q = c.param;
|
||||
if(false == detail::check_probability(function, q, &result, Policy()))
|
||||
return result;
|
||||
result = boost::math::erfc_inv(2 * q, Policy());
|
||||
result *= sd * constants::root_two<RealType>();
|
||||
result += mean;
|
||||
return result;
|
||||
} // quantile
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mean(const normal_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
return dist.mean();
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType standard_deviation(const normal_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
return dist.standard_deviation();
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mode(const normal_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
return dist.mean();
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType median(const normal_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
return dist.mean();
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType skewness(const normal_distribution<RealType, Policy>& /*dist*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis(const normal_distribution<RealType, Policy>& /*dist*/)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis_excess(const normal_distribution<RealType, Policy>& /*dist*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
// This include must be at the end, *after* the accessors
|
||||
// for this distribution have been defined, in order to
|
||||
// keep compilers that support two-phase lookup happy.
|
||||
#include <boost/math/distributions/detail/derived_accessors.hpp>
|
||||
|
||||
#endif // BOOST_STATS_NORMAL_HPP
|
||||
|
||||
|
||||
444
test/external/boost/math/distributions/pareto.hpp
vendored
Normal file
444
test/external/boost/math/distributions/pareto.hpp
vendored
Normal file
@@ -0,0 +1,444 @@
|
||||
// Copyright John Maddock 2007.
|
||||
// Copyright Paul A. Bristow 2007, 2009
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_STATS_PARETO_HPP
|
||||
#define BOOST_STATS_PARETO_HPP
|
||||
|
||||
// http://en.wikipedia.org/wiki/Pareto_distribution
|
||||
// http://www.itl.nist.gov/div898/handbook/eda/section3/eda3661.htm
|
||||
// Also:
|
||||
// Weisstein, Eric W. "Pareto Distribution."
|
||||
// From MathWorld--A Wolfram Web Resource.
|
||||
// http://mathworld.wolfram.com/ParetoDistribution.html
|
||||
// Handbook of Statistical Distributions with Applications, K Krishnamoorthy, ISBN 1-58488-635-8, Chapter 23, pp 257 - 267.
|
||||
// Caution KK's a and b are the reverse of Mathworld!
|
||||
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#include <boost/math/distributions/complement.hpp>
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp>
|
||||
#include <boost/math/special_functions/powm1.hpp>
|
||||
|
||||
#include <utility> // for BOOST_CURRENT_VALUE?
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace math
|
||||
{
|
||||
namespace detail
|
||||
{ // Parameter checking.
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_pareto_scale(
|
||||
const char* function,
|
||||
RealType scale,
|
||||
RealType* result, const Policy& pol)
|
||||
{
|
||||
if((boost::math::isfinite)(scale))
|
||||
{ // any > 0 finite value is OK.
|
||||
if (scale > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Scale parameter is %1%, but must be > 0!", scale, pol);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // Not finite.
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Scale parameter is %1%, but must be finite!", scale, pol);
|
||||
return false;
|
||||
}
|
||||
} // bool check_pareto_scale
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_pareto_shape(
|
||||
const char* function,
|
||||
RealType shape,
|
||||
RealType* result, const Policy& pol)
|
||||
{
|
||||
if((boost::math::isfinite)(shape))
|
||||
{ // Any finite value > 0 is OK.
|
||||
if (shape > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Shape parameter is %1%, but must be > 0!", shape, pol);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // Not finite.
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Shape parameter is %1%, but must be finite!", shape, pol);
|
||||
return false;
|
||||
}
|
||||
} // bool check_pareto_shape(
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_pareto_x(
|
||||
const char* function,
|
||||
RealType const& x,
|
||||
RealType* result, const Policy& pol)
|
||||
{
|
||||
if((boost::math::isfinite)(x))
|
||||
{ //
|
||||
if (x > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"x parameter is %1%, but must be > 0 !", x, pol);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // Not finite..
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"x parameter is %1%, but must be finite!", x, pol);
|
||||
return false;
|
||||
}
|
||||
} // bool check_pareto_x
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_pareto( // distribution parameters.
|
||||
const char* function,
|
||||
RealType scale,
|
||||
RealType shape,
|
||||
RealType* result, const Policy& pol)
|
||||
{
|
||||
return check_pareto_scale(function, scale, result, pol)
|
||||
&& check_pareto_shape(function, shape, result, pol);
|
||||
} // bool check_pareto(
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class RealType = double, class Policy = policies::policy<> >
|
||||
class pareto_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
|
||||
pareto_distribution(RealType scale = 1, RealType shape = 1)
|
||||
: m_scale(scale), m_shape(shape)
|
||||
{ // Constructor.
|
||||
RealType result = 0;
|
||||
detail::check_pareto("boost::math::pareto_distribution<%1%>::pareto_distribution", scale, shape, &result, Policy());
|
||||
}
|
||||
|
||||
RealType scale()const
|
||||
{ // AKA Xm and Wolfram b and beta
|
||||
return m_scale;
|
||||
}
|
||||
|
||||
RealType shape()const
|
||||
{ // AKA k and Wolfram a and alpha
|
||||
return m_shape;
|
||||
}
|
||||
private:
|
||||
// Data members:
|
||||
RealType m_scale; // distribution scale (xm) or beta
|
||||
RealType m_shape; // distribution shape (k) or alpha
|
||||
};
|
||||
|
||||
typedef pareto_distribution<double> pareto; // Convenience to allow pareto(2., 3.);
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const pareto_distribution<RealType, Policy>& /*dist*/)
|
||||
{ // Range of permissible values for random variable x.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>()); // scale zero to + infinity.
|
||||
} // range
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> support(const pareto_distribution<RealType, Policy>& dist)
|
||||
{ // Range of supported values for random variable x.
|
||||
// This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(dist.scale(), max_value<RealType>() ); // scale to + infinity.
|
||||
} // support
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType pdf(const pareto_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std function pow.
|
||||
static const char* function = "boost::math::pdf(const pareto_distribution<%1%>&, %1%)";
|
||||
RealType scale = dist.scale();
|
||||
RealType shape = dist.shape();
|
||||
RealType result = 0;
|
||||
if(false == (detail::check_pareto_x(function, x, &result, Policy())
|
||||
&& detail::check_pareto(function, scale, shape, &result, Policy())))
|
||||
return result;
|
||||
if (x < scale)
|
||||
{ // regardless of shape, pdf is zero (or should be disallow x < scale and throw an exception?).
|
||||
return 0;
|
||||
}
|
||||
result = shape * pow(scale, shape) / pow(x, shape+1);
|
||||
return result;
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const pareto_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std function pow.
|
||||
static const char* function = "boost::math::cdf(const pareto_distribution<%1%>&, %1%)";
|
||||
RealType scale = dist.scale();
|
||||
RealType shape = dist.shape();
|
||||
RealType result = 0;
|
||||
|
||||
if(false == (detail::check_pareto_x(function, x, &result, Policy())
|
||||
&& detail::check_pareto(function, scale, shape, &result, Policy())))
|
||||
return result;
|
||||
|
||||
if (x <= scale)
|
||||
{ // regardless of shape, cdf is zero.
|
||||
return 0;
|
||||
}
|
||||
|
||||
// result = RealType(1) - pow((scale / x), shape);
|
||||
result = -boost::math::powm1(scale/x, shape, Policy()); // should be more accurate.
|
||||
return result;
|
||||
} // cdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const pareto_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std function pow.
|
||||
static const char* function = "boost::math::quantile(const pareto_distribution<%1%>&, %1%)";
|
||||
RealType result = 0;
|
||||
RealType scale = dist.scale();
|
||||
RealType shape = dist.shape();
|
||||
if(false == (detail::check_probability(function, p, &result, Policy())
|
||||
&& detail::check_pareto(function, scale, shape, &result, Policy())))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if (p == 0)
|
||||
{
|
||||
return scale; // x must be scale (or less).
|
||||
}
|
||||
if (p == 1)
|
||||
{
|
||||
return tools::max_value<RealType>(); // x = + infinity.
|
||||
}
|
||||
result = scale /
|
||||
(pow((1 - p), 1 / shape));
|
||||
// K. Krishnamoorthy, ISBN 1-58488-635-8 eq 23.1.3
|
||||
return result;
|
||||
} // quantile
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const complemented2_type<pareto_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std function pow.
|
||||
static const char* function = "boost::math::cdf(const pareto_distribution<%1%>&, %1%)";
|
||||
RealType result = 0;
|
||||
RealType x = c.param;
|
||||
RealType scale = c.dist.scale();
|
||||
RealType shape = c.dist.shape();
|
||||
if(false == (detail::check_pareto_x(function, x, &result, Policy())
|
||||
&& detail::check_pareto(function, scale, shape, &result, Policy())))
|
||||
return result;
|
||||
|
||||
if (x <= scale)
|
||||
{ // regardless of shape, cdf is zero, and complement is unity.
|
||||
return 1;
|
||||
}
|
||||
result = pow((scale/x), shape);
|
||||
|
||||
return result;
|
||||
} // cdf complement
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const complemented2_type<pareto_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std function pow.
|
||||
static const char* function = "boost::math::quantile(const pareto_distribution<%1%>&, %1%)";
|
||||
RealType result = 0;
|
||||
RealType q = c.param;
|
||||
RealType scale = c.dist.scale();
|
||||
RealType shape = c.dist.shape();
|
||||
if(false == (detail::check_probability(function, q, &result, Policy())
|
||||
&& detail::check_pareto(function, scale, shape, &result, Policy())))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if (q == 1)
|
||||
{
|
||||
return scale; // x must be scale (or less).
|
||||
}
|
||||
if (q == 0)
|
||||
{
|
||||
return tools::max_value<RealType>(); // x = + infinity.
|
||||
}
|
||||
result = scale / (pow(q, 1 / shape));
|
||||
// K. Krishnamoorthy, ISBN 1-58488-635-8 eq 23.1.3
|
||||
return result;
|
||||
} // quantile complement
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mean(const pareto_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType result = 0;
|
||||
static const char* function = "boost::math::mean(const pareto_distribution<%1%>&, %1%)";
|
||||
if(false == detail::check_pareto(function, dist.scale(), dist.shape(), &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if (dist.shape() > RealType(1))
|
||||
{
|
||||
return dist.shape() * dist.scale() / (dist.shape() - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
using boost::math::tools::max_value;
|
||||
return max_value<RealType>(); // +infinity.
|
||||
}
|
||||
} // mean
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mode(const pareto_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
return dist.scale();
|
||||
} // mode
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType median(const pareto_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType result = 0;
|
||||
static const char* function = "boost::math::median(const pareto_distribution<%1%>&, %1%)";
|
||||
if(false == detail::check_pareto(function, dist.scale(), dist.shape(), &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
BOOST_MATH_STD_USING
|
||||
return dist.scale() * pow(RealType(2), (1/dist.shape()));
|
||||
} // median
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType variance(const pareto_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType result = 0;
|
||||
RealType scale = dist.scale();
|
||||
RealType shape = dist.shape();
|
||||
static const char* function = "boost::math::variance(const pareto_distribution<%1%>&, %1%)";
|
||||
if(false == detail::check_pareto(function, scale, shape, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if (shape > 2)
|
||||
{
|
||||
result = (scale * scale * shape) /
|
||||
((shape - 1) * (shape - 1) * (shape - 2));
|
||||
}
|
||||
else
|
||||
{
|
||||
result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"variance is undefined for shape <= 2, but got %1%.", dist.shape(), Policy());
|
||||
}
|
||||
return result;
|
||||
} // variance
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType skewness(const pareto_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
RealType result = 0;
|
||||
RealType shape = dist.shape();
|
||||
static const char* function = "boost::math::pdf(const pareto_distribution<%1%>&, %1%)";
|
||||
if(false == detail::check_pareto(function, dist.scale(), shape, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if (shape > 3)
|
||||
{
|
||||
result = sqrt((shape - 2) / shape) *
|
||||
2 * (shape + 1) /
|
||||
(shape - 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"skewness is undefined for shape <= 3, but got %1%.", dist.shape(), Policy());
|
||||
}
|
||||
return result;
|
||||
} // skewness
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis(const pareto_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType result = 0;
|
||||
RealType shape = dist.shape();
|
||||
static const char* function = "boost::math::pdf(const pareto_distribution<%1%>&, %1%)";
|
||||
if(false == detail::check_pareto(function, dist.scale(), shape, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if (shape > 4)
|
||||
{
|
||||
result = 3 * ((shape - 2) * (3 * shape * shape + shape + 2)) /
|
||||
(shape * (shape - 3) * (shape - 4));
|
||||
}
|
||||
else
|
||||
{
|
||||
result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"kurtosis_excess is undefined for shape <= 4, but got %1%.", shape, Policy());
|
||||
}
|
||||
return result;
|
||||
} // kurtosis
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis_excess(const pareto_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType result = 0;
|
||||
RealType shape = dist.shape();
|
||||
static const char* function = "boost::math::pdf(const pareto_distribution<%1%>&, %1%)";
|
||||
if(false == detail::check_pareto(function, dist.scale(), shape, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if (shape > 4)
|
||||
{
|
||||
result = 6 * ((shape * shape * shape) + (shape * shape) - 6 * shape - 2) /
|
||||
(shape * (shape - 3) * (shape - 4));
|
||||
}
|
||||
else
|
||||
{
|
||||
result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"kurtosis_excess is undefined for shape <= 4, but got %1%.", dist.shape(), Policy());
|
||||
}
|
||||
return result;
|
||||
} // kurtosis_excess
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
// This include must be at the end, *after* the accessors
|
||||
// for this distribution have been defined, in order to
|
||||
// keep compilers that support two-phase lookup happy.
|
||||
#include <boost/math/distributions/detail/derived_accessors.hpp>
|
||||
|
||||
#endif // BOOST_STATS_PARETO_HPP
|
||||
|
||||
|
||||
588
test/external/boost/math/distributions/poisson.hpp
vendored
Normal file
588
test/external/boost/math/distributions/poisson.hpp
vendored
Normal file
@@ -0,0 +1,588 @@
|
||||
// boost\math\distributions\poisson.hpp
|
||||
|
||||
// Copyright John Maddock 2006.
|
||||
// Copyright Paul A. Bristow 2007.
|
||||
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
// Poisson distribution is a discrete probability distribution.
|
||||
// It expresses the probability of a number (k) of
|
||||
// events, occurrences, failures or arrivals occurring in a fixed time,
|
||||
// assuming these events occur with a known average or mean rate (lambda)
|
||||
// and are independent of the time since the last event.
|
||||
// The distribution was discovered by Simeon-Denis Poisson (1781-1840).
|
||||
|
||||
// Parameter lambda is the mean number of events in the given time interval.
|
||||
// The random variate k is the number of events, occurrences or arrivals.
|
||||
// k argument may be integral, signed, or unsigned, or floating point.
|
||||
// If necessary, it has already been promoted from an integral type.
|
||||
|
||||
// Note that the Poisson distribution
|
||||
// (like others including the binomial, negative binomial & Bernoulli)
|
||||
// is strictly defined as a discrete function:
|
||||
// only integral values of k are envisaged.
|
||||
// However because the method of calculation uses a continuous gamma function,
|
||||
// it is convenient to treat it as if a continous function,
|
||||
// and permit non-integral values of k.
|
||||
// To enforce the strict mathematical model, users should use floor or ceil functions
|
||||
// on k outside this function to ensure that k is integral.
|
||||
|
||||
// See http://en.wikipedia.org/wiki/Poisson_distribution
|
||||
// http://documents.wolfram.com/v5/Add-onsLinks/StandardPackages/Statistics/DiscreteDistributions.html
|
||||
|
||||
#ifndef BOOST_MATH_SPECIAL_POISSON_HPP
|
||||
#define BOOST_MATH_SPECIAL_POISSON_HPP
|
||||
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#include <boost/math/special_functions/gamma.hpp> // for incomplete gamma. gamma_q
|
||||
#include <boost/math/special_functions/trunc.hpp> // for incomplete gamma. gamma_q
|
||||
#include <boost/math/distributions/complement.hpp> // complements
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp> // error checks
|
||||
#include <boost/math/special_functions/fpclassify.hpp> // isnan.
|
||||
#include <boost/math/special_functions/factorials.hpp> // factorials.
|
||||
#include <boost/math/tools/roots.hpp> // for root finding.
|
||||
#include <boost/math/distributions/detail/inv_discrete_quantile.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace math
|
||||
{
|
||||
namespace detail{
|
||||
template <class Dist>
|
||||
inline typename Dist::value_type
|
||||
inverse_discrete_quantile(
|
||||
const Dist& dist,
|
||||
const typename Dist::value_type& p,
|
||||
const typename Dist::value_type& guess,
|
||||
const typename Dist::value_type& multiplier,
|
||||
const typename Dist::value_type& adder,
|
||||
const policies::discrete_quantile<policies::integer_round_nearest>&,
|
||||
boost::uintmax_t& max_iter);
|
||||
template <class Dist>
|
||||
inline typename Dist::value_type
|
||||
inverse_discrete_quantile(
|
||||
const Dist& dist,
|
||||
const typename Dist::value_type& p,
|
||||
const typename Dist::value_type& guess,
|
||||
const typename Dist::value_type& multiplier,
|
||||
const typename Dist::value_type& adder,
|
||||
const policies::discrete_quantile<policies::integer_round_up>&,
|
||||
boost::uintmax_t& max_iter);
|
||||
template <class Dist>
|
||||
inline typename Dist::value_type
|
||||
inverse_discrete_quantile(
|
||||
const Dist& dist,
|
||||
const typename Dist::value_type& p,
|
||||
const typename Dist::value_type& guess,
|
||||
const typename Dist::value_type& multiplier,
|
||||
const typename Dist::value_type& adder,
|
||||
const policies::discrete_quantile<policies::integer_round_down>&,
|
||||
boost::uintmax_t& max_iter);
|
||||
template <class Dist>
|
||||
inline typename Dist::value_type
|
||||
inverse_discrete_quantile(
|
||||
const Dist& dist,
|
||||
const typename Dist::value_type& p,
|
||||
const typename Dist::value_type& guess,
|
||||
const typename Dist::value_type& multiplier,
|
||||
const typename Dist::value_type& adder,
|
||||
const policies::discrete_quantile<policies::integer_round_outwards>&,
|
||||
boost::uintmax_t& max_iter);
|
||||
template <class Dist>
|
||||
inline typename Dist::value_type
|
||||
inverse_discrete_quantile(
|
||||
const Dist& dist,
|
||||
const typename Dist::value_type& p,
|
||||
const typename Dist::value_type& guess,
|
||||
const typename Dist::value_type& multiplier,
|
||||
const typename Dist::value_type& adder,
|
||||
const policies::discrete_quantile<policies::integer_round_inwards>&,
|
||||
boost::uintmax_t& max_iter);
|
||||
template <class Dist>
|
||||
inline typename Dist::value_type
|
||||
inverse_discrete_quantile(
|
||||
const Dist& dist,
|
||||
const typename Dist::value_type& p,
|
||||
const typename Dist::value_type& guess,
|
||||
const typename Dist::value_type& multiplier,
|
||||
const typename Dist::value_type& adder,
|
||||
const policies::discrete_quantile<policies::real>&,
|
||||
boost::uintmax_t& max_iter);
|
||||
}
|
||||
namespace poisson_detail
|
||||
{
|
||||
// Common error checking routines for Poisson distribution functions.
|
||||
// These are convoluted, & apparently redundant, to try to ensure that
|
||||
// checks are always performed, even if exceptions are not enabled.
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_mean(const char* function, const RealType& mean, RealType* result, const Policy& pol)
|
||||
{
|
||||
if(!(boost::math::isfinite)(mean) || (mean < 0))
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Mean argument is %1%, but must be >= 0 !", mean, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // bool check_mean
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_mean_NZ(const char* function, const RealType& mean, RealType* result, const Policy& pol)
|
||||
{ // mean == 0 is considered an error.
|
||||
if( !(boost::math::isfinite)(mean) || (mean <= 0))
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Mean argument is %1%, but must be > 0 !", mean, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // bool check_mean_NZ
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_dist(const char* function, const RealType& mean, RealType* result, const Policy& pol)
|
||||
{ // Only one check, so this is redundant really but should be optimized away.
|
||||
return check_mean_NZ(function, mean, result, pol);
|
||||
} // bool check_dist
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_k(const char* function, const RealType& k, RealType* result, const Policy& pol)
|
||||
{
|
||||
if((k < 0) || !(boost::math::isfinite)(k))
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Number of events k argument is %1%, but must be >= 0 !", k, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // bool check_k
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_dist_and_k(const char* function, RealType mean, RealType k, RealType* result, const Policy& pol)
|
||||
{
|
||||
if((check_dist(function, mean, result, pol) == false) ||
|
||||
(check_k(function, k, result, pol) == false))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // bool check_dist_and_k
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_prob(const char* function, const RealType& p, RealType* result, const Policy& pol)
|
||||
{ // Check 0 <= p <= 1
|
||||
if(!(boost::math::isfinite)(p) || (p < 0) || (p > 1))
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Probability argument is %1%, but must be >= 0 and <= 1 !", p, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // bool check_prob
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_dist_and_prob(const char* function, RealType mean, RealType p, RealType* result, const Policy& pol)
|
||||
{
|
||||
if((check_dist(function, mean, result, pol) == false) ||
|
||||
(check_prob(function, p, result, pol) == false))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // bool check_dist_and_prob
|
||||
|
||||
} // namespace poisson_detail
|
||||
|
||||
template <class RealType = double, class Policy = policies::policy<> >
|
||||
class poisson_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
|
||||
poisson_distribution(RealType mean = 1) : m_l(mean) // mean (lambda).
|
||||
{ // Expected mean number of events that occur during the given interval.
|
||||
RealType r;
|
||||
poisson_detail::check_dist(
|
||||
"boost::math::poisson_distribution<%1%>::poisson_distribution",
|
||||
m_l,
|
||||
&r, Policy());
|
||||
} // poisson_distribution constructor.
|
||||
|
||||
RealType mean() const
|
||||
{ // Private data getter function.
|
||||
return m_l;
|
||||
}
|
||||
private:
|
||||
// Data member, initialized by constructor.
|
||||
RealType m_l; // mean number of occurrences.
|
||||
}; // template <class RealType, class Policy> class poisson_distribution
|
||||
|
||||
typedef poisson_distribution<double> poisson; // Reserved name of type double.
|
||||
|
||||
// Non-member functions to give properties of the distribution.
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const poisson_distribution<RealType, Policy>& /* dist */)
|
||||
{ // Range of permissible values for random variable k.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>()); // Max integer?
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> support(const poisson_distribution<RealType, Policy>& /* dist */)
|
||||
{ // Range of supported values for random variable k.
|
||||
// This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mean(const poisson_distribution<RealType, Policy>& dist)
|
||||
{ // Mean of poisson distribution = lambda.
|
||||
return dist.mean();
|
||||
} // mean
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mode(const poisson_distribution<RealType, Policy>& dist)
|
||||
{ // mode.
|
||||
BOOST_MATH_STD_USING // ADL of std functions.
|
||||
return floor(dist.mean());
|
||||
}
|
||||
|
||||
//template <class RealType, class Policy>
|
||||
//inline RealType median(const poisson_distribution<RealType, Policy>& dist)
|
||||
//{ // median = approximately lambda + 1/3 - 0.2/lambda
|
||||
// RealType l = dist.mean();
|
||||
// return dist.mean() + static_cast<RealType>(0.3333333333333333333333333333333333333333333333)
|
||||
// - static_cast<RealType>(0.2) / l;
|
||||
//} // BUT this formula appears to be out-by-one compared to quantile(half)
|
||||
// Query posted on Wikipedia.
|
||||
// Now implemented via quantile(half) in derived accessors.
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType variance(const poisson_distribution<RealType, Policy>& dist)
|
||||
{ // variance.
|
||||
return dist.mean();
|
||||
}
|
||||
|
||||
// RealType standard_deviation(const poisson_distribution<RealType, Policy>& dist)
|
||||
// standard_deviation provided by derived accessors.
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType skewness(const poisson_distribution<RealType, Policy>& dist)
|
||||
{ // skewness = sqrt(l).
|
||||
BOOST_MATH_STD_USING // ADL of std functions.
|
||||
return 1 / sqrt(dist.mean());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis_excess(const poisson_distribution<RealType, Policy>& dist)
|
||||
{ // skewness = sqrt(l).
|
||||
return 1 / dist.mean(); // kurtosis_excess 1/mean from Wiki & MathWorld eq 31.
|
||||
// http://mathworld.wolfram.com/Kurtosis.html explains that the kurtosis excess
|
||||
// is more convenient because the kurtosis excess of a normal distribution is zero
|
||||
// whereas the true kurtosis is 3.
|
||||
} // RealType kurtosis_excess
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis(const poisson_distribution<RealType, Policy>& dist)
|
||||
{ // kurtosis is 4th moment about the mean = u4 / sd ^ 4
|
||||
// http://en.wikipedia.org/wiki/Curtosis
|
||||
// kurtosis can range from -2 (flat top) to +infinity (sharp peak & heavy tails).
|
||||
// http://www.itl.nist.gov/div898/handbook/eda/section3/eda35b.htm
|
||||
return 3 + 1 / dist.mean(); // NIST.
|
||||
// http://mathworld.wolfram.com/Kurtosis.html explains that the kurtosis excess
|
||||
// is more convenient because the kurtosis excess of a normal distribution is zero
|
||||
// whereas the true kurtosis is 3.
|
||||
} // RealType kurtosis
|
||||
|
||||
template <class RealType, class Policy>
|
||||
RealType pdf(const poisson_distribution<RealType, Policy>& dist, const RealType& k)
|
||||
{ // Probability Density/Mass Function.
|
||||
// Probability that there are EXACTLY k occurrences (or arrivals).
|
||||
BOOST_FPU_EXCEPTION_GUARD
|
||||
|
||||
BOOST_MATH_STD_USING // for ADL of std functions.
|
||||
|
||||
RealType mean = dist.mean();
|
||||
// Error check:
|
||||
RealType result = 0;
|
||||
if(false == poisson_detail::check_dist_and_k(
|
||||
"boost::math::pdf(const poisson_distribution<%1%>&, %1%)",
|
||||
mean,
|
||||
k,
|
||||
&result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
// Special case of mean zero, regardless of the number of events k.
|
||||
if (mean == 0)
|
||||
{ // Probability for any k is zero.
|
||||
return 0;
|
||||
}
|
||||
if (k == 0)
|
||||
{ // mean ^ k = 1, and k! = 1, so can simplify.
|
||||
return exp(-mean);
|
||||
}
|
||||
return boost::math::gamma_p_derivative(k+1, mean, Policy());
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
RealType cdf(const poisson_distribution<RealType, Policy>& dist, const RealType& k)
|
||||
{ // Cumulative Distribution Function Poisson.
|
||||
// The random variate k is the number of occurrences(or arrivals)
|
||||
// k argument may be integral, signed, or unsigned, or floating point.
|
||||
// If necessary, it has already been promoted from an integral type.
|
||||
// Returns the sum of the terms 0 through k of the Poisson Probability Density or Mass (pdf).
|
||||
|
||||
// But note that the Poisson distribution
|
||||
// (like others including the binomial, negative binomial & Bernoulli)
|
||||
// is strictly defined as a discrete function: only integral values of k are envisaged.
|
||||
// However because of the method of calculation using a continuous gamma function,
|
||||
// it is convenient to treat it as if it is a continous function
|
||||
// and permit non-integral values of k.
|
||||
// To enforce the strict mathematical model, users should use floor or ceil functions
|
||||
// outside this function to ensure that k is integral.
|
||||
|
||||
// The terms are not summed directly (at least for larger k)
|
||||
// instead the incomplete gamma integral is employed,
|
||||
|
||||
BOOST_MATH_STD_USING // for ADL of std function exp.
|
||||
|
||||
RealType mean = dist.mean();
|
||||
// Error checks:
|
||||
RealType result = 0;
|
||||
if(false == poisson_detail::check_dist_and_k(
|
||||
"boost::math::cdf(const poisson_distribution<%1%>&, %1%)",
|
||||
mean,
|
||||
k,
|
||||
&result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
// Special cases:
|
||||
if (mean == 0)
|
||||
{ // Probability for any k is zero.
|
||||
return 0;
|
||||
}
|
||||
if (k == 0)
|
||||
{ // return pdf(dist, static_cast<RealType>(0));
|
||||
// but mean (and k) have already been checked,
|
||||
// so this avoids unnecessary repeated checks.
|
||||
return exp(-mean);
|
||||
}
|
||||
// For small integral k could use a finite sum -
|
||||
// it's cheaper than the gamma function.
|
||||
// BUT this is now done efficiently by gamma_q function.
|
||||
// Calculate poisson cdf using the gamma_q function.
|
||||
return gamma_q(k+1, mean, Policy());
|
||||
} // binomial cdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
RealType cdf(const complemented2_type<poisson_distribution<RealType, Policy>, RealType>& c)
|
||||
{ // Complemented Cumulative Distribution Function Poisson
|
||||
// The random variate k is the number of events, occurrences or arrivals.
|
||||
// k argument may be integral, signed, or unsigned, or floating point.
|
||||
// If necessary, it has already been promoted from an integral type.
|
||||
// But note that the Poisson distribution
|
||||
// (like others including the binomial, negative binomial & Bernoulli)
|
||||
// is strictly defined as a discrete function: only integral values of k are envisaged.
|
||||
// However because of the method of calculation using a continuous gamma function,
|
||||
// it is convenient to treat it as is it is a continous function
|
||||
// and permit non-integral values of k.
|
||||
// To enforce the strict mathematical model, users should use floor or ceil functions
|
||||
// outside this function to ensure that k is integral.
|
||||
|
||||
// Returns the sum of the terms k+1 through inf of the Poisson Probability Density/Mass (pdf).
|
||||
// The terms are not summed directly (at least for larger k)
|
||||
// instead the incomplete gamma integral is employed,
|
||||
|
||||
RealType const& k = c.param;
|
||||
poisson_distribution<RealType, Policy> const& dist = c.dist;
|
||||
|
||||
RealType mean = dist.mean();
|
||||
|
||||
// Error checks:
|
||||
RealType result = 0;
|
||||
if(false == poisson_detail::check_dist_and_k(
|
||||
"boost::math::cdf(const poisson_distribution<%1%>&, %1%)",
|
||||
mean,
|
||||
k,
|
||||
&result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
// Special case of mean, regardless of the number of events k.
|
||||
if (mean == 0)
|
||||
{ // Probability for any k is unity, complement of zero.
|
||||
return 1;
|
||||
}
|
||||
if (k == 0)
|
||||
{ // Avoid repeated checks on k and mean in gamma_p.
|
||||
return -boost::math::expm1(-mean, Policy());
|
||||
}
|
||||
// Unlike un-complemented cdf (sum from 0 to k),
|
||||
// can't use finite sum from k+1 to infinity for small integral k,
|
||||
// anyway it is now done efficiently by gamma_p.
|
||||
return gamma_p(k + 1, mean, Policy()); // Calculate Poisson cdf using the gamma_p function.
|
||||
// CCDF = gamma_p(k+1, lambda)
|
||||
} // poisson ccdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const poisson_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
{ // Quantile (or Percent Point) Poisson function.
|
||||
// Return the number of expected events k for a given probability p.
|
||||
RealType result = 0; // of Argument checks:
|
||||
if(false == poisson_detail::check_prob(
|
||||
"boost::math::quantile(const poisson_distribution<%1%>&, %1%)",
|
||||
p,
|
||||
&result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
// Special case:
|
||||
if (dist.mean() == 0)
|
||||
{ // if mean = 0 then p = 0, so k can be anything?
|
||||
if (false == poisson_detail::check_mean_NZ(
|
||||
"boost::math::quantile(const poisson_distribution<%1%>&, %1%)",
|
||||
dist.mean(),
|
||||
&result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
/*
|
||||
BOOST_MATH_STD_USING // ADL of std functions.
|
||||
// if(p == 0) NOT necessarily zero!
|
||||
// Not necessarily any special value of k because is unlimited.
|
||||
if (p <= exp(-dist.mean()))
|
||||
{ // if p <= cdf for 0 events (== pdf for 0 events), then quantile must be zero.
|
||||
return 0;
|
||||
}
|
||||
return gamma_q_inva(dist.mean(), p, Policy()) - 1;
|
||||
*/
|
||||
typedef typename Policy::discrete_quantile_type discrete_type;
|
||||
boost::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
|
||||
RealType guess, factor = 8;
|
||||
RealType z = dist.mean();
|
||||
if(z < 1)
|
||||
guess = z;
|
||||
else
|
||||
guess = boost::math::detail::inverse_poisson_cornish_fisher(z, p, RealType(1-p), Policy());
|
||||
if(z > 5)
|
||||
{
|
||||
if(z > 1000)
|
||||
factor = 1.01f;
|
||||
else if(z > 50)
|
||||
factor = 1.1f;
|
||||
else if(guess > 10)
|
||||
factor = 1.25f;
|
||||
else
|
||||
factor = 2;
|
||||
if(guess < 1.1)
|
||||
factor = 8;
|
||||
}
|
||||
|
||||
return detail::inverse_discrete_quantile(
|
||||
dist,
|
||||
p,
|
||||
1-p,
|
||||
guess,
|
||||
factor,
|
||||
RealType(1),
|
||||
discrete_type(),
|
||||
max_iter);
|
||||
} // quantile
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const complemented2_type<poisson_distribution<RealType, Policy>, RealType>& c)
|
||||
{ // Quantile (or Percent Point) of Poisson function.
|
||||
// Return the number of expected events k for a given
|
||||
// complement of the probability q.
|
||||
//
|
||||
// Error checks:
|
||||
RealType q = c.param;
|
||||
const poisson_distribution<RealType, Policy>& dist = c.dist;
|
||||
RealType result = 0; // of argument checks.
|
||||
if(false == poisson_detail::check_prob(
|
||||
"boost::math::quantile(const poisson_distribution<%1%>&, %1%)",
|
||||
q,
|
||||
&result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
// Special case:
|
||||
if (dist.mean() == 0)
|
||||
{ // if mean = 0 then p = 0, so k can be anything?
|
||||
if (false == poisson_detail::check_mean_NZ(
|
||||
"boost::math::quantile(const poisson_distribution<%1%>&, %1%)",
|
||||
dist.mean(),
|
||||
&result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
/*
|
||||
if (-q <= boost::math::expm1(-dist.mean()))
|
||||
{ // if q <= cdf(complement for 0 events, then quantile must be zero.
|
||||
return 0;
|
||||
}
|
||||
return gamma_p_inva(dist.mean(), q, Policy()) -1;
|
||||
*/
|
||||
typedef typename Policy::discrete_quantile_type discrete_type;
|
||||
boost::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
|
||||
RealType guess, factor = 8;
|
||||
RealType z = dist.mean();
|
||||
if(z < 1)
|
||||
guess = z;
|
||||
else
|
||||
guess = boost::math::detail::inverse_poisson_cornish_fisher(z, RealType(1-q), q, Policy());
|
||||
if(z > 5)
|
||||
{
|
||||
if(z > 1000)
|
||||
factor = 1.01f;
|
||||
else if(z > 50)
|
||||
factor = 1.1f;
|
||||
else if(guess > 10)
|
||||
factor = 1.25f;
|
||||
else
|
||||
factor = 2;
|
||||
if(guess < 1.1)
|
||||
factor = 8;
|
||||
}
|
||||
|
||||
return detail::inverse_discrete_quantile(
|
||||
dist,
|
||||
1-q,
|
||||
q,
|
||||
guess,
|
||||
factor,
|
||||
RealType(1),
|
||||
discrete_type(),
|
||||
max_iter);
|
||||
} // quantile complement.
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
// This include must be at the end, *after* the accessors
|
||||
// for this distribution have been defined, in order to
|
||||
// keep compilers that support two-phase lookup happy.
|
||||
#include <boost/math/distributions/detail/derived_accessors.hpp>
|
||||
#include <boost/math/distributions/detail/inv_discrete_quantile.hpp>
|
||||
|
||||
#endif // BOOST_MATH_SPECIAL_POISSON_HPP
|
||||
|
||||
|
||||
|
||||
293
test/external/boost/math/distributions/rayleigh.hpp
vendored
Normal file
293
test/external/boost/math/distributions/rayleigh.hpp
vendored
Normal file
@@ -0,0 +1,293 @@
|
||||
// Copyright Paul A. Bristow 2007.
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_STATS_rayleigh_HPP
|
||||
#define BOOST_STATS_rayleigh_HPP
|
||||
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#include <boost/math/constants/constants.hpp>
|
||||
#include <boost/math/special_functions/log1p.hpp>
|
||||
#include <boost/math/special_functions/expm1.hpp>
|
||||
#include <boost/math/distributions/complement.hpp>
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp>
|
||||
#include <boost/config/no_tr1/cmath.hpp>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4702) // unreachable code (return after domain_error throw).
|
||||
#endif
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace boost{ namespace math{
|
||||
|
||||
namespace detail
|
||||
{ // Error checks:
|
||||
template <class RealType, class Policy>
|
||||
inline bool verify_sigma(const char* function, RealType sigma, RealType* presult, const Policy& pol)
|
||||
{
|
||||
if(sigma <= 0)
|
||||
{
|
||||
*presult = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"The scale parameter \"sigma\" must be > 0, but was: %1%.", sigma, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // bool verify_sigma
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool verify_rayleigh_x(const char* function, RealType x, RealType* presult, const Policy& pol)
|
||||
{
|
||||
if(x < 0)
|
||||
{
|
||||
*presult = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"The random variable must be >= 0, but was: %1%.", x, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // bool verify_rayleigh_x
|
||||
} // namespace detail
|
||||
|
||||
template <class RealType = double, class Policy = policies::policy<> >
|
||||
class rayleigh_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
|
||||
rayleigh_distribution(RealType sigma = 1)
|
||||
: m_sigma(sigma)
|
||||
{
|
||||
RealType err;
|
||||
detail::verify_sigma("boost::math::rayleigh_distribution<%1%>::rayleigh_distribution", sigma, &err, Policy());
|
||||
} // rayleigh_distribution
|
||||
|
||||
RealType sigma()const
|
||||
{ // Accessor.
|
||||
return m_sigma;
|
||||
}
|
||||
|
||||
private:
|
||||
RealType m_sigma;
|
||||
}; // class rayleigh_distribution
|
||||
|
||||
typedef rayleigh_distribution<double> rayleigh;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const rayleigh_distribution<RealType, Policy>& /*dist*/)
|
||||
{ // Range of permissible values for random variable x.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> support(const rayleigh_distribution<RealType, Policy>& /*dist*/)
|
||||
{ // Range of supported values for random variable x.
|
||||
// This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType pdf(const rayleigh_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std function exp.
|
||||
|
||||
RealType sigma = dist.sigma();
|
||||
RealType result = 0;
|
||||
static const char* function = "boost::math::pdf(const rayleigh_distribution<%1%>&, %1%)";
|
||||
if(false == detail::verify_sigma(function, sigma, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(false == detail::verify_rayleigh_x(function, x, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
RealType sigmasqr = sigma * sigma;
|
||||
result = x * (exp(-(x * x) / ( 2 * sigmasqr))) / sigmasqr;
|
||||
return result;
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const rayleigh_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
RealType result = 0;
|
||||
RealType sigma = dist.sigma();
|
||||
static const char* function = "boost::math::cdf(const rayleigh_distribution<%1%>&, %1%)";
|
||||
if(false == detail::verify_sigma(function, sigma, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(false == detail::verify_rayleigh_x(function, x, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
result = -boost::math::expm1(-x * x / ( 2 * sigma * sigma), Policy());
|
||||
return result;
|
||||
} // cdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const rayleigh_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
RealType result = 0;
|
||||
RealType sigma = dist.sigma();
|
||||
static const char* function = "boost::math::quantile(const rayleigh_distribution<%1%>&, %1%)";
|
||||
if(false == detail::verify_sigma(function, sigma, &result, Policy()))
|
||||
return result;
|
||||
if(false == detail::check_probability(function, p, &result, Policy()))
|
||||
return result;
|
||||
|
||||
if(p == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if(p == 1)
|
||||
{
|
||||
return policies::raise_overflow_error<RealType>(function, 0, Policy());
|
||||
}
|
||||
result = sqrt(-2 * sigma * sigma * boost::math::log1p(-p, Policy()));
|
||||
return result;
|
||||
} // quantile
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const complemented2_type<rayleigh_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
RealType result = 0;
|
||||
RealType sigma = c.dist.sigma();
|
||||
static const char* function = "boost::math::cdf(const rayleigh_distribution<%1%>&, %1%)";
|
||||
if(false == detail::verify_sigma(function, sigma, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
RealType x = c.param;
|
||||
if(false == detail::verify_rayleigh_x(function, x, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
result = exp(-x * x / ( 2 * sigma * sigma));
|
||||
return result;
|
||||
} // cdf complement
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const complemented2_type<rayleigh_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions, log & sqrt.
|
||||
|
||||
RealType result = 0;
|
||||
RealType sigma = c.dist.sigma();
|
||||
static const char* function = "boost::math::quantile(const rayleigh_distribution<%1%>&, %1%)";
|
||||
if(false == detail::verify_sigma(function, sigma, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
RealType q = c.param;
|
||||
if(false == detail::check_probability(function, q, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(q == 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if(q == 0)
|
||||
{
|
||||
return policies::raise_overflow_error<RealType>(function, 0, Policy());
|
||||
}
|
||||
result = sqrt(-2 * sigma * sigma * log(q));
|
||||
return result;
|
||||
} // quantile complement
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mean(const rayleigh_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType result = 0;
|
||||
RealType sigma = dist.sigma();
|
||||
static const char* function = "boost::math::mean(const rayleigh_distribution<%1%>&, %1%)";
|
||||
if(false == detail::verify_sigma(function, sigma, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
using boost::math::constants::root_half_pi;
|
||||
return sigma * root_half_pi<RealType>();
|
||||
} // mean
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType variance(const rayleigh_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType result = 0;
|
||||
RealType sigma = dist.sigma();
|
||||
static const char* function = "boost::math::variance(const rayleigh_distribution<%1%>&, %1%)";
|
||||
if(false == detail::verify_sigma(function, sigma, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
using boost::math::constants::four_minus_pi;
|
||||
return four_minus_pi<RealType>() * sigma * sigma / 2;
|
||||
} // variance
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mode(const rayleigh_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
return dist.sigma();
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType median(const rayleigh_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
using boost::math::constants::root_ln_four;
|
||||
return root_ln_four<RealType>() * dist.sigma();
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType skewness(const rayleigh_distribution<RealType, Policy>& /*dist*/)
|
||||
{
|
||||
// using namespace boost::math::constants;
|
||||
return static_cast<RealType>(0.63111065781893713819189935154422777984404221106391L);
|
||||
// Computed using NTL at 150 bit, about 50 decimal digits.
|
||||
// return 2 * root_pi<RealType>() * pi_minus_three<RealType>() / pow23_four_minus_pi<RealType>();
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis(const rayleigh_distribution<RealType, Policy>& /*dist*/)
|
||||
{
|
||||
// using namespace boost::math::constants;
|
||||
return static_cast<RealType>(3.2450893006876380628486604106197544154170667057995L);
|
||||
// Computed using NTL at 150 bit, about 50 decimal digits.
|
||||
// return 3 - (6 * pi<RealType>() * pi<RealType>() - 24 * pi<RealType>() + 16) /
|
||||
// (four_minus_pi<RealType>() * four_minus_pi<RealType>());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis_excess(const rayleigh_distribution<RealType, Policy>& /*dist*/)
|
||||
{
|
||||
//using namespace boost::math::constants;
|
||||
// Computed using NTL at 150 bit, about 50 decimal digits.
|
||||
return static_cast<RealType>(0.2450893006876380628486604106197544154170667057995L);
|
||||
// return -(6 * pi<RealType>() * pi<RealType>() - 24 * pi<RealType>() + 16) /
|
||||
// (four_minus_pi<RealType>() * four_minus_pi<RealType>());
|
||||
} // kurtosis
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
// This include must be at the end, *after* the accessors
|
||||
// for this distribution have been defined, in order to
|
||||
// keep compilers that support two-phase lookup happy.
|
||||
#include <boost/math/distributions/detail/derived_accessors.hpp>
|
||||
|
||||
#endif // BOOST_STATS_rayleigh_HPP
|
||||
374
test/external/boost/math/distributions/students_t.hpp
vendored
Normal file
374
test/external/boost/math/distributions/students_t.hpp
vendored
Normal file
@@ -0,0 +1,374 @@
|
||||
// Copyright John Maddock 2006.
|
||||
// Copyright Paul A. Bristow 2006.
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_STATS_STUDENTS_T_HPP
|
||||
#define BOOST_STATS_STUDENTS_T_HPP
|
||||
|
||||
// http://en.wikipedia.org/wiki/Student%27s_t_distribution
|
||||
// http://www.itl.nist.gov/div898/handbook/eda/section3/eda3664.htm
|
||||
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#include <boost/math/special_functions/beta.hpp> // for ibeta(a, b, x).
|
||||
#include <boost/math/distributions/complement.hpp>
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4702) // unreachable code (return after domain_error throw).
|
||||
#endif
|
||||
|
||||
namespace boost{ namespace math{
|
||||
|
||||
template <class RealType = double, class Policy = policies::policy<> >
|
||||
class students_t_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
|
||||
students_t_distribution(RealType i) : m_df(i)
|
||||
{ // Constructor.
|
||||
RealType result;
|
||||
detail::check_df(
|
||||
"boost::math::students_t_distribution<%1%>::students_t_distribution", m_df, &result, Policy());
|
||||
} // students_t_distribution
|
||||
|
||||
RealType degrees_of_freedom()const
|
||||
{
|
||||
return m_df;
|
||||
}
|
||||
|
||||
// Parameter estimation:
|
||||
static RealType find_degrees_of_freedom(
|
||||
RealType difference_from_mean,
|
||||
RealType alpha,
|
||||
RealType beta,
|
||||
RealType sd,
|
||||
RealType hint = 100);
|
||||
|
||||
private:
|
||||
//
|
||||
// Data members:
|
||||
//
|
||||
RealType m_df; // degrees of freedom are a real number.
|
||||
};
|
||||
|
||||
typedef students_t_distribution<double> students_t;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const students_t_distribution<RealType, Policy>& /*dist*/)
|
||||
{ // Range of permissible values for random variable x.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(-max_value<RealType>(), max_value<RealType>());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> support(const students_t_distribution<RealType, Policy>& /*dist*/)
|
||||
{ // Range of supported values for random variable x.
|
||||
// This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(-max_value<RealType>(), max_value<RealType>());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType pdf(const students_t_distribution<RealType, Policy>& dist, const RealType& t)
|
||||
{
|
||||
BOOST_FPU_EXCEPTION_GUARD
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
RealType degrees_of_freedom = dist.degrees_of_freedom();
|
||||
// Error check:
|
||||
RealType error_result;
|
||||
if(false == detail::check_df(
|
||||
"boost::math::pdf(const students_t_distribution<%1%>&, %1%)", degrees_of_freedom, &error_result, Policy()))
|
||||
return error_result;
|
||||
// Might conceivably permit df = +infinity and use normal distribution.
|
||||
RealType result;
|
||||
RealType basem1 = t * t / degrees_of_freedom;
|
||||
if(basem1 < 0.125)
|
||||
{
|
||||
result = exp(-boost::math::log1p(basem1, Policy()) * (1+degrees_of_freedom) / 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = pow(1 / (1 + basem1), (degrees_of_freedom + 1) / 2);
|
||||
}
|
||||
result /= sqrt(degrees_of_freedom) * boost::math::beta(degrees_of_freedom / 2, RealType(0.5f), Policy());
|
||||
return result;
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const students_t_distribution<RealType, Policy>& dist, const RealType& t)
|
||||
{
|
||||
RealType degrees_of_freedom = dist.degrees_of_freedom();
|
||||
// Error check:
|
||||
RealType error_result;
|
||||
if(false == detail::check_df(
|
||||
"boost::math::cdf(const students_t_distribution<%1%>&, %1%)", degrees_of_freedom, &error_result, Policy()))
|
||||
return error_result;
|
||||
|
||||
if (t == 0)
|
||||
{
|
||||
return 0.5;
|
||||
}
|
||||
//
|
||||
// Calculate probability of Student's t using the incomplete beta function.
|
||||
// probability = ibeta(degrees_of_freedom / 2, 1/2, degrees_of_freedom / (degrees_of_freedom + t*t))
|
||||
//
|
||||
// However when t is small compared to the degrees of freedom, that formula
|
||||
// suffers from rounding error, use the identity formula to work around
|
||||
// the problem:
|
||||
//
|
||||
// I[x](a,b) = 1 - I[1-x](b,a)
|
||||
//
|
||||
// and:
|
||||
//
|
||||
// x = df / (df + t^2)
|
||||
//
|
||||
// so:
|
||||
//
|
||||
// 1 - x = t^2 / (df + t^2)
|
||||
//
|
||||
RealType t2 = t * t;
|
||||
RealType probability;
|
||||
if(degrees_of_freedom > 2 * t2)
|
||||
{
|
||||
RealType z = t2 / (degrees_of_freedom + t2);
|
||||
probability = ibetac(static_cast<RealType>(0.5), degrees_of_freedom / 2, z, Policy()) / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
RealType z = degrees_of_freedom / (degrees_of_freedom + t2);
|
||||
probability = ibeta(degrees_of_freedom / 2, static_cast<RealType>(0.5), z, Policy()) / 2;
|
||||
}
|
||||
return (t > 0 ? 1 - probability : probability);
|
||||
} // cdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const students_t_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
//
|
||||
// Obtain parameters:
|
||||
//
|
||||
RealType degrees_of_freedom = dist.degrees_of_freedom();
|
||||
RealType probability = p;
|
||||
//
|
||||
// Check for domain errors:
|
||||
//
|
||||
static const char* function = "boost::math::quantile(const students_t_distribution<%1%>&, %1%)";
|
||||
RealType error_result;
|
||||
if(false == detail::check_df(
|
||||
function, degrees_of_freedom, &error_result, Policy())
|
||||
&& detail::check_probability(function, probability, &error_result, Policy()))
|
||||
return error_result;
|
||||
|
||||
// Special cases, regardless of degrees_of_freedom.
|
||||
if (probability == 0)
|
||||
return -policies::raise_overflow_error<RealType>(function, 0, Policy());
|
||||
if (probability == 1)
|
||||
return policies::raise_overflow_error<RealType>(function, 0, Policy());
|
||||
if (probability == static_cast<RealType>(0.5))
|
||||
return 0;
|
||||
//
|
||||
// This next block is disabled in favour of a faster method than
|
||||
// incomplete beta inverse, code retained for future reference:
|
||||
//
|
||||
#if 0
|
||||
//
|
||||
// Calculate quantile of Student's t using the incomplete beta function inverse:
|
||||
//
|
||||
probability = (probability > 0.5) ? 1 - probability : probability;
|
||||
RealType t, x, y;
|
||||
x = ibeta_inv(degrees_of_freedom / 2, RealType(0.5), 2 * probability, &y);
|
||||
if(degrees_of_freedom * y > tools::max_value<RealType>() * x)
|
||||
t = tools::overflow_error<RealType>(function);
|
||||
else
|
||||
t = sqrt(degrees_of_freedom * y / x);
|
||||
//
|
||||
// Figure out sign based on the size of p:
|
||||
//
|
||||
if(p < 0.5)
|
||||
t = -t;
|
||||
|
||||
return t;
|
||||
#endif
|
||||
//
|
||||
// Depending on how many digits RealType has, this may forward
|
||||
// to the incomplete beta inverse as above. Otherwise uses a
|
||||
// faster method that is accurate to ~15 digits everywhere
|
||||
// and a couple of epsilon at double precision and in the central
|
||||
// region where most use cases will occur...
|
||||
//
|
||||
return boost::math::detail::fast_students_t_quantile(degrees_of_freedom, probability, Policy());
|
||||
} // quantile
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const complemented2_type<students_t_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
return cdf(c.dist, -c.param);
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const complemented2_type<students_t_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
return -quantile(c.dist, c.param);
|
||||
}
|
||||
|
||||
//
|
||||
// Parameter estimation follows:
|
||||
//
|
||||
namespace detail{
|
||||
//
|
||||
// Functors for finding degrees of freedom:
|
||||
//
|
||||
template <class RealType, class Policy>
|
||||
struct sample_size_func
|
||||
{
|
||||
sample_size_func(RealType a, RealType b, RealType s, RealType d)
|
||||
: alpha(a), beta(b), ratio(s*s/(d*d)) {}
|
||||
|
||||
RealType operator()(const RealType& df)
|
||||
{
|
||||
if(df <= tools::min_value<RealType>())
|
||||
return 1;
|
||||
students_t_distribution<RealType, Policy> t(df);
|
||||
RealType qa = quantile(complement(t, alpha));
|
||||
RealType qb = quantile(complement(t, beta));
|
||||
qa += qb;
|
||||
qa *= qa;
|
||||
qa *= ratio;
|
||||
qa -= (df + 1);
|
||||
return qa;
|
||||
}
|
||||
RealType alpha, beta, ratio;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class RealType, class Policy>
|
||||
RealType students_t_distribution<RealType, Policy>::find_degrees_of_freedom(
|
||||
RealType difference_from_mean,
|
||||
RealType alpha,
|
||||
RealType beta,
|
||||
RealType sd,
|
||||
RealType hint)
|
||||
{
|
||||
static const char* function = "boost::math::students_t_distribution<%1%>::find_degrees_of_freedom";
|
||||
//
|
||||
// Check for domain errors:
|
||||
//
|
||||
RealType error_result;
|
||||
if(false == detail::check_probability(
|
||||
function, alpha, &error_result, Policy())
|
||||
&& detail::check_probability(function, beta, &error_result, Policy()))
|
||||
return error_result;
|
||||
|
||||
if(hint <= 0)
|
||||
hint = 1;
|
||||
|
||||
detail::sample_size_func<RealType, Policy> f(alpha, beta, sd, difference_from_mean);
|
||||
tools::eps_tolerance<RealType> tol(policies::digits<RealType, Policy>());
|
||||
boost::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
|
||||
std::pair<RealType, RealType> r = tools::bracket_and_solve_root(f, hint, RealType(2), false, tol, max_iter, Policy());
|
||||
RealType result = r.first + (r.second - r.first) / 2;
|
||||
if(max_iter >= policies::get_max_root_iterations<Policy>())
|
||||
{
|
||||
policies::raise_evaluation_error<RealType>(function, "Unable to locate solution in a reasonable time:"
|
||||
" either there is no answer to how many degrees of freedom are required"
|
||||
" or the answer is infinite. Current best guess is %1%", result, Policy());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mean(const students_t_distribution<RealType, Policy>& )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType variance(const students_t_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
// Error check:
|
||||
RealType error_result;
|
||||
if(false == detail::check_df(
|
||||
"boost::math::variance(students_t_distribution<%1%> const&, %1%)", dist.degrees_of_freedom(), &error_result, Policy()))
|
||||
return error_result;
|
||||
|
||||
RealType v = dist.degrees_of_freedom();
|
||||
return v / (v - 2);
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mode(const students_t_distribution<RealType, Policy>& /*dist*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType median(const students_t_distribution<RealType, Policy>& /*dist*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType skewness(const students_t_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
if(dist.degrees_of_freedom() <= 3)
|
||||
{
|
||||
policies::raise_domain_error<RealType>(
|
||||
"boost::math::skewness(students_t_distribution<%1%> const&, %1%)",
|
||||
"Skewness is undefined for degrees of freedom <= 3, but got %1%.",
|
||||
dist.degrees_of_freedom(), Policy());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis(const students_t_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType df = dist.degrees_of_freedom();
|
||||
if(df <= 3)
|
||||
{
|
||||
policies::raise_domain_error<RealType>(
|
||||
"boost::math::kurtosis(students_t_distribution<%1%> const&, %1%)",
|
||||
"Skewness is undefined for degrees of freedom <= 3, but got %1%.",
|
||||
df, Policy());
|
||||
}
|
||||
return 3 * (df - 2) / (df - 4);
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis_excess(const students_t_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
// see http://mathworld.wolfram.com/Kurtosis.html
|
||||
RealType df = dist.degrees_of_freedom();
|
||||
if(df <= 3)
|
||||
{
|
||||
policies::raise_domain_error<RealType>(
|
||||
"boost::math::kurtosis_excess(students_t_distribution<%1%> const&, %1%)",
|
||||
"Skewness is undefined for degrees of freedom <= 3, but got %1%.",
|
||||
df, Policy());
|
||||
}
|
||||
return 6 / (df - 4);
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
// This include must be at the end, *after* the accessors
|
||||
// for this distribution have been defined, in order to
|
||||
// keep compilers that support two-phase lookup happy.
|
||||
#include <boost/math/distributions/detail/derived_accessors.hpp>
|
||||
|
||||
#endif // BOOST_STATS_STUDENTS_T_HPP
|
||||
523
test/external/boost/math/distributions/triangular.hpp
vendored
Normal file
523
test/external/boost/math/distributions/triangular.hpp
vendored
Normal file
@@ -0,0 +1,523 @@
|
||||
// Copyright John Maddock 2006, 2007.
|
||||
// Copyright Paul A. Bristow 2006, 2007.
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_STATS_TRIANGULAR_HPP
|
||||
#define BOOST_STATS_TRIANGULAR_HPP
|
||||
|
||||
// http://mathworld.wolfram.com/TriangularDistribution.html
|
||||
// http://en.wikipedia.org/wiki/Triangular_distribution
|
||||
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#include <boost/math/special_functions/expm1.hpp>
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp>
|
||||
#include <boost/math/distributions/complement.hpp>
|
||||
#include <boost/math/constants/constants.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace boost{ namespace math
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_triangular_lower(
|
||||
const char* function,
|
||||
RealType lower,
|
||||
RealType* result, const Policy& pol)
|
||||
{
|
||||
if((boost::math::isfinite)(lower))
|
||||
{ // Any finite value is OK.
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{ // Not finite: infinity or NaN.
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Lower parameter is %1%, but must be finite!", lower, pol);
|
||||
return false;
|
||||
}
|
||||
} // bool check_triangular_lower(
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_triangular_mode(
|
||||
const char* function,
|
||||
RealType mode,
|
||||
RealType* result, const Policy& pol)
|
||||
{
|
||||
if((boost::math::isfinite)(mode))
|
||||
{ // any finite value is OK.
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{ // Not finite: infinity or NaN.
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Mode parameter is %1%, but must be finite!", mode, pol);
|
||||
return false;
|
||||
}
|
||||
} // bool check_triangular_mode(
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_triangular_upper(
|
||||
const char* function,
|
||||
RealType upper,
|
||||
RealType* result, const Policy& pol)
|
||||
{
|
||||
if((boost::math::isfinite)(upper))
|
||||
{ // any finite value is OK.
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{ // Not finite: infinity or NaN.
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Upper parameter is %1%, but must be finite!", upper, pol);
|
||||
return false;
|
||||
}
|
||||
} // bool check_triangular_upper(
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_triangular_x(
|
||||
const char* function,
|
||||
RealType const& x,
|
||||
RealType* result, const Policy& pol)
|
||||
{
|
||||
if((boost::math::isfinite)(x))
|
||||
{ // Any finite value is OK
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{ // Not finite: infinity or NaN.
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"x parameter is %1%, but must be finite!", x, pol);
|
||||
return false;
|
||||
}
|
||||
} // bool check_triangular_x
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_triangular(
|
||||
const char* function,
|
||||
RealType lower,
|
||||
RealType mode,
|
||||
RealType upper,
|
||||
RealType* result, const Policy& pol)
|
||||
{
|
||||
if ((check_triangular_lower(function, lower, result, pol) == false)
|
||||
|| (check_triangular_mode(function, mode, result, pol) == false)
|
||||
|| (check_triangular_upper(function, upper, result, pol) == false))
|
||||
{ // Some parameter not finite.
|
||||
return false;
|
||||
}
|
||||
else if (lower >= upper) // lower == upper NOT useful.
|
||||
{ // lower >= upper.
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"lower parameter is %1%, but must be less than upper!", lower, pol);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{ // Check lower <= mode <= upper.
|
||||
if (mode < lower)
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"mode parameter is %1%, but must be >= than lower!", lower, pol);
|
||||
return false;
|
||||
}
|
||||
if (mode > upper)
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"mode parameter is %1%, but must be <= than upper!", upper, pol);
|
||||
return false;
|
||||
}
|
||||
return true; // All OK.
|
||||
}
|
||||
} // bool check_triangular
|
||||
} // namespace detail
|
||||
|
||||
template <class RealType = double, class Policy = policies::policy<> >
|
||||
class triangular_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
|
||||
triangular_distribution(RealType lower = -1, RealType mode = 0, RealType upper = 1)
|
||||
: m_lower(lower), m_mode(mode), m_upper(upper) // Constructor.
|
||||
{ // Evans says 'standard triangular' is lower 0, mode 1/2, upper 1,
|
||||
// has median sqrt(c/2) for c <=1/2 and 1 - sqrt(1-c)/2 for c >= 1/2
|
||||
// But this -1, 0, 1 is more useful in most applications to approximate normal distribution,
|
||||
// where the central value is the most likely and deviations either side equally likely.
|
||||
RealType result;
|
||||
detail::check_triangular("boost::math::triangular_distribution<%1%>::triangular_distribution",lower, mode, upper, &result, Policy());
|
||||
}
|
||||
// Accessor functions.
|
||||
RealType lower()const
|
||||
{
|
||||
return m_lower;
|
||||
}
|
||||
RealType mode()const
|
||||
{
|
||||
return m_mode;
|
||||
}
|
||||
RealType upper()const
|
||||
{
|
||||
return m_upper;
|
||||
}
|
||||
private:
|
||||
// Data members:
|
||||
RealType m_lower; // distribution lower aka a
|
||||
RealType m_mode; // distribution mode aka c
|
||||
RealType m_upper; // distribution upper aka b
|
||||
}; // class triangular_distribution
|
||||
|
||||
typedef triangular_distribution<double> triangular;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const triangular_distribution<RealType, Policy>& /* dist */)
|
||||
{ // Range of permissible values for random variable x.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(-max_value<RealType>(), max_value<RealType>());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> support(const triangular_distribution<RealType, Policy>& dist)
|
||||
{ // Range of supported values for random variable x.
|
||||
// This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
|
||||
return std::pair<RealType, RealType>(dist.lower(), dist.upper());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
RealType pdf(const triangular_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
static const char* function = "boost::math::pdf(const triangular_distribution<%1%>&, %1%)";
|
||||
RealType lower = dist.lower();
|
||||
RealType mode = dist.mode();
|
||||
RealType upper = dist.upper();
|
||||
RealType result = 0; // of checks.
|
||||
if(false == detail::check_triangular(function, lower, mode, upper, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(false == detail::check_triangular_x(function, x, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if((x < lower) || (x > upper))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (x == lower)
|
||||
{ // (mode - lower) == 0 which would lead to divide by zero!
|
||||
return (mode == lower) ? 2 / (upper - lower) : RealType(0);
|
||||
}
|
||||
else if (x == upper)
|
||||
{
|
||||
return (mode == upper) ? 2 / (upper - lower) : RealType(0);
|
||||
}
|
||||
else if (x <= mode)
|
||||
{
|
||||
return 2 * (x - lower) / ((upper - lower) * (mode - lower));
|
||||
}
|
||||
else
|
||||
{ // (x > mode)
|
||||
return 2 * (upper - x) / ((upper - lower) * (upper - mode));
|
||||
}
|
||||
} // RealType pdf(const triangular_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const triangular_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
static const char* function = "boost::math::cdf(const triangular_distribution<%1%>&, %1%)";
|
||||
RealType lower = dist.lower();
|
||||
RealType mode = dist.mode();
|
||||
RealType upper = dist.upper();
|
||||
RealType result = 0; // of checks.
|
||||
if(false == detail::check_triangular(function, lower, mode, upper, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(false == detail::check_triangular_x(function, x, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if((x <= lower))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (x >= upper)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
// else lower < x < upper
|
||||
if (x <= mode)
|
||||
{
|
||||
return ((x - lower) * (x - lower)) / ((upper - lower) * (mode - lower));
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1 - (upper - x) * (upper - x) / ((upper - lower) * (upper - mode));
|
||||
}
|
||||
} // RealType cdf(const triangular_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
|
||||
template <class RealType, class Policy>
|
||||
RealType quantile(const triangular_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions (sqrt).
|
||||
static const char* function = "boost::math::quantile(const triangular_distribution<%1%>&, %1%)";
|
||||
RealType lower = dist.lower();
|
||||
RealType mode = dist.mode();
|
||||
RealType upper = dist.upper();
|
||||
RealType result = 0; // of checks
|
||||
if(false == detail::check_triangular(function,lower, mode, upper, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(false == detail::check_probability(function, p, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(p == 0)
|
||||
{
|
||||
return lower;
|
||||
}
|
||||
if(p == 1)
|
||||
{
|
||||
return upper;
|
||||
}
|
||||
RealType p0 = (mode - lower) / (upper - lower);
|
||||
RealType q = 1 - p;
|
||||
if (p < p0)
|
||||
{
|
||||
result = sqrt((upper - lower) * (mode - lower) * p) + lower;
|
||||
}
|
||||
else if (p == p0)
|
||||
{
|
||||
result = mode;
|
||||
}
|
||||
else // p > p0
|
||||
{
|
||||
result = upper - sqrt((upper - lower) * (upper - mode) * q);
|
||||
}
|
||||
return result;
|
||||
|
||||
} // RealType quantile(const triangular_distribution<RealType, Policy>& dist, const RealType& q)
|
||||
|
||||
template <class RealType, class Policy>
|
||||
RealType cdf(const complemented2_type<triangular_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
static const char* function = "boost::math::cdf(const triangular_distribution<%1%>&, %1%)";
|
||||
RealType lower = c.dist.lower();
|
||||
RealType mode = c.dist.mode();
|
||||
RealType upper = c.dist.upper();
|
||||
RealType x = c.param;
|
||||
RealType result = 0; // of checks.
|
||||
if(false == detail::check_triangular(function, lower, mode, upper, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(false == detail::check_triangular_x(function, x, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if (x <= lower)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (x >= upper)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (x <= mode)
|
||||
{
|
||||
return 1 - ((x - lower) * (x - lower)) / ((upper - lower) * (mode - lower));
|
||||
}
|
||||
else
|
||||
{
|
||||
return (upper - x) * (upper - x) / ((upper - lower) * (upper - mode));
|
||||
}
|
||||
} // RealType cdf(const complemented2_type<triangular_distribution<RealType, Policy>, RealType>& c)
|
||||
|
||||
template <class RealType, class Policy>
|
||||
RealType quantile(const complemented2_type<triangular_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
BOOST_MATH_STD_USING // Aid ADL for sqrt.
|
||||
static const char* function = "boost::math::quantile(const triangular_distribution<%1%>&, %1%)";
|
||||
RealType l = c.dist.lower();
|
||||
RealType m = c.dist.mode();
|
||||
RealType u = c.dist.upper();
|
||||
RealType q = c.param; // probability 0 to 1.
|
||||
RealType result = 0; // of checks.
|
||||
if(false == detail::check_triangular(function, l, m, u, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(false == detail::check_probability(function, q, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(q == 0)
|
||||
{
|
||||
return u;
|
||||
}
|
||||
if(q == 1)
|
||||
{
|
||||
return l;
|
||||
}
|
||||
RealType lower = c.dist.lower();
|
||||
RealType mode = c.dist.mode();
|
||||
RealType upper = c.dist.upper();
|
||||
|
||||
RealType p = 1 - q;
|
||||
RealType p0 = (mode - lower) / (upper - lower);
|
||||
if(p < p0)
|
||||
{
|
||||
RealType s = (upper - lower) * (mode - lower);
|
||||
s *= p;
|
||||
result = sqrt((upper - lower) * (mode - lower) * p) + lower;
|
||||
}
|
||||
else if (p == p0)
|
||||
{
|
||||
result = mode;
|
||||
}
|
||||
else // p > p0
|
||||
{
|
||||
result = upper - sqrt((upper - lower) * (upper - mode) * q);
|
||||
}
|
||||
return result;
|
||||
} // RealType quantile(const complemented2_type<triangular_distribution<RealType, Policy>, RealType>& c)
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mean(const triangular_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
static const char* function = "boost::math::mean(const triangular_distribution<%1%>&)";
|
||||
RealType lower = dist.lower();
|
||||
RealType mode = dist.mode();
|
||||
RealType upper = dist.upper();
|
||||
RealType result = 0; // of checks.
|
||||
if(false == detail::check_triangular(function, lower, mode, upper, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return (lower + upper + mode) / 3;
|
||||
} // RealType mean(const triangular_distribution<RealType, Policy>& dist)
|
||||
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType variance(const triangular_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
static const char* function = "boost::math::mean(const triangular_distribution<%1%>&)";
|
||||
RealType lower = dist.lower();
|
||||
RealType mode = dist.mode();
|
||||
RealType upper = dist.upper();
|
||||
RealType result = 0; // of checks.
|
||||
if(false == detail::check_triangular(function, lower, mode, upper, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return (lower * lower + upper * upper + mode * mode - lower * upper - lower * mode - upper * mode) / 18;
|
||||
} // RealType variance(const triangular_distribution<RealType, Policy>& dist)
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mode(const triangular_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
static const char* function = "boost::math::mode(const triangular_distribution<%1%>&)";
|
||||
RealType mode = dist.mode();
|
||||
RealType result = 0; // of checks.
|
||||
if(false == detail::check_triangular_mode(function, mode, &result, Policy()))
|
||||
{ // This should never happen!
|
||||
return result;
|
||||
}
|
||||
return mode;
|
||||
} // RealType mode
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType median(const triangular_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING // ADL of std functions.
|
||||
static const char* function = "boost::math::median(const triangular_distribution<%1%>&)";
|
||||
RealType mode = dist.mode();
|
||||
RealType result = 0; // of checks.
|
||||
if(false == detail::check_triangular_mode(function, mode, &result, Policy()))
|
||||
{ // This should never happen!
|
||||
return result;
|
||||
}
|
||||
RealType lower = dist.lower();
|
||||
RealType upper = dist.upper();
|
||||
if (mode < (upper - lower) / 2)
|
||||
{
|
||||
return lower + sqrt((upper - lower) * (mode - lower)) / constants::root_two<RealType>();
|
||||
}
|
||||
else
|
||||
{
|
||||
return upper - sqrt((upper - lower) * (upper - mode)) / constants::root_two<RealType>();
|
||||
}
|
||||
} // RealType mode
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType skewness(const triangular_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
using namespace boost::math::constants; // for root_two
|
||||
static const char* function = "boost::math::skewness(const triangular_distribution<%1%>&)";
|
||||
|
||||
RealType lower = dist.lower();
|
||||
RealType mode = dist.mode();
|
||||
RealType upper = dist.upper();
|
||||
RealType result = 0; // of checks.
|
||||
if(false == detail::check_triangular(function,lower, mode, upper, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return root_two<RealType>() * (lower + upper - 2 * mode) * (2 * lower - upper - mode) * (lower - 2 * upper + mode) /
|
||||
(5 * pow((lower * lower + upper + upper + mode * mode - lower * upper - lower * mode - upper * mode), RealType(3)/RealType(2)));
|
||||
} // RealType skewness(const triangular_distribution<RealType, Policy>& dist)
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis(const triangular_distribution<RealType, Policy>& dist)
|
||||
{ // These checks may be belt and braces as should have been checked on construction?
|
||||
static const char* function = "boost::math::kurtosis(const triangular_distribution<%1%>&)";
|
||||
RealType lower = dist.lower();
|
||||
RealType upper = dist.upper();
|
||||
RealType mode = dist.mode();
|
||||
RealType result = 0; // of checks.
|
||||
if(false == detail::check_triangular(function,lower, mode, upper, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return static_cast<RealType>(12)/5; // 12/5 = 2.4;
|
||||
} // RealType kurtosis_excess(const triangular_distribution<RealType, Policy>& dist)
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis_excess(const triangular_distribution<RealType, Policy>& dist)
|
||||
{ // These checks may be belt and braces as should have been checked on construction?
|
||||
static const char* function = "boost::math::kurtosis_excess(const triangular_distribution<%1%>&)";
|
||||
RealType lower = dist.lower();
|
||||
RealType upper = dist.upper();
|
||||
RealType mode = dist.mode();
|
||||
RealType result = 0; // of checks.
|
||||
if(false == detail::check_triangular(function,lower, mode, upper, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return static_cast<RealType>(-3)/5; // - 3/5 = -0.6
|
||||
// Assuming mathworld really means kurtosis excess? Wikipedia now corrected to match this.
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
// This include must be at the end, *after* the accessors
|
||||
// for this distribution have been defined, in order to
|
||||
// keep compilers that support two-phase lookup happy.
|
||||
#include <boost/math/distributions/detail/derived_accessors.hpp>
|
||||
|
||||
#endif // BOOST_STATS_TRIANGULAR_HPP
|
||||
|
||||
|
||||
|
||||
379
test/external/boost/math/distributions/uniform.hpp
vendored
Normal file
379
test/external/boost/math/distributions/uniform.hpp
vendored
Normal file
@@ -0,0 +1,379 @@
|
||||
// Copyright John Maddock 2006.
|
||||
// Copyright Paul A. Bristow 2006.
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
// TODO deal with infinity as special better - or remove.
|
||||
//
|
||||
|
||||
#ifndef BOOST_STATS_UNIFORM_HPP
|
||||
#define BOOST_STATS_UNIFORM_HPP
|
||||
|
||||
// http://www.itl.nist.gov/div898/handbook/eda/section3/eda3668.htm
|
||||
// http://mathworld.wolfram.com/UniformDistribution.html
|
||||
// http://documents.wolfram.com/calculationcenter/v2/Functions/ListsMatrices/Statistics/UniformDistribution.html
|
||||
// http://en.wikipedia.org/wiki/Uniform_distribution_%28continuous%29
|
||||
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp>
|
||||
#include <boost/math/distributions/complement.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace boost{ namespace math
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_uniform_lower(
|
||||
const char* function,
|
||||
RealType lower,
|
||||
RealType* result, const Policy& pol)
|
||||
{
|
||||
if((boost::math::isfinite)(lower))
|
||||
{ // any finite value is OK.
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{ // Not finite.
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Lower parameter is %1%, but must be finite!", lower, pol);
|
||||
return false;
|
||||
}
|
||||
} // bool check_uniform_lower(
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_uniform_upper(
|
||||
const char* function,
|
||||
RealType upper,
|
||||
RealType* result, const Policy& pol)
|
||||
{
|
||||
if((boost::math::isfinite)(upper))
|
||||
{ // Any finite value is OK.
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{ // Not finite.
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Upper parameter is %1%, but must be finite!", upper, pol);
|
||||
return false;
|
||||
}
|
||||
} // bool check_uniform_upper(
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_uniform_x(
|
||||
const char* function,
|
||||
RealType const& x,
|
||||
RealType* result, const Policy& pol)
|
||||
{
|
||||
if((boost::math::isfinite)(x))
|
||||
{ // Any finite value is OK
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{ // Not finite..
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"x parameter is %1%, but must be finite!", x, pol);
|
||||
return false;
|
||||
}
|
||||
} // bool check_uniform_x
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_uniform(
|
||||
const char* function,
|
||||
RealType lower,
|
||||
RealType upper,
|
||||
RealType* result, const Policy& pol)
|
||||
{
|
||||
if((check_uniform_lower(function, lower, result, pol) == false)
|
||||
|| (check_uniform_upper(function, upper, result, pol) == false))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (lower >= upper) // If lower == upper then 1 / (upper-lower) = 1/0 = +infinity!
|
||||
{ // upper and lower have been checked before, so must be lower >= upper.
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"lower parameter is %1%, but must be less than upper!", lower, pol);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{ // All OK,
|
||||
return true;
|
||||
}
|
||||
} // bool check_uniform(
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class RealType = double, class Policy = policies::policy<> >
|
||||
class uniform_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
|
||||
uniform_distribution(RealType lower = 0, RealType upper = 1) // Constructor.
|
||||
: m_lower(lower), m_upper(upper) // Default is standard uniform distribution.
|
||||
{
|
||||
RealType result;
|
||||
detail::check_uniform("boost::math::uniform_distribution<%1%>::uniform_distribution", lower, upper, &result, Policy());
|
||||
}
|
||||
// Accessor functions.
|
||||
RealType lower()const
|
||||
{
|
||||
return m_lower;
|
||||
}
|
||||
|
||||
RealType upper()const
|
||||
{
|
||||
return m_upper;
|
||||
}
|
||||
private:
|
||||
// Data members:
|
||||
RealType m_lower; // distribution lower aka a.
|
||||
RealType m_upper; // distribution upper aka b.
|
||||
}; // class uniform_distribution
|
||||
|
||||
typedef uniform_distribution<double> uniform;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const uniform_distribution<RealType, Policy>& /* dist */)
|
||||
{ // Range of permissible values for random variable x.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(-max_value<RealType>(), max_value<RealType>()); // - to + 'infinity'.
|
||||
// Note RealType infinity is NOT permitted, only max_value.
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> support(const uniform_distribution<RealType, Policy>& dist)
|
||||
{ // Range of supported values for random variable x.
|
||||
// This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(dist.lower(), dist.upper());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType pdf(const uniform_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
RealType lower = dist.lower();
|
||||
RealType upper = dist.upper();
|
||||
RealType result = 0; // of checks.
|
||||
if(false == detail::check_uniform("boost::math::pdf(const uniform_distribution<%1%>&, %1%)", lower, upper, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(false == detail::check_uniform_x("boost::math::pdf(const uniform_distribution<%1%>&, %1%)", x, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if((x < lower) || (x > upper) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1 / (upper - lower);
|
||||
}
|
||||
} // RealType pdf(const uniform_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const uniform_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
RealType lower = dist.lower();
|
||||
RealType upper = dist.upper();
|
||||
RealType result = 0; // of checks.
|
||||
if(false == detail::check_uniform("boost::math::cdf(const uniform_distribution<%1%>&, %1%)",lower, upper, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(false == detail::check_uniform_x("boost::math::cdf(const uniform_distribution<%1%>&, %1%)", x, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if (x < lower)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (x > upper)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return (x - lower) / (upper - lower); // lower <= x <= upper
|
||||
} // RealType cdf(const uniform_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const uniform_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
{
|
||||
RealType lower = dist.lower();
|
||||
RealType upper = dist.upper();
|
||||
RealType result = 0; // of checks
|
||||
if(false == detail::check_uniform("boost::math::quantile(const uniform_distribution<%1%>&, %1%)",lower, upper, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(false == detail::check_probability("boost::math::quantile(const uniform_distribution<%1%>&, %1%)", p, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(p == 0)
|
||||
{
|
||||
return lower;
|
||||
}
|
||||
if(p == 1)
|
||||
{
|
||||
return upper;
|
||||
}
|
||||
return p * (upper - lower) + lower;
|
||||
} // RealType quantile(const uniform_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const complemented2_type<uniform_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
RealType lower = c.dist.lower();
|
||||
RealType upper = c.dist.upper();
|
||||
RealType x = c.param;
|
||||
RealType result = 0; // of checks.
|
||||
if(false == detail::check_uniform("boost::math::cdf(const uniform_distribution<%1%>&, %1%)", lower, upper, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(false == detail::check_uniform_x("boost::math::cdf(const uniform_distribution<%1%>&, %1%)", x, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if (x < lower)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (x > upper)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return (upper - x) / (upper - lower);
|
||||
} // RealType cdf(const complemented2_type<uniform_distribution<RealType, Policy>, RealType>& c)
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const complemented2_type<uniform_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
RealType lower = c.dist.lower();
|
||||
RealType upper = c.dist.upper();
|
||||
RealType q = c.param;
|
||||
RealType result = 0; // of checks.
|
||||
if(false == detail::check_uniform("boost::math::quantile(const uniform_distribution<%1%>&, %1%)", lower, upper, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(false == detail::check_probability("boost::math::quantile(const uniform_distribution<%1%>&, %1%)", q, &result, Policy()))
|
||||
if(q == 0)
|
||||
{
|
||||
return lower;
|
||||
}
|
||||
if(q == 1)
|
||||
{
|
||||
return upper;
|
||||
}
|
||||
return -q * (upper - lower) + upper;
|
||||
} // RealType quantile(const complemented2_type<uniform_distribution<RealType, Policy>, RealType>& c)
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mean(const uniform_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType lower = dist.lower();
|
||||
RealType upper = dist.upper();
|
||||
RealType result = 0; // of checks.
|
||||
if(false == detail::check_uniform("boost::math::mean(const uniform_distribution<%1%>&)", lower, upper, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return (lower + upper ) / 2;
|
||||
} // RealType mean(const uniform_distribution<RealType, Policy>& dist)
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType variance(const uniform_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType lower = dist.lower();
|
||||
RealType upper = dist.upper();
|
||||
RealType result = 0; // of checks.
|
||||
if(false == detail::check_uniform("boost::math::variance(const uniform_distribution<%1%>&)", lower, upper, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return (upper - lower) * ( upper - lower) / 12;
|
||||
// for standard uniform = 0.833333333333333333333333333333333333333333;
|
||||
} // RealType variance(const uniform_distribution<RealType, Policy>& dist)
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mode(const uniform_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType lower = dist.lower();
|
||||
RealType upper = dist.upper();
|
||||
RealType result = 0; // of checks.
|
||||
if(false == detail::check_uniform("boost::math::mode(const uniform_distribution<%1%>&)", lower, upper, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
result = lower; // Any value [lower, upper] but arbitrarily choose lower.
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType median(const uniform_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType lower = dist.lower();
|
||||
RealType upper = dist.upper();
|
||||
RealType result = 0; // of checks.
|
||||
if(false == detail::check_uniform("boost::math::median(const uniform_distribution<%1%>&)", lower, upper, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return (lower + upper) / 2; //
|
||||
}
|
||||
template <class RealType, class Policy>
|
||||
inline RealType skewness(const uniform_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType lower = dist.lower();
|
||||
RealType upper = dist.upper();
|
||||
RealType result = 0; // of checks.
|
||||
if(false == detail::check_uniform("boost::math::skewness(const uniform_distribution<%1%>&)",lower, upper, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return 0;
|
||||
} // RealType skewness(const uniform_distribution<RealType, Policy>& dist)
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis_excess(const uniform_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType lower = dist.lower();
|
||||
RealType upper = dist.upper();
|
||||
RealType result = 0; // of checks.
|
||||
if(false == detail::check_uniform("boost::math::kurtosis_execess(const uniform_distribution<%1%>&)", lower, upper, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return static_cast<RealType>(-6)/5; // -6/5 = -1.2;
|
||||
} // RealType kurtosis_excess(const uniform_distribution<RealType, Policy>& dist)
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis(const uniform_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
return kurtosis_excess(dist) + 3;
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
// This include must be at the end, *after* the accessors
|
||||
// for this distribution have been defined, in order to
|
||||
// keep compilers that support two-phase lookup happy.
|
||||
#include <boost/math/distributions/detail/derived_accessors.hpp>
|
||||
|
||||
#endif // BOOST_STATS_UNIFORM_HPP
|
||||
|
||||
|
||||
|
||||
387
test/external/boost/math/distributions/weibull.hpp
vendored
Normal file
387
test/external/boost/math/distributions/weibull.hpp
vendored
Normal file
@@ -0,0 +1,387 @@
|
||||
// Copyright John Maddock 2006.
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_STATS_WEIBULL_HPP
|
||||
#define BOOST_STATS_WEIBULL_HPP
|
||||
|
||||
// http://www.itl.nist.gov/div898/handbook/eda/section3/eda3668.htm
|
||||
// http://mathworld.wolfram.com/WeibullDistribution.html
|
||||
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#include <boost/math/special_functions/gamma.hpp>
|
||||
#include <boost/math/special_functions/log1p.hpp>
|
||||
#include <boost/math/special_functions/expm1.hpp>
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp>
|
||||
#include <boost/math/distributions/complement.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace boost{ namespace math
|
||||
{
|
||||
namespace detail{
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_weibull_shape(
|
||||
const char* function,
|
||||
RealType shape,
|
||||
RealType* result, const Policy& pol)
|
||||
{
|
||||
if((shape < 0) || !(boost::math::isfinite)(shape))
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Shape parameter is %1%, but must be > 0 !", shape, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_weibull_x(
|
||||
const char* function,
|
||||
RealType const& x,
|
||||
RealType* result, const Policy& pol)
|
||||
{
|
||||
if((x < 0) || !(boost::math::isfinite)(x))
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Random variate is %1% but must be >= 0 !", x, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_weibull(
|
||||
const char* function,
|
||||
RealType scale,
|
||||
RealType shape,
|
||||
RealType* result, const Policy& pol)
|
||||
{
|
||||
return check_scale(function, scale, result, pol) && check_weibull_shape(function, shape, result, pol);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class RealType = double, class Policy = policies::policy<> >
|
||||
class weibull_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
|
||||
weibull_distribution(RealType shape, RealType scale = 1)
|
||||
: m_shape(shape), m_scale(scale)
|
||||
{
|
||||
RealType result;
|
||||
detail::check_weibull("boost::math::weibull_distribution<%1%>::weibull_distribution", scale, shape, &result, Policy());
|
||||
}
|
||||
|
||||
RealType shape()const
|
||||
{
|
||||
return m_shape;
|
||||
}
|
||||
|
||||
RealType scale()const
|
||||
{
|
||||
return m_scale;
|
||||
}
|
||||
private:
|
||||
//
|
||||
// Data members:
|
||||
//
|
||||
RealType m_shape; // distribution shape
|
||||
RealType m_scale; // distribution scale
|
||||
};
|
||||
|
||||
typedef weibull_distribution<double> weibull;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const weibull_distribution<RealType, Policy>& /*dist*/)
|
||||
{ // Range of permissible values for random variable x.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> support(const weibull_distribution<RealType, Policy>& /*dist*/)
|
||||
{ // Range of supported values for random variable x.
|
||||
// This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
|
||||
using boost::math::tools::max_value;
|
||||
using boost::math::tools::min_value;
|
||||
return std::pair<RealType, RealType>(min_value<RealType>(), max_value<RealType>());
|
||||
// A discontinuity at x == 0, so only support down to min_value.
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType pdf(const weibull_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::pdf(const weibull_distribution<%1%>, %1%)";
|
||||
|
||||
RealType shape = dist.shape();
|
||||
RealType scale = dist.scale();
|
||||
|
||||
RealType result = 0;
|
||||
if(false == detail::check_weibull(function, scale, shape, &result, Policy()))
|
||||
return result;
|
||||
if(false == detail::check_weibull_x(function, x, &result, Policy()))
|
||||
return result;
|
||||
|
||||
if(x == 0)
|
||||
{ // Special case, but x == min, pdf = 1 for shape = 1,
|
||||
return 0;
|
||||
}
|
||||
result = exp(-pow(x / scale, shape));
|
||||
result *= pow(x / scale, shape) * shape / x;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const weibull_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::cdf(const weibull_distribution<%1%>, %1%)";
|
||||
|
||||
RealType shape = dist.shape();
|
||||
RealType scale = dist.scale();
|
||||
|
||||
RealType result = 0;
|
||||
if(false == detail::check_weibull(function, scale, shape, &result, Policy()))
|
||||
return result;
|
||||
if(false == detail::check_weibull_x(function, x, &result, Policy()))
|
||||
return result;
|
||||
|
||||
result = -boost::math::expm1(-pow(x / scale, shape), Policy());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const weibull_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::quantile(const weibull_distribution<%1%>, %1%)";
|
||||
|
||||
RealType shape = dist.shape();
|
||||
RealType scale = dist.scale();
|
||||
|
||||
RealType result = 0;
|
||||
if(false == detail::check_weibull(function, scale, shape, &result, Policy()))
|
||||
return result;
|
||||
if(false == detail::check_probability(function, p, &result, Policy()))
|
||||
return result;
|
||||
|
||||
if(p == 1)
|
||||
return policies::raise_overflow_error<RealType>(function, 0, Policy());
|
||||
|
||||
result = scale * pow(-boost::math::log1p(-p, Policy()), 1 / shape);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const complemented2_type<weibull_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::cdf(const weibull_distribution<%1%>, %1%)";
|
||||
|
||||
RealType shape = c.dist.shape();
|
||||
RealType scale = c.dist.scale();
|
||||
|
||||
RealType result = 0;
|
||||
if(false == detail::check_weibull(function, scale, shape, &result, Policy()))
|
||||
return result;
|
||||
if(false == detail::check_weibull_x(function, c.param, &result, Policy()))
|
||||
return result;
|
||||
|
||||
result = exp(-pow(c.param / scale, shape));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const complemented2_type<weibull_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::quantile(const weibull_distribution<%1%>, %1%)";
|
||||
|
||||
RealType shape = c.dist.shape();
|
||||
RealType scale = c.dist.scale();
|
||||
RealType q = c.param;
|
||||
|
||||
RealType result = 0;
|
||||
if(false == detail::check_weibull(function, scale, shape, &result, Policy()))
|
||||
return result;
|
||||
if(false == detail::check_probability(function, q, &result, Policy()))
|
||||
return result;
|
||||
|
||||
if(q == 0)
|
||||
return policies::raise_overflow_error<RealType>(function, 0, Policy());
|
||||
|
||||
result = scale * pow(-log(q), 1 / shape);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mean(const weibull_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::mean(const weibull_distribution<%1%>)";
|
||||
|
||||
RealType shape = dist.shape();
|
||||
RealType scale = dist.scale();
|
||||
|
||||
RealType result = 0;
|
||||
if(false == detail::check_weibull(function, scale, shape, &result, Policy()))
|
||||
return result;
|
||||
|
||||
result = scale * boost::math::tgamma(1 + 1 / shape, Policy());
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType variance(const weibull_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType shape = dist.shape();
|
||||
RealType scale = dist.scale();
|
||||
|
||||
static const char* function = "boost::math::variance(const weibull_distribution<%1%>)";
|
||||
|
||||
RealType result = 0;
|
||||
if(false == detail::check_weibull(function, scale, shape, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
result = boost::math::tgamma(1 + 1 / shape, Policy());
|
||||
result *= -result;
|
||||
result += boost::math::tgamma(1 + 2 / shape, Policy());
|
||||
result *= scale * scale;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mode(const weibull_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std function pow.
|
||||
|
||||
static const char* function = "boost::math::mode(const weibull_distribution<%1%>)";
|
||||
|
||||
RealType shape = dist.shape();
|
||||
RealType scale = dist.scale();
|
||||
|
||||
RealType result = 0;
|
||||
if(false == detail::check_weibull(function, scale, shape, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(shape <= 1)
|
||||
return 0;
|
||||
result = scale * pow((shape - 1) / shape, 1 / shape);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType median(const weibull_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std function pow.
|
||||
|
||||
static const char* function = "boost::math::median(const weibull_distribution<%1%>)";
|
||||
|
||||
RealType shape = dist.shape(); // Wikipedia k
|
||||
RealType scale = dist.scale(); // Wikipedia lambda
|
||||
|
||||
RealType result = 0;
|
||||
if(false == detail::check_weibull(function, scale, shape, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
using boost::math::constants::ln_two;
|
||||
result = scale * pow(ln_two<RealType>(), 1 / shape);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType skewness(const weibull_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::skewness(const weibull_distribution<%1%>)";
|
||||
|
||||
RealType shape = dist.shape();
|
||||
RealType scale = dist.scale();
|
||||
|
||||
RealType result = 0;
|
||||
if(false == detail::check_weibull(function, scale, shape, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
RealType g1, g2, g3, d;
|
||||
|
||||
g1 = boost::math::tgamma(1 + 1 / shape, Policy());
|
||||
g2 = boost::math::tgamma(1 + 2 / shape, Policy());
|
||||
g3 = boost::math::tgamma(1 + 3 / shape, Policy());
|
||||
d = pow(g2 - g1 * g1, RealType(1.5));
|
||||
|
||||
result = (2 * g1 * g1 * g1 - 3 * g1 * g2 + g3) / d;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis_excess(const weibull_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::kurtosis_excess(const weibull_distribution<%1%>)";
|
||||
|
||||
RealType shape = dist.shape();
|
||||
RealType scale = dist.scale();
|
||||
|
||||
RealType result = 0;
|
||||
if(false == detail::check_weibull(function, scale, shape, &result, Policy()))
|
||||
return result;
|
||||
|
||||
RealType g1, g2, g3, g4, d, g1_2, g1_4;
|
||||
|
||||
g1 = boost::math::tgamma(1 + 1 / shape, Policy());
|
||||
g2 = boost::math::tgamma(1 + 2 / shape, Policy());
|
||||
g3 = boost::math::tgamma(1 + 3 / shape, Policy());
|
||||
g4 = boost::math::tgamma(1 + 4 / shape, Policy());
|
||||
g1_2 = g1 * g1;
|
||||
g1_4 = g1_2 * g1_2;
|
||||
d = g2 - g1_2;
|
||||
d *= d;
|
||||
|
||||
result = -6 * g1_4 + 12 * g1_2 * g2 - 3 * g2 * g2 - 4 * g1 * g3 + g4;
|
||||
result /= d;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis(const weibull_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
return kurtosis_excess(dist) + 3;
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
// This include must be at the end, *after* the accessors
|
||||
// for this distribution have been defined, in order to
|
||||
// keep compilers that support two-phase lookup happy.
|
||||
#include <boost/math/distributions/detail/derived_accessors.hpp>
|
||||
|
||||
#endif // BOOST_STATS_WEIBULL_HPP
|
||||
|
||||
|
||||
Reference in New Issue
Block a user