update boost
This commit is contained in:
@@ -29,6 +29,7 @@
|
||||
#ifndef BOOST_MATH_DIST_ARCSINE_HPP
|
||||
#define BOOST_MATH_DIST_ARCSINE_HPP
|
||||
|
||||
#include <cmath>
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#include <boost/math/distributions/complement.hpp> // complements.
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp> // error checks.
|
||||
@@ -85,15 +86,14 @@ namespace boost
|
||||
{ // Check x_min < x_max
|
||||
if (x_min >= x_max)
|
||||
{
|
||||
std::string msg = "x_max argument is %1%, but must be > x_min = " + lexical_cast<std::string>(x_min) + "!";
|
||||
std::string msg = "x_max argument is %1%, but must be > x_min";
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
msg.c_str(), x_max, pol);
|
||||
// "x_max argument is %1%, but must be > x_min !", x_max, pol);
|
||||
// "x_max argument is %1%, but must be > x_min %2!", x_max, x_min, pol); would be better.
|
||||
// But would require replication of all helpers functions in /policies/error_handling.hpp for two values,
|
||||
// as well as two value versions of raise_error, raise_domain_error and do_format ...
|
||||
// so use slightly hacky lexical_cast to string instead.
|
||||
// "x_max argument is %1%, but must be > x_min !", x_max, pol);
|
||||
// "x_max argument is %1%, but must be > x_min %2!", x_max, x_min, pol); would be better.
|
||||
// But would require replication of all helpers functions in /policies/error_handling.hpp for two values,
|
||||
// as well as two value versions of raise_error, raise_domain_error and do_format
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -195,6 +195,12 @@ namespace boost
|
||||
// Convenient typedef to construct double version.
|
||||
typedef arcsine_distribution<double> arcsine;
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
arcsine_distribution(RealType)->arcsine_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
template <class RealType>
|
||||
arcsine_distribution(RealType, RealType)->arcsine_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const arcsine_distribution<RealType, Policy>& dist)
|
||||
@@ -428,7 +434,7 @@ namespace boost
|
||||
// is less accurate, so use acos instead of asin for complement.
|
||||
result = static_cast<RealType>(2) * acos(sqrt((x - x_min) / (x_max - x_min))) / pi<RealType>();
|
||||
return result;
|
||||
} // arcine ccdf
|
||||
} // arcsine ccdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const arcsine_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
// (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,
|
||||
// it is convenient to treat it as if a continuous 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.
|
||||
@@ -55,12 +55,12 @@ namespace boost
|
||||
return true;
|
||||
}
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_dist(const char* function, const RealType& p, RealType* result, const Policy& /* pol */, const mpl::true_&)
|
||||
inline bool check_dist(const char* function, const RealType& p, RealType* result, const Policy& /* pol */, const std::true_type&)
|
||||
{
|
||||
return check_success_fraction(function, p, result, Policy());
|
||||
}
|
||||
template <class RealType, class Policy>
|
||||
inline bool check_dist(const char* , const RealType& , RealType* , const Policy& /* pol */, const mpl::false_&)
|
||||
inline bool check_dist(const char* , const RealType& , RealType* , const Policy& /* pol */, const std::false_type&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -126,6 +126,11 @@ namespace boost
|
||||
|
||||
typedef bernoulli_distribution<double> bernoulli;
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
bernoulli_distribution(RealType)->bernoulli_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
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}.
|
||||
@@ -146,7 +151,7 @@ namespace boost
|
||||
return dist.success_fraction();
|
||||
} // mean
|
||||
|
||||
// Rely on dereived_accessors quantile(half)
|
||||
// Rely on derived_accessors quantile(half)
|
||||
//template <class RealType>
|
||||
//inline RealType median(const bernoulli_distribution<RealType, Policy>& dist)
|
||||
//{ // Median of bernoulli distribution is not defined.
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
// Copyright John Maddock 2006.
|
||||
// Copyright Paul A. Bristow 2006.
|
||||
// Copyright Matt Borland 2023.
|
||||
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0.
|
||||
@@ -241,7 +242,7 @@ namespace boost
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return ibeta_inva(beta, x, probability, Policy());
|
||||
return static_cast<RealType>(ibeta_inva(beta, x, probability, Policy()));
|
||||
} // RealType find_alpha(beta, a, probability)
|
||||
|
||||
static RealType find_beta(
|
||||
@@ -264,7 +265,7 @@ namespace boost
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return ibeta_invb(alpha, x, probability, Policy());
|
||||
return static_cast<RealType>(ibeta_invb(alpha, x, probability, Policy()));
|
||||
} // RealType find_beta(alpha, x, probability)
|
||||
|
||||
private:
|
||||
@@ -272,6 +273,13 @@ namespace boost
|
||||
RealType m_beta;
|
||||
}; // template <class RealType, class Policy> class beta_distribution
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
beta_distribution(RealType)->beta_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
template <class RealType>
|
||||
beta_distribution(RealType, RealType)->beta_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
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.
|
||||
@@ -382,7 +390,41 @@ namespace boost
|
||||
return result;
|
||||
}
|
||||
using boost::math::beta;
|
||||
return ibeta_derivative(a, b, x, Policy());
|
||||
|
||||
// Corner cases: check_x ensures x element of [0, 1], but PDF is 0 for x = 0 and x = 1. PDF EQN:
|
||||
// https://wikimedia.org/api/rest_v1/media/math/render/svg/125fdaa41844a8703d1a8610ac00fbf3edacc8e7
|
||||
if(x == 0)
|
||||
{
|
||||
if (a == 1)
|
||||
{
|
||||
return static_cast<RealType>(1 / beta(a, b));
|
||||
}
|
||||
else if (a < 1)
|
||||
{
|
||||
policies::raise_overflow_error<RealType>(function, nullptr, Policy());
|
||||
}
|
||||
else
|
||||
{
|
||||
return RealType(0);
|
||||
}
|
||||
}
|
||||
else if (x == 1)
|
||||
{
|
||||
if (b == 1)
|
||||
{
|
||||
return static_cast<RealType>(1 / beta(a, b));
|
||||
}
|
||||
else if (b < 1)
|
||||
{
|
||||
policies::raise_overflow_error<RealType>(function, nullptr, Policy());
|
||||
}
|
||||
else
|
||||
{
|
||||
return RealType(0);
|
||||
}
|
||||
}
|
||||
|
||||
return static_cast<RealType>(ibeta_derivative(a, b, x, Policy()));
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
@@ -413,7 +455,7 @@ namespace boost
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return ibeta(a, b, x, Policy());
|
||||
return static_cast<RealType>(ibeta(a, b, x, Policy()));
|
||||
} // beta cdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
@@ -440,16 +482,16 @@ namespace boost
|
||||
}
|
||||
if (x == 0)
|
||||
{
|
||||
return 1;
|
||||
return RealType(1);
|
||||
}
|
||||
else if (x == 1)
|
||||
{
|
||||
return 0;
|
||||
return RealType(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());
|
||||
return static_cast<RealType>(ibetac(a, b, x, Policy()));
|
||||
} // beta cdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
@@ -478,13 +520,13 @@ namespace boost
|
||||
// Special cases:
|
||||
if (p == 0)
|
||||
{
|
||||
return 0;
|
||||
return RealType(0);
|
||||
}
|
||||
if (p == 1)
|
||||
{
|
||||
return 1;
|
||||
return RealType(1);
|
||||
}
|
||||
return ibeta_inv(a, b, p, static_cast<RealType*>(0), Policy());
|
||||
return static_cast<RealType>(ibeta_inv(a, b, p, static_cast<RealType*>(nullptr), Policy()));
|
||||
} // quantile
|
||||
|
||||
template <class RealType, class Policy>
|
||||
@@ -514,14 +556,14 @@ namespace boost
|
||||
// Special cases:
|
||||
if(q == 1)
|
||||
{
|
||||
return 0;
|
||||
return RealType(0);
|
||||
}
|
||||
if(q == 0)
|
||||
{
|
||||
return 1;
|
||||
return RealType(1);
|
||||
}
|
||||
|
||||
return ibetac_inv(a, b, q, static_cast<RealType*>(0), Policy());
|
||||
return static_cast<RealType>(ibetac_inv(a, b, q, static_cast<RealType*>(nullptr), Policy()));
|
||||
} // Quantile Complement
|
||||
|
||||
} // namespace math
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
// (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,
|
||||
// it is convenient to treat it as if a continuous 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.
|
||||
@@ -224,7 +224,7 @@ namespace boost
|
||||
// but zero is the best we can do:
|
||||
return 0;
|
||||
}
|
||||
if(p == 1)
|
||||
if(p == 1 || success_fraction == 1)
|
||||
{ // Probability of n or fewer successes is always one,
|
||||
// so n is the most sensible answer here:
|
||||
return trials;
|
||||
@@ -233,10 +233,6 @@ namespace boost
|
||||
{ // p <= pdf(dist, 0) == cdf(dist, 0)
|
||||
return 0; // So the only reasonable result is zero.
|
||||
} // And root finder would fail otherwise.
|
||||
if(success_fraction == 1)
|
||||
{ // our formulae break down in this case:
|
||||
return p > 0.5f ? trials : 0;
|
||||
}
|
||||
|
||||
// Solve for quantile numerically:
|
||||
//
|
||||
@@ -261,7 +257,7 @@ namespace boost
|
||||
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>();
|
||||
std::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
|
||||
return detail::inverse_discrete_quantile(
|
||||
dist,
|
||||
comp ? q : p,
|
||||
@@ -335,8 +331,8 @@ namespace boost
|
||||
// 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());
|
||||
return (t == clopper_pearson_exact_interval) ? ibeta_inv(successes, trials - successes + 1, probability, static_cast<RealType*>(nullptr), Policy())
|
||||
: ibeta_inv(successes + 0.5f, trials - successes + 0.5f, probability, static_cast<RealType*>(nullptr), Policy());
|
||||
}
|
||||
static RealType find_upper_bound_on_p(
|
||||
RealType trials,
|
||||
@@ -357,8 +353,8 @@ namespace boost
|
||||
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());
|
||||
return (t == clopper_pearson_exact_interval) ? ibetac_inv(successes + 1, trials - successes, probability, static_cast<RealType*>(nullptr), Policy())
|
||||
: ibetac_inv(successes + 0.5f, trials - successes + 0.5f, probability, static_cast<RealType*>(nullptr), Policy());
|
||||
}
|
||||
// Estimate number of trials parameter:
|
||||
//
|
||||
@@ -414,6 +410,13 @@ namespace boost
|
||||
// IS now included since no longer a name clash with function binomial.
|
||||
//typedef binomial_distribution<double> binomial; // Reserved name of type double.
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
binomial_distribution(RealType)->binomial_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
template <class RealType>
|
||||
binomial_distribution(RealType,RealType)->binomial_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
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.
|
||||
@@ -476,11 +479,6 @@ namespace boost
|
||||
{
|
||||
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
|
||||
@@ -679,7 +677,7 @@ namespace boost
|
||||
// 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
|
||||
// Bounds for median and 50 percentage 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.
|
||||
|
||||
@@ -17,9 +17,8 @@
|
||||
#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>
|
||||
#include <cmath>
|
||||
|
||||
namespace boost{ namespace math
|
||||
{
|
||||
@@ -50,7 +49,7 @@ RealType cdf_imp(const cauchy_distribution<RealType, Policy>& dist, const RealTy
|
||||
//
|
||||
// CDF = -atan(1/x) ; x < 0
|
||||
//
|
||||
// So the proceedure is to calculate the cdf for -fabs(x)
|
||||
// So the procedure is to calculate the cdf for -fabs(x)
|
||||
// using the above formula, and then subtract from 1 when required
|
||||
// to get the result.
|
||||
//
|
||||
@@ -82,7 +81,7 @@ RealType cdf_imp(const cauchy_distribution<RealType, Policy>& dist, const RealTy
|
||||
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;
|
||||
return static_cast<RealType>(0.5f);
|
||||
}
|
||||
result = -atan(1 / mx) / constants::pi<RealType>();
|
||||
return (((x > location) != complement) ? 1 - result : result);
|
||||
@@ -98,7 +97,7 @@ RealType quantile_imp(
|
||||
// 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
|
||||
// when calculating the tangent, then calculates 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.
|
||||
//
|
||||
@@ -177,6 +176,13 @@ private:
|
||||
|
||||
typedef cauchy_distribution<double> cauchy;
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
cauchy_distribution(RealType)->cauchy_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
template <class RealType>
|
||||
cauchy_distribution(RealType,RealType)->cauchy_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
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.
|
||||
@@ -271,7 +277,7 @@ 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);
|
||||
static_assert(assert_type::value == 0, "assert type is undefined");
|
||||
|
||||
return policies::raise_domain_error<RealType>(
|
||||
"boost::math::mean(cauchy<%1%>&)",
|
||||
@@ -285,7 +291,7 @@ 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);
|
||||
static_assert(assert_type::value == 0, "assert type is undefined");
|
||||
|
||||
return policies::raise_domain_error<RealType>(
|
||||
"boost::math::variance(cauchy<%1%>&)",
|
||||
@@ -310,7 +316,7 @@ 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);
|
||||
static_assert(assert_type::value == 0, "assert type is undefined");
|
||||
|
||||
return policies::raise_domain_error<RealType>(
|
||||
"boost::math::skewness(cauchy<%1%>&)",
|
||||
@@ -324,7 +330,7 @@ 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);
|
||||
static_assert(assert_type::value == 0, "assert type is undefined");
|
||||
|
||||
return policies::raise_domain_error<RealType>(
|
||||
"boost::math::kurtosis(cauchy<%1%>&)",
|
||||
@@ -338,7 +344,7 @@ inline RealType kurtosis_excess(const cauchy_distribution<RealType, Policy>& /*d
|
||||
{
|
||||
// There is no kurtosis excess:
|
||||
typedef typename Policy::assert_undefined_type assert_type;
|
||||
BOOST_STATIC_ASSERT(assert_type::value == 0);
|
||||
static_assert(assert_type::value == 0, "assert type is undefined");
|
||||
|
||||
return policies::raise_domain_error<RealType>(
|
||||
"boost::math::kurtosis_excess(cauchy<%1%>&)",
|
||||
@@ -347,6 +353,13 @@ inline RealType kurtosis_excess(const cauchy_distribution<RealType, Policy>& /*d
|
||||
std::numeric_limits<RealType>::quiet_NaN(), Policy());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType entropy(const cauchy_distribution<RealType, Policy> & dist)
|
||||
{
|
||||
using std::log;
|
||||
return log(2*constants::two_pi<RealType>()*dist.scale());
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
|
||||
@@ -23,10 +23,10 @@ template <class RealType = double, class Policy = policies::policy<> >
|
||||
class chi_squared_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
using value_type = RealType;
|
||||
using policy_type = Policy;
|
||||
|
||||
chi_squared_distribution(RealType i) : m_df(i)
|
||||
explicit chi_squared_distribution(RealType i) : m_df(i)
|
||||
{
|
||||
RealType result;
|
||||
detail::check_df(
|
||||
@@ -53,15 +53,20 @@ private:
|
||||
RealType m_df; // degrees of freedom is a positive real number.
|
||||
}; // class chi_squared_distribution
|
||||
|
||||
typedef chi_squared_distribution<double> chi_squared;
|
||||
using chi_squared = chi_squared_distribution<double>;
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
chi_squared_distribution(RealType)->chi_squared_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4127)
|
||||
#endif
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const chi_squared_distribution<RealType, Policy>& /*dist*/)
|
||||
inline std::pair<RealType, RealType> range(const chi_squared_distribution<RealType, Policy>& /*dist*/)
|
||||
{ // Range of permissible values for random variable x.
|
||||
if (std::numeric_limits<RealType>::has_infinity)
|
||||
{
|
||||
@@ -74,12 +79,12 @@ inline const std::pair<RealType, RealType> range(const chi_squared_distribution<
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> support(const chi_squared_distribution<RealType, Policy>& /*dist*/)
|
||||
inline 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.
|
||||
@@ -219,17 +224,6 @@ 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>(
|
||||
@@ -239,25 +233,12 @@ inline RealType mode(const chi_squared_distribution<RealType, Policy>& dist)
|
||||
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);
|
||||
return sqrt (8 / df);
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
@@ -340,7 +321,7 @@ RealType chi_squared_distribution<RealType, Policy>::find_degrees_of_freedom(
|
||||
|
||||
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::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;
|
||||
|
||||
@@ -29,7 +29,7 @@ struct complemented2_type
|
||||
const RealType& param;
|
||||
|
||||
private:
|
||||
complemented2_type& operator=(const complemented2_type&);
|
||||
complemented2_type& operator=(const complemented2_type&) = delete;
|
||||
};
|
||||
|
||||
template <class Dist, class RealType1, class RealType2>
|
||||
@@ -47,7 +47,7 @@ struct complemented3_type
|
||||
const RealType1& param1;
|
||||
const RealType2& param2;
|
||||
private:
|
||||
complemented3_type& operator=(const complemented3_type&);
|
||||
complemented3_type& operator=(const complemented3_type&) = delete;
|
||||
};
|
||||
|
||||
template <class Dist, class RealType1, class RealType2, class RealType3>
|
||||
@@ -68,7 +68,7 @@ struct complemented4_type
|
||||
const RealType2& param2;
|
||||
const RealType3& param3;
|
||||
private:
|
||||
complemented4_type& operator=(const complemented4_type&);
|
||||
complemented4_type& operator=(const complemented4_type&) = delete;
|
||||
};
|
||||
|
||||
template <class Dist, class RealType1, class RealType2, class RealType3, class RealType4>
|
||||
@@ -92,7 +92,7 @@ struct complemented5_type
|
||||
const RealType3& param3;
|
||||
const RealType4& param4;
|
||||
private:
|
||||
complemented5_type& operator=(const complemented5_type&);
|
||||
complemented5_type& operator=(const complemented5_type&) = delete;
|
||||
};
|
||||
|
||||
template <class Dist, class RealType1, class RealType2, class RealType3, class RealType4, class RealType5>
|
||||
@@ -119,7 +119,7 @@ struct complemented6_type
|
||||
const RealType4& param4;
|
||||
const RealType5& param5;
|
||||
private:
|
||||
complemented6_type& operator=(const complemented6_type&);
|
||||
complemented6_type& operator=(const complemented6_type&) = delete;
|
||||
};
|
||||
|
||||
template <class Dist, class RealType1, class RealType2, class RealType3, class RealType4, class RealType5, class RealType6>
|
||||
@@ -149,7 +149,7 @@ struct complemented7_type
|
||||
const RealType5& param5;
|
||||
const RealType6& param6;
|
||||
private:
|
||||
complemented7_type& operator=(const complemented7_type&);
|
||||
complemented7_type& operator=(const complemented7_type&) = delete;
|
||||
};
|
||||
|
||||
template <class Dist, class RealType>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// using boost::math::isfinite;
|
||||
// using boost::math::isnan;
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4702) // unreachable code (return after domain_error throw).
|
||||
#endif
|
||||
@@ -185,11 +185,12 @@ inline bool check_non_centrality(
|
||||
RealType* result,
|
||||
const Policy& pol)
|
||||
{
|
||||
if((ncp < 0) || !(boost::math::isfinite)(ncp))
|
||||
{ // Assume scale == 0 is NOT valid for any distribution.
|
||||
static const RealType upper_limit = static_cast<RealType>((std::numeric_limits<long long>::max)()) - boost::math::policies::get_max_root_iterations<Policy>();
|
||||
if((ncp < 0) || !(boost::math::isfinite)(ncp) || ncp > upper_limit)
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Non centrality parameter is %1%, but must be > 0 !", ncp, pol);
|
||||
"Non centrality parameter is %1%, but must be > 0, and a countable value such that x+1 != x", ncp, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -216,7 +217,7 @@ inline bool check_finite(
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
|
||||
@@ -24,13 +24,13 @@
|
||||
// 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.
|
||||
// can find the definitions referred to herein.
|
||||
//
|
||||
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <cmath>
|
||||
#include <boost/math/tools/assert.hpp>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4723) // potential divide by 0
|
||||
// Suppressing spurious warning in coefficient_of_variation
|
||||
@@ -65,7 +65,7 @@ inline typename Distribution::value_type hazard(const Distribution& dist, const
|
||||
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());
|
||||
"boost::math::hazard(const Distribution&, %1%)", nullptr, policy_type());
|
||||
if(d == 0)
|
||||
{
|
||||
// This protects against 0/0, but is it the right thing to do?
|
||||
@@ -94,7 +94,7 @@ inline typename Distribution::value_type coefficient_of_variation(const Distribu
|
||||
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 policies::raise_overflow_error<value_type>("boost::math::coefficient_of_variation(const Distribution&, %1%)", nullptr, policy_type());
|
||||
}
|
||||
return d / m; // so MSVC warning on zerodivide is spurious, and suppressed.
|
||||
}
|
||||
@@ -110,11 +110,25 @@ inline typename Distribution::value_type pdf(const Distribution& dist, const Rea
|
||||
return pdf(dist, static_cast<value_type>(x));
|
||||
}
|
||||
template <class Distribution, class RealType>
|
||||
inline typename Distribution::value_type logpdf(const Distribution& dist, const RealType& x)
|
||||
{
|
||||
using std::log;
|
||||
typedef typename Distribution::value_type value_type;
|
||||
return log(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 logcdf(const Distribution& dist, const Realtype& x)
|
||||
{
|
||||
using std::log;
|
||||
using value_type = typename Distribution::value_type;
|
||||
return log(cdf(dist, static_cast<value_type>(x)));
|
||||
}
|
||||
template <class Distribution, class RealType>
|
||||
inline typename Distribution::value_type quantile(const Distribution& dist, const RealType& x)
|
||||
{
|
||||
@@ -136,6 +150,14 @@ inline typename Distribution::value_type cdf(const complemented2_type<Distributi
|
||||
return cdf(complement(c.dist, static_cast<value_type>(c.param)));
|
||||
}
|
||||
|
||||
template <class Distribution, class RealType>
|
||||
inline typename Distribution::value_type logcdf(const complemented2_type<Distribution, RealType>& c)
|
||||
{
|
||||
using std::log;
|
||||
typedef typename Distribution::value_type value_type;
|
||||
return log(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)
|
||||
{
|
||||
@@ -156,7 +178,7 @@ inline typename Dist::value_type median(const Dist& d)
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ typename Dist::value_type generic_find_mode(const Dist& dist, typename Dist::val
|
||||
v = pdf(dist, lower_bound);
|
||||
}while(maxval < v);
|
||||
|
||||
boost::uintmax_t max_iter = policies::get_max_root_iterations<policy_type>();
|
||||
std::uintmax_t max_iter = policies::get_max_root_iterations<policy_type>();
|
||||
|
||||
value_type result = tools::brent_find_minima(
|
||||
pdf_minimizer<Dist>(dist),
|
||||
@@ -125,7 +125,7 @@ typename Dist::value_type generic_find_mode_01(const Dist& dist, typename Dist::
|
||||
v = pdf(dist, lower_bound);
|
||||
}while(maxval < v);
|
||||
|
||||
boost::uintmax_t max_iter = policies::get_max_root_iterations<policy_type>();
|
||||
std::uintmax_t max_iter = policies::get_max_root_iterations<policy_type>();
|
||||
|
||||
value_type result = tools::brent_find_minima(
|
||||
pdf_minimizer<Dist>(dist),
|
||||
|
||||
@@ -11,8 +11,8 @@ 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;
|
||||
using value_type = typename Dist::value_type;
|
||||
using policy_type = typename Dist::policy_type;
|
||||
|
||||
generic_quantile_finder(const Dist& d, value_type t, bool c)
|
||||
: dist(d), target(t), comp(c) {}
|
||||
@@ -34,25 +34,31 @@ 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);
|
||||
{
|
||||
return policies::raise_underflow_error<T>(function, nullptr, pol);
|
||||
}
|
||||
if(x <= -tools::max_value<T>())
|
||||
return -policies::raise_overflow_error<T>(function, 0, pol);
|
||||
{
|
||||
return -policies::raise_overflow_error<T>(function, nullptr, pol);
|
||||
}
|
||||
if(x >= tools::max_value<T>())
|
||||
return policies::raise_overflow_error<T>(function, 0, pol);
|
||||
{
|
||||
return policies::raise_overflow_error<T>(function, nullptr, 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;
|
||||
using value_type = typename Dist::value_type;
|
||||
using policy_type = typename Dist::policy_type;
|
||||
using forwarding_policy = typename policies::normalise<
|
||||
policy_type,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
policies::discrete_quantile<>,
|
||||
policies::assert_undefined<> >::type;
|
||||
|
||||
//
|
||||
// Special cases first:
|
||||
@@ -72,7 +78,7 @@ typename Dist::value_type generic_quantile(const Dist& dist, const typename Dist
|
||||
|
||||
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::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;
|
||||
|
||||
@@ -10,13 +10,14 @@
|
||||
|
||||
#include <boost/math/policies/error_handling.hpp>
|
||||
#include <boost/math/distributions/detail/hypergeometric_pdf.hpp>
|
||||
#include <cstdint>
|
||||
|
||||
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)
|
||||
T hypergeometric_cdf_imp(std::uint64_t x, std::uint64_t r, std::uint64_t n, std::uint64_t N, bool invert, const Policy& pol)
|
||||
{
|
||||
#ifdef BOOST_MSVC
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4267)
|
||||
#endif
|
||||
@@ -27,7 +28,7 @@ namespace boost{ namespace math{ namespace detail{
|
||||
{
|
||||
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)));
|
||||
const auto lower_limit = static_cast<std::uint64_t>((std::max)(INT64_C(0), static_cast<std::int64_t>(n + r) - static_cast<std::int64_t>(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));
|
||||
@@ -43,7 +44,7 @@ namespace boost{ namespace math{ namespace detail{
|
||||
else
|
||||
{
|
||||
invert = !invert;
|
||||
unsigned upper_limit = (std::min)(r, n);
|
||||
const auto upper_limit = (std::min)(r, n);
|
||||
if(x != upper_limit)
|
||||
{
|
||||
++x;
|
||||
@@ -63,21 +64,21 @@ namespace boost{ namespace math{ namespace detail{
|
||||
if(invert)
|
||||
result = 1 - result;
|
||||
return result;
|
||||
#ifdef BOOST_MSVC
|
||||
#ifdef _MSC_VER
|
||||
# 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&)
|
||||
inline T hypergeometric_cdf(std::uint64_t x, std::uint64_t r, std::uint64_t n, std::uint64_t 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>,
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
policies::discrete_quantile<>,
|
||||
policies::assert_undefined<> >::type forwarding_policy;
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#include <boost/math/special_functions/pow.hpp>
|
||||
#include <boost/math/special_functions/prime.hpp>
|
||||
#include <boost/math/policies/error_handling.hpp>
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
|
||||
#ifdef BOOST_MATH_INSTRUMENT
|
||||
#include <typeinfo>
|
||||
@@ -40,7 +42,7 @@ template <class T>
|
||||
struct sort_functor
|
||||
{
|
||||
sort_functor(const T* exponents) : m_exponents(exponents){}
|
||||
bool operator()(int i, int j)
|
||||
bool operator()(std::size_t i, std::size_t j)
|
||||
{
|
||||
return m_exponents[i] > m_exponents[j];
|
||||
}
|
||||
@@ -49,7 +51,7 @@ private:
|
||||
};
|
||||
|
||||
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&)
|
||||
T hypergeometric_pdf_lanczos_imp(T /*dummy*/, std::uint64_t x, std::uint64_t r, std::uint64_t n, std::uint64_t N, const Lanczos&, const Policy&)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
|
||||
@@ -137,7 +139,7 @@ T hypergeometric_pdf_lanczos_imp(T /*dummy*/, unsigned x, unsigned r, unsigned n
|
||||
//
|
||||
// Combine equal powers:
|
||||
//
|
||||
int j = 8;
|
||||
std::size_t j = 8;
|
||||
while(exponents[sorted_indexes[j]] == 0) --j;
|
||||
while(j)
|
||||
{
|
||||
@@ -184,7 +186,7 @@ T hypergeometric_pdf_lanczos_imp(T /*dummy*/, unsigned x, unsigned r, unsigned n
|
||||
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)
|
||||
for(std::size_t i = 1; (i < 9) && (exponents[sorted_indexes[i]] > 0); ++i)
|
||||
{
|
||||
BOOST_FPU_EXCEPTION_GUARD
|
||||
if(result < tools::min_value<T>())
|
||||
@@ -215,7 +217,7 @@ T hypergeometric_pdf_lanczos_imp(T /*dummy*/, unsigned x, unsigned r, unsigned n
|
||||
}
|
||||
|
||||
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)
|
||||
T hypergeometric_pdf_lanczos_imp(T /*dummy*/, std::uint64_t x, std::uint64_t r, std::uint64_t n, std::uint64_t N, const boost::math::lanczos::undefined_lanczos&, const Policy& pol)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
return exp(
|
||||
@@ -260,7 +262,7 @@ inline T integer_power(const T& x, int ex)
|
||||
#ifdef __SUNPRO_CC
|
||||
return pow(x, T(ex));
|
||||
#else
|
||||
return pow(x, ex);
|
||||
return static_cast<T>(pow(x, ex));
|
||||
#endif
|
||||
}
|
||||
template <class T>
|
||||
@@ -270,22 +272,22 @@ struct hypergeometric_pdf_prime_loop_result_entry
|
||||
const hypergeometric_pdf_prime_loop_result_entry* next;
|
||||
};
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#ifdef _MSC_VER
|
||||
#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;
|
||||
const std::uint64_t x;
|
||||
const std::uint64_t r;
|
||||
const std::uint64_t n;
|
||||
const std::uint64_t N;
|
||||
std::size_t prime_index;
|
||||
std::uint64_t current_prime;
|
||||
};
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
@@ -294,8 +296,8 @@ T hypergeometric_pdf_prime_loop_imp(hypergeometric_pdf_prime_loop_data& data, hy
|
||||
{
|
||||
while(data.current_prime <= data.N)
|
||||
{
|
||||
unsigned base = data.current_prime;
|
||||
int prime_powers = 0;
|
||||
std::uint64_t base = data.current_prime;
|
||||
std::int64_t prime_powers = 0;
|
||||
while(base <= data.N)
|
||||
{
|
||||
prime_powers += data.n / base;
|
||||
@@ -381,7 +383,7 @@ T hypergeometric_pdf_prime_loop_imp(hypergeometric_pdf_prime_loop_data& data, hy
|
||||
}
|
||||
|
||||
template <class T, class Policy>
|
||||
inline T hypergeometric_pdf_prime_imp(unsigned x, unsigned r, unsigned n, unsigned N, const Policy&)
|
||||
inline T hypergeometric_pdf_prime_imp(std::uint64_t x, std::uint64_t r, std::uint64_t n, std::uint64_t 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) };
|
||||
@@ -389,10 +391,10 @@ inline T hypergeometric_pdf_prime_imp(unsigned x, unsigned r, unsigned n, unsign
|
||||
}
|
||||
|
||||
template <class T, class Policy>
|
||||
T hypergeometric_pdf_factorial_imp(unsigned x, unsigned r, unsigned n, unsigned N, const Policy&)
|
||||
T hypergeometric_pdf_factorial_imp(std::uint64_t x, std::uint64_t r, std::uint64_t n, std::uint64_t N, const Policy&)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
BOOST_ASSERT(N <= boost::math::max_factorial<T>::value);
|
||||
BOOST_MATH_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),
|
||||
@@ -406,8 +408,8 @@ T hypergeometric_pdf_factorial_imp(unsigned x, unsigned r, unsigned n, unsigned
|
||||
boost::math::unchecked_factorial<T>(r - x),
|
||||
boost::math::unchecked_factorial<T>(N - n - r + x)
|
||||
};
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
std::size_t i = 0;
|
||||
std::size_t j = 0;
|
||||
while((i < 3) || (j < 5))
|
||||
{
|
||||
while((j < 5) && ((result >= 1) || (i >= 3)))
|
||||
@@ -427,7 +429,7 @@ T hypergeometric_pdf_factorial_imp(unsigned x, unsigned r, unsigned n, unsigned
|
||||
|
||||
template <class T, class Policy>
|
||||
inline typename tools::promote_args<T>::type
|
||||
hypergeometric_pdf(unsigned x, unsigned r, unsigned n, unsigned N, const Policy&)
|
||||
hypergeometric_pdf(std::uint64_t x, std::uint64_t r, std::uint64_t n, std::uint64_t N, const Policy&)
|
||||
{
|
||||
BOOST_FPU_EXCEPTION_GUARD
|
||||
typedef typename tools::promote_args<T>::type result_type;
|
||||
|
||||
@@ -104,7 +104,7 @@ inline unsigned round_x_from_q(unsigned x, T /*q*/, T /*cum*/, T /*fudge_factor*
|
||||
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
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4267)
|
||||
#endif
|
||||
@@ -113,7 +113,7 @@ unsigned hypergeometric_quantile_imp(T p, T q, unsigned r, unsigned n, unsigned
|
||||
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 base = static_cast<unsigned>((std::max)(0, static_cast<int>(n + r) - static_cast<int>(N)));
|
||||
unsigned lim = (std::min)(r, n);
|
||||
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(p);
|
||||
@@ -150,12 +150,12 @@ unsigned hypergeometric_quantile_imp(T p, T q, unsigned r, unsigned n, unsigned
|
||||
++x;
|
||||
}
|
||||
// By the time we get here, log_pdf may be fairly inaccurate due to
|
||||
// roundoff errors, get a fresh PDF calculation before proceding:
|
||||
// roundoff errors, get a fresh PDF calculation before proceeding:
|
||||
diff = hypergeometric_pdf<T>(x, r, n, N, pol);
|
||||
}
|
||||
while(result < p)
|
||||
{
|
||||
diff = (diff > tools::min_value<T>() * 8)
|
||||
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)
|
||||
@@ -198,7 +198,7 @@ unsigned hypergeometric_quantile_imp(T p, T q, unsigned r, unsigned n, unsigned
|
||||
--x;
|
||||
}
|
||||
// By the time we get here, log_pdf may be fairly inaccurate due to
|
||||
// roundoff errors, get a fresh PDF calculation before proceding:
|
||||
// roundoff errors, get a fresh PDF calculation before proceeding:
|
||||
diff = hypergeometric_pdf<T>(x, r, n, N, pol);
|
||||
}
|
||||
while(result + diff / 2 < q)
|
||||
@@ -219,7 +219,7 @@ unsigned hypergeometric_quantile_imp(T p, T q, unsigned r, unsigned n, unsigned
|
||||
}
|
||||
return round_x_from_q(x, q, result, fudge_factor, base, lim, discrete_quantile_type());
|
||||
}
|
||||
#ifdef BOOST_MSVC
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
}
|
||||
@@ -231,9 +231,9 @@ inline unsigned hypergeometric_quantile(T p, T q, unsigned r, unsigned n, unsign
|
||||
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>,
|
||||
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());
|
||||
|
||||
@@ -78,7 +78,7 @@ typename Dist::value_type
|
||||
const typename Dist::value_type& multiplier,
|
||||
typename Dist::value_type adder,
|
||||
const Tolerance& tol,
|
||||
boost::uintmax_t& max_iter)
|
||||
std::uintmax_t& max_iter)
|
||||
{
|
||||
typedef typename Dist::value_type value_type;
|
||||
typedef typename Dist::policy_type policy_type;
|
||||
@@ -100,7 +100,7 @@ typename Dist::value_type
|
||||
guess = min_bound;
|
||||
|
||||
value_type fa = f(guess);
|
||||
boost::uintmax_t count = max_iter - 1;
|
||||
std::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)
|
||||
@@ -316,7 +316,7 @@ inline typename Dist::value_type round_to_floor(const Dist& d, typename Dist::va
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4127)
|
||||
#endif
|
||||
@@ -350,7 +350,7 @@ inline typename Dist::value_type round_to_ceil(const Dist& d, typename Dist::val
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
//
|
||||
@@ -370,7 +370,7 @@ inline typename Dist::value_type
|
||||
const typename Dist::value_type& multiplier,
|
||||
const typename Dist::value_type& adder,
|
||||
const policies::discrete_quantile<policies::real>&,
|
||||
boost::uintmax_t& max_iter)
|
||||
std::uintmax_t& max_iter)
|
||||
{
|
||||
if(p > 0.5)
|
||||
{
|
||||
@@ -401,7 +401,7 @@ inline typename Dist::value_type
|
||||
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)
|
||||
std::uintmax_t& max_iter)
|
||||
{
|
||||
typedef typename Dist::value_type value_type;
|
||||
BOOST_MATH_STD_USING
|
||||
@@ -444,7 +444,7 @@ inline typename Dist::value_type
|
||||
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)
|
||||
std::uintmax_t& max_iter)
|
||||
{
|
||||
typedef typename Dist::value_type value_type;
|
||||
BOOST_MATH_STD_USING
|
||||
@@ -487,7 +487,7 @@ inline typename Dist::value_type
|
||||
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)
|
||||
std::uintmax_t& max_iter)
|
||||
{
|
||||
typedef typename Dist::value_type value_type;
|
||||
BOOST_MATH_STD_USING
|
||||
@@ -515,7 +515,7 @@ inline typename Dist::value_type
|
||||
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)
|
||||
std::uintmax_t& max_iter)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
typename Dist::value_type pp = c ? 1 - p : p;
|
||||
@@ -542,7 +542,7 @@ inline typename Dist::value_type
|
||||
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)
|
||||
std::uintmax_t& max_iter)
|
||||
{
|
||||
typedef typename Dist::value_type value_type;
|
||||
BOOST_MATH_STD_USING
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
// Copyright Nick Thompson 2019.
|
||||
// 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_EMPIRICAL_CUMULATIVE_DISTRIBUTION_FUNCTION_HPP
|
||||
#define BOOST_MATH_DISTRIBUTIONS_EMPIRICAL_CUMULATIVE_DISTRIBUTION_FUNCTION_HPP
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <boost/math/tools/is_standalone.hpp>
|
||||
#ifndef BOOST_MATH_STANDALONE
|
||||
#include <boost/config.hpp>
|
||||
#ifdef BOOST_NO_CXX17_IF_CONSTEXPR
|
||||
#error "The header <boost/math/norms.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace boost { namespace math{
|
||||
|
||||
template<class RandomAccessContainer>
|
||||
class empirical_cumulative_distribution_function {
|
||||
using Real = typename RandomAccessContainer::value_type;
|
||||
public:
|
||||
empirical_cumulative_distribution_function(RandomAccessContainer && v, bool sorted = false)
|
||||
{
|
||||
if (v.size() == 0) {
|
||||
throw std::domain_error("At least one sample is required to compute an empirical CDF.");
|
||||
}
|
||||
m_v = std::move(v);
|
||||
if (!sorted) {
|
||||
std::sort(m_v.begin(), m_v.end());
|
||||
}
|
||||
}
|
||||
|
||||
auto operator()(Real x) const {
|
||||
if constexpr (std::is_integral_v<Real>)
|
||||
{
|
||||
if (x < m_v[0]) {
|
||||
return static_cast<double>(0);
|
||||
}
|
||||
if (x >= m_v[m_v.size()-1]) {
|
||||
return static_cast<double>(1);
|
||||
}
|
||||
auto it = std::upper_bound(m_v.begin(), m_v.end(), x);
|
||||
return static_cast<double>(std::distance(m_v.begin(), it))/static_cast<double>(m_v.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x < m_v[0]) {
|
||||
return Real(0);
|
||||
}
|
||||
if (x >= m_v[m_v.size()-1]) {
|
||||
return Real(1);
|
||||
}
|
||||
auto it = std::upper_bound(m_v.begin(), m_v.end(), x);
|
||||
return static_cast<Real>(std::distance(m_v.begin(), it))/static_cast<Real>(m_v.size());
|
||||
}
|
||||
}
|
||||
|
||||
RandomAccessContainer&& return_data() {
|
||||
return std::move(m_v);
|
||||
}
|
||||
|
||||
private:
|
||||
RandomAccessContainer m_v;
|
||||
};
|
||||
|
||||
}}
|
||||
#endif
|
||||
@@ -12,15 +12,15 @@
|
||||
#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
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4127) // conditional expression is constant
|
||||
# pragma warning(disable: 4702) // unreachable code (return after domain_error throw).
|
||||
#endif
|
||||
|
||||
#include <utility>
|
||||
#include <cmath>
|
||||
|
||||
namespace boost{ namespace math{
|
||||
|
||||
@@ -60,10 +60,10 @@ template <class RealType = double, class Policy = policies::policy<> >
|
||||
class exponential_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
using value_type = RealType;
|
||||
using policy_type = Policy;
|
||||
|
||||
exponential_distribution(RealType l_lambda = 1)
|
||||
explicit exponential_distribution(RealType l_lambda = 1)
|
||||
: m_lambda(l_lambda)
|
||||
{
|
||||
RealType err;
|
||||
@@ -76,10 +76,15 @@ private:
|
||||
RealType m_lambda;
|
||||
};
|
||||
|
||||
typedef exponential_distribution<double> exponential;
|
||||
using exponential = exponential_distribution<double>;
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
exponential_distribution(RealType)->exponential_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const exponential_distribution<RealType, Policy>& /*dist*/)
|
||||
inline std::pair<RealType, RealType> range(const exponential_distribution<RealType, Policy>& /*dist*/)
|
||||
{ // Range of permissible values for random variable x.
|
||||
if (std::numeric_limits<RealType>::has_infinity)
|
||||
{
|
||||
@@ -93,7 +98,7 @@ inline const std::pair<RealType, RealType> range(const exponential_distribution<
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> support(const exponential_distribution<RealType, Policy>& /*dist*/)
|
||||
inline 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;
|
||||
@@ -122,6 +127,24 @@ inline RealType pdf(const exponential_distribution<RealType, Policy>& dist, cons
|
||||
return result;
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType logpdf(const exponential_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::logpdf(const exponential_distribution<%1%>&, %1%)";
|
||||
|
||||
RealType lambda = dist.lambda();
|
||||
RealType result = -std::numeric_limits<RealType>::infinity();
|
||||
if(0 == detail::verify_lambda(function, lambda, &result, Policy()))
|
||||
return result;
|
||||
if(0 == detail::verify_exp_x(function, x, &result, Policy()))
|
||||
return result;
|
||||
|
||||
result = log(lambda) - lambda * x;
|
||||
return result;
|
||||
} // logpdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const exponential_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
@@ -140,6 +163,24 @@ inline RealType cdf(const exponential_distribution<RealType, Policy>& dist, cons
|
||||
return result;
|
||||
} // cdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType logcdf(const exponential_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::logcdf(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::log1p(-exp(-x * lambda), Policy());
|
||||
|
||||
return result;
|
||||
} // cdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const exponential_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
{
|
||||
@@ -184,6 +225,27 @@ inline RealType cdf(const complemented2_type<exponential_distribution<RealType,
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType logcdf(const complemented2_type<exponential_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::logcdf(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;
|
||||
// Workaround for VC11/12 bug:
|
||||
if (c.param >= tools::max_value<RealType>())
|
||||
return 0;
|
||||
result = -c.param * lambda;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const complemented2_type<exponential_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
@@ -260,10 +322,17 @@ inline RealType kurtosis_excess(const exponential_distribution<RealType, Policy>
|
||||
return 6;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType entropy(const exponential_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
using std::log;
|
||||
return 1 - log(dist.lambda());
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#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
|
||||
@@ -22,8 +21,9 @@
|
||||
// distribution or a Gumbel distribution.
|
||||
|
||||
#include <utility>
|
||||
#include <cmath>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4702) // unreachable code (return after domain_error throw).
|
||||
#endif
|
||||
@@ -53,10 +53,10 @@ template <class RealType = double, class Policy = policies::policy<> >
|
||||
class extreme_value_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
using value_type = RealType;
|
||||
using policy_type = Policy;
|
||||
|
||||
extreme_value_distribution(RealType a = 0, RealType b = 1)
|
||||
explicit extreme_value_distribution(RealType a = 0, RealType b = 1)
|
||||
: m_a(a), m_b(b)
|
||||
{
|
||||
RealType err;
|
||||
@@ -68,13 +68,21 @@ public:
|
||||
RealType scale()const { return m_b; }
|
||||
|
||||
private:
|
||||
RealType m_a, m_b;
|
||||
RealType m_a;
|
||||
RealType m_b;
|
||||
};
|
||||
|
||||
typedef extreme_value_distribution<double> extreme_value;
|
||||
using extreme_value = extreme_value_distribution<double>;
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
extreme_value_distribution(RealType)->extreme_value_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
template <class RealType>
|
||||
extreme_value_distribution(RealType,RealType)->extreme_value_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const extreme_value_distribution<RealType, Policy>& /*dist*/)
|
||||
inline 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>(
|
||||
@@ -83,7 +91,7 @@ inline const std::pair<RealType, RealType> range(const extreme_value_distributio
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> support(const extreme_value_distribution<RealType, Policy>& /*dist*/)
|
||||
inline 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;
|
||||
@@ -115,6 +123,31 @@ inline RealType pdf(const extreme_value_distribution<RealType, Policy>& dist, co
|
||||
return result;
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType logpdf(const extreme_value_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::logpdf(const extreme_value_distribution<%1%>&, %1%)";
|
||||
|
||||
RealType a = dist.location();
|
||||
RealType b = dist.scale();
|
||||
RealType result = -std::numeric_limits<RealType>::infinity();
|
||||
if(0 == detail::verify_scale_b(function, b, &result, Policy()))
|
||||
return result;
|
||||
if(0 == detail::check_finite(function, a, &result, Policy()))
|
||||
return result;
|
||||
if((boost::math::isinf)(x))
|
||||
return 0.0f;
|
||||
if(0 == detail::check_x(function, x, &result, Policy()))
|
||||
return result;
|
||||
RealType e = (a - x) / b;
|
||||
if(e < tools::log_max_value<RealType>())
|
||||
result = log(1/b) + e - exp(e);
|
||||
// else.... result *must* be zero since exp(e) is infinite...
|
||||
return result;
|
||||
} // logpdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const extreme_value_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
@@ -141,6 +174,32 @@ inline RealType cdf(const extreme_value_distribution<RealType, Policy>& dist, co
|
||||
return result;
|
||||
} // cdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType logcdf(const extreme_value_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::logcdf(const extreme_value_distribution<%1%>&, %1%)";
|
||||
|
||||
if((boost::math::isinf)(x))
|
||||
return x < 0 ? 0.0f : 1.0f;
|
||||
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_finite(function, a, &result, Policy()))
|
||||
return result;
|
||||
if(0 == detail::check_finite(function, a, &result, Policy()))
|
||||
return result;
|
||||
if(0 == detail::check_x("boost::math::logcdf(const extreme_value_distribution<%1%>&, %1%)", x, &result, Policy()))
|
||||
return result;
|
||||
|
||||
result = -exp((a-x)/b);
|
||||
|
||||
return result;
|
||||
} // logcdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
RealType quantile(const extreme_value_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
{
|
||||
@@ -192,6 +251,30 @@ inline RealType cdf(const complemented2_type<extreme_value_distribution<RealType
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType logcdf(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::logcdf(const extreme_value_distribution<%1%>&, %1%)";
|
||||
|
||||
if((boost::math::isinf)(c.param))
|
||||
return c.param < 0 ? 1.0f : 0.0f;
|
||||
RealType a = c.dist.location();
|
||||
RealType b = c.dist.scale();
|
||||
RealType result = 0;
|
||||
if(0 == detail::verify_scale_b(function, b, &result, Policy()))
|
||||
return result;
|
||||
if(0 == detail::check_finite(function, a, &result, Policy()))
|
||||
return result;
|
||||
if(0 == detail::check_x(function, c.param, &result, Policy()))
|
||||
return result;
|
||||
|
||||
result = log1p(-exp(-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)
|
||||
{
|
||||
@@ -288,7 +371,7 @@ inline RealType kurtosis_excess(const extreme_value_distribution<RealType, Polic
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#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;
|
||||
@@ -26,7 +25,7 @@ namespace boost
|
||||
// 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.
|
||||
// enforced by static_assert below.
|
||||
|
||||
template <class Dist, class Policy>
|
||||
inline
|
||||
@@ -38,13 +37,8 @@ namespace boost
|
||||
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_assert(::boost::math::tools::is_distribution<Dist>::value, "The provided distribution does not meet the conceptual requirements of a distribution.");
|
||||
static_assert(::boost::math::tools::is_scaled_distribution<Dist>::value, "The provided distribution does not meet the conceptual requirements of a scaled distribution.");
|
||||
static const char* function = "boost::math::find_location<Dist, Policy>&, %1%)";
|
||||
|
||||
if(!(boost::math::isfinite)(p) || (p < 0) || (p > 1))
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#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/tools/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,
|
||||
@@ -39,10 +39,8 @@ namespace boost
|
||||
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_assert(::boost::math::tools::is_distribution<Dist>::value, "The provided distribution does not meet the conceptual requirements of a distribution.");
|
||||
static_assert(::boost::math::tools::is_scaled_distribution<Dist>::value, "The provided distribution does not meet the conceptual requirements of a scaled distribution.");
|
||||
static const char* function = "boost::math::find_scale<Dist, Policy>(%1%, %1%, %1%, Policy)";
|
||||
|
||||
if(!(boost::math::isfinite)(p) || (p < 0) || (p > 1))
|
||||
@@ -111,10 +109,8 @@ namespace boost
|
||||
// << 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_assert(::boost::math::tools::is_distribution<Dist>::value, "The provided distribution does not meet the conceptual requirements of a distribution.");
|
||||
static_assert(::boost::math::tools::is_scaled_distribution<Dist>::value, "The provided distribution does not meet the conceptual requirements of a scaled distribution.");
|
||||
static const char* function = "boost::math::find_scale<Dist, Policy>(complement(%1%, %1%, %1%, Policy))";
|
||||
|
||||
// Checks on arguments, as not complemented version,
|
||||
@@ -165,10 +161,8 @@ namespace boost
|
||||
// << 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_assert(::boost::math::tools::is_distribution<Dist>::value, "The provided distribution does not meet the conceptual requirements of a distribution.");
|
||||
static_assert(::boost::math::tools::is_scaled_distribution<Dist>::value, "The provided distribution does not meet the conceptual requirements of a scaled distribution.");
|
||||
static const char* function = "boost::math::find_scale<Dist, Policy>(complement(%1%, %1%, %1%, Policy))";
|
||||
|
||||
// Checks on arguments, as not complemented version,
|
||||
|
||||
@@ -54,6 +54,11 @@ private:
|
||||
|
||||
typedef fisher_f_distribution<double> fisher_f;
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
fisher_f_distribution(RealType,RealType)->fisher_f_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
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.
|
||||
@@ -178,7 +183,7 @@ inline RealType quantile(const fisher_f_distribution<RealType, Policy>& dist, co
|
||||
return error_result;
|
||||
|
||||
// With optimizations turned on, gcc wrongly warns about y being used
|
||||
// uninitializated unless we initialize it to something:
|
||||
// uninitialized unless we initialize it to something:
|
||||
RealType x, y(0);
|
||||
|
||||
x = boost::math::ibeta_inv(df1 / 2, df2 / 2, p, &y, Policy());
|
||||
@@ -301,10 +306,10 @@ inline RealType mode(const fisher_f_distribution<RealType, Policy>& dist)
|
||||
&& detail::check_df(
|
||||
function, df2, &error_result, Policy()))
|
||||
return error_result;
|
||||
if(df2 <= 2)
|
||||
if(df1 <= 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());
|
||||
function, "First degree of freedom was %1% but must be > 2 in order for the distribution to have a mode.", df1, Policy());
|
||||
}
|
||||
return df2 * (df1 - 2) / (df1 * (df2 + 2));
|
||||
}
|
||||
@@ -366,7 +371,7 @@ inline RealType kurtosis_excess(const fisher_f_distribution<RealType, Policy>& d
|
||||
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());
|
||||
function, "Second degree of freedom was %1% but must be > 8 in order for the distribution to have a kurtosis.", df2, Policy());
|
||||
}
|
||||
RealType df2_2 = df2 * df2;
|
||||
RealType df1_2 = df1 * df1;
|
||||
|
||||
@@ -63,6 +63,9 @@ class inverse_gamma_distribution;
|
||||
template <class RealType, class Policy>
|
||||
class inverse_gaussian_distribution;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class kolmogorov_smirnov_distribution;
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class laplace_distribution;
|
||||
|
||||
@@ -129,6 +132,7 @@ class weibull_distribution;
|
||||
typedef boost::math::gamma_distribution<Type, Policy> gamma;\
|
||||
typedef boost::math::geometric_distribution<Type, Policy> geometric;\
|
||||
typedef boost::math::hypergeometric_distribution<Type, Policy> hypergeometric;\
|
||||
typedef boost::math::kolmogorov_smirnov_distribution<Type, Policy> kolmogorov_smirnov;\
|
||||
typedef boost::math::inverse_chi_squared_distribution<Type, Policy> inverse_chi_squared;\
|
||||
typedef boost::math::inverse_gaussian_distribution<Type, Policy> inverse_gaussian;\
|
||||
typedef boost::math::inverse_gamma_distribution<Type, Policy> inverse_gamma;\
|
||||
|
||||
@@ -12,10 +12,12 @@
|
||||
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#include <boost/math/special_functions/gamma.hpp>
|
||||
#include <boost/math/special_functions/digamma.hpp>
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp>
|
||||
#include <boost/math/distributions/complement.hpp>
|
||||
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost{ namespace math
|
||||
{
|
||||
@@ -70,10 +72,10 @@ template <class RealType = double, class Policy = policies::policy<> >
|
||||
class gamma_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
using value_type = RealType;
|
||||
using policy_type = Policy;
|
||||
|
||||
gamma_distribution(RealType l_shape, RealType l_scale = 1)
|
||||
explicit gamma_distribution(RealType l_shape, RealType l_scale = 1)
|
||||
: m_shape(l_shape), m_scale(l_scale)
|
||||
{
|
||||
RealType result;
|
||||
@@ -99,15 +101,22 @@ private:
|
||||
|
||||
// NO typedef because of clash with name of gamma function.
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
gamma_distribution(RealType)->gamma_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
template <class RealType>
|
||||
gamma_distribution(RealType,RealType)->gamma_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const gamma_distribution<RealType, Policy>& /* dist */)
|
||||
inline 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 */)
|
||||
inline 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;
|
||||
@@ -139,6 +148,33 @@ inline RealType pdf(const gamma_distribution<RealType, Policy>& dist, const Real
|
||||
return result;
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType logpdf(const gamma_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
using boost::math::lgamma;
|
||||
|
||||
static const char* function = "boost::math::logpdf(const gamma_distribution<%1%>&, %1%)";
|
||||
|
||||
RealType k = dist.shape();
|
||||
RealType theta = dist.scale();
|
||||
|
||||
RealType result = -std::numeric_limits<RealType>::infinity();
|
||||
if(false == detail::check_gamma(function, theta, k, &result, Policy()))
|
||||
return result;
|
||||
if(false == detail::check_gamma_x(function, x, &result, Policy()))
|
||||
return result;
|
||||
|
||||
if(x == 0)
|
||||
{
|
||||
return std::numeric_limits<RealType>::quiet_NaN();
|
||||
}
|
||||
|
||||
result = -k*log(theta) + (k-1)*log(x) - lgamma(k) - (x/theta);
|
||||
|
||||
return result;
|
||||
} // logpdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const gamma_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
@@ -336,6 +372,15 @@ inline RealType kurtosis(const gamma_distribution<RealType, Policy>& dist)
|
||||
return kurtosis_excess(dist) + 3;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType entropy(const gamma_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType k = dist.shape();
|
||||
RealType theta = dist.scale();
|
||||
using std::log;
|
||||
return k + log(theta) + lgamma(k) + (1-k)*digamma(k);
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
// 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,
|
||||
// it is convenient to treat it as if a continuous 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.
|
||||
@@ -43,14 +43,11 @@
|
||||
#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 <boost/math/special_functions/log1p.hpp>
|
||||
|
||||
#include <limits> // using std::numeric_limits;
|
||||
#include <utility>
|
||||
#include <cmath>
|
||||
|
||||
#if defined (BOOST_MSVC)
|
||||
# pragma warning(push)
|
||||
@@ -163,7 +160,7 @@ namespace boost
|
||||
// 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());
|
||||
return ibeta_inv(successes, failures + 1, alpha, static_cast<RealType*>(nullptr), Policy());
|
||||
} // find_lower_bound_on_p
|
||||
|
||||
static RealType find_upper_bound_on_p(
|
||||
@@ -192,7 +189,7 @@ namespace boost
|
||||
// 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());
|
||||
return ibetac_inv(successes, failures, alpha, static_cast<RealType*>(nullptr), Policy());
|
||||
} // find_upper_bound_on_p
|
||||
|
||||
// Estimate number of trials :
|
||||
@@ -227,7 +224,7 @@ namespace boost
|
||||
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
|
||||
@@ -241,6 +238,11 @@ namespace boost
|
||||
|
||||
typedef geometric_distribution<double> geometric; // Reserved name of type double.
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
geometric_distribution(RealType)->geometric_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
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.
|
||||
@@ -270,7 +272,7 @@ namespace boost
|
||||
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.
|
||||
@@ -378,9 +380,39 @@ namespace boost
|
||||
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.
|
||||
template <class RealType, class Policy>
|
||||
inline RealType logcdf(const geometric_distribution<RealType, Policy>& dist, const RealType& k)
|
||||
{ // Cumulative Distribution Function of geometric.
|
||||
using std::pow;
|
||||
static const char* function = "boost::math::logcdf(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 -std::numeric_limits<RealType>::infinity();
|
||||
}
|
||||
if(k == 0)
|
||||
{
|
||||
return log(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, Policy()) * (k + 1);
|
||||
return log1p(-exp(z), Policy());
|
||||
} // logcdf 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.
|
||||
@@ -403,6 +435,30 @@ namespace boost
|
||||
return probability;
|
||||
} // cdf Complemented Cumulative Distribution Function geometric.
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType logcdf(const complemented2_type<geometric_distribution<RealType, Policy>, RealType>& c)
|
||||
{ // Complemented Cumulative Distribution Function geometric.
|
||||
BOOST_MATH_STD_USING
|
||||
static const char* function = "boost::math::logcdf(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 -std::numeric_limits<RealType>::infinity();
|
||||
}
|
||||
|
||||
return boost::math::log1p(-p, Policy()) * (k+1);
|
||||
} // logcdf 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.
|
||||
@@ -446,7 +502,7 @@ namespace boost
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// log(1-x) /log(1-success_fraction) -1; but use log1p in case success_fraction is small
|
||||
result = boost::math::log1p(-x, Policy()) / boost::math::log1p(-success_fraction, Policy()) - 1;
|
||||
// Subtract a few epsilons here too?
|
||||
|
||||
@@ -15,8 +15,7 @@
|
||||
#ifndef BOOST_MATH_DISTRIBUTIONS_HYPEREXPONENTIAL_HPP
|
||||
#define BOOST_MATH_DISTRIBUTIONS_HYPEREXPONENTIAL_HPP
|
||||
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/math/tools/cxx03_warn.hpp>
|
||||
#include <boost/math/distributions/complement.hpp>
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp>
|
||||
#include <boost/math/distributions/exponential.hpp>
|
||||
@@ -24,20 +23,16 @@
|
||||
#include <boost/math/special_functions/fpclassify.hpp>
|
||||
#include <boost/math/tools/precision.hpp>
|
||||
#include <boost/math/tools/roots.hpp>
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/size.hpp>
|
||||
#include <boost/type_traits/has_pre_increment.hpp>
|
||||
#include <boost/math/tools/is_detected.hpp>
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
#include <numeric>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <type_traits>
|
||||
#include <initializer_list>
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
# include <initializer_list>
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning (push)
|
||||
@@ -142,7 +137,7 @@ bool check_dist(char const* function, std::vector<RealT> const& probabilities, s
|
||||
if (probabilities.size() != rates.size())
|
||||
{
|
||||
*presult = policies::raise_domain_error<RealT>(function,
|
||||
"The parameters \"probabilities\" and \"rates\" must have the same length, but their size differ by: %1%.",
|
||||
R"(The parameters "probabilities" and "rates" must have the same length, but their size differ by: %1%.)",
|
||||
fabs(static_cast<RealT>(probabilities.size())-static_cast<RealT>(rates.size())),
|
||||
pol);
|
||||
return false;
|
||||
@@ -277,16 +272,29 @@ class hyperexponential_distribution
|
||||
&err,
|
||||
PolicyT());
|
||||
}
|
||||
private: template <typename T, typename = void>
|
||||
struct is_iterator
|
||||
{
|
||||
static constexpr bool value = false;
|
||||
};
|
||||
|
||||
// Two arg constructor from 2 ranges, we SFINAE this out of existance if
|
||||
template <typename T>
|
||||
struct is_iterator<T, boost::math::tools::void_t<typename std::iterator_traits<T>::difference_type>>
|
||||
{
|
||||
// std::iterator_traits<T>::difference_type returns void for invalid types
|
||||
static constexpr bool value = !std::is_same<typename std::iterator_traits<T>::difference_type, void>::value;
|
||||
};
|
||||
|
||||
// Two arg constructor from 2 ranges, we SFINAE this out of existence if
|
||||
// either argument type is incrementable as in that case the type is
|
||||
// probably an iterator:
|
||||
public: template <typename ProbRangeT, typename RateRangeT>
|
||||
public: template <typename ProbRangeT, typename RateRangeT,
|
||||
typename std::enable_if<!is_iterator<ProbRangeT>::value &&
|
||||
!is_iterator<RateRangeT>::value, bool>::type = true>
|
||||
hyperexponential_distribution(ProbRangeT const& prob_range,
|
||||
RateRangeT const& rate_range,
|
||||
typename boost::disable_if_c<boost::has_pre_increment<ProbRangeT>::value || boost::has_pre_increment<RateRangeT>::value>::type* = 0)
|
||||
: probs_(boost::begin(prob_range), boost::end(prob_range)),
|
||||
rates_(boost::begin(rate_range), boost::end(rate_range))
|
||||
RateRangeT const& rate_range)
|
||||
: probs_(std::begin(prob_range), std::end(prob_range)),
|
||||
rates_(std::begin(rate_range), std::end(rate_range))
|
||||
{
|
||||
hyperexp_detail::normalize(probs_);
|
||||
|
||||
@@ -299,13 +307,14 @@ class hyperexponential_distribution
|
||||
}
|
||||
|
||||
// Two arg constructor for a pair of iterators: we SFINAE this out of
|
||||
// existance if neither argument types are incrementable.
|
||||
// existence if neither argument types are incrementable.
|
||||
// Note that we allow different argument types here to allow for
|
||||
// construction from an array plus a pointer into that array.
|
||||
public: template <typename RateIterT, typename RateIterT2>
|
||||
public: template <typename RateIterT, typename RateIterT2,
|
||||
typename std::enable_if<is_iterator<RateIterT>::value ||
|
||||
is_iterator<RateIterT2>::value, bool>::type = true>
|
||||
hyperexponential_distribution(RateIterT const& rate_first,
|
||||
RateIterT2 const& rate_last,
|
||||
typename boost::enable_if_c<boost::has_pre_increment<RateIterT>::value || boost::has_pre_increment<RateIterT2>::value>::type* = 0)
|
||||
RateIterT2 const& rate_last)
|
||||
: probs_(std::distance(rate_first, rate_last), 1), // will be normalized below
|
||||
rates_(rate_first, rate_last)
|
||||
{
|
||||
@@ -319,7 +328,6 @@ class hyperexponential_distribution
|
||||
PolicyT());
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
// Initializer list constructor: allows for construction from array literals:
|
||||
public: hyperexponential_distribution(std::initializer_list<RealT> l1, std::initializer_list<RealT> l2)
|
||||
: probs_(l1.begin(), l1.end()),
|
||||
@@ -348,13 +356,12 @@ public: hyperexponential_distribution(std::initializer_list<RealT> l1)
|
||||
&err,
|
||||
PolicyT());
|
||||
}
|
||||
#endif // !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
|
||||
// Single argument constructor: argument must be a range.
|
||||
public: template <typename RateRangeT>
|
||||
hyperexponential_distribution(RateRangeT const& rate_range)
|
||||
: probs_(boost::size(rate_range), 1), // will be normalized below
|
||||
rates_(boost::begin(rate_range), boost::end(rate_range))
|
||||
: probs_(std::distance(std::begin(rate_range), std::end(rate_range)), 1), // will be normalized below
|
||||
rates_(std::begin(rate_range), std::end(rate_range))
|
||||
{
|
||||
hyperexp_detail::normalize(probs_);
|
||||
|
||||
@@ -622,7 +629,7 @@ RealT mode(hyperexponential_distribution<RealT,PolicyT> const& /*dist*/)
|
||||
|
||||
}} // namespace boost::math
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
// This include must be at the end, *after* the accessors
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// Copyright 2008 Gautam Sewani
|
||||
// Copyright 2008 John Maddock
|
||||
// Copyright 2021 Paul A. Bristow
|
||||
//
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0.
|
||||
@@ -15,7 +16,7 @@
|
||||
#include <boost/math/distributions/detail/hypergeometric_cdf.hpp>
|
||||
#include <boost/math/distributions/detail/hypergeometric_quantile.hpp>
|
||||
#include <boost/math/special_functions/fpclassify.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace boost { namespace math {
|
||||
|
||||
@@ -26,7 +27,7 @@ namespace boost { namespace math {
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
|
||||
hypergeometric_distribution(unsigned r, unsigned n, unsigned N) // Constructor.
|
||||
hypergeometric_distribution(std::uint64_t r, std::uint64_t n, std::uint64_t N) // Constructor. r=defective/failures/success, n=trials/draws, N=total population.
|
||||
: m_n(n), m_N(N), m_r(r)
|
||||
{
|
||||
static const char* function = "boost::math::hypergeometric_distribution<%1%>::hypergeometric_distribution";
|
||||
@@ -34,17 +35,17 @@ namespace boost { namespace math {
|
||||
check_params(function, &ret);
|
||||
}
|
||||
// Accessor functions.
|
||||
unsigned total()const
|
||||
std::uint64_t total() const
|
||||
{
|
||||
return m_N;
|
||||
}
|
||||
|
||||
unsigned defective()const
|
||||
std::uint64_t defective() const // successes/failures/events
|
||||
{
|
||||
return m_r;
|
||||
}
|
||||
|
||||
unsigned sample_count()const
|
||||
std::uint64_t sample_count()const
|
||||
{
|
||||
return m_n;
|
||||
}
|
||||
@@ -65,9 +66,9 @@ namespace boost { namespace math {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool check_x(unsigned x, const char* function, RealType* result)const
|
||||
bool check_x(std::uint64_t x, const char* function, RealType* result)const
|
||||
{
|
||||
if(x < static_cast<unsigned>((std::max)(0, (int)(m_n + m_r) - (int)(m_N))))
|
||||
if(x < static_cast<std::uint64_t>((std::max)(INT64_C(0), static_cast<std::int64_t>(m_n + m_r) - static_cast<std::int64_t>(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());
|
||||
@@ -84,40 +85,40 @@ namespace boost { namespace math {
|
||||
|
||||
private:
|
||||
// Data members:
|
||||
unsigned m_n; // number of items picked
|
||||
unsigned m_N; // number of "total" items
|
||||
unsigned m_r; // number of "defective" items
|
||||
std::uint64_t m_n; // number of items picked or drawn.
|
||||
std::uint64_t m_N; // number of "total" items.
|
||||
std::uint64_t m_r; // number of "defective/successes/failures/events items.
|
||||
|
||||
}; // 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)
|
||||
inline const std::pair<std::uint64_t, std::uint64_t> range(const hypergeometric_distribution<RealType, Policy>& dist)
|
||||
{ // Range of permissible values for random variable x.
|
||||
#ifdef BOOST_MSVC
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4267)
|
||||
#endif
|
||||
unsigned r = dist.defective();
|
||||
unsigned n = dist.sample_count();
|
||||
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
|
||||
const auto r = dist.defective();
|
||||
const auto n = dist.sample_count();
|
||||
const auto N = dist.total();
|
||||
const auto l = static_cast<std::uint64_t>((std::max)(INT64_C(0), static_cast<std::int64_t>(n + r) - static_cast<std::int64_t>(N)));
|
||||
const auto u = (std::min)(r, n);
|
||||
return std::make_pair(l, u);
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<unsigned, unsigned> support(const hypergeometric_distribution<RealType, Policy>& d)
|
||||
{
|
||||
inline const std::pair<std::uint64_t, std::uint64_t> 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)
|
||||
inline RealType pdf(const hypergeometric_distribution<RealType, Policy>& dist, const std::uint64_t& x)
|
||||
{
|
||||
static const char* function = "boost::math::pdf(const hypergeometric_distribution<%1%>&, const %1%&)";
|
||||
RealType result = 0;
|
||||
@@ -136,7 +137,7 @@ namespace boost { namespace math {
|
||||
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, typename policies::normalise<Policy, policies::rounding_error<policies::ignore_error> >::type());
|
||||
auto u = static_cast<std::uint64_t>(lltrunc(r, typename policies::normalise<Policy, policies::rounding_error<policies::ignore_error> >::type()));
|
||||
if(u != r)
|
||||
{
|
||||
return boost::math::policies::raise_domain_error<RealType>(
|
||||
@@ -146,7 +147,7 @@ namespace boost { namespace math {
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const hypergeometric_distribution<RealType, Policy>& dist, const unsigned& x)
|
||||
inline RealType cdf(const hypergeometric_distribution<RealType, Policy>& dist, const std::uint64_t& x)
|
||||
{
|
||||
static const char* function = "boost::math::cdf(const hypergeometric_distribution<%1%>&, const %1%&)";
|
||||
RealType result = 0;
|
||||
@@ -165,7 +166,7 @@ namespace boost { namespace math {
|
||||
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, typename policies::normalise<Policy, policies::rounding_error<policies::ignore_error> >::type());
|
||||
auto u = static_cast<std::uint64_t>(lltrunc(r, typename policies::normalise<Policy, policies::rounding_error<policies::ignore_error> >::type()));
|
||||
if(u != r)
|
||||
{
|
||||
return boost::math::policies::raise_domain_error<RealType>(
|
||||
@@ -175,7 +176,7 @@ namespace boost { namespace math {
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const complemented2_type<hypergeometric_distribution<RealType, Policy>, unsigned>& c)
|
||||
inline RealType cdf(const complemented2_type<hypergeometric_distribution<RealType, Policy>, std::uint64_t>& c)
|
||||
{
|
||||
static const char* function = "boost::math::cdf(const hypergeometric_distribution<%1%>&, const %1%&)";
|
||||
RealType result = 0;
|
||||
@@ -194,7 +195,7 @@ namespace boost { namespace math {
|
||||
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, typename policies::normalise<Policy, policies::rounding_error<policies::ignore_error> >::type());
|
||||
auto u = static_cast<std::uint64_t>(lltrunc(r, typename policies::normalise<Policy, policies::rounding_error<policies::ignore_error> >::type()));
|
||||
if(u != r)
|
||||
{
|
||||
return boost::math::policies::raise_domain_error<RealType>(
|
||||
@@ -208,11 +209,14 @@ namespace boost { namespace math {
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
// Checking function argument
|
||||
RealType result = 0;
|
||||
// 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;
|
||||
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.defective(), dist.sample_count(), dist.total(), Policy()));
|
||||
} // quantile
|
||||
@@ -225,12 +229,16 @@ namespace boost { namespace math {
|
||||
// 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;
|
||||
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.defective(), c.dist.sample_count(), c.dist.total(), Policy()));
|
||||
} // quantile
|
||||
|
||||
// https://www.wolframalpha.com/input/?i=kurtosis+hypergeometric+distribution
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mean(const hypergeometric_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
@@ -269,13 +277,23 @@ namespace boost { namespace math {
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis_excess(const hypergeometric_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType r = static_cast<RealType>(dist.defective());
|
||||
RealType n = static_cast<RealType>(dist.sample_count());
|
||||
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;
|
||||
// https://www.wolframalpha.com/input/?i=kurtosis+hypergeometric+distribution shown as plain text:
|
||||
// mean | (m n)/N
|
||||
// standard deviation | sqrt((m n(N - m) (N - n))/(N - 1))/N
|
||||
// variance | (m n(1 - m/N) (N - n))/((N - 1) N)
|
||||
// skewness | (sqrt(N - 1) (N - 2 m) (N - 2 n))/((N - 2) sqrt(m n(N - m) (N - n)))
|
||||
// kurtosis | ((N - 1) N^2 ((3 m(N - m) (n^2 (-N) + (n - 2) N^2 + 6 n(N - n)))/N^2 - 6 n(N - n) + N(N + 1)))/(m n(N - 3) (N - 2) (N - m) (N - n))
|
||||
// Kurtosis[HypergeometricDistribution[n, m, N]]
|
||||
RealType m = static_cast<RealType>(dist.defective()); // Failures or success events. (Also symbols K or M are used).
|
||||
RealType n = static_cast<RealType>(dist.sample_count()); // draws or trials.
|
||||
RealType n2 = n * n; // n^2
|
||||
RealType N = static_cast<RealType>(dist.total()); // Total population from which n draws or trials are made.
|
||||
RealType N2 = N * N; // N^2
|
||||
// result = ((N - 1) N^2 ((3 m(N - m) (n^2 (-N) + (n - 2) N^2 + 6 n(N - n)))/N^2 - 6 n(N - n) + N(N + 1)))/(m n(N - 3) (N - 2) (N - m) (N - n));
|
||||
RealType result = ((N-1)*N2*((3*m*(N-m)*(n2*(-N)+(n-2)*N2+6*n*(N-n)))/N2-6*n*(N-n)+N*(N+1)))/(m*n*(N-3)*(N-2)*(N-m)*(N-n));
|
||||
// Agrees with kurtosis hypergeometric distribution(50,200,500) kurtosis = 2.96917
|
||||
// N[kurtosis[hypergeometricdistribution(50,200,500)], 55] 2.969174035736058474901169623721804275002985337280263464
|
||||
return result;
|
||||
} // RealType kurtosis_excess(const hypergeometric_distribution<RealType, Policy>& dist)
|
||||
|
||||
template <class RealType, class Policy>
|
||||
|
||||
@@ -97,6 +97,13 @@ private:
|
||||
|
||||
typedef inverse_chi_squared_distribution<double> inverse_chi_squared;
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
inverse_chi_squared_distribution(RealType)->inverse_chi_squared_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
template <class RealType>
|
||||
inverse_chi_squared_distribution(RealType,RealType)->inverse_chi_squared_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
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.
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <boost/math/distributions/complement.hpp>
|
||||
|
||||
#include <utility>
|
||||
#include <cfenv>
|
||||
|
||||
namespace boost{ namespace math
|
||||
{
|
||||
@@ -88,10 +89,10 @@ template <class RealType = double, class Policy = policies::policy<> >
|
||||
class inverse_gamma_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
using value_type = RealType;
|
||||
using policy_type = Policy;
|
||||
|
||||
inverse_gamma_distribution(RealType l_shape = 1, RealType l_scale = 1)
|
||||
explicit inverse_gamma_distribution(RealType l_shape = 1, RealType l_scale = 1)
|
||||
: m_shape(l_shape), m_scale(l_scale)
|
||||
{
|
||||
RealType result;
|
||||
@@ -117,22 +118,28 @@ private:
|
||||
RealType m_scale; // distribution scale
|
||||
};
|
||||
|
||||
typedef inverse_gamma_distribution<double> inverse_gamma;
|
||||
using inverse_gamma = inverse_gamma_distribution<double>;
|
||||
// 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;
|
||||
// but there is a typedef for the gamma distribution (gamma)
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
inverse_gamma_distribution(RealType)->inverse_gamma_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
template <class RealType>
|
||||
inverse_gamma_distribution(RealType,RealType)->inverse_gamma_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
// 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 */)
|
||||
inline 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 */)
|
||||
inline 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;
|
||||
@@ -183,11 +190,47 @@ inline RealType pdf(const inverse_gamma_distribution<RealType, Policy>& dist, co
|
||||
}
|
||||
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 logpdf(const inverse_gamma_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
using boost::math::lgamma;
|
||||
|
||||
static const char* function = "boost::math::logpdf(const inverse_gamma_distribution<%1%>&, %1%)";
|
||||
|
||||
RealType shape = dist.shape();
|
||||
RealType scale = dist.scale();
|
||||
|
||||
RealType result = -std::numeric_limits<RealType>::infinity();
|
||||
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 result;
|
||||
}
|
||||
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 result; // random variable is infinite or so close as to make no difference.
|
||||
|
||||
// x * x may under or overflow, likewise our result
|
||||
if (!(boost::math::isfinite)(x*x))
|
||||
{
|
||||
return policies::raise_overflow_error<RealType, Policy>(function, "PDF is infinite.", Policy());
|
||||
}
|
||||
|
||||
return shape * log(scale) + (-shape-1)*log(x) - lgamma(shape) - (scale/x);
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const inverse_gamma_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
@@ -262,7 +305,6 @@ inline RealType cdf(const complemented2_type<inverse_gamma_distribution<RealType
|
||||
if(c.param == 0)
|
||||
return 1; // Avoid division by zero
|
||||
|
||||
//result = 1. - gamma_q(shape, c.param / scale, Policy());
|
||||
result = gamma_p(shape, scale/c.param, Policy());
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -55,13 +55,9 @@
|
||||
#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>
|
||||
|
||||
@@ -71,10 +67,10 @@ template <class RealType = double, class Policy = policies::policy<> >
|
||||
class inverse_gaussian_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
using value_type = RealType;
|
||||
using policy_type = Policy;
|
||||
|
||||
inverse_gaussian_distribution(RealType l_mean = 1, RealType l_scale = 1)
|
||||
explicit inverse_gaussian_distribution(RealType l_mean = 1, RealType l_scale = 1)
|
||||
: m_mean(l_mean), m_scale(l_scale)
|
||||
{ // Default is a 1,1 inverse_gaussian distribution.
|
||||
static const char* function = "boost::math::inverse_gaussian_distribution<%1%>::inverse_gaussian_distribution";
|
||||
@@ -113,17 +109,24 @@ private:
|
||||
RealType m_scale; // distribution standard deviation or scale, aka lambda.
|
||||
}; // class normal_distribution
|
||||
|
||||
typedef inverse_gaussian_distribution<double> inverse_gaussian;
|
||||
using inverse_gaussian = inverse_gaussian_distribution<double>;
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
inverse_gaussian_distribution(RealType)->inverse_gaussian_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
template <class RealType>
|
||||
inverse_gaussian_distribution(RealType,RealType)->inverse_gaussian_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const inverse_gaussian_distribution<RealType, Policy>& /*dist*/)
|
||||
inline 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*/)
|
||||
inline 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;
|
||||
@@ -167,6 +170,43 @@ inline RealType pdf(const inverse_gaussian_distribution<RealType, Policy>& dist,
|
||||
return result;
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType logpdf(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 = -std::numeric_limits<RealType>::infinity();
|
||||
static const char* function = "boost::math::logpdf(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_x_gt0(function, mean, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(false == detail::check_positive_x(function, x, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (x == 0)
|
||||
{
|
||||
return std::numeric_limits<RealType>::quiet_NaN(); // Convenient, even if not defined mathematically. log(0)
|
||||
}
|
||||
|
||||
const RealType two_pi = boost::math::constants::two_pi<RealType>();
|
||||
|
||||
result = (-scale*pow(mean - x, RealType(2))/(mean*mean*x) + log(scale) - 3*log(x) - log(two_pi)) / 2;
|
||||
return result;
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const inverse_gaussian_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{ // Cumulative Density Function.
|
||||
@@ -196,10 +236,7 @@ inline RealType cdf(const inverse_gaussian_distribution<RealType, Policy>& dist,
|
||||
{
|
||||
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()));
|
||||
// Problem with this formula for large scale > 1000 or small x
|
||||
// so use normal distribution version:
|
||||
// Wikipedia CDF equation http://en.wikipedia.org/wiki/Inverse_Gaussian_distribution.
|
||||
|
||||
@@ -263,22 +300,20 @@ 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;
|
||||
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;
|
||||
using no_overthrow_policy = policy<overflow_error<ignore_error>>;
|
||||
|
||||
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
|
||||
@@ -293,14 +328,12 @@ namespace detail
|
||||
using boost::math::gamma_distribution;
|
||||
|
||||
// Define the distribution, using gamma_nooverflow:
|
||||
typedef gamma_distribution<RealType, no_overthrow_policy> gamma_nooverflow;
|
||||
using gamma_nooverflow = gamma_distribution<RealType, no_overthrow_policy>;
|
||||
|
||||
gamma_nooverflow 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
|
||||
// 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?
|
||||
@@ -343,19 +376,19 @@ inline RealType quantile(const inverse_gaussian_distribution<RealType, Policy>&
|
||||
{ // overflow
|
||||
result = policies::raise_overflow_error<RealType>(function,
|
||||
"probability parameter is 1, but must be < 1!", Policy());
|
||||
return result; // std::numeric_limits<RealType>::infinity();
|
||||
return result; // 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 min = static_cast<RealType>(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.
|
||||
std::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, Policy>(dist, p), guess, min, max, get_digits, m);
|
||||
@@ -371,21 +404,7 @@ inline RealType cdf(const complemented2_type<inverse_gaussian_distribution<RealT
|
||||
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;
|
||||
@@ -435,12 +454,12 @@ inline RealType quantile(const complemented2_type<inverse_gaussian_distribution<
|
||||
// Complement.
|
||||
using boost::math::tools::max_value;
|
||||
|
||||
RealType min = 0.; // Minimum possible value is bottom of range of distribution.
|
||||
RealType min = static_cast<RealType>(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>();
|
||||
std::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, Policy>(c.dist, q), guess, min, max, get_digits, m);
|
||||
|
||||
499
linx64/include/boost/math/distributions/kolmogorov_smirnov.hpp
Normal file
499
linx64/include/boost/math/distributions/kolmogorov_smirnov.hpp
Normal file
@@ -0,0 +1,499 @@
|
||||
// Kolmogorov-Smirnov 1st order asymptotic distribution
|
||||
// Copyright Evan Miller 2020
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
// The Kolmogorov-Smirnov test in statistics compares two empirical distributions,
|
||||
// or an empirical distribution against any theoretical distribution. It makes
|
||||
// use of a specific distribution which doesn't have a formal name, but which
|
||||
// is often called the Kolmogorv-Smirnov distribution for lack of anything
|
||||
// better. This file implements the limiting form of this distribution, first
|
||||
// identified by Andrey Kolmogorov in
|
||||
//
|
||||
// Kolmogorov, A. (1933) "Sulla Determinazione Empirica di una Legge di
|
||||
// Distribuzione." Giornale dell' Istituto Italiano degli Attuari
|
||||
//
|
||||
// This limiting form of the CDF is a first-order Taylor expansion that is
|
||||
// easily implemented by the fourth Jacobi Theta function (setting z=0). The
|
||||
// PDF is then implemented here as a derivative of the Theta function. Note
|
||||
// that this derivative is with respect to x, which enters into \tau, and not
|
||||
// with respect to the z argument, which is always zero, and so the derivative
|
||||
// identities in DLMF 20.4 do not apply here.
|
||||
//
|
||||
// A higher order order expansion is possible, and was first outlined by
|
||||
//
|
||||
// Pelz W, Good IJ (1976). "Approximating the Lower Tail-Areas of the
|
||||
// Kolmogorov-Smirnov One-sample Statistic." Journal of the Royal Statistical
|
||||
// Society B.
|
||||
//
|
||||
// The terms in this expansion get fairly complicated, and as far as I know the
|
||||
// Pelz-Good expansion is not used in any statistics software. Someone could
|
||||
// consider updating this implementation to use the Pelz-Good expansion in the
|
||||
// future, but the math gets considerably hairier with each additional term.
|
||||
//
|
||||
// A formula for an exact version of the Kolmogorov-Smirnov test is laid out in
|
||||
// Equation 2.4.4 of
|
||||
//
|
||||
// Durbin J (1973). "Distribution Theory for Tests Based on the Sample
|
||||
// Distribution Func- tion." In SIAM CBMS-NSF Regional Conference Series in
|
||||
// Applied Mathematics. SIAM, Philadelphia, PA.
|
||||
//
|
||||
// which is available in book form from Amazon and others. This exact version
|
||||
// involves taking powers of large matrices. To do that right you need to
|
||||
// compute eigenvalues and eigenvectors, which are beyond the scope of Boost.
|
||||
// (Some recent work indicates the exact form can also be computed via FFT, see
|
||||
// https://cran.r-project.org/web/packages/KSgeneral/KSgeneral.pdf).
|
||||
//
|
||||
// Even if the CDF of the exact distribution could be computed using Boost
|
||||
// libraries (which would be cumbersome), the PDF would present another
|
||||
// difficulty. Therefore I am limiting this implementation to the asymptotic
|
||||
// form, even though the exact form has trivial values for certain specific
|
||||
// values of x and n. For more on trivial values see
|
||||
//
|
||||
// Ruben H, Gambino J (1982). "The Exact Distribution of Kolmogorov's Statistic
|
||||
// Dn for n <= 10." Annals of the Institute of Statistical Mathematics.
|
||||
//
|
||||
// For a good bibliography and overview of the various algorithms, including
|
||||
// both exact and asymptotic forms, see
|
||||
// https://www.jstatsoft.org/article/view/v039i11
|
||||
//
|
||||
// As for this implementation: the distribution is parameterized by n (number
|
||||
// of observations) in the spirit of chi-squared's degrees of freedom. It then
|
||||
// takes a single argument x. In terms of the Kolmogorov-Smirnov statistical
|
||||
// test, x represents the distribution of D_n, where D_n is the maximum
|
||||
// difference between the CDFs being compared, that is,
|
||||
//
|
||||
// D_n = sup|F_n(x) - G(x)|
|
||||
//
|
||||
// In the exact distribution, x is confined to the support [0, 1], but in this
|
||||
// limiting approximation, we allow x to exceed unity (similar to how a normal
|
||||
// approximation always spills over any boundaries).
|
||||
//
|
||||
// As mentioned previously, the CDF is implemented using the \tau
|
||||
// parameterization of the fourth Jacobi Theta function as
|
||||
//
|
||||
// CDF=theta_4(0|2*x*x*n/pi)
|
||||
//
|
||||
// The PDF is a hand-coded derivative of that function. Actually, there are two
|
||||
// (independent) derivatives, as separate code paths are used for "small x"
|
||||
// (2*x*x*n < pi) and "large x", mirroring the separate code paths in the
|
||||
// Jacobi Theta implementation to achieve fast convergence. Quantiles are
|
||||
// computed using a Newton-Raphson iteration from an initial guess that I
|
||||
// arrived at by trial and error.
|
||||
//
|
||||
// The mean and variance are implemented using simple closed-form expressions.
|
||||
// Skewness and kurtosis use slightly more complicated closed-form expressions
|
||||
// that involve the zeta function. The mode is calculated at run-time by
|
||||
// maximizing the PDF. If you have an analytical solution for the mode, feel
|
||||
// free to plop it in.
|
||||
//
|
||||
// The CDF and PDF could almost certainly be re-implemented and sped up using a
|
||||
// polynomial or rational approximation, since the only meaningful argument is
|
||||
// x * sqrt(n). But that is left as an exercise for the next maintainer.
|
||||
//
|
||||
// In the future, the Pelz-Good approximation could be added. I suggest adding
|
||||
// a second parameter representing the order, e.g.
|
||||
//
|
||||
// kolmogorov_smirnov_dist<>(100) // N=100, order=1
|
||||
// kolmogorov_smirnov_dist<>(100, 1) // N=100, order=1, i.e. Kolmogorov's formula
|
||||
// kolmogorov_smirnov_dist<>(100, 4) // N=100, order=4, i.e. Pelz-Good formula
|
||||
//
|
||||
// The exact distribution could be added to the API with a special order
|
||||
// parameter (e.g. 0 or infinity), or a separate distribution type altogether
|
||||
// (e.g. kolmogorov_smirnov_exact_distribution).
|
||||
//
|
||||
#ifndef BOOST_MATH_DISTRIBUTIONS_KOLMOGOROV_SMIRNOV_HPP
|
||||
#define BOOST_MATH_DISTRIBUTIONS_KOLMOGOROV_SMIRNOV_HPP
|
||||
|
||||
#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/jacobi_theta.hpp>
|
||||
#include <boost/math/tools/tuple.hpp>
|
||||
#include <boost/math/tools/roots.hpp> // Newton-Raphson
|
||||
#include <boost/math/tools/minima.hpp> // For the mode
|
||||
|
||||
namespace boost { namespace math {
|
||||
|
||||
namespace detail {
|
||||
template <class RealType>
|
||||
inline RealType kolmogorov_smirnov_quantile_guess(RealType p) {
|
||||
// Choose a starting point for the Newton-Raphson iteration
|
||||
if (p > 0.9)
|
||||
return RealType(1.8) - 5 * (1 - p);
|
||||
if (p < 0.3)
|
||||
return p + RealType(0.45);
|
||||
return p + RealType(0.3);
|
||||
}
|
||||
|
||||
// d/dk (theta2(0, 1/(2*k*k/M_PI))/sqrt(2*k*k*M_PI))
|
||||
template <class RealType, class Policy>
|
||||
RealType kolmogorov_smirnov_pdf_small_x(RealType x, RealType n, const Policy&) {
|
||||
BOOST_MATH_STD_USING
|
||||
RealType value = RealType(0), delta = RealType(0), last_delta = RealType(0);
|
||||
RealType eps = policies::get_epsilon<RealType, Policy>();
|
||||
int i = 0;
|
||||
RealType pi2 = constants::pi_sqr<RealType>();
|
||||
RealType x2n = x*x*n;
|
||||
if (x2n*x2n == 0.0) {
|
||||
return static_cast<RealType>(0);
|
||||
}
|
||||
while (true) {
|
||||
delta = exp(-RealType(i+0.5)*RealType(i+0.5)*pi2/(2*x2n)) * (RealType(i+0.5)*RealType(i+0.5)*pi2 - x2n);
|
||||
|
||||
if (delta == 0.0)
|
||||
break;
|
||||
|
||||
if (last_delta != 0.0 && fabs(delta/last_delta) < eps)
|
||||
break;
|
||||
|
||||
value += delta + delta;
|
||||
last_delta = delta;
|
||||
i++;
|
||||
}
|
||||
|
||||
return value * sqrt(n) * constants::root_half_pi<RealType>() / (x2n*x2n);
|
||||
}
|
||||
|
||||
// d/dx (theta4(0, 2*x*x*n/M_PI))
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kolmogorov_smirnov_pdf_large_x(RealType x, RealType n, const Policy&) {
|
||||
BOOST_MATH_STD_USING
|
||||
RealType value = RealType(0), delta = RealType(0), last_delta = RealType(0);
|
||||
RealType eps = policies::get_epsilon<RealType, Policy>();
|
||||
int i = 1;
|
||||
while (true) {
|
||||
delta = 8*x*i*i*exp(-2*i*i*x*x*n);
|
||||
|
||||
if (delta == 0.0)
|
||||
break;
|
||||
|
||||
if (last_delta != 0.0 && fabs(delta / last_delta) < eps)
|
||||
break;
|
||||
|
||||
if (i%2 == 0)
|
||||
delta = -delta;
|
||||
|
||||
value += delta;
|
||||
last_delta = delta;
|
||||
i++;
|
||||
}
|
||||
|
||||
return value * n;
|
||||
}
|
||||
|
||||
} // detail
|
||||
|
||||
template <class RealType = double, class Policy = policies::policy<> >
|
||||
class kolmogorov_smirnov_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
|
||||
// Constructor
|
||||
kolmogorov_smirnov_distribution( RealType n ) : n_obs_(n)
|
||||
{
|
||||
RealType result;
|
||||
detail::check_df(
|
||||
"boost::math::kolmogorov_smirnov_distribution<%1%>::kolmogorov_smirnov_distribution", n_obs_, &result, Policy());
|
||||
}
|
||||
|
||||
RealType number_of_observations()const
|
||||
{
|
||||
return n_obs_;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
RealType n_obs_; // positive integer
|
||||
};
|
||||
|
||||
typedef kolmogorov_smirnov_distribution<double> kolmogorov_k; // Convenience typedef for double version.
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
kolmogorov_smirnov_distribution(RealType)->kolmogorov_smirnov_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
namespace detail {
|
||||
template <class RealType, class Policy>
|
||||
struct kolmogorov_smirnov_quantile_functor
|
||||
{
|
||||
kolmogorov_smirnov_quantile_functor(const boost::math::kolmogorov_smirnov_distribution<RealType, Policy> dist, RealType const& p)
|
||||
: distribution(dist), prob(p)
|
||||
{
|
||||
}
|
||||
|
||||
boost::math::tuple<RealType, RealType> operator()(RealType const& x)
|
||||
{
|
||||
RealType fx = cdf(distribution, x) - 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::kolmogorov_smirnov_distribution<RealType, Policy> distribution;
|
||||
RealType prob;
|
||||
};
|
||||
|
||||
template <class RealType, class Policy>
|
||||
struct kolmogorov_smirnov_complementary_quantile_functor
|
||||
{
|
||||
kolmogorov_smirnov_complementary_quantile_functor(const boost::math::kolmogorov_smirnov_distribution<RealType, Policy> dist, RealType const& p)
|
||||
: distribution(dist), prob(p)
|
||||
{
|
||||
}
|
||||
|
||||
boost::math::tuple<RealType, RealType> operator()(RealType const& x)
|
||||
{
|
||||
RealType fx = cdf(complement(distribution, x)) - prob; // Difference cdf - value - to minimize.
|
||||
RealType dx = -pdf(distribution, x); // pdf is the negative of the derivative of (1-CDF)
|
||||
// return both function evaluation difference f(x) and 1st derivative f'(x).
|
||||
return boost::math::make_tuple(fx, dx);
|
||||
}
|
||||
private:
|
||||
const boost::math::kolmogorov_smirnov_distribution<RealType, Policy> distribution;
|
||||
RealType prob;
|
||||
};
|
||||
|
||||
template <class RealType, class Policy>
|
||||
struct kolmogorov_smirnov_negative_pdf_functor
|
||||
{
|
||||
RealType operator()(RealType const& x) {
|
||||
if (2*x*x < constants::pi<RealType>()) {
|
||||
return -kolmogorov_smirnov_pdf_small_x(x, static_cast<RealType>(1), Policy());
|
||||
}
|
||||
return -kolmogorov_smirnov_pdf_large_x(x, static_cast<RealType>(1), Policy());
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const kolmogorov_smirnov_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 kolmogorov_smirnov_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.
|
||||
// In the exact distribution, the upper limit would be 1.
|
||||
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 kolmogorov_smirnov_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_FPU_EXCEPTION_GUARD
|
||||
BOOST_MATH_STD_USING // for ADL of std functions.
|
||||
|
||||
RealType n = dist.number_of_observations();
|
||||
RealType error_result;
|
||||
static const char* function = "boost::math::pdf(const kolmogorov_smirnov_distribution<%1%>&, %1%)";
|
||||
if(false == detail::check_x_not_NaN(function, x, &error_result, Policy()))
|
||||
return error_result;
|
||||
|
||||
if(false == detail::check_df(function, n, &error_result, Policy()))
|
||||
return error_result;
|
||||
|
||||
if (x < 0 || !(boost::math::isfinite)(x))
|
||||
{
|
||||
return policies::raise_domain_error<RealType>(
|
||||
function, "Kolmogorov-Smirnov parameter was %1%, but must be > 0 !", x, Policy());
|
||||
}
|
||||
|
||||
if (2*x*x*n < constants::pi<RealType>()) {
|
||||
return detail::kolmogorov_smirnov_pdf_small_x(x, n, Policy());
|
||||
}
|
||||
|
||||
return detail::kolmogorov_smirnov_pdf_large_x(x, n, Policy());
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const kolmogorov_smirnov_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std function exp.
|
||||
static const char* function = "boost::math::cdf(const kolmogorov_smirnov_distribution<%1%>&, %1%)";
|
||||
RealType error_result;
|
||||
RealType n = dist.number_of_observations();
|
||||
if(false == detail::check_x_not_NaN(function, x, &error_result, Policy()))
|
||||
return error_result;
|
||||
if(false == detail::check_df(function, n, &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 between > 0 !", x, Policy());
|
||||
}
|
||||
|
||||
if (x*x*n == 0)
|
||||
return 0;
|
||||
|
||||
return jacobi_theta4tau(RealType(0), 2*x*x*n/constants::pi<RealType>(), Policy());
|
||||
} // cdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const complemented2_type<kolmogorov_smirnov_distribution<RealType, Policy>, RealType>& c) {
|
||||
BOOST_MATH_STD_USING // for ADL of std function exp.
|
||||
RealType x = c.param;
|
||||
static const char* function = "boost::math::cdf(const complemented2_type<const kolmogorov_smirnov_distribution<%1%>&, %1%>)";
|
||||
RealType error_result;
|
||||
kolmogorov_smirnov_distribution<RealType, Policy> const& dist = c.dist;
|
||||
RealType n = dist.number_of_observations();
|
||||
|
||||
if(false == detail::check_x_not_NaN(function, x, &error_result, Policy()))
|
||||
return error_result;
|
||||
if(false == detail::check_df(function, n, &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 between > 0 !", x, Policy());
|
||||
|
||||
if (x*x*n == 0)
|
||||
return 1;
|
||||
|
||||
if (2*x*x*n > constants::pi<RealType>())
|
||||
return -jacobi_theta4m1tau(RealType(0), 2*x*x*n/constants::pi<RealType>(), Policy());
|
||||
|
||||
return RealType(1) - jacobi_theta4tau(RealType(0), 2*x*x*n/constants::pi<RealType>(), Policy());
|
||||
} // cdf (complemented)
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const kolmogorov_smirnov_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
static const char* function = "boost::math::quantile(const kolmogorov_smirnov_distribution<%1%>&, %1%)";
|
||||
// Error check:
|
||||
RealType error_result;
|
||||
RealType n = dist.number_of_observations();
|
||||
if(false == detail::check_probability(function, p, &error_result, Policy()))
|
||||
return error_result;
|
||||
if(false == detail::check_df(function, n, &error_result, Policy()))
|
||||
return error_result;
|
||||
|
||||
RealType k = detail::kolmogorov_smirnov_quantile_guess(p) / sqrt(n);
|
||||
const int get_digits = policies::digits<RealType, Policy>();// get digits from policy,
|
||||
std::uintmax_t m = policies::get_max_root_iterations<Policy>(); // and max iterations.
|
||||
|
||||
return tools::newton_raphson_iterate(detail::kolmogorov_smirnov_quantile_functor<RealType, Policy>(dist, p),
|
||||
k, RealType(0), boost::math::tools::max_value<RealType>(), get_digits, m);
|
||||
} // quantile
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const complemented2_type<kolmogorov_smirnov_distribution<RealType, Policy>, RealType>& c) {
|
||||
BOOST_MATH_STD_USING
|
||||
static const char* function = "boost::math::quantile(const kolmogorov_smirnov_distribution<%1%>&, %1%)";
|
||||
kolmogorov_smirnov_distribution<RealType, Policy> const& dist = c.dist;
|
||||
RealType n = dist.number_of_observations();
|
||||
// Error check:
|
||||
RealType error_result;
|
||||
RealType p = c.param;
|
||||
|
||||
if(false == detail::check_probability(function, p, &error_result, Policy()))
|
||||
return error_result;
|
||||
if(false == detail::check_df(function, n, &error_result, Policy()))
|
||||
return error_result;
|
||||
|
||||
RealType k = detail::kolmogorov_smirnov_quantile_guess(RealType(1-p)) / sqrt(n);
|
||||
|
||||
const int get_digits = policies::digits<RealType, Policy>();// get digits from policy,
|
||||
std::uintmax_t m = policies::get_max_root_iterations<Policy>(); // and max iterations.
|
||||
|
||||
return tools::newton_raphson_iterate(
|
||||
detail::kolmogorov_smirnov_complementary_quantile_functor<RealType, Policy>(dist, p),
|
||||
k, RealType(0), boost::math::tools::max_value<RealType>(), get_digits, m);
|
||||
} // quantile (complemented)
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mode(const kolmogorov_smirnov_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
static const char* function = "boost::math::mode(const kolmogorov_smirnov_distribution<%1%>&)";
|
||||
RealType n = dist.number_of_observations();
|
||||
RealType error_result;
|
||||
if(false == detail::check_df(function, n, &error_result, Policy()))
|
||||
return error_result;
|
||||
|
||||
std::pair<RealType, RealType> r = boost::math::tools::brent_find_minima(
|
||||
detail::kolmogorov_smirnov_negative_pdf_functor<RealType, Policy>(),
|
||||
static_cast<RealType>(0), static_cast<RealType>(1), policies::digits<RealType, Policy>());
|
||||
return r.first / sqrt(n);
|
||||
}
|
||||
|
||||
// Mean and variance come directly from
|
||||
// https://www.jstatsoft.org/article/view/v008i18 Section 3
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mean(const kolmogorov_smirnov_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
static const char* function = "boost::math::mean(const kolmogorov_smirnov_distribution<%1%>&)";
|
||||
RealType n = dist.number_of_observations();
|
||||
RealType error_result;
|
||||
if(false == detail::check_df(function, n, &error_result, Policy()))
|
||||
return error_result;
|
||||
return constants::root_half_pi<RealType>() * constants::ln_two<RealType>() / sqrt(n);
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType variance(const kolmogorov_smirnov_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
static const char* function = "boost::math::variance(const kolmogorov_smirnov_distribution<%1%>&)";
|
||||
RealType n = dist.number_of_observations();
|
||||
RealType error_result;
|
||||
if(false == detail::check_df(function, n, &error_result, Policy()))
|
||||
return error_result;
|
||||
return (constants::pi_sqr_div_six<RealType>()
|
||||
- constants::pi<RealType>() * constants::ln_two<RealType>() * constants::ln_two<RealType>()) / (2*n);
|
||||
}
|
||||
|
||||
// Skewness and kurtosis come from integrating the PDF
|
||||
// The alternating series pops out a Dirichlet eta function which is related to the zeta function
|
||||
template <class RealType, class Policy>
|
||||
inline RealType skewness(const kolmogorov_smirnov_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
static const char* function = "boost::math::skewness(const kolmogorov_smirnov_distribution<%1%>&)";
|
||||
RealType n = dist.number_of_observations();
|
||||
RealType error_result;
|
||||
if(false == detail::check_df(function, n, &error_result, Policy()))
|
||||
return error_result;
|
||||
RealType ex3 = RealType(0.5625) * constants::root_half_pi<RealType>() * constants::zeta_three<RealType>() / n / sqrt(n);
|
||||
RealType mean = boost::math::mean(dist);
|
||||
RealType var = boost::math::variance(dist);
|
||||
return (ex3 - 3 * mean * var - mean * mean * mean) / var / sqrt(var);
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis(const kolmogorov_smirnov_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
static const char* function = "boost::math::kurtosis(const kolmogorov_smirnov_distribution<%1%>&)";
|
||||
RealType n = dist.number_of_observations();
|
||||
RealType error_result;
|
||||
if(false == detail::check_df(function, n, &error_result, Policy()))
|
||||
return error_result;
|
||||
RealType ex4 = 7 * constants::pi_sqr_div_six<RealType>() * constants::pi_sqr_div_six<RealType>() / 20 / n / n;
|
||||
RealType mean = boost::math::mean(dist);
|
||||
RealType var = boost::math::variance(dist);
|
||||
RealType skew = boost::math::skewness(dist);
|
||||
return (ex4 - 4 * mean * skew * var * sqrt(var) - 6 * mean * mean * var - mean * mean * mean * mean) / var / var;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis_excess(const kolmogorov_smirnov_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
static const char* function = "boost::math::kurtosis_excess(const kolmogorov_smirnov_distribution<%1%>&)";
|
||||
RealType n = dist.number_of_observations();
|
||||
RealType error_result;
|
||||
if(false == detail::check_df(function, n, &error_result, Policy()))
|
||||
return error_result;
|
||||
return kurtosis(dist) - 3;
|
||||
}
|
||||
}}
|
||||
#endif
|
||||
@@ -17,6 +17,7 @@
|
||||
#ifndef BOOST_STATS_LAPLACE_HPP
|
||||
#define BOOST_STATS_LAPLACE_HPP
|
||||
|
||||
#include <boost/math/special_functions/log1p.hpp>
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp>
|
||||
#include <boost/math/distributions/complement.hpp>
|
||||
#include <boost/math/constants/constants.hpp>
|
||||
@@ -24,7 +25,7 @@
|
||||
|
||||
namespace boost{ namespace math{
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4127) // conditional expression is constant
|
||||
#endif
|
||||
@@ -36,13 +37,13 @@ public:
|
||||
// ----------------------------------
|
||||
// public Types
|
||||
// ----------------------------------
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
using value_type = RealType;
|
||||
using policy_type = Policy;
|
||||
|
||||
// ----------------------------------
|
||||
// Constructor(s)
|
||||
// ----------------------------------
|
||||
laplace_distribution(RealType l_location = 0, RealType l_scale = 1)
|
||||
explicit laplace_distribution(RealType l_location = 0, RealType l_scale = 1)
|
||||
: m_location(l_location), m_scale(l_scale)
|
||||
{
|
||||
RealType result;
|
||||
@@ -78,14 +79,21 @@ private:
|
||||
|
||||
//
|
||||
// Convenient type synonym for double.
|
||||
typedef laplace_distribution<double> laplace;
|
||||
using laplace = laplace_distribution<double>;
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
laplace_distribution(RealType)->laplace_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
template <class RealType>
|
||||
laplace_distribution(RealType,RealType)->laplace_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
//
|
||||
// Non-member functions.
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const laplace_distribution<RealType, Policy>&)
|
||||
inline std::pair<RealType, RealType> range(const laplace_distribution<RealType, Policy>&)
|
||||
{
|
||||
if (std::numeric_limits<RealType>::has_infinity)
|
||||
if (std::numeric_limits<RealType>::has_infinity)
|
||||
{ // Can use infinity.
|
||||
return std::pair<RealType, RealType>(-std::numeric_limits<RealType>::infinity(), std::numeric_limits<RealType>::infinity()); // - to + infinity.
|
||||
}
|
||||
@@ -98,7 +106,7 @@ inline const std::pair<RealType, RealType> range(const laplace_distribution<Real
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> support(const laplace_distribution<RealType, Policy>&)
|
||||
inline std::pair<RealType, RealType> support(const laplace_distribution<RealType, Policy>&)
|
||||
{
|
||||
if (std::numeric_limits<RealType>::has_infinity)
|
||||
{ // Can Use infinity.
|
||||
@@ -143,6 +151,48 @@ inline RealType pdf(const laplace_distribution<RealType, Policy>& dist, const Re
|
||||
return result;
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType logpdf(const laplace_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
// Checking function argument
|
||||
RealType result = -std::numeric_limits<RealType>::infinity();
|
||||
const char* function = "boost::math::logpdf(const laplace_distribution<%1%>&, %1%))";
|
||||
|
||||
// Check scale and location.
|
||||
if (false == dist.check_parameters(function, &result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
// Special pdf values.
|
||||
if((boost::math::isinf)(x))
|
||||
{
|
||||
return result; // pdf + and - infinity is zero so logpdf is -INF
|
||||
}
|
||||
if (false == detail::check_x(function, x, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
const RealType mu = dist.scale();
|
||||
const RealType b = dist.location();
|
||||
|
||||
// if b is 0 avoid divde by 0 error
|
||||
if(abs(b) < std::numeric_limits<RealType>::epsilon())
|
||||
{
|
||||
result = log(pdf(dist, x));
|
||||
}
|
||||
else
|
||||
{
|
||||
// General case
|
||||
const RealType log2 = boost::math::constants::ln_two<RealType>();
|
||||
result = -abs(x-mu)/b - log(b) - log2;
|
||||
}
|
||||
|
||||
return result;
|
||||
} // logpdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const laplace_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
@@ -177,6 +227,50 @@ inline RealType cdf(const laplace_distribution<RealType, Policy>& dist, const Re
|
||||
return result;
|
||||
} // cdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType logcdf(const laplace_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING // For ADL of std functions.
|
||||
|
||||
RealType result = 0;
|
||||
// Checking function argument.
|
||||
const char* function = "boost::math::logcdf(const laplace_distribution<%1%>&, %1%)";
|
||||
// Check scale and location.
|
||||
if (false == dist.check_parameters(function, &result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
// Special cdf values:
|
||||
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;
|
||||
}
|
||||
|
||||
// General cdf values
|
||||
RealType scale( dist.scale() );
|
||||
RealType location( dist.location() );
|
||||
|
||||
if (x < location)
|
||||
{
|
||||
result = ((x - location) / scale) - boost::math::constants::ln_two<RealType>();
|
||||
}
|
||||
else
|
||||
{
|
||||
result = log1p(-exp((location - x) / scale) / 2);
|
||||
}
|
||||
|
||||
return result;
|
||||
} // logcdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const laplace_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
@@ -194,14 +288,14 @@ inline RealType quantile(const laplace_distribution<RealType, Policy>& dist, con
|
||||
{
|
||||
result = policies::raise_overflow_error<RealType>(function,
|
||||
"probability parameter is 0, but must be > 0!", Policy());
|
||||
return -result; // -std::numeric_limits<RealType>::infinity();
|
||||
return -result; // -inf
|
||||
}
|
||||
|
||||
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();
|
||||
return result; // inf
|
||||
}
|
||||
// Calculate Quantile
|
||||
RealType scale( dist.scale() );
|
||||
@@ -231,8 +325,6 @@ inline RealType cdf(const complemented2_type<laplace_distribution<RealType, Poli
|
||||
const char* function = "boost::math::cdf(const complemented2_type<laplace_distribution<%1%>, %1%>&)";
|
||||
|
||||
// Check scale and location.
|
||||
//if(false == detail::check_scale(function, scale, result, Policy())) return false;
|
||||
//if(false == detail::check_location(function, location, result, Policy())) return false;
|
||||
if (false == c.dist.check_parameters(function, &result)) return result;
|
||||
|
||||
// Special cdf values.
|
||||
@@ -255,6 +347,46 @@ inline RealType cdf(const complemented2_type<laplace_distribution<RealType, Poli
|
||||
return result;
|
||||
} // cdf complement
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType logcdf(const complemented2_type<laplace_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
// Calculate complement of logcdf.
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
RealType scale = c.dist.scale();
|
||||
RealType location = c.dist.location();
|
||||
RealType x = c.param;
|
||||
RealType result = 0;
|
||||
|
||||
// Checking function argument.
|
||||
const char* function = "boost::math::logcdf(const complemented2_type<laplace_distribution<%1%>, %1%>&)";
|
||||
|
||||
// Check scale and location.
|
||||
if (false == c.dist.check_parameters(function, &result)) return result;
|
||||
|
||||
// Special cdf values.
|
||||
if((boost::math::isinf)(x))
|
||||
{
|
||||
if(x < 0)
|
||||
{
|
||||
return 1; // cdf complement -infinity is unity.
|
||||
}
|
||||
|
||||
return 0; // cdf complement +infinity is zero.
|
||||
}
|
||||
if(false == detail::check_x(function, x, &result, Policy()))return result;
|
||||
|
||||
// Cdf interval value.
|
||||
if (-x < -location)
|
||||
{
|
||||
result = (-x+location)/scale - boost::math::constants::ln_two<RealType>();
|
||||
}
|
||||
else
|
||||
{
|
||||
result = log1p(-exp( (-location+x)/scale )/2, Policy());
|
||||
}
|
||||
return result;
|
||||
} // cdf complement
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const complemented2_type<laplace_distribution<RealType, Policy>, RealType>& c)
|
||||
@@ -333,7 +465,14 @@ inline RealType kurtosis_excess(const laplace_distribution<RealType, Policy>& /*
|
||||
return 3;
|
||||
}
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
template <class RealType, class Policy>
|
||||
inline RealType entropy(const laplace_distribution<RealType, Policy> & dist)
|
||||
{
|
||||
using std::log;
|
||||
return log(2*dist.scale()*constants::e<RealType>());
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
|
||||
@@ -51,7 +51,14 @@ namespace boost { namespace math {
|
||||
|
||||
|
||||
typedef logistic_distribution<double> logistic;
|
||||
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
logistic_distribution(RealType)->logistic_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
template <class RealType>
|
||||
logistic_distribution(RealType,RealType)->logistic_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
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.
|
||||
@@ -139,6 +146,49 @@ namespace boost { namespace math {
|
||||
if(power < -tools::log_max_value<RealType>())
|
||||
return 1;
|
||||
return 1 / (1 + exp(power));
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType logcdf(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 -log1p(exp(power));
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
@@ -212,6 +262,42 @@ namespace boost { namespace math {
|
||||
return 1 / (1 + exp(power));
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType logcdf(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%)";
|
||||
|
||||
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((boost::math::isinf)(x))
|
||||
{
|
||||
if(x < 0) return 1; // cdf complement -infinity is unity.
|
||||
return 0; // cdf complement +infinity is zero.
|
||||
}
|
||||
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 -log1p(exp(power));
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const complemented2_type<logistic_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
@@ -290,6 +376,13 @@ namespace boost { namespace math {
|
||||
{
|
||||
return kurtosis_excess(dist) + 3;
|
||||
} // RealType kurtosis_excess(const logistic_distribution<RealType, Policy>& dist)
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType entropy(const logistic_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
using std::log;
|
||||
return 2 + log(dist.scale());
|
||||
}
|
||||
}}
|
||||
|
||||
|
||||
|
||||
@@ -75,6 +75,13 @@ private:
|
||||
|
||||
typedef lognormal_distribution<double> lognormal;
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
lognormal_distribution(RealType)->lognormal_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
template <class RealType>
|
||||
lognormal_distribution(RealType,RealType)->lognormal_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
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.
|
||||
@@ -328,6 +335,15 @@ inline RealType kurtosis_excess(const lognormal_distribution<RealType, Policy>&
|
||||
return exp(4 * ss) + 2 * exp(3 * ss) + 3 * exp(2 * ss) - 6;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType entropy(const lognormal_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
using std::log;
|
||||
RealType mu = dist.location();
|
||||
RealType sigma = dist.scale();
|
||||
return mu + log(constants::two_pi<RealType>()*constants::e<RealType>()*sigma*sigma)/2;
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
// 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.
|
||||
// precede 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.
|
||||
@@ -27,7 +27,7 @@
|
||||
// (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,
|
||||
// it is convenient to treat it as if a continuous function,
|
||||
// and permit non-integral values of k.
|
||||
|
||||
// However, by default the policy is to use discrete_quantile_policy.
|
||||
@@ -52,11 +52,6 @@
|
||||
#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>
|
||||
|
||||
@@ -181,7 +176,7 @@ namespace boost
|
||||
// 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());
|
||||
return ibeta_inv(successes, failures + 1, alpha, static_cast<RealType*>(nullptr), Policy());
|
||||
} // find_lower_bound_on_p
|
||||
|
||||
static RealType find_upper_bound_on_p(
|
||||
@@ -209,7 +204,7 @@ namespace boost
|
||||
// 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());
|
||||
return ibetac_inv(successes, failures, alpha, static_cast<RealType*>(nullptr), Policy());
|
||||
} // find_upper_bound_on_p
|
||||
|
||||
// Estimate number of trials :
|
||||
@@ -256,6 +251,11 @@ namespace boost
|
||||
|
||||
typedef negative_binomial_distribution<double> negative_binomial; // Reserved name of type double.
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
negative_binomial_distribution(RealType,RealType)->negative_binomial_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
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.
|
||||
@@ -492,7 +492,7 @@ namespace boost
|
||||
//
|
||||
// Max iterations permitted:
|
||||
//
|
||||
boost::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
|
||||
std::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
|
||||
typedef typename Policy::discrete_quantile_type discrete_type;
|
||||
return detail::inverse_discrete_quantile(
|
||||
dist,
|
||||
@@ -579,7 +579,7 @@ namespace boost
|
||||
//
|
||||
// Max iterations permitted:
|
||||
//
|
||||
boost::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
|
||||
std::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
|
||||
typedef typename Policy::discrete_quantile_type discrete_type;
|
||||
return detail::inverse_discrete_quantile(
|
||||
dist,
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#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/special_functions/trunc.hpp>
|
||||
#include <boost/math/tools/roots.hpp> // for root finding.
|
||||
#include <boost/math/tools/series.hpp>
|
||||
|
||||
@@ -38,7 +39,7 @@ namespace boost
|
||||
//
|
||||
// Variables come first:
|
||||
//
|
||||
boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
|
||||
std::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
|
||||
T errtol = boost::math::policies::get_epsilon<T, Policy>();
|
||||
T l2 = lam / 2;
|
||||
//
|
||||
@@ -48,7 +49,7 @@ namespace boost
|
||||
// k to zero, when l2 is small, as forward iteration
|
||||
// is unstable:
|
||||
//
|
||||
int k = itrunc(l2);
|
||||
long long k = lltrunc(l2);
|
||||
if(k == 0)
|
||||
k = 1;
|
||||
// Starting Poisson weight:
|
||||
@@ -74,8 +75,8 @@ namespace boost
|
||||
// direction for recursion:
|
||||
//
|
||||
T last_term = 0;
|
||||
boost::uintmax_t count = k;
|
||||
for(int i = k; i >= 0; --i)
|
||||
std::uintmax_t count = k;
|
||||
for(auto i = k; i >= 0; --i)
|
||||
{
|
||||
T term = beta * pois;
|
||||
sum += term;
|
||||
@@ -86,10 +87,15 @@ namespace boost
|
||||
}
|
||||
pois *= i / l2;
|
||||
beta += xterm;
|
||||
xterm *= (a + i - 1) / (x * (a + b + i - 2));
|
||||
|
||||
if (a + b + i != 2)
|
||||
{
|
||||
xterm *= (a + i - 1) / (x * (a + b + i - 2));
|
||||
}
|
||||
|
||||
last_term = term;
|
||||
}
|
||||
for(int i = k + 1; ; ++i)
|
||||
for(auto i = k + 1; ; ++i)
|
||||
{
|
||||
poisf *= l2 / i;
|
||||
xtermf *= (x * (a + b + i - 2)) / (a + i - 1);
|
||||
@@ -101,7 +107,7 @@ namespace boost
|
||||
{
|
||||
break;
|
||||
}
|
||||
if(static_cast<boost::uintmax_t>(count + i - k) > max_iter)
|
||||
if(static_cast<std::uintmax_t>(count + i - k) > max_iter)
|
||||
{
|
||||
return policies::raise_evaluation_error(
|
||||
"cdf(non_central_beta_distribution<%1%>, %1%)",
|
||||
@@ -119,14 +125,14 @@ namespace boost
|
||||
//
|
||||
// Variables come first:
|
||||
//
|
||||
boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
|
||||
std::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);
|
||||
long long k = lltrunc(l2);
|
||||
T pois;
|
||||
if(k <= 30)
|
||||
{
|
||||
@@ -168,8 +174,8 @@ namespace boost
|
||||
// of the bulk of the sum:
|
||||
//
|
||||
T last_term = 0;
|
||||
boost::uintmax_t count = 0;
|
||||
for(int i = k + 1; ; ++i)
|
||||
std::uintmax_t count = 0;
|
||||
for(auto i = k + 1; ; ++i)
|
||||
{
|
||||
poisf *= l2 / i;
|
||||
xtermf *= (x * (a + b + i - 2)) / (a + i - 1);
|
||||
@@ -182,7 +188,7 @@ namespace boost
|
||||
count = i - k;
|
||||
break;
|
||||
}
|
||||
if(static_cast<boost::uintmax_t>(i - k) > max_iter)
|
||||
if(static_cast<std::uintmax_t>(i - k) > max_iter)
|
||||
{
|
||||
return policies::raise_evaluation_error(
|
||||
"cdf(non_central_beta_distribution<%1%>, %1%)",
|
||||
@@ -190,7 +196,7 @@ namespace boost
|
||||
}
|
||||
last_term = term;
|
||||
}
|
||||
for(int i = k; i >= 0; --i)
|
||||
for(auto i = k; i >= 0; --i)
|
||||
{
|
||||
T term = beta * pois;
|
||||
sum += term;
|
||||
@@ -198,7 +204,7 @@ namespace boost
|
||||
{
|
||||
break;
|
||||
}
|
||||
if(static_cast<boost::uintmax_t>(count + k - i) > max_iter)
|
||||
if(static_cast<std::uintmax_t>(count + k - i) > max_iter)
|
||||
{
|
||||
return policies::raise_evaluation_error(
|
||||
"cdf(non_central_beta_distribution<%1%>, %1%)",
|
||||
@@ -289,12 +295,12 @@ namespace boost
|
||||
// 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)
|
||||
std::pair<T, T> bracket_and_solve_root_01(F f, const T& guess, T factor, bool rising, Tol tol, std::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:
|
||||
// Set up initial brackets:
|
||||
//
|
||||
T a = guess;
|
||||
T b = a;
|
||||
@@ -303,7 +309,7 @@ namespace boost
|
||||
//
|
||||
// Set up invocation count:
|
||||
//
|
||||
boost::uintmax_t count = max_iter - 1;
|
||||
std::uintmax_t count = max_iter - 1;
|
||||
|
||||
if((fa < 0) == (guess < 0 ? !rising : rising))
|
||||
{
|
||||
@@ -424,7 +430,7 @@ namespace boost
|
||||
static_cast<value_type>(p),
|
||||
&r,
|
||||
Policy()))
|
||||
return (RealType)r;
|
||||
return static_cast<RealType>(r);
|
||||
//
|
||||
// Special cases first:
|
||||
//
|
||||
@@ -489,7 +495,7 @@ namespace boost
|
||||
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::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
|
||||
|
||||
std::pair<value_type, value_type> ir
|
||||
= bracket_and_solve_root_01(
|
||||
@@ -523,14 +529,14 @@ namespace boost
|
||||
//
|
||||
// Variables come first:
|
||||
//
|
||||
boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
|
||||
std::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);
|
||||
long long k = lltrunc(l2);
|
||||
// Starting Poisson weight:
|
||||
T pois = gamma_p_derivative(T(k+1), l2, pol);
|
||||
// Starting beta term:
|
||||
@@ -544,8 +550,8 @@ namespace boost
|
||||
//
|
||||
// Stable backwards recursion first:
|
||||
//
|
||||
boost::uintmax_t count = k;
|
||||
for(int i = k; i >= 0; --i)
|
||||
std::uintmax_t count = k;
|
||||
for(auto i = k; i >= 0; --i)
|
||||
{
|
||||
T term = beta * pois;
|
||||
sum += term;
|
||||
@@ -555,9 +561,13 @@ namespace boost
|
||||
break;
|
||||
}
|
||||
pois *= i / l2;
|
||||
beta *= (a + i - 1) / (x * (a + i + b - 1));
|
||||
|
||||
if (a + b + i != 1)
|
||||
{
|
||||
beta *= (a + i - 1) / (x * (a + i + b - 1));
|
||||
}
|
||||
}
|
||||
for(int i = k + 1; ; ++i)
|
||||
for(auto i = k + 1; ; ++i)
|
||||
{
|
||||
poisf *= l2 / i;
|
||||
betaf *= x * (a + b + i - 1) / (a + i - 1);
|
||||
@@ -568,7 +578,7 @@ namespace boost
|
||||
{
|
||||
break;
|
||||
}
|
||||
if(static_cast<boost::uintmax_t>(count + i - k) > max_iter)
|
||||
if(static_cast<std::uintmax_t>(count + i - k) > max_iter)
|
||||
{
|
||||
return policies::raise_evaluation_error(
|
||||
"pdf(non_central_beta_distribution<%1%>, %1%)",
|
||||
@@ -614,7 +624,7 @@ namespace boost
|
||||
static_cast<value_type>(x),
|
||||
&r,
|
||||
Policy()))
|
||||
return (RealType)r;
|
||||
return static_cast<RealType>(r);
|
||||
|
||||
if(l == 0)
|
||||
return pdf(boost::math::beta_distribution<RealType, Policy>(dist.alpha(), dist.beta()), x);
|
||||
@@ -652,13 +662,10 @@ namespace boost
|
||||
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
|
||||
std::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -710,6 +717,11 @@ namespace boost
|
||||
|
||||
typedef non_central_beta_distribution<double> non_central_beta; // Reserved name of type double.
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
non_central_beta_distribution(RealType,RealType,RealType)->non_central_beta_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
// Non-member functions to give properties of the distribution.
|
||||
|
||||
template <class RealType, class Policy>
|
||||
@@ -749,7 +761,7 @@ namespace boost
|
||||
l,
|
||||
&r,
|
||||
Policy()))
|
||||
return (RealType)r;
|
||||
return static_cast<RealType>(r);
|
||||
RealType c = a + b + l / 2;
|
||||
RealType mean = 1 - (b / c) * (1 + l / (2 * c * c));
|
||||
return detail::generic_find_mode_01(
|
||||
@@ -779,7 +791,7 @@ namespace boost
|
||||
inline RealType variance(const non_central_beta_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
//
|
||||
// Relative error of this function may be arbitarily large... absolute
|
||||
// Relative error of this function may be arbitrarily large... absolute
|
||||
// error will be small however... that's the best we can do for now.
|
||||
//
|
||||
BOOST_MATH_STD_USING
|
||||
@@ -800,7 +812,7 @@ namespace boost
|
||||
{ // 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);
|
||||
static_assert(assert_type::value == 0, "Assert type is undefined.");
|
||||
|
||||
return policies::raise_evaluation_error<RealType>(
|
||||
function,
|
||||
@@ -813,7 +825,7 @@ namespace boost
|
||||
{
|
||||
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);
|
||||
static_assert(assert_type::value == 0, "Assert type is undefined.");
|
||||
|
||||
return policies::raise_evaluation_error<RealType>(
|
||||
function,
|
||||
@@ -860,7 +872,7 @@ namespace boost
|
||||
x,
|
||||
&r,
|
||||
Policy()))
|
||||
return (RealType)r;
|
||||
return static_cast<RealType>(r);
|
||||
|
||||
if(l == 0)
|
||||
return cdf(beta_distribution<RealType, Policy>(a, b), x);
|
||||
@@ -897,7 +909,7 @@ namespace boost
|
||||
x,
|
||||
&r,
|
||||
Policy()))
|
||||
return (RealType)r;
|
||||
return static_cast<RealType>(r);
|
||||
|
||||
if(l == 0)
|
||||
return cdf(complement(beta_distribution<RealType, Policy>(a, b), x));
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#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/special_functions/round.hpp> // for llround
|
||||
#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
|
||||
@@ -46,7 +46,7 @@ namespace boost
|
||||
// Computing discrete mixtures of continuous
|
||||
// distributions: noncentral chisquare, noncentral t
|
||||
// and the distribution of the square of the sample
|
||||
// multiple correlation coeficient.
|
||||
// multiple correlation coefficient.
|
||||
// D. Benton, K. Krishnamoorthy.
|
||||
// Computational Statistics & Data Analysis 43 (2003) 249 - 267
|
||||
//
|
||||
@@ -62,7 +62,7 @@ namespace boost
|
||||
T lambda = theta / 2;
|
||||
T del = f / 2;
|
||||
T y = x / 2;
|
||||
boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
|
||||
std::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
|
||||
T errtol = boost::math::policies::get_epsilon<T, Policy>();
|
||||
T sum = init_sum;
|
||||
//
|
||||
@@ -71,7 +71,7 @@ namespace boost
|
||||
// k is chosen as the peek of the Poisson weights, which
|
||||
// will occur *before* the largest term.
|
||||
//
|
||||
int k = iround(lambda, pol);
|
||||
long long k = llround(lambda, pol);
|
||||
// Forwards and backwards Poisson weights:
|
||||
T poisf = boost::math::gamma_p_derivative(static_cast<T>(1 + k), lambda, pol);
|
||||
T poisb = poisf * k / lambda;
|
||||
@@ -88,8 +88,8 @@ namespace boost
|
||||
// stable direction for the gamma function
|
||||
// recurrences:
|
||||
//
|
||||
int i;
|
||||
for(i = k; static_cast<boost::uintmax_t>(i-k) < max_iter; ++i)
|
||||
long long i;
|
||||
for(i = k; static_cast<std::uintmax_t>(i-k) < max_iter; ++i)
|
||||
{
|
||||
T term = poisf * gamf;
|
||||
sum += term;
|
||||
@@ -100,14 +100,14 @@ namespace boost
|
||||
break;
|
||||
}
|
||||
//Error check:
|
||||
if(static_cast<boost::uintmax_t>(i-k) >= max_iter)
|
||||
if(static_cast<std::uintmax_t>(i-k) >= max_iter)
|
||||
return 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
|
||||
// direction, we rely on the terms diminishing 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
|
||||
@@ -141,7 +141,7 @@ namespace boost
|
||||
// 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.
|
||||
// * The first term may underflow to zero.
|
||||
// * We may need an extra-ordinary number of terms
|
||||
// before we reach the first *significant* term.
|
||||
//
|
||||
@@ -157,12 +157,12 @@ namespace boost
|
||||
if(sum == 0)
|
||||
return sum;
|
||||
|
||||
boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
|
||||
std::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)
|
||||
for(i = 1; static_cast<std::uintmax_t>(i) < max_iter; ++i)
|
||||
{
|
||||
tk = tk * x / (f + 2 * i);
|
||||
uk = uk * lambda / i;
|
||||
@@ -174,7 +174,7 @@ namespace boost
|
||||
break;
|
||||
}
|
||||
//Error check:
|
||||
if(static_cast<boost::uintmax_t>(i) >= max_iter)
|
||||
if(static_cast<std::uintmax_t>(i) >= max_iter)
|
||||
return policies::raise_evaluation_error(
|
||||
"cdf(non_central_chi_squared_distribution<%1%>, %1%)",
|
||||
"Series did not converge, closest value was %1%", sum, pol);
|
||||
@@ -191,7 +191,7 @@ namespace boost
|
||||
// Computing discrete mixtures of continuous
|
||||
// distributions: noncentral chisquare, noncentral t
|
||||
// and the distribution of the square of the sample
|
||||
// multiple correlation coeficient.
|
||||
// multiple correlation coefficient.
|
||||
// D. Benton, K. Krishnamoorthy.
|
||||
// Computational Statistics & Data Analysis 43 (2003) 249 - 267
|
||||
//
|
||||
@@ -202,7 +202,7 @@ namespace boost
|
||||
// Special case:
|
||||
if(y == 0)
|
||||
return 0;
|
||||
boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
|
||||
std::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
|
||||
T errtol = boost::math::policies::get_epsilon<T, Policy>();
|
||||
T errorf(0), errorb(0);
|
||||
|
||||
@@ -215,7 +215,7 @@ namespace boost
|
||||
// function, which ocurrs *after* the largest term in the
|
||||
// sum.
|
||||
//
|
||||
int k = iround(del, pol);
|
||||
long long k = llround(del, pol);
|
||||
T a = n / 2 + k;
|
||||
// Central chi squared term for forward iteration:
|
||||
T gamkf = boost::math::gamma_p(a, x, pol);
|
||||
@@ -270,10 +270,10 @@ namespace boost
|
||||
errorf = poiskf * gamkf;
|
||||
sum += errorf;
|
||||
++i;
|
||||
}while((fabs(errorf / sum) > errtol) && (static_cast<boost::uintmax_t>(i) < max_iter));
|
||||
}while((fabs(errorf / sum) > errtol) && (static_cast<std::uintmax_t>(i) < max_iter));
|
||||
|
||||
//Error check:
|
||||
if(static_cast<boost::uintmax_t>(i) >= max_iter)
|
||||
if(static_cast<std::uintmax_t>(i) >= max_iter)
|
||||
return policies::raise_evaluation_error(
|
||||
"cdf(non_central_chi_squared_distribution<%1%>, %1%)",
|
||||
"Series did not converge, closest value was %1%", sum, pol);
|
||||
@@ -288,29 +288,29 @@ namespace boost
|
||||
// As above but for the PDF:
|
||||
//
|
||||
BOOST_MATH_STD_USING
|
||||
boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
|
||||
std::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);
|
||||
long long k = lltrunc(l2);
|
||||
T pois = gamma_p_derivative(static_cast<T>(k + 1), l2, pol) * gamma_p_derivative(static_cast<T>(n2 + k), x2);
|
||||
if(pois == 0)
|
||||
return 0;
|
||||
T poisb = pois;
|
||||
for(int i = k; ; ++i)
|
||||
for(long long i = k; ; ++i)
|
||||
{
|
||||
sum += pois;
|
||||
if(pois / sum < errtol)
|
||||
break;
|
||||
if(static_cast<boost::uintmax_t>(i - k) >= max_iter)
|
||||
if(static_cast<std::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)
|
||||
for(long long i = k - 1; i >= 0; --i)
|
||||
{
|
||||
poisb *= (i + 1) * (n2 + i) / (l2 * x2);
|
||||
sum += poisb;
|
||||
@@ -428,7 +428,7 @@ namespace boost
|
||||
static_cast<value_type>(p),
|
||||
&r,
|
||||
Policy()))
|
||||
return (RealType)r;
|
||||
return static_cast<RealType>(r);
|
||||
//
|
||||
// Special cases get short-circuited first:
|
||||
//
|
||||
@@ -519,7 +519,7 @@ namespace boost
|
||||
(value_type)x,
|
||||
&r,
|
||||
Policy()))
|
||||
return (RealType)r;
|
||||
return static_cast<RealType>(r);
|
||||
|
||||
if(l == 0)
|
||||
return pdf(boost::math::chi_squared_distribution<RealType, forwarding_policy>(dist.degrees_of_freedom()), x);
|
||||
@@ -587,7 +587,7 @@ namespace boost
|
||||
}
|
||||
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>();
|
||||
std::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.
|
||||
@@ -643,7 +643,7 @@ namespace boost
|
||||
}
|
||||
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>();
|
||||
std::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.
|
||||
@@ -783,6 +783,11 @@ namespace boost
|
||||
|
||||
typedef non_central_chi_squared_distribution<double> non_central_chi_squared; // Reserved name of type double.
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
non_central_chi_squared_distribution(RealType,RealType)->non_central_chi_squared_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
// Non-member functions to give properties of the distribution.
|
||||
|
||||
template <class RealType, class Policy>
|
||||
@@ -816,7 +821,7 @@ namespace boost
|
||||
l,
|
||||
&r,
|
||||
Policy()))
|
||||
return r;
|
||||
return static_cast<RealType>(r);
|
||||
return k + l;
|
||||
} // mean
|
||||
|
||||
@@ -837,8 +842,10 @@ namespace boost
|
||||
l,
|
||||
&r,
|
||||
Policy()))
|
||||
return (RealType)r;
|
||||
return detail::generic_find_mode(dist, 1 + k, function);
|
||||
return static_cast<RealType>(r);
|
||||
bool asymptotic_mode = k < l/4;
|
||||
RealType starting_point = asymptotic_mode ? k + l - RealType(3) : RealType(1) + k;
|
||||
return detail::generic_find_mode(dist, starting_point, function);
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
@@ -857,7 +864,7 @@ namespace boost
|
||||
l,
|
||||
&r,
|
||||
Policy()))
|
||||
return r;
|
||||
return static_cast<RealType>(r);
|
||||
return 2 * (2 * l + k);
|
||||
}
|
||||
|
||||
@@ -880,7 +887,7 @@ namespace boost
|
||||
l,
|
||||
&r,
|
||||
Policy()))
|
||||
return r;
|
||||
return static_cast<RealType>(r);
|
||||
BOOST_MATH_STD_USING
|
||||
return pow(2 / (k + 2 * l), RealType(3)/2) * (k + 3 * l);
|
||||
}
|
||||
@@ -901,7 +908,7 @@ namespace boost
|
||||
l,
|
||||
&r,
|
||||
Policy()))
|
||||
return r;
|
||||
return static_cast<RealType>(r);
|
||||
return 12 * (k + 4 * l) / ((k + 2 * l) * (k + 2 * l));
|
||||
} // kurtosis_excess
|
||||
|
||||
@@ -939,7 +946,7 @@ namespace boost
|
||||
x,
|
||||
&r,
|
||||
Policy()))
|
||||
return r;
|
||||
return static_cast<RealType>(r);
|
||||
|
||||
return detail::non_central_chi_squared_cdf(x, k, l, false, Policy());
|
||||
} // cdf
|
||||
@@ -968,7 +975,7 @@ namespace boost
|
||||
x,
|
||||
&r,
|
||||
Policy()))
|
||||
return r;
|
||||
return static_cast<RealType>(r);
|
||||
|
||||
return detail::non_central_chi_squared_cdf(x, k, l, true, Policy());
|
||||
} // ccdf
|
||||
@@ -994,6 +1001,3 @@ namespace boost
|
||||
#include <boost/math/distributions/detail/derived_accessors.hpp>
|
||||
|
||||
#endif // BOOST_MATH_SPECIAL_NON_CENTRAL_CHI_SQUARE_HPP
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -63,6 +63,11 @@ namespace boost
|
||||
|
||||
typedef non_central_f_distribution<double> non_central_f; // Reserved name of type double.
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
non_central_f_distribution(RealType,RealType,RealType)->non_central_f_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
// Non-member functions to give properties of the distribution.
|
||||
|
||||
template <class RealType, class Policy>
|
||||
@@ -101,7 +106,7 @@ namespace boost
|
||||
l,
|
||||
&r,
|
||||
Policy()))
|
||||
return r;
|
||||
return r;
|
||||
if(v2 <= 2)
|
||||
return policies::raise_domain_error(
|
||||
function,
|
||||
@@ -132,7 +137,7 @@ namespace boost
|
||||
l,
|
||||
&r,
|
||||
Policy()))
|
||||
return r;
|
||||
return r;
|
||||
RealType guess = m > 2 ? RealType(m * (n + l) / (n * (m - 2))) : RealType(1);
|
||||
return detail::generic_find_mode(
|
||||
dist,
|
||||
@@ -161,7 +166,7 @@ namespace boost
|
||||
l,
|
||||
&r,
|
||||
Policy()))
|
||||
return r;
|
||||
return r;
|
||||
if(m <= 4)
|
||||
return policies::raise_domain_error(
|
||||
function,
|
||||
@@ -198,7 +203,7 @@ namespace boost
|
||||
l,
|
||||
&r,
|
||||
Policy()))
|
||||
return r;
|
||||
return r;
|
||||
if(m <= 6)
|
||||
return policies::raise_domain_error(
|
||||
function,
|
||||
@@ -235,7 +240,7 @@ namespace boost
|
||||
l,
|
||||
&r,
|
||||
Policy()))
|
||||
return r;
|
||||
return r;
|
||||
if(m <= 8)
|
||||
return policies::raise_domain_error(
|
||||
function,
|
||||
@@ -304,7 +309,7 @@ namespace boost
|
||||
dist.non_centrality(),
|
||||
&r,
|
||||
Policy()))
|
||||
return r;
|
||||
return r;
|
||||
|
||||
if((x < 0) || !(boost::math::isfinite)(x))
|
||||
{
|
||||
@@ -345,7 +350,7 @@ namespace boost
|
||||
c.dist.non_centrality(),
|
||||
&r,
|
||||
Policy()))
|
||||
return r;
|
||||
return r;
|
||||
|
||||
if((c.param < 0) || !(boost::math::isfinite)(c.param))
|
||||
{
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <boost/math/distributions/normal.hpp> // for normal CDF and quantile
|
||||
#include <boost/math/distributions/students_t.hpp>
|
||||
#include <boost/math/distributions/detail/generic_quantile.hpp> // quantile
|
||||
#include <boost/math/special_functions/trunc.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
@@ -33,7 +34,7 @@ namespace boost
|
||||
//
|
||||
// Variables come first:
|
||||
//
|
||||
boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
|
||||
std::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
|
||||
T errtol = policies::get_epsilon<T, Policy>();
|
||||
T d2 = delta * delta / 2;
|
||||
//
|
||||
@@ -43,17 +44,17 @@ namespace boost
|
||||
// cancellation errors later (test case is v = 1621286869049072.3
|
||||
// delta = 0.16212868690490723, x = 0.86987415482475994).
|
||||
//
|
||||
int k = itrunc(d2);
|
||||
long long k = lltrunc(d2);
|
||||
T pois;
|
||||
if(k == 0) k = 1;
|
||||
// Starting Poisson weight:
|
||||
pois = gamma_p_derivative(T(k+1), d2, pol)
|
||||
pois = gamma_p_derivative(T(k+1), d2, pol)
|
||||
* tgamma_delta_ratio(T(k + 1), T(0.5f))
|
||||
* delta / constants::root_two<T>();
|
||||
if(pois == 0)
|
||||
return init_val;
|
||||
T xterm, beta;
|
||||
// Recurrance & starting beta terms:
|
||||
// Recurrence & starting beta terms:
|
||||
beta = x < y
|
||||
? detail::ibeta_imp(T(k + 1), T(v / 2), x, pol, false, true, &xterm)
|
||||
: detail::ibeta_imp(T(v / 2), T(k + 1), y, pol, true, true, &xterm);
|
||||
@@ -67,14 +68,14 @@ namespace boost
|
||||
// Backwards recursion first, this is the stable
|
||||
// direction for recursion:
|
||||
//
|
||||
boost::uintmax_t count = 0;
|
||||
std::uintmax_t count = 0;
|
||||
T last_term = 0;
|
||||
for(int i = k; i >= 0; --i)
|
||||
for(auto i = k; i >= 0; --i)
|
||||
{
|
||||
T term = beta * pois;
|
||||
sum += term;
|
||||
// Don't terminate on first term in case we "fixed" k above:
|
||||
if((fabs(last_term) > fabs(term)) && fabs(term/sum) < errtol)
|
||||
if(((fabs(last_term) > fabs(term)) && fabs(term/sum) < errtol) || (v == 2 && i == 0))
|
||||
break;
|
||||
last_term = term;
|
||||
pois *= (i + 0.5f) / d2;
|
||||
@@ -83,7 +84,7 @@ namespace boost
|
||||
++count;
|
||||
}
|
||||
last_term = 0;
|
||||
for(int i = k + 1; ; ++i)
|
||||
for(auto i = k + 1; ; ++i)
|
||||
{
|
||||
poisf *= d2 / (i + 0.5f);
|
||||
xtermf *= (x * (v / 2 + i - 1)) / (i);
|
||||
@@ -97,7 +98,7 @@ namespace boost
|
||||
if(count > max_iter)
|
||||
{
|
||||
return policies::raise_evaluation_error(
|
||||
"cdf(non_central_t_distribution<%1%>, %1%)",
|
||||
"cdf(non_central_t_distribution<%1%>, %1%)",
|
||||
"Series did not converge, closest value was %1%", sum, pol);
|
||||
}
|
||||
}
|
||||
@@ -111,7 +112,7 @@ namespace boost
|
||||
//
|
||||
// Variables come first:
|
||||
//
|
||||
boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
|
||||
std::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
|
||||
T errtol = boost::math::policies::get_epsilon<T, Policy>();
|
||||
T d2 = delta * delta / 2;
|
||||
//
|
||||
@@ -121,11 +122,11 @@ namespace boost
|
||||
// (test case is v = 561908036470413.25, delta = 0.056190803647041321,
|
||||
// x = 1.6155232703966216):
|
||||
//
|
||||
int k = itrunc(d2);
|
||||
long long k = lltrunc(d2);
|
||||
if(k == 0) k = 1;
|
||||
// Starting Poisson weight:
|
||||
T pois;
|
||||
if((k < (int)(max_factorial<T>::value)) && (d2 < tools::log_max_value<T>()) && (log(d2) * k < tools::log_max_value<T>()))
|
||||
if((k < static_cast<long long>(max_factorial<T>::value)) && (d2 < tools::log_max_value<T>()) && (log(d2) * k < tools::log_max_value<T>()))
|
||||
{
|
||||
//
|
||||
// For small k we can optimise this calculation by using
|
||||
@@ -138,7 +139,7 @@ namespace boost
|
||||
}
|
||||
else
|
||||
{
|
||||
pois = gamma_p_derivative(T(k+1), d2, pol)
|
||||
pois = gamma_p_derivative(T(k+1), d2, pol)
|
||||
* tgamma_delta_ratio(T(k + 1), T(0.5f))
|
||||
* delta / constants::root_two<T>();
|
||||
}
|
||||
@@ -150,8 +151,8 @@ namespace boost
|
||||
// Starting beta term:
|
||||
if(k != 0)
|
||||
{
|
||||
beta = x < y
|
||||
? detail::ibeta_imp(T(k + 1), T(v / 2), x, pol, true, true, &xterm)
|
||||
beta = x < y
|
||||
? detail::ibeta_imp(T(k + 1), T(v / 2), x, pol, true, true, &xterm)
|
||||
: detail::ibeta_imp(T(v / 2), T(k + 1), y, pol, false, true, &xterm);
|
||||
|
||||
xterm *= y / (v / 2 + k);
|
||||
@@ -169,9 +170,9 @@ namespace boost
|
||||
//
|
||||
// Fused forward and backwards recursion:
|
||||
//
|
||||
boost::uintmax_t count = 0;
|
||||
std::uintmax_t count = 0;
|
||||
T last_term = 0;
|
||||
for(int i = k + 1, j = k; ; ++i, --j)
|
||||
for(auto i = k + 1, j = k; ; ++i, --j)
|
||||
{
|
||||
poisf *= d2 / (i + 0.5f);
|
||||
xtermf *= (x * (v / 2 + i - 1)) / (i);
|
||||
@@ -183,7 +184,8 @@ namespace boost
|
||||
term += beta * pois;
|
||||
pois *= (j + 0.5f) / d2;
|
||||
beta -= xterm;
|
||||
xterm *= (j) / (x * (v / 2 + j - 1));
|
||||
if(!(v == 2 && j == 0))
|
||||
xterm *= (j) / (x * (v / 2 + j - 1));
|
||||
}
|
||||
|
||||
sum += term;
|
||||
@@ -194,7 +196,7 @@ namespace boost
|
||||
if(count > max_iter)
|
||||
{
|
||||
return policies::raise_evaluation_error(
|
||||
"cdf(non_central_t_distribution<%1%>, %1%)",
|
||||
"cdf(non_central_t_distribution<%1%>, %1%)",
|
||||
"Series did not converge, closest value was %1%", sum, pol);
|
||||
}
|
||||
++count;
|
||||
@@ -208,7 +210,7 @@ namespace boost
|
||||
BOOST_MATH_STD_USING
|
||||
if ((boost::math::isinf)(v))
|
||||
{ // Infinite degrees of freedom, so use normal distribution located at delta.
|
||||
normal_distribution<T, Policy> n(delta, 1);
|
||||
normal_distribution<T, Policy> n(delta, 1);
|
||||
return cdf(n, t);
|
||||
}
|
||||
//
|
||||
@@ -294,9 +296,9 @@ namespace boost
|
||||
// now passed as function
|
||||
typedef typename policies::evaluation<T, Policy>::type value_type;
|
||||
typedef typename policies::normalise<
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
policies::discrete_quantile<>,
|
||||
policies::assert_undefined<> >::type forwarding_policy;
|
||||
|
||||
@@ -305,9 +307,9 @@ namespace boost
|
||||
function,
|
||||
v, &r, Policy())
|
||||
||
|
||||
!detail::check_finite(
|
||||
!detail::check_non_centrality(
|
||||
function,
|
||||
delta,
|
||||
static_cast<T>(delta * delta),
|
||||
&r,
|
||||
Policy())
|
||||
||
|
||||
@@ -342,14 +344,14 @@ namespace boost
|
||||
guess = quantile(complement(normal_distribution<value_type, forwarding_policy>(mean, var), q));
|
||||
}
|
||||
//
|
||||
// We *must* get the sign of the initial guess correct,
|
||||
// We *must* get the sign of the initial guess correct,
|
||||
// or our root-finder will fail, so double check it now:
|
||||
//
|
||||
value_type pzero = non_central_t_cdf(
|
||||
static_cast<value_type>(v),
|
||||
static_cast<value_type>(delta),
|
||||
static_cast<value_type>(0),
|
||||
!(p < q),
|
||||
static_cast<value_type>(v),
|
||||
static_cast<value_type>(delta),
|
||||
static_cast<value_type>(0),
|
||||
!(p < q),
|
||||
forwarding_policy());
|
||||
int s;
|
||||
if(p < q)
|
||||
@@ -362,13 +364,13 @@ namespace boost
|
||||
}
|
||||
|
||||
value_type result = detail::generic_quantile(
|
||||
non_central_t_distribution<value_type, forwarding_policy>(v, delta),
|
||||
(p < q ? p : q),
|
||||
guess,
|
||||
(p >= q),
|
||||
non_central_t_distribution<value_type, forwarding_policy>(v, delta),
|
||||
(p < q ? p : q),
|
||||
guess,
|
||||
(p >= q),
|
||||
function);
|
||||
return policies::checked_narrowing_cast<T, forwarding_policy>(
|
||||
result,
|
||||
result,
|
||||
function);
|
||||
}
|
||||
|
||||
@@ -379,19 +381,19 @@ namespace boost
|
||||
//
|
||||
// Variables come first:
|
||||
//
|
||||
boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
|
||||
std::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
|
||||
T errtol = boost::math::policies::get_epsilon<T, Policy>();
|
||||
T d2 = delta * delta / 2;
|
||||
//
|
||||
// k is the starting point for iteration, and is the
|
||||
// maximum of the poisson weighting term:
|
||||
//
|
||||
int k = itrunc(d2);
|
||||
long long k = lltrunc(d2);
|
||||
T pois, xterm;
|
||||
if(k == 0)
|
||||
k = 1;
|
||||
// Starting Poisson weight:
|
||||
pois = gamma_p_derivative(T(k+1), d2, pol)
|
||||
pois = gamma_p_derivative(T(k+1), d2, pol)
|
||||
* tgamma_delta_ratio(T(k + 1), T(0.5f))
|
||||
* delta / constants::root_two<T>();
|
||||
// Starting beta term:
|
||||
@@ -407,8 +409,8 @@ namespace boost
|
||||
// Backwards recursion first, this is the stable
|
||||
// direction for recursion:
|
||||
//
|
||||
boost::uintmax_t count = 0;
|
||||
for(int i = k; i >= 0; --i)
|
||||
std::uintmax_t count = 0;
|
||||
for(auto i = k; i >= 0; --i)
|
||||
{
|
||||
T term = xterm * pois;
|
||||
sum += term;
|
||||
@@ -420,11 +422,11 @@ namespace boost
|
||||
if(count > max_iter)
|
||||
{
|
||||
return policies::raise_evaluation_error(
|
||||
"pdf(non_central_t_distribution<%1%>, %1%)",
|
||||
"pdf(non_central_t_distribution<%1%>, %1%)",
|
||||
"Series did not converge, closest value was %1%", sum, pol);
|
||||
}
|
||||
}
|
||||
for(int i = k + 1; ; ++i)
|
||||
for(auto i = k + 1; ; ++i)
|
||||
{
|
||||
poisf *= d2 / (i + 0.5f);
|
||||
xtermf *= (x * (n / 2 + i)) / (i);
|
||||
@@ -436,7 +438,7 @@ namespace boost
|
||||
if(count > max_iter)
|
||||
{
|
||||
return policies::raise_evaluation_error(
|
||||
"pdf(non_central_t_distribution<%1%>, %1%)",
|
||||
"pdf(non_central_t_distribution<%1%>, %1%)",
|
||||
"Series did not converge, closest value was %1%", sum, pol);
|
||||
}
|
||||
}
|
||||
@@ -449,7 +451,7 @@ namespace boost
|
||||
BOOST_MATH_STD_USING
|
||||
if ((boost::math::isinf)(n))
|
||||
{ // Infinite degrees of freedom, so use normal distribution located at delta.
|
||||
normal_distribution<T, Policy> norm(delta, 1);
|
||||
normal_distribution<T, Policy> norm(delta, 1);
|
||||
return pdf(norm, t);
|
||||
}
|
||||
//
|
||||
@@ -463,16 +465,16 @@ namespace boost
|
||||
{
|
||||
//
|
||||
// Handle this as a special case, using the formula
|
||||
// from Weisstein, Eric W.
|
||||
// "Noncentral Student's t-Distribution."
|
||||
// From MathWorld--A Wolfram Web Resource.
|
||||
// http://mathworld.wolfram.com/NoncentralStudentst-Distribution.html
|
||||
//
|
||||
// from Weisstein, Eric W.
|
||||
// "Noncentral Student's t-Distribution."
|
||||
// From MathWorld--A Wolfram Web Resource.
|
||||
// http://mathworld.wolfram.com/NoncentralStudentst-Distribution.html
|
||||
//
|
||||
// The formula is simplified thanks to the relation
|
||||
// 1F1(a,b,0) = 1.
|
||||
//
|
||||
return tgamma_delta_ratio(n / 2 + 0.5f, T(0.5f))
|
||||
* sqrt(n / constants::pi<T>())
|
||||
* sqrt(n / constants::pi<T>())
|
||||
* exp(-delta * delta / 2) / 2;
|
||||
}
|
||||
if(fabs(delta / (4 * n)) < policies::get_epsilon<T, Policy>())
|
||||
@@ -523,7 +525,7 @@ namespace boost
|
||||
if (v > 1 / boost::math::tools::epsilon<T>() )
|
||||
{
|
||||
//normal_distribution<T, Policy> n(delta, 1);
|
||||
//return boost::math::mean(n);
|
||||
//return boost::math::mean(n);
|
||||
return delta;
|
||||
}
|
||||
else
|
||||
@@ -578,11 +580,11 @@ namespace boost
|
||||
BOOST_MATH_STD_USING
|
||||
if ((boost::math::isinf)(v))
|
||||
{
|
||||
return 3;
|
||||
return 1;
|
||||
}
|
||||
if (delta == 0)
|
||||
{ // == Student's t
|
||||
return 3;
|
||||
return 1;
|
||||
}
|
||||
T mean = boost::math::detail::mean(v, delta, pol);
|
||||
T l2 = delta * delta;
|
||||
@@ -592,11 +594,12 @@ namespace boost
|
||||
result *= -mean * mean;
|
||||
result += v * v * (l2 * l2 + 6 * l2 + 3) / ((v - 4) * (v - 2));
|
||||
result /= var * var;
|
||||
result -= static_cast<T>(3);
|
||||
return result;
|
||||
}
|
||||
|
||||
#if 0
|
||||
//
|
||||
//
|
||||
// This code is disabled, since there can be multiple answers to the
|
||||
// question, and it's not clear how to find the "right" one.
|
||||
//
|
||||
@@ -631,13 +634,13 @@ namespace boost
|
||||
//
|
||||
// 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%",
|
||||
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());
|
||||
}
|
||||
t_degrees_of_freedom_finder<RealType, Policy> f(delta, 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>();
|
||||
std::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
|
||||
//
|
||||
// Pick an initial guess:
|
||||
//
|
||||
@@ -684,13 +687,13 @@ namespace boost
|
||||
//
|
||||
// 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%",
|
||||
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());
|
||||
}
|
||||
t_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>();
|
||||
std::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
|
||||
//
|
||||
// Pick an initial guess that we know is the right side of
|
||||
// zero:
|
||||
@@ -721,15 +724,15 @@ namespace boost
|
||||
typedef Policy policy_type;
|
||||
|
||||
non_central_t_distribution(RealType v_, RealType lambda) : v(v_), ncp(lambda)
|
||||
{
|
||||
{
|
||||
const char* function = "boost::math::non_central_t_distribution<%1%>::non_central_t_distribution(%1%,%1%)";
|
||||
RealType r;
|
||||
detail::check_df_gt0_to_inf(
|
||||
function,
|
||||
v, &r, Policy());
|
||||
detail::check_finite(
|
||||
detail::check_non_centrality(
|
||||
function,
|
||||
lambda,
|
||||
static_cast<value_type>(lambda * lambda),
|
||||
&r,
|
||||
Policy());
|
||||
} // non_central_t_distribution constructor.
|
||||
@@ -743,7 +746,7 @@ namespace boost
|
||||
return ncp;
|
||||
}
|
||||
#if 0
|
||||
//
|
||||
//
|
||||
// This code is disabled, since there can be multiple answers to the
|
||||
// question, and it's not clear how to find the "right" one.
|
||||
//
|
||||
@@ -752,19 +755,19 @@ namespace boost
|
||||
const char* function = "non_central_t<%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>,
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
policies::discrete_quantile<>,
|
||||
policies::assert_undefined<> >::type forwarding_policy;
|
||||
value_type result = detail::find_t_degrees_of_freedom(
|
||||
static_cast<value_type>(delta),
|
||||
static_cast<value_type>(x),
|
||||
static_cast<value_type>(p),
|
||||
static_cast<value_type>(1-p),
|
||||
static_cast<value_type>(delta),
|
||||
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,
|
||||
result,
|
||||
function);
|
||||
}
|
||||
template <class A, class B, class C>
|
||||
@@ -773,19 +776,19 @@ namespace boost
|
||||
const char* function = "non_central_t<%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>,
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
policies::discrete_quantile<>,
|
||||
policies::assert_undefined<> >::type forwarding_policy;
|
||||
value_type result = detail::find_t_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),
|
||||
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,
|
||||
result,
|
||||
function);
|
||||
}
|
||||
static RealType find_non_centrality(RealType v, RealType x, RealType p)
|
||||
@@ -793,19 +796,19 @@ namespace boost
|
||||
const char* function = "non_central_t<%1%>::find_t_non_centrality";
|
||||
typedef typename policies::evaluation<RealType, Policy>::type value_type;
|
||||
typedef typename policies::normalise<
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
policies::discrete_quantile<>,
|
||||
policies::assert_undefined<> >::type forwarding_policy;
|
||||
value_type result = detail::find_t_non_centrality(
|
||||
static_cast<value_type>(v),
|
||||
static_cast<value_type>(x),
|
||||
static_cast<value_type>(p),
|
||||
static_cast<value_type>(1-p),
|
||||
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,
|
||||
result,
|
||||
function);
|
||||
}
|
||||
template <class A, class B, class C>
|
||||
@@ -814,19 +817,19 @@ namespace boost
|
||||
const char* function = "non_central_t<%1%>::find_t_non_centrality";
|
||||
typedef typename policies::evaluation<RealType, Policy>::type value_type;
|
||||
typedef typename policies::normalise<
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
policies::discrete_quantile<>,
|
||||
policies::assert_undefined<> >::type forwarding_policy;
|
||||
value_type result = detail::find_t_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),
|
||||
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,
|
||||
result,
|
||||
function);
|
||||
}
|
||||
#endif
|
||||
@@ -838,6 +841,11 @@ namespace boost
|
||||
|
||||
typedef non_central_t_distribution<double> non_central_t; // Reserved name of type double.
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
non_central_t_distribution(RealType,RealType)->non_central_t_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
// Non-member functions to give properties of the distribution.
|
||||
|
||||
template <class RealType, class Policy>
|
||||
@@ -866,12 +874,12 @@ namespace boost
|
||||
function,
|
||||
v, &r, Policy())
|
||||
||
|
||||
!detail::check_finite(
|
||||
!detail::check_non_centrality(
|
||||
function,
|
||||
l,
|
||||
static_cast<RealType>(l * l),
|
||||
&r,
|
||||
Policy()))
|
||||
return (RealType)r;
|
||||
return static_cast<RealType>(r);
|
||||
|
||||
BOOST_MATH_STD_USING
|
||||
|
||||
@@ -879,7 +887,7 @@ namespace boost
|
||||
RealType var = v < 4 ? 1 : detail::variance(v, l, Policy());
|
||||
|
||||
return detail::generic_find_mode(
|
||||
dist,
|
||||
dist,
|
||||
m,
|
||||
function,
|
||||
sqrt(var));
|
||||
@@ -887,14 +895,14 @@ namespace boost
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mean(const non_central_t_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
const char* function = "mean(const non_central_t_distribution<%1%>&)";
|
||||
typedef typename policies::evaluation<RealType, Policy>::type value_type;
|
||||
typedef typename policies::normalise<
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
policies::discrete_quantile<>,
|
||||
policies::assert_undefined<> >::type forwarding_policy;
|
||||
RealType v = dist.degrees_of_freedom();
|
||||
@@ -904,15 +912,15 @@ namespace boost
|
||||
function,
|
||||
v, &r, Policy())
|
||||
||
|
||||
!detail::check_finite(
|
||||
!detail::check_non_centrality(
|
||||
function,
|
||||
l,
|
||||
static_cast<RealType>(l * l),
|
||||
&r,
|
||||
Policy()))
|
||||
return (RealType)r;
|
||||
return static_cast<RealType>(r);
|
||||
if(v <= 1)
|
||||
return policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
function,
|
||||
"The non-central t distribution has no defined mean for degrees of freedom <= 1: got v=%1%.", v, Policy());
|
||||
// return l * sqrt(v / 2) * tgamma_delta_ratio((v - 1) * 0.5f, RealType(0.5f));
|
||||
return policies::checked_narrowing_cast<RealType, forwarding_policy>(
|
||||
@@ -926,9 +934,9 @@ namespace boost
|
||||
const char* function = "variance(const non_central_t_distribution<%1%>&)";
|
||||
typedef typename policies::evaluation<RealType, Policy>::type value_type;
|
||||
typedef typename policies::normalise<
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
policies::discrete_quantile<>,
|
||||
policies::assert_undefined<> >::type forwarding_policy;
|
||||
BOOST_MATH_STD_USING
|
||||
@@ -939,15 +947,15 @@ namespace boost
|
||||
function,
|
||||
v, &r, Policy())
|
||||
||
|
||||
!detail::check_finite(
|
||||
!detail::check_non_centrality(
|
||||
function,
|
||||
l,
|
||||
static_cast<RealType>(l * l),
|
||||
&r,
|
||||
Policy()))
|
||||
return (RealType)r;
|
||||
return static_cast<RealType>(r);
|
||||
if(v <= 2)
|
||||
return policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
function,
|
||||
"The non-central t distribution has no defined variance for degrees of freedom <= 2: got v=%1%.", v, Policy());
|
||||
return policies::checked_narrowing_cast<RealType, forwarding_policy>(
|
||||
detail::variance(static_cast<value_type>(v), static_cast<value_type>(l), forwarding_policy()), function);
|
||||
@@ -962,9 +970,9 @@ namespace boost
|
||||
const char* function = "skewness(const non_central_t_distribution<%1%>&)";
|
||||
typedef typename policies::evaluation<RealType, Policy>::type value_type;
|
||||
typedef typename policies::normalise<
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
policies::discrete_quantile<>,
|
||||
policies::assert_undefined<> >::type forwarding_policy;
|
||||
RealType v = dist.degrees_of_freedom();
|
||||
@@ -974,15 +982,15 @@ namespace boost
|
||||
function,
|
||||
v, &r, Policy())
|
||||
||
|
||||
!detail::check_finite(
|
||||
!detail::check_non_centrality(
|
||||
function,
|
||||
l,
|
||||
static_cast<RealType>(l * l),
|
||||
&r,
|
||||
Policy()))
|
||||
return (RealType)r;
|
||||
return static_cast<RealType>(r);
|
||||
if(v <= 3)
|
||||
return policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
function,
|
||||
"The non-central t distribution has no defined skewness for degrees of freedom <= 3: got v=%1%.", v, Policy());;
|
||||
return policies::checked_narrowing_cast<RealType, forwarding_policy>(
|
||||
detail::skewness(static_cast<value_type>(v), static_cast<value_type>(l), forwarding_policy()), function);
|
||||
@@ -990,13 +998,13 @@ namespace boost
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType kurtosis_excess(const non_central_t_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
{
|
||||
const char* function = "kurtosis_excess(const non_central_t_distribution<%1%>&)";
|
||||
typedef typename policies::evaluation<RealType, Policy>::type value_type;
|
||||
typedef typename policies::normalise<
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
policies::discrete_quantile<>,
|
||||
policies::assert_undefined<> >::type forwarding_policy;
|
||||
RealType v = dist.degrees_of_freedom();
|
||||
@@ -1006,15 +1014,15 @@ namespace boost
|
||||
function,
|
||||
v, &r, Policy())
|
||||
||
|
||||
!detail::check_finite(
|
||||
!detail::check_non_centrality(
|
||||
function,
|
||||
l,
|
||||
static_cast<RealType>(l * l),
|
||||
&r,
|
||||
Policy()))
|
||||
return (RealType)r;
|
||||
return static_cast<RealType>(r);
|
||||
if(v <= 4)
|
||||
return policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
function,
|
||||
"The non-central t distribution has no defined kurtosis for degrees of freedom <= 4: got v=%1%.", v, Policy());;
|
||||
return policies::checked_narrowing_cast<RealType, forwarding_policy>(
|
||||
detail::kurtosis_excess(static_cast<value_type>(v), static_cast<value_type>(l), forwarding_policy()), function);
|
||||
@@ -1032,9 +1040,9 @@ namespace boost
|
||||
const char* function = "pdf(non_central_t_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>,
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
policies::discrete_quantile<>,
|
||||
policies::assert_undefined<> >::type forwarding_policy;
|
||||
|
||||
@@ -1045,9 +1053,9 @@ namespace boost
|
||||
function,
|
||||
v, &r, Policy())
|
||||
||
|
||||
!detail::check_finite(
|
||||
!detail::check_non_centrality(
|
||||
function,
|
||||
l,
|
||||
static_cast<RealType>(l * l), // we need l^2 to be countable.
|
||||
&r,
|
||||
Policy())
|
||||
||
|
||||
@@ -1056,25 +1064,25 @@ namespace boost
|
||||
t,
|
||||
&r,
|
||||
Policy()))
|
||||
return (RealType)r;
|
||||
return static_cast<RealType>(r);
|
||||
return policies::checked_narrowing_cast<RealType, forwarding_policy>(
|
||||
detail::non_central_t_pdf(static_cast<value_type>(v),
|
||||
static_cast<value_type>(l),
|
||||
static_cast<value_type>(t),
|
||||
detail::non_central_t_pdf(static_cast<value_type>(v),
|
||||
static_cast<value_type>(l),
|
||||
static_cast<value_type>(t),
|
||||
Policy()),
|
||||
function);
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
RealType cdf(const non_central_t_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
{
|
||||
const char* function = "boost::math::cdf(non_central_t_distribution<%1%>&, %1%)";
|
||||
// was const char* function = "boost::math::non_central_t_distribution<%1%>::cdf(%1%)";
|
||||
typedef typename policies::evaluation<RealType, Policy>::type value_type;
|
||||
typedef typename policies::normalise<
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
policies::discrete_quantile<>,
|
||||
policies::assert_undefined<> >::type forwarding_policy;
|
||||
|
||||
@@ -1085,9 +1093,9 @@ namespace boost
|
||||
function,
|
||||
v, &r, Policy())
|
||||
||
|
||||
!detail::check_finite(
|
||||
!detail::check_non_centrality(
|
||||
function,
|
||||
l,
|
||||
static_cast<RealType>(l * l),
|
||||
&r,
|
||||
Policy())
|
||||
||
|
||||
@@ -1096,10 +1104,10 @@ namespace boost
|
||||
x,
|
||||
&r,
|
||||
Policy()))
|
||||
return (RealType)r;
|
||||
if ((boost::math::isinf)(v))
|
||||
return static_cast<RealType>(r);
|
||||
if ((boost::math::isinf)(v))
|
||||
{ // Infinite degrees of freedom, so use normal distribution located at delta.
|
||||
normal_distribution<RealType, Policy> n(l, 1);
|
||||
normal_distribution<RealType, Policy> n(l, 1);
|
||||
cdf(n, x);
|
||||
//return cdf(normal_distribution<RealType, Policy>(l, 1), x);
|
||||
}
|
||||
@@ -1110,9 +1118,9 @@ namespace boost
|
||||
}
|
||||
return policies::checked_narrowing_cast<RealType, forwarding_policy>(
|
||||
detail::non_central_t_cdf(
|
||||
static_cast<value_type>(v),
|
||||
static_cast<value_type>(l),
|
||||
static_cast<value_type>(x),
|
||||
static_cast<value_type>(v),
|
||||
static_cast<value_type>(l),
|
||||
static_cast<value_type>(x),
|
||||
false, Policy()),
|
||||
function);
|
||||
} // cdf
|
||||
@@ -1124,9 +1132,9 @@ namespace boost
|
||||
const char* function = "boost::math::cdf(const complement(non_central_t_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>,
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
policies::discrete_quantile<>,
|
||||
policies::assert_undefined<> >::type forwarding_policy;
|
||||
|
||||
@@ -1139,9 +1147,9 @@ namespace boost
|
||||
function,
|
||||
v, &r, Policy())
|
||||
||
|
||||
!detail::check_finite(
|
||||
!detail::check_non_centrality(
|
||||
function,
|
||||
l,
|
||||
static_cast<RealType>(l * l),
|
||||
&r,
|
||||
Policy())
|
||||
||
|
||||
@@ -1150,11 +1158,11 @@ namespace boost
|
||||
x,
|
||||
&r,
|
||||
Policy()))
|
||||
return (RealType)r;
|
||||
return static_cast<RealType>(r);
|
||||
|
||||
if ((boost::math::isinf)(v))
|
||||
{ // Infinite degrees of freedom, so use normal distribution located at delta.
|
||||
normal_distribution<RealType, Policy> n(l, 1);
|
||||
normal_distribution<RealType, Policy> n(l, 1);
|
||||
return cdf(complement(n, x));
|
||||
}
|
||||
if(l == 0)
|
||||
@@ -1163,9 +1171,9 @@ namespace boost
|
||||
}
|
||||
return policies::checked_narrowing_cast<RealType, forwarding_policy>(
|
||||
detail::non_central_t_cdf(
|
||||
static_cast<value_type>(v),
|
||||
static_cast<value_type>(l),
|
||||
static_cast<value_type>(x),
|
||||
static_cast<value_type>(v),
|
||||
static_cast<value_type>(l),
|
||||
static_cast<value_type>(x),
|
||||
true, Policy()),
|
||||
function);
|
||||
} // ccdf
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp>
|
||||
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost{ namespace math{
|
||||
|
||||
@@ -28,10 +29,10 @@ template <class RealType = double, class Policy = policies::policy<> >
|
||||
class normal_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
using value_type = RealType;
|
||||
using policy_type = Policy;
|
||||
|
||||
normal_distribution(RealType l_mean = 0, RealType sd = 1)
|
||||
explicit normal_distribution(RealType l_mean = 0, RealType sd = 1)
|
||||
: m_mean(l_mean), m_sd(sd)
|
||||
{ // Default is a 'standard' normal distribution N01.
|
||||
static const char* function = "boost::math::normal_distribution<%1%>::normal_distribution";
|
||||
@@ -69,15 +70,29 @@ private:
|
||||
RealType m_sd; // distribution standard deviation or scale.
|
||||
}; // class normal_distribution
|
||||
|
||||
typedef normal_distribution<double> normal;
|
||||
using normal = normal_distribution<double>;
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
//
|
||||
// Deduction guides, note we don't check the
|
||||
// value of __cpp_deduction_guides, just assume
|
||||
// they work as advertised, even if this is pre-final C++17.
|
||||
//
|
||||
#ifdef __cpp_deduction_guides
|
||||
|
||||
template <class RealType>
|
||||
normal_distribution(RealType, RealType)->normal_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
template <class RealType>
|
||||
normal_distribution(RealType)->normal_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4127)
|
||||
#endif
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const normal_distribution<RealType, Policy>& /*dist*/)
|
||||
inline std::pair<RealType, RealType> range(const normal_distribution<RealType, Policy>& /*dist*/)
|
||||
{ // Range of permissible values for random variable x.
|
||||
if (std::numeric_limits<RealType>::has_infinity)
|
||||
{
|
||||
@@ -91,7 +106,7 @@ inline const std::pair<RealType, RealType> range(const normal_distribution<RealT
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> support(const normal_distribution<RealType, Policy>& /*dist*/)
|
||||
inline std::pair<RealType, RealType> support(const normal_distribution<RealType, Policy>& /*dist*/)
|
||||
{ // This is range values for random variable x where cdf rises from 0 to 1, and outside it, the pdf is zero.
|
||||
if (std::numeric_limits<RealType>::has_infinity)
|
||||
{
|
||||
@@ -104,7 +119,7 @@ inline const std::pair<RealType, RealType> support(const normal_distribution<Rea
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
@@ -131,11 +146,6 @@ inline RealType pdf(const normal_distribution<RealType, Policy>& dist, const Rea
|
||||
{
|
||||
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;
|
||||
//}
|
||||
if(false == detail::check_x(function, x, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
@@ -151,6 +161,42 @@ inline RealType pdf(const normal_distribution<RealType, Policy>& dist, const Rea
|
||||
return result;
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType logpdf(const normal_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
const RealType sd = dist.standard_deviation();
|
||||
const RealType mean = dist.mean();
|
||||
|
||||
static const char* function = "boost::math::logpdf(const normal_distribution<%1%>&, %1%)";
|
||||
|
||||
RealType result = -std::numeric_limits<RealType>::infinity();
|
||||
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))
|
||||
{
|
||||
return result; // pdf + and - infinity is zero so logpdf is -inf
|
||||
}
|
||||
if(false == detail::check_x(function, x, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
const RealType pi = boost::math::constants::pi<RealType>();
|
||||
const RealType half = boost::math::constants::half<RealType>();
|
||||
|
||||
result = -log(sd) - half*log(2*pi) - (x-mean)*(x-mean)/(2*sd*sd);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const normal_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
@@ -173,15 +219,6 @@ inline RealType cdf(const normal_distribution<RealType, Policy>& dist, const Rea
|
||||
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;
|
||||
@@ -235,15 +272,6 @@ inline RealType cdf(const complemented2_type<normal_distribution<RealType, Polic
|
||||
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;
|
||||
//}
|
||||
if(false == detail::check_x(function, x, &result, Policy()))
|
||||
return result;
|
||||
|
||||
@@ -316,6 +344,14 @@ inline RealType kurtosis_excess(const normal_distribution<RealType, Policy>& /*d
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType entropy(const normal_distribution<RealType, Policy> & dist)
|
||||
{
|
||||
using std::log;
|
||||
RealType arg = constants::two_pi<RealType>()*constants::e<RealType>()*dist.standard_deviation()*dist.standard_deviation();
|
||||
return log(arg)/2;
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// Copyright John Maddock 2007.
|
||||
// Copyright Paul A. Bristow 2007, 2009
|
||||
// Copyright Matt Borland 2023.
|
||||
// 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)
|
||||
@@ -20,8 +21,11 @@
|
||||
#include <boost/math/distributions/complement.hpp>
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp>
|
||||
#include <boost/math/special_functions/powm1.hpp>
|
||||
#include <boost/math/special_functions/log1p.hpp>
|
||||
|
||||
#include <utility> // for BOOST_CURRENT_VALUE?
|
||||
#include <limits>
|
||||
#include <cmath>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
@@ -160,6 +164,14 @@ namespace boost
|
||||
|
||||
typedef pareto_distribution<double> pareto; // Convenience to allow pareto(2., 3.);
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
pareto_distribution(RealType)->pareto_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
template <class RealType>
|
||||
pareto_distribution(RealType,RealType)->pareto_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
|
||||
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.
|
||||
@@ -217,6 +229,28 @@ namespace boost
|
||||
return result;
|
||||
} // cdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType logcdf(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::logcdf(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 -std::numeric_limits<RealType>::infinity();
|
||||
}
|
||||
|
||||
result = log1p(-pow(scale/x, shape), Policy());
|
||||
return result;
|
||||
} // logcdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const pareto_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
{
|
||||
@@ -266,6 +300,28 @@ namespace boost
|
||||
return result;
|
||||
} // cdf complement
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType logcdf(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::logcdf(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 0;
|
||||
}
|
||||
result = log(pow((scale/x), shape));
|
||||
|
||||
return result;
|
||||
} // logcdf complement
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const complemented2_type<pareto_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
@@ -431,6 +487,15 @@ namespace boost
|
||||
return result;
|
||||
} // kurtosis_excess
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType entropy(const pareto_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
using std::log;
|
||||
RealType xm = dist.scale();
|
||||
RealType alpha = dist.shape();
|
||||
return log(xm/alpha) + 1 + 1/alpha;
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
// 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,
|
||||
// it is convenient to treat it as if a continuous 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.
|
||||
@@ -47,6 +47,7 @@
|
||||
#include <boost/math/distributions/detail/inv_discrete_quantile.hpp>
|
||||
|
||||
#include <utility>
|
||||
#include <limits>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
@@ -144,10 +145,10 @@ namespace boost
|
||||
class poisson_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
using value_type = RealType;
|
||||
using policy_type = Policy;
|
||||
|
||||
poisson_distribution(RealType l_mean = 1) : m_l(l_mean) // mean (lambda).
|
||||
explicit poisson_distribution(RealType l_mean = 1) : m_l(l_mean) // mean (lambda).
|
||||
{ // Expected mean number of events that occur during the given interval.
|
||||
RealType r;
|
||||
poisson_detail::check_dist(
|
||||
@@ -165,19 +166,24 @@ namespace boost
|
||||
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.
|
||||
using poisson = poisson_distribution<double>; // Reserved name of type double.
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
poisson_distribution(RealType)->poisson_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
// 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 */)
|
||||
inline 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 */)
|
||||
inline 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;
|
||||
@@ -197,15 +203,7 @@ namespace boost
|
||||
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.
|
||||
// Median now implemented via quantile(half) in derived accessors.
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType variance(const poisson_distribution<RealType, Policy>& dist)
|
||||
@@ -213,7 +211,6 @@ namespace boost
|
||||
return dist.mean();
|
||||
}
|
||||
|
||||
// RealType standard_deviation(const poisson_distribution<RealType, Policy>& dist)
|
||||
// standard_deviation provided by derived accessors.
|
||||
|
||||
template <class RealType, class Policy>
|
||||
@@ -235,7 +232,7 @@ namespace boost
|
||||
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
|
||||
// http://en.wikipedia.org/wiki/Kurtosis
|
||||
// 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.
|
||||
@@ -276,6 +273,42 @@ namespace boost
|
||||
return boost::math::gamma_p_derivative(k+1, mean, Policy());
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
RealType logpdf(const poisson_distribution<RealType, Policy>& dist, const RealType& k)
|
||||
{
|
||||
BOOST_FPU_EXCEPTION_GUARD
|
||||
|
||||
BOOST_MATH_STD_USING // for ADL of std functions.
|
||||
using boost::math::lgamma;
|
||||
|
||||
RealType mean = dist.mean();
|
||||
// Error check:
|
||||
RealType result = -std::numeric_limits<RealType>::infinity();
|
||||
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 std::numeric_limits<RealType>::quiet_NaN();
|
||||
}
|
||||
|
||||
// Special case where k and lambda are both positive
|
||||
if(k > 0 && mean > 0)
|
||||
{
|
||||
return -lgamma(k+1) + k*log(mean) - mean;
|
||||
}
|
||||
|
||||
result = log(pdf(dist, k));
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
RealType cdf(const poisson_distribution<RealType, Policy>& dist, const RealType& k)
|
||||
{ // Cumulative Distribution Function Poisson.
|
||||
@@ -288,7 +321,7 @@ namespace boost
|
||||
// (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
|
||||
// it is convenient to treat it as if it is a continuous 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.
|
||||
@@ -315,8 +348,8 @@ namespace boost
|
||||
return 0;
|
||||
}
|
||||
if (k == 0)
|
||||
{ // return pdf(dist, static_cast<RealType>(0));
|
||||
// but mean (and k) have already been checked,
|
||||
{
|
||||
// mean (and k) have already been checked,
|
||||
// so this avoids unnecessary repeated checks.
|
||||
return exp(-mean);
|
||||
}
|
||||
@@ -337,7 +370,7 @@ namespace boost
|
||||
// (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
|
||||
// it is convenient to treat it as is it is a continuous 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.
|
||||
@@ -409,9 +442,10 @@ namespace boost
|
||||
{
|
||||
return policies::raise_overflow_error<RealType>(function, 0, Policy());
|
||||
}
|
||||
typedef typename Policy::discrete_quantile_type discrete_type;
|
||||
boost::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
|
||||
RealType guess, factor = 8;
|
||||
using discrete_type = typename Policy::discrete_quantile_type;
|
||||
std::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
|
||||
RealType guess;
|
||||
RealType factor = 8;
|
||||
RealType z = dist.mean();
|
||||
if(z < 1)
|
||||
guess = z;
|
||||
@@ -479,9 +513,10 @@ namespace boost
|
||||
{
|
||||
return 0; // Exact result regardless of discrete-quantile Policy
|
||||
}
|
||||
typedef typename Policy::discrete_quantile_type discrete_type;
|
||||
boost::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
|
||||
RealType guess, factor = 8;
|
||||
using discrete_type = typename Policy::discrete_quantile_type;
|
||||
std::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
|
||||
RealType guess;
|
||||
RealType factor = 8;
|
||||
RealType z = dist.mean();
|
||||
if(z < 1)
|
||||
guess = z;
|
||||
@@ -519,7 +554,6 @@ namespace boost
|
||||
// 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
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// Copyright Paul A. Bristow 2007.
|
||||
// Copyright Matt Borland 2023.
|
||||
// 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)
|
||||
@@ -12,14 +13,15 @@
|
||||
#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
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4702) // unreachable code (return after domain_error throw).
|
||||
#endif
|
||||
|
||||
#include <utility>
|
||||
#include <limits>
|
||||
#include <cmath>
|
||||
|
||||
namespace boost{ namespace math{
|
||||
|
||||
@@ -56,10 +58,10 @@ template <class RealType = double, class Policy = policies::policy<> >
|
||||
class rayleigh_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
using value_type = RealType;
|
||||
using policy_type = Policy;
|
||||
|
||||
rayleigh_distribution(RealType l_sigma = 1)
|
||||
explicit rayleigh_distribution(RealType l_sigma = 1)
|
||||
: m_sigma(l_sigma)
|
||||
{
|
||||
RealType err;
|
||||
@@ -75,17 +77,22 @@ private:
|
||||
RealType m_sigma;
|
||||
}; // class rayleigh_distribution
|
||||
|
||||
typedef rayleigh_distribution<double> rayleigh;
|
||||
using rayleigh = rayleigh_distribution<double>;
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
rayleigh_distribution(RealType)->rayleigh_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const rayleigh_distribution<RealType, Policy>& /*dist*/)
|
||||
inline 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), std::numeric_limits<RealType>::has_infinity ? std::numeric_limits<RealType>::infinity() : max_value<RealType>());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> support(const rayleigh_distribution<RealType, Policy>& /*dist*/)
|
||||
inline 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;
|
||||
@@ -117,6 +124,32 @@ inline RealType pdf(const rayleigh_distribution<RealType, Policy>& dist, const R
|
||||
return result;
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType logpdf(const rayleigh_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std function exp.
|
||||
|
||||
const RealType sigma = dist.sigma();
|
||||
RealType result = -std::numeric_limits<RealType>::infinity();
|
||||
static const char* function = "boost::math::logpdf(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;
|
||||
}
|
||||
if((boost::math::isinf)(x))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
result = -(x*x)/(2*sigma*sigma) - 2*log(sigma) + log(x);
|
||||
return result;
|
||||
} // logpdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const rayleigh_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
@@ -137,6 +170,26 @@ inline RealType cdf(const rayleigh_distribution<RealType, Policy>& dist, const R
|
||||
return result;
|
||||
} // cdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType logcdf(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::logcdf(const rayleigh_distribution<%1%>&, %1%)";
|
||||
if(false == detail::verify_sigma(function, sigma, &result, Policy()))
|
||||
{
|
||||
return -std::numeric_limits<RealType>::infinity();
|
||||
}
|
||||
if(false == detail::verify_rayleigh_x(function, x, &result, Policy()))
|
||||
{
|
||||
return -std::numeric_limits<RealType>::infinity();
|
||||
}
|
||||
result = log1p(-exp(-x * x / ( 2 * sigma * sigma)), Policy());
|
||||
return result;
|
||||
} // logcdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const rayleigh_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
{
|
||||
@@ -187,6 +240,31 @@ inline RealType cdf(const complemented2_type<rayleigh_distribution<RealType, Pol
|
||||
return result;
|
||||
} // cdf complement
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType logcdf(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::logcdf(const rayleigh_distribution<%1%>&, %1%)";
|
||||
if(false == detail::verify_sigma(function, sigma, &result, Policy()))
|
||||
{
|
||||
return -std::numeric_limits<RealType>::infinity();
|
||||
}
|
||||
RealType x = c.param;
|
||||
if(false == detail::verify_rayleigh_x(function, x, &result, Policy()))
|
||||
{
|
||||
return -std::numeric_limits<RealType>::infinity();
|
||||
}
|
||||
RealType ea = x * x / (2 * sigma * sigma);
|
||||
// Fix for VC11/12 x64 bug in exp(float):
|
||||
if (ea >= tools::max_value<RealType>())
|
||||
return 0;
|
||||
result = -ea;
|
||||
return result;
|
||||
} // logcdf complement
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const complemented2_type<rayleigh_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
@@ -260,36 +338,38 @@ inline RealType median(const rayleigh_distribution<RealType, Policy>& dist)
|
||||
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>();
|
||||
// 2 * sqrt(pi) * (pi-3) / pow(4, 2/3) - pi
|
||||
}
|
||||
|
||||
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>());
|
||||
// 3 - (6*pi*pi - 24*pi + 16) / pow(4-pi, 2)
|
||||
}
|
||||
|
||||
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
|
||||
// Computed using NTL at 150 bit, about 50 decimal digits.
|
||||
// -(6*pi*pi - 24*pi + 16) / pow(4-pi,2)
|
||||
} // kurtosis_excess
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType entropy(const rayleigh_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
using std::log;
|
||||
return 1 + log(dist.sigma()*constants::one_div_root_two<RealType>()) + constants::euler<RealType>()/2;
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include <boost/math/constants/constants.hpp>
|
||||
#include <boost/math/tools/tuple.hpp>
|
||||
#include <boost/math/tools/roots.hpp> // Newton-Raphson
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/math/tools/assert.hpp>
|
||||
#include <boost/math/distributions/detail/generic_mode.hpp> // pdf max finder.
|
||||
|
||||
#include <utility>
|
||||
@@ -70,17 +70,17 @@ namespace boost{ namespace math{
|
||||
}
|
||||
|
||||
RealType location()const
|
||||
{
|
||||
{
|
||||
return location_;
|
||||
}
|
||||
|
||||
RealType scale()const
|
||||
{
|
||||
{
|
||||
return scale_;
|
||||
}
|
||||
|
||||
RealType shape()const
|
||||
{
|
||||
{
|
||||
return shape_;
|
||||
}
|
||||
|
||||
@@ -96,12 +96,21 @@ namespace boost{ namespace math{
|
||||
|
||||
typedef skew_normal_distribution<double> skew_normal;
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
skew_normal_distribution(RealType)->skew_normal_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
template <class RealType>
|
||||
skew_normal_distribution(RealType,RealType)->skew_normal_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
template <class RealType>
|
||||
skew_normal_distribution(RealType,RealType,RealType)->skew_normal_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const skew_normal_distribution<RealType, Policy>& /*dist*/)
|
||||
{ // Range of permissible values for random variable x.
|
||||
using boost::math::tools::max_value;
|
||||
return std::pair<RealType, RealType>(
|
||||
std::numeric_limits<RealType>::has_infinity ? -std::numeric_limits<RealType>::infinity() : -max_value<RealType>(),
|
||||
std::numeric_limits<RealType>::has_infinity ? -std::numeric_limits<RealType>::infinity() : -max_value<RealType>(),
|
||||
std::numeric_limits<RealType>::has_infinity ? std::numeric_limits<RealType>::infinity() : max_value<RealType>()); // - to + max value.
|
||||
}
|
||||
|
||||
@@ -287,7 +296,7 @@ namespace boost{ namespace math{
|
||||
{
|
||||
using namespace boost::math::constants;
|
||||
|
||||
const RealType delta2 = static_cast<RealType>(1) / (static_cast<RealType>(1)+static_cast<RealType>(1)/(dist.shape()*dist.shape()));
|
||||
const RealType delta2 = dist.shape() != 0 ? static_cast<RealType>(1) / (static_cast<RealType>(1)+static_cast<RealType>(1)/(dist.shape()*dist.shape())) : static_cast<RealType>(0);
|
||||
//const RealType inv_delta2 = static_cast<RealType>(1)+static_cast<RealType>(1)/(dist.shape()*dist.shape());
|
||||
|
||||
RealType variance = dist.scale()*dist.scale()*(static_cast<RealType>(1)-two_div_pi<RealType>()*delta2);
|
||||
@@ -301,7 +310,7 @@ namespace boost{ namespace math{
|
||||
/*
|
||||
TODO No closed expression for mode, so use max of pdf.
|
||||
*/
|
||||
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mode_fallback(const skew_normal_distribution<RealType, Policy>& dist)
|
||||
{ // mode.
|
||||
@@ -309,7 +318,7 @@ namespace boost{ namespace math{
|
||||
const RealType scale = dist.scale();
|
||||
const RealType location = dist.location();
|
||||
const RealType shape = dist.shape();
|
||||
|
||||
|
||||
RealType result;
|
||||
if(!detail::check_scale(
|
||||
function,
|
||||
@@ -334,7 +343,7 @@ namespace boost{ namespace math{
|
||||
result = location-scale*result;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
BOOST_MATH_STD_USING
|
||||
|
||||
// 21 elements
|
||||
@@ -389,10 +398,10 @@ namespace boost{ namespace math{
|
||||
const RealType* result_ptr = std::lower_bound(shapes, shapes+21, shape);
|
||||
|
||||
typedef typename std::iterator_traits<RealType*>::difference_type diff_type;
|
||||
|
||||
|
||||
const diff_type d = std::distance(shapes, result_ptr);
|
||||
|
||||
BOOST_ASSERT(d > static_cast<diff_type>(0));
|
||||
|
||||
BOOST_MATH_ASSERT(d > static_cast<diff_type>(0));
|
||||
|
||||
// refine
|
||||
if(d < static_cast<diff_type>(21)) // shape smaller 100
|
||||
@@ -407,21 +416,21 @@ namespace boost{ namespace math{
|
||||
}
|
||||
|
||||
skew_normal_distribution<RealType, Policy> helper(0, 1, shape);
|
||||
|
||||
|
||||
result = detail::generic_find_mode_01(helper, result, function);
|
||||
|
||||
|
||||
result = result*scale + location;
|
||||
|
||||
|
||||
return result;
|
||||
} // mode_fallback
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* TODO No closed expression for mode, so use f'(x) = 0
|
||||
*/
|
||||
template <class RealType, class Policy>
|
||||
struct skew_normal_mode_functor
|
||||
{
|
||||
{
|
||||
skew_normal_mode_functor(const boost::math::skew_normal_distribution<RealType, Policy> dist)
|
||||
: distribution(dist)
|
||||
{
|
||||
@@ -442,9 +451,9 @@ namespace boost{ namespace math{
|
||||
private:
|
||||
const boost::math::skew_normal_distribution<RealType, Policy> distribution;
|
||||
};
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType mode(const skew_normal_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
@@ -477,7 +486,7 @@ namespace boost{ namespace math{
|
||||
|
||||
// 21 elements
|
||||
static const RealType shapes[] = {
|
||||
0.0,
|
||||
static_cast<RealType>(0.0),
|
||||
static_cast<RealType>(1.000000000000000e-004),
|
||||
static_cast<RealType>(2.069138081114790e-004),
|
||||
static_cast<RealType>(4.281332398719396e-004),
|
||||
@@ -502,7 +511,7 @@ namespace boost{ namespace math{
|
||||
|
||||
// 21 elements
|
||||
static const RealType guess[] = {
|
||||
0.0,
|
||||
static_cast<RealType>(0.0),
|
||||
static_cast<RealType>(5.000050000525391e-005),
|
||||
static_cast<RealType>(1.500015000148736e-004),
|
||||
static_cast<RealType>(3.500035000350010e-004),
|
||||
@@ -528,10 +537,10 @@ namespace boost{ namespace math{
|
||||
const RealType* result_ptr = std::lower_bound(shapes, shapes+21, shape);
|
||||
|
||||
typedef typename std::iterator_traits<RealType*>::difference_type diff_type;
|
||||
|
||||
|
||||
const diff_type d = std::distance(shapes, result_ptr);
|
||||
|
||||
BOOST_ASSERT(d > static_cast<diff_type>(0));
|
||||
|
||||
BOOST_MATH_ASSERT(d > static_cast<diff_type>(0));
|
||||
|
||||
// TODO: make the search bounds smarter, depending on the shape parameter
|
||||
RealType search_min = 0; // below zero was caught above
|
||||
@@ -550,22 +559,22 @@ namespace boost{ namespace math{
|
||||
result = 1e-4f;
|
||||
search_max = guess[19]; // set 19 instead of 20 to have a safety margin because the table may not be exact @ shape=100
|
||||
}
|
||||
|
||||
const int get_digits = policies::digits<RealType, Policy>();// get digits from policy,
|
||||
boost::uintmax_t m = policies::get_max_root_iterations<Policy>(); // and max iterations.
|
||||
|
||||
const int get_digits = policies::digits<RealType, Policy>();// get digits from policy,
|
||||
std::uintmax_t m = policies::get_max_root_iterations<Policy>(); // and max iterations.
|
||||
|
||||
skew_normal_distribution<RealType, Policy> helper(0, 1, shape);
|
||||
|
||||
result = tools::newton_raphson_iterate(detail::skew_normal_mode_functor<RealType, Policy>(helper), result,
|
||||
search_min, search_max, get_digits, m);
|
||||
|
||||
|
||||
result = result*scale + location;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType skewness(const skew_normal_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
@@ -575,8 +584,8 @@ namespace boost{ namespace math{
|
||||
static const RealType factor = four_minus_pi<RealType>()/static_cast<RealType>(2);
|
||||
const RealType delta = dist.shape() / sqrt(static_cast<RealType>(1)+dist.shape()*dist.shape());
|
||||
|
||||
return factor * pow(root_two_div_pi<RealType>() * delta, 3) /
|
||||
pow(static_cast<RealType>(1)-two_div_pi<RealType>()*delta*delta, static_cast<RealType>(1.5));
|
||||
return static_cast<RealType>(factor * pow(root_two_div_pi<RealType>() * delta, 3) /
|
||||
pow(static_cast<RealType>(1)-two_div_pi<RealType>()*delta*delta, static_cast<RealType>(1.5)));
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
@@ -592,7 +601,7 @@ namespace boost{ namespace math{
|
||||
|
||||
static const RealType factor = pi_minus_three<RealType>()*static_cast<RealType>(2);
|
||||
|
||||
const RealType delta2 = static_cast<RealType>(1) / (static_cast<RealType>(1)+static_cast<RealType>(1)/(dist.shape()*dist.shape()));
|
||||
const RealType delta2 = dist.shape() != 0 ? static_cast<RealType>(1) / (static_cast<RealType>(1)+static_cast<RealType>(1)/(dist.shape()*dist.shape())) : static_cast<RealType>(0);
|
||||
|
||||
const RealType x = static_cast<RealType>(1)-two_div_pi<RealType>()*delta2;
|
||||
const RealType y = two_div_pi<RealType>() * delta2;
|
||||
@@ -605,7 +614,7 @@ namespace boost{ namespace math{
|
||||
|
||||
template <class RealType, class Policy>
|
||||
struct skew_normal_quantile_functor
|
||||
{
|
||||
{
|
||||
skew_normal_quantile_functor(const boost::math::skew_normal_distribution<RealType, Policy> dist, RealType const& p)
|
||||
: distribution(dist), prob(p)
|
||||
{
|
||||
@@ -621,7 +630,7 @@ namespace boost{ namespace math{
|
||||
}
|
||||
private:
|
||||
const boost::math::skew_normal_distribution<RealType, Policy> distribution;
|
||||
RealType prob;
|
||||
RealType prob;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
@@ -670,8 +679,8 @@ namespace boost{ namespace math{
|
||||
const RealType search_min = range(dist).first;
|
||||
const RealType search_max = range(dist).second;
|
||||
|
||||
const int get_digits = policies::digits<RealType, Policy>();// get digits from policy,
|
||||
boost::uintmax_t m = policies::get_max_root_iterations<Policy>(); // and max iterations.
|
||||
const int get_digits = policies::digits<RealType, Policy>();// get digits from policy,
|
||||
std::uintmax_t m = policies::get_max_root_iterations<Policy>(); // and max iterations.
|
||||
|
||||
result = tools::newton_raphson_iterate(detail::skew_normal_quantile_functor<RealType, Policy>(dist, p), result,
|
||||
search_min, search_max, get_digits, m);
|
||||
|
||||
@@ -14,13 +14,14 @@
|
||||
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#include <boost/math/special_functions/beta.hpp> // for ibeta(a, b, x).
|
||||
#include <boost/math/special_functions/digamma.hpp>
|
||||
#include <boost/math/distributions/complement.hpp>
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp>
|
||||
#include <boost/math/distributions/normal.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4702) // unreachable code (return after domain_error throw).
|
||||
#endif
|
||||
@@ -61,6 +62,11 @@ private:
|
||||
|
||||
typedef students_t_distribution<double> students_t; // Convenience typedef for double version.
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
students_t_distribution(RealType)->students_t_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
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.
|
||||
@@ -324,7 +330,7 @@ RealType students_t_distribution<RealType, Policy>::find_degrees_of_freedom(
|
||||
|
||||
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::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>())
|
||||
@@ -478,10 +484,22 @@ inline RealType kurtosis_excess(const students_t_distribution<RealType, Policy>&
|
||||
}
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType entropy(const students_t_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
using std::log;
|
||||
using std::sqrt;
|
||||
RealType v = dist.degrees_of_freedom();
|
||||
RealType vp1 = (v+1)/2;
|
||||
RealType vd2 = v/2;
|
||||
|
||||
return vp1*(digamma(vp1) - digamma(vd2)) + log(sqrt(v)*beta(vd2, RealType(1)/RealType(2)));
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
|
||||
@@ -184,6 +184,15 @@ namespace boost{ namespace math
|
||||
|
||||
typedef triangular_distribution<double> triangular;
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
triangular_distribution(RealType)->triangular_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
template <class RealType>
|
||||
triangular_distribution(RealType,RealType)->triangular_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
template <class RealType>
|
||||
triangular_distribution(RealType,RealType,RealType)->triangular_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
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.
|
||||
@@ -517,6 +526,13 @@ namespace boost{ namespace math
|
||||
// Assuming mathworld really means kurtosis excess? Wikipedia now corrected to match this.
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType entropy(const triangular_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
using std::log;
|
||||
return constants::half<RealType>() + log((dist.upper() - dist.lower())/2);
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
|
||||
@@ -140,6 +140,13 @@ namespace boost{ namespace math
|
||||
|
||||
typedef uniform_distribution<double> uniform;
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
uniform_distribution(RealType)->uniform_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
template <class RealType>
|
||||
uniform_distribution(RealType,RealType)->uniform_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
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.
|
||||
@@ -355,7 +362,7 @@ namespace boost{ namespace math
|
||||
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()))
|
||||
if(false == detail::check_uniform("boost::math::kurtosis_excess(const uniform_distribution<%1%>&)", lower, upper, &result, Policy()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
@@ -368,6 +375,13 @@ namespace boost{ namespace math
|
||||
return kurtosis_excess(dist) + 3;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType entropy(const uniform_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
using std::log;
|
||||
return log(dist.upper() - dist.lower());
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
|
||||
@@ -70,10 +70,10 @@ template <class RealType = double, class Policy = policies::policy<> >
|
||||
class weibull_distribution
|
||||
{
|
||||
public:
|
||||
typedef RealType value_type;
|
||||
typedef Policy policy_type;
|
||||
using value_type = RealType;
|
||||
using policy_type = Policy;
|
||||
|
||||
weibull_distribution(RealType l_shape, RealType l_scale = 1)
|
||||
explicit weibull_distribution(RealType l_shape, RealType l_scale = 1)
|
||||
: m_shape(l_shape), m_scale(l_scale)
|
||||
{
|
||||
RealType result;
|
||||
@@ -97,17 +97,24 @@ private:
|
||||
RealType m_scale; // distribution scale
|
||||
};
|
||||
|
||||
typedef weibull_distribution<double> weibull;
|
||||
using weibull = weibull_distribution<double>;
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
weibull_distribution(RealType)->weibull_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
template <class RealType>
|
||||
weibull_distribution(RealType,RealType)->weibull_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline const std::pair<RealType, RealType> range(const weibull_distribution<RealType, Policy>& /*dist*/)
|
||||
inline 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*/)
|
||||
inline 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;
|
||||
@@ -150,6 +157,40 @@ inline RealType pdf(const weibull_distribution<RealType, Policy>& dist, const Re
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType logpdf(const weibull_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::logpdf(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)
|
||||
{
|
||||
if(shape == 1)
|
||||
{
|
||||
return log(1 / scale);
|
||||
}
|
||||
if(shape > 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return policies::raise_overflow_error<RealType>(function, 0, Policy());
|
||||
}
|
||||
|
||||
result = log(shape) - shape * log(scale) + log(x) * (shape - 1) - pow(x / scale, shape);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType cdf(const weibull_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
@@ -171,6 +212,27 @@ inline RealType cdf(const weibull_distribution<RealType, Policy>& dist, const Re
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType logcdf(const weibull_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::logcdf(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 = log1p(-exp(-pow(x / scale, shape)), Policy());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const weibull_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
{
|
||||
@@ -216,6 +278,27 @@ inline RealType cdf(const complemented2_type<weibull_distribution<RealType, Poli
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType logcdf(const complemented2_type<weibull_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
BOOST_MATH_STD_USING // for ADL of std functions
|
||||
|
||||
static const char* function = "boost::math::logcdf(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 = -pow(c.param / scale, shape);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType quantile(const complemented2_type<weibull_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
@@ -335,12 +418,11 @@ inline RealType skewness(const weibull_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
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));
|
||||
RealType g1 = boost::math::tgamma(1 + 1 / shape, Policy());
|
||||
RealType g2 = boost::math::tgamma(1 + 2 / shape, Policy());
|
||||
RealType g3 = boost::math::tgamma(1 + 3 / shape, Policy());
|
||||
RealType d = pow(g2 - g1 * g1, RealType(1.5));
|
||||
|
||||
result = (2 * g1 * g1 * g1 - 3 * g1 * g2 + g3) / d;
|
||||
return result;
|
||||
@@ -360,15 +442,13 @@ inline RealType kurtosis_excess(const weibull_distribution<RealType, Policy>& di
|
||||
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;
|
||||
RealType g1 = boost::math::tgamma(1 + 1 / shape, Policy());
|
||||
RealType g2 = boost::math::tgamma(1 + 2 / shape, Policy());
|
||||
RealType g3 = boost::math::tgamma(1 + 3 / shape, Policy());
|
||||
RealType g4 = boost::math::tgamma(1 + 4 / shape, Policy());
|
||||
RealType g1_2 = g1 * g1;
|
||||
RealType g1_4 = g1_2 * g1_2;
|
||||
RealType d = g2 - g1_2;
|
||||
d *= d;
|
||||
|
||||
result = -6 * g1_4 + 12 * g1_2 * g2 - 3 * g2 * g2 - 4 * g1 * g3 + g4;
|
||||
@@ -382,6 +462,15 @@ inline RealType kurtosis(const weibull_distribution<RealType, Policy>& dist)
|
||||
return kurtosis_excess(dist) + 3;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
inline RealType entropy(const weibull_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
using std::log;
|
||||
RealType k = dist.shape();
|
||||
RealType lambda = dist.scale();
|
||||
return constants::euler<RealType>()*(1-1/k) + log(lambda/k) + 1;
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
|
||||
Reference in New Issue
Block a user