Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:39:38

0001 //  Copyright John Maddock 2006.
0002 //  Use, modification and distribution are subject to the
0003 //  Boost Software License, Version 1.0. (See accompanying file
0004 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 #ifndef BOOST_STATS_DERIVED_HPP
0007 #define BOOST_STATS_DERIVED_HPP
0008 
0009 // This file implements various common properties of distributions
0010 // that can be implemented in terms of other properties:
0011 // variance OR standard deviation (see note below),
0012 // hazard, cumulative hazard (chf), coefficient_of_variation.
0013 //
0014 // Note that while both variance and standard_deviation are provided
0015 // here, each distribution MUST SPECIALIZE AT LEAST ONE OF THESE
0016 // otherwise these two versions will just call each other over and over
0017 // until stack space runs out ...
0018 
0019 // Of course there may be more efficient means of implementing these
0020 // that are specific to a particular distribution, but these generic
0021 // versions give these properties "for free" with most distributions.
0022 //
0023 // In order to make use of this header, it must be included AT THE END
0024 // of the distribution header, AFTER the distribution and its core
0025 // property accessors have been defined: this is so that compilers
0026 // that implement 2-phase lookup and early-type-checking of templates
0027 // can find the definitions referred to herein.
0028 //
0029 
0030 #include <cmath>
0031 #include <boost/math/tools/assert.hpp>
0032 
0033 #ifdef _MSC_VER
0034 # pragma warning(push)
0035 # pragma warning(disable: 4723) // potential divide by 0
0036 // Suppressing spurious warning in coefficient_of_variation
0037 #endif
0038 
0039 namespace boost{ namespace math{
0040 
0041 template <class Distribution>
0042 typename Distribution::value_type variance(const Distribution& dist);
0043 
0044 template <class Distribution>
0045 inline typename Distribution::value_type standard_deviation(const Distribution& dist)
0046 {
0047    BOOST_MATH_STD_USING  // ADL of sqrt.
0048    return sqrt(variance(dist));
0049 }
0050 
0051 template <class Distribution>
0052 inline typename Distribution::value_type variance(const Distribution& dist)
0053 {
0054    typename Distribution::value_type result = standard_deviation(dist);
0055    return result * result;
0056 }
0057 
0058 template <class Distribution, class RealType>
0059 inline typename Distribution::value_type hazard(const Distribution& dist, const RealType& x)
0060 { // hazard function
0061   // http://www.itl.nist.gov/div898/handbook/eda/section3/eda362.htm#HAZ
0062    typedef typename Distribution::value_type value_type;
0063    typedef typename Distribution::policy_type policy_type;
0064    value_type p = cdf(complement(dist, x));
0065    value_type d = pdf(dist, x);
0066    if(d > p * tools::max_value<value_type>())
0067       return policies::raise_overflow_error<value_type>(
0068       "boost::math::hazard(const Distribution&, %1%)", nullptr, policy_type());
0069    if(d == 0)
0070    {
0071       // This protects against 0/0, but is it the right thing to do?
0072       return 0;
0073    }
0074    return d / p;
0075 }
0076 
0077 template <class Distribution, class RealType>
0078 inline typename Distribution::value_type chf(const Distribution& dist, const RealType& x)
0079 { // cumulative hazard function.
0080   // http://www.itl.nist.gov/div898/handbook/eda/section3/eda362.htm#HAZ
0081    BOOST_MATH_STD_USING
0082    return -log(cdf(complement(dist, x)));
0083 }
0084 
0085 template <class Distribution>
0086 inline typename Distribution::value_type coefficient_of_variation(const Distribution& dist)
0087 {
0088    typedef typename Distribution::value_type value_type;
0089    typedef typename Distribution::policy_type policy_type;
0090 
0091    using std::abs;
0092 
0093    value_type m = mean(dist);
0094    value_type d = standard_deviation(dist);
0095    if((abs(m) < 1) && (d > abs(m) * tools::max_value<value_type>()))
0096    { // Checks too that m is not zero,
0097       return policies::raise_overflow_error<value_type>("boost::math::coefficient_of_variation(const Distribution&, %1%)", nullptr, policy_type());
0098    }
0099    return d / m; // so MSVC warning on zerodivide is spurious, and suppressed.
0100 }
0101 //
0102 // Next follow overloads of some of the standard accessors with mixed
0103 // argument types. We just use a typecast to forward on to the "real"
0104 // implementation with all arguments of the same type:
0105 //
0106 template <class Distribution, class RealType>
0107 inline typename Distribution::value_type pdf(const Distribution& dist, const RealType& x)
0108 {
0109    typedef typename Distribution::value_type value_type;
0110    return pdf(dist, static_cast<value_type>(x));
0111 }
0112 template <class Distribution, class RealType>
0113 inline typename Distribution::value_type logpdf(const Distribution& dist, const RealType& x)
0114 {
0115    using std::log;
0116    typedef typename Distribution::value_type value_type;
0117    return log(pdf(dist, static_cast<value_type>(x)));
0118 }
0119 template <class Distribution, class RealType>
0120 inline typename Distribution::value_type cdf(const Distribution& dist, const RealType& x)
0121 {
0122    typedef typename Distribution::value_type value_type;
0123    return cdf(dist, static_cast<value_type>(x));
0124 }
0125 template <class Distribution, class Realtype>
0126 inline typename Distribution::value_type logcdf(const Distribution& dist, const Realtype& x)
0127 {
0128    using std::log;
0129    using value_type = typename Distribution::value_type;
0130    return log(cdf(dist, static_cast<value_type>(x)));
0131 }
0132 template <class Distribution, class RealType>
0133 inline typename Distribution::value_type quantile(const Distribution& dist, const RealType& x)
0134 {
0135    typedef typename Distribution::value_type value_type;
0136    return quantile(dist, static_cast<value_type>(x));
0137 }
0138 /*
0139 template <class Distribution, class RealType>
0140 inline typename Distribution::value_type chf(const Distribution& dist, const RealType& x)
0141 {
0142    typedef typename Distribution::value_type value_type;
0143    return chf(dist, static_cast<value_type>(x));
0144 }
0145 */
0146 template <class Distribution, class RealType>
0147 inline typename Distribution::value_type cdf(const complemented2_type<Distribution, RealType>& c)
0148 {
0149    typedef typename Distribution::value_type value_type;
0150    return cdf(complement(c.dist, static_cast<value_type>(c.param)));
0151 }
0152 
0153 template <class Distribution, class RealType>
0154 inline typename Distribution::value_type logcdf(const complemented2_type<Distribution, RealType>& c)
0155 {
0156    using std::log;
0157    typedef typename Distribution::value_type value_type;
0158    return log(cdf(complement(c.dist, static_cast<value_type>(c.param))));
0159 }
0160 
0161 template <class Distribution, class RealType>
0162 inline typename Distribution::value_type quantile(const complemented2_type<Distribution, RealType>& c)
0163 {
0164    typedef typename Distribution::value_type value_type;
0165    return quantile(complement(c.dist, static_cast<value_type>(c.param)));
0166 }
0167 
0168 template <class Dist>
0169 inline typename Dist::value_type median(const Dist& d)
0170 { // median - default definition for those distributions for which a
0171   // simple closed form is not known,
0172   // and for which a domain_error and/or NaN generating function is NOT defined.
0173   typedef typename Dist::value_type value_type;
0174   return quantile(d, static_cast<value_type>(0.5f));
0175 }
0176 
0177 } // namespace math
0178 } // namespace boost
0179 
0180 
0181 #ifdef _MSC_VER
0182 # pragma warning(pop)
0183 #endif
0184 
0185 #endif // BOOST_STATS_DERIVED_HPP