brintos

brintos / llvm-project-archived public Read only

0
0
Text · 13.6 KiB · 08472f9 Raw
399 lines · plain
1//  Copyright John Maddock 2006.2//  Copyright Paul A. Bristow 2006.3//  Copyright Matt Borland 2024.4//  Use, modification and distribution are subject to the5//  Boost Software License, Version 1.0. (See accompanying file6//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)7 8// TODO deal with infinity as special better - or remove.9//10 11#ifndef BOOST_STATS_UNIFORM_HPP12#define BOOST_STATS_UNIFORM_HPP13 14// http://www.itl.nist.gov/div898/handbook/eda/section3/eda3668.htm15// http://mathworld.wolfram.com/UniformDistribution.html16// http://documents.wolfram.com/calculationcenter/v2/Functions/ListsMatrices/Statistics/UniformDistribution.html17// http://en.wikipedia.org/wiki/Uniform_distribution_%28continuous%2918 19#include <boost/math/tools/config.hpp>20#include <boost/math/tools/tuple.hpp>21#include <boost/math/tools/promotion.hpp>22#include <boost/math/distributions/fwd.hpp>23#include <boost/math/distributions/detail/common_error_handling.hpp>24#include <boost/math/distributions/complement.hpp>25 26namespace boost{ namespace math27{28  namespace detail29  {30    template <class RealType, class Policy>31    BOOST_MATH_GPU_ENABLED inline bool check_uniform_lower(32      const char* function,33      RealType lower,34      RealType* result, const Policy& pol)35    {36      if((boost::math::isfinite)(lower))37      { // any finite value is OK.38        return true;39      }40      else41      { // Not finite.42        *result = policies::raise_domain_error<RealType>(43          function,44          "Lower parameter is %1%, but must be finite!", lower, pol);45        return false;46      }47    } // bool check_uniform_lower(48 49    template <class RealType, class Policy>50    BOOST_MATH_GPU_ENABLED inline bool check_uniform_upper(51      const char* function,52      RealType upper,53      RealType* result, const Policy& pol)54    {55      if((boost::math::isfinite)(upper))56      { // Any finite value is OK.57        return true;58      }59      else60      { // Not finite.61        *result = policies::raise_domain_error<RealType>(62          function,63          "Upper parameter is %1%, but must be finite!", upper, pol);64        return false;65      }66    } // bool check_uniform_upper(67 68    template <class RealType, class Policy>69    BOOST_MATH_GPU_ENABLED inline bool check_uniform_x(70      const char* function,71      RealType const& x,72      RealType* result, const Policy& pol)73    {74      if((boost::math::isfinite)(x))75      { // Any finite value is OK76        return true;77      }78      else79      { // Not finite..80        *result = policies::raise_domain_error<RealType>(81          function,82          "x parameter is %1%, but must be finite!", x, pol);83        return false;84      }85    } // bool check_uniform_x86 87    template <class RealType, class Policy>88    BOOST_MATH_GPU_ENABLED inline bool check_uniform(89      const char* function,90      RealType lower,91      RealType upper,92      RealType* result, const Policy& pol)93    {94      if((check_uniform_lower(function, lower, result, pol) == false)95        || (check_uniform_upper(function, upper, result, pol) == false))96      {97        return false;98      }99      else if (lower >= upper) // If lower == upper then 1 / (upper-lower) = 1/0 = +infinity!100      { // upper and lower have been checked before, so must be lower >= upper.101        *result = policies::raise_domain_error<RealType>(102          function,103          "lower parameter is %1%, but must be less than upper!", lower, pol);104        return false;105      }106      else107      { // All OK,108        return true;109      }110    } // bool check_uniform(111 112  } // namespace detail113 114  template <class RealType = double, class Policy = policies::policy<> >115  class uniform_distribution116  {117  public:118    typedef RealType value_type;119    typedef Policy policy_type;120 121    BOOST_MATH_GPU_ENABLED uniform_distribution(RealType l_lower = 0, RealType l_upper = 1) // Constructor.122      : m_lower(l_lower), m_upper(l_upper) // Default is standard uniform distribution.123    {124      RealType result;125      detail::check_uniform("boost::math::uniform_distribution<%1%>::uniform_distribution", l_lower, l_upper, &result, Policy());126    }127    // Accessor functions.128    BOOST_MATH_GPU_ENABLED RealType lower()const129    {130      return m_lower;131    }132 133    BOOST_MATH_GPU_ENABLED RealType upper()const134    {135      return m_upper;136    }137  private:138    // Data members:139    RealType m_lower;  // distribution lower aka a.140    RealType m_upper;  // distribution upper aka b.141  }; // class uniform_distribution142 143  typedef uniform_distribution<double> uniform;144 145  #ifdef __cpp_deduction_guides146  template <class RealType>147  uniform_distribution(RealType)->uniform_distribution<typename boost::math::tools::promote_args<RealType>::type>;148  template <class RealType>149  uniform_distribution(RealType,RealType)->uniform_distribution<typename boost::math::tools::promote_args<RealType>::type>;150  #endif151 152  template <class RealType, class Policy>153  BOOST_MATH_GPU_ENABLED inline const boost::math::pair<RealType, RealType> range(const uniform_distribution<RealType, Policy>& /* dist */)154  { // Range of permissible values for random variable x.155     using boost::math::tools::max_value;156     return boost::math::pair<RealType, RealType>(-max_value<RealType>(), max_value<RealType>()); // - to + 'infinity'.157     // Note RealType infinity is NOT permitted, only max_value.158  }159 160  template <class RealType, class Policy>161  BOOST_MATH_GPU_ENABLED inline const boost::math::pair<RealType, RealType> support(const uniform_distribution<RealType, Policy>& dist)162  { // Range of supported values for random variable x.163     // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.164     using boost::math::tools::max_value;165     return boost::math::pair<RealType, RealType>(dist.lower(),  dist.upper());166  }167 168  template <class RealType, class Policy>169  BOOST_MATH_GPU_ENABLED inline RealType pdf(const uniform_distribution<RealType, Policy>& dist, const RealType& x)170  {171    RealType lower = dist.lower();172    RealType upper = dist.upper();173    RealType result = 0; // of checks.174    if(false == detail::check_uniform("boost::math::pdf(const uniform_distribution<%1%>&, %1%)", lower, upper, &result, Policy()))175    {176      return result;177    }178    if(false == detail::check_uniform_x("boost::math::pdf(const uniform_distribution<%1%>&, %1%)", x, &result, Policy()))179    {180      return result;181    }182 183    if((x < lower) || (x > upper) )184    {185      return 0;186    }187    else188    {189      return 1 / (upper - lower);190    }191  } // RealType pdf(const uniform_distribution<RealType, Policy>& dist, const RealType& x)192 193  template <class RealType, class Policy>194  BOOST_MATH_GPU_ENABLED inline RealType cdf(const uniform_distribution<RealType, Policy>& dist, const RealType& x)195  {196    RealType lower = dist.lower();197    RealType upper = dist.upper();198    RealType result = 0; // of checks.199    if(false == detail::check_uniform("boost::math::cdf(const uniform_distribution<%1%>&, %1%)",lower, upper, &result, Policy()))200    {201      return result;202    }203    if(false == detail::check_uniform_x("boost::math::cdf(const uniform_distribution<%1%>&, %1%)", x, &result, Policy()))204    {205      return result;206    }207    if (x < lower)208    {209      return 0;210    }211    if (x > upper)212    {213      return 1;214    }215    return (x - lower) / (upper - lower); // lower <= x <= upper216  } // RealType cdf(const uniform_distribution<RealType, Policy>& dist, const RealType& x)217 218  template <class RealType, class Policy>219  BOOST_MATH_GPU_ENABLED inline RealType quantile(const uniform_distribution<RealType, Policy>& dist, const RealType& p)220  {221    RealType lower = dist.lower();222    RealType upper = dist.upper();223    RealType result = 0; // of checks224    if(false == detail::check_uniform("boost::math::quantile(const uniform_distribution<%1%>&, %1%)",lower, upper, &result, Policy()))225    {226      return result;227    }228    if(false == detail::check_probability("boost::math::quantile(const uniform_distribution<%1%>&, %1%)", p, &result, Policy()))229    {230      return result;231    }232    if(p == 0)233    {234      return lower;235    }236    if(p == 1)237    {238      return upper;239    }240    return p * (upper - lower) + lower;241  } // RealType quantile(const uniform_distribution<RealType, Policy>& dist, const RealType& p)242 243  template <class RealType, class Policy>244  BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type<uniform_distribution<RealType, Policy>, RealType>& c)245  {246    RealType lower = c.dist.lower();247    RealType upper = c.dist.upper();248    RealType x = c.param;249    RealType result = 0; // of checks.250    if(false == detail::check_uniform("boost::math::cdf(const uniform_distribution<%1%>&, %1%)", lower, upper, &result, Policy()))251    {252      return result;253    }254    if(false == detail::check_uniform_x("boost::math::cdf(const uniform_distribution<%1%>&, %1%)", x, &result, Policy()))255    {256      return result;257    }258    if (x < lower)259    {260      return 1;261    }262    if (x > upper)263    {264      return 0;265    }266    return (upper - x) / (upper - lower);267  } // RealType cdf(const complemented2_type<uniform_distribution<RealType, Policy>, RealType>& c)268 269  template <class RealType, class Policy>270  BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type<uniform_distribution<RealType, Policy>, RealType>& c)271  {272    RealType lower = c.dist.lower();273    RealType upper = c.dist.upper();274    RealType q = c.param;275    RealType result = 0; // of checks.276    if(false == detail::check_uniform("boost::math::quantile(const uniform_distribution<%1%>&, %1%)", lower, upper, &result, Policy()))277    {278      return result;279    }280    if(false == detail::check_probability("boost::math::quantile(const uniform_distribution<%1%>&, %1%)", q, &result, Policy()))281    {282       return result;283    }284    if(q == 0)285    {286       return upper;287    }288    if(q == 1)289    {290       return lower;291    }292    return -q * (upper - lower) + upper;293  } // RealType quantile(const complemented2_type<uniform_distribution<RealType, Policy>, RealType>& c)294 295  template <class RealType, class Policy>296  BOOST_MATH_GPU_ENABLED inline RealType mean(const uniform_distribution<RealType, Policy>& dist)297  {298    RealType lower = dist.lower();299    RealType upper = dist.upper();300    RealType result = 0;  // of checks.301    if(false == detail::check_uniform("boost::math::mean(const uniform_distribution<%1%>&)", lower, upper, &result, Policy()))302    {303      return result;304    }305    return (lower + upper ) / 2;306  } // RealType mean(const uniform_distribution<RealType, Policy>& dist)307 308  template <class RealType, class Policy>309  BOOST_MATH_GPU_ENABLED inline RealType variance(const uniform_distribution<RealType, Policy>& dist)310  {311    RealType lower = dist.lower();312    RealType upper = dist.upper();313    RealType result = 0; // of checks.314    if(false == detail::check_uniform("boost::math::variance(const uniform_distribution<%1%>&)", lower, upper, &result, Policy()))315    {316      return result;317    }318    return (upper - lower) * ( upper - lower) / 12;319    // for standard uniform = 0.833333333333333333333333333333333333333333;320  } // RealType variance(const uniform_distribution<RealType, Policy>& dist)321 322  template <class RealType, class Policy>323  BOOST_MATH_GPU_ENABLED inline RealType mode(const uniform_distribution<RealType, Policy>& dist)324  {325    RealType lower = dist.lower();326    RealType upper = dist.upper();327    RealType result = 0; // of checks.328    if(false == detail::check_uniform("boost::math::mode(const uniform_distribution<%1%>&)", lower, upper, &result, Policy()))329    {330      return result;331    }332    result = lower; // Any value [lower, upper] but arbitrarily choose lower.333    return result;334  }335 336  template <class RealType, class Policy>337  BOOST_MATH_GPU_ENABLED inline RealType median(const uniform_distribution<RealType, Policy>& dist)338  {339    RealType lower = dist.lower();340    RealType upper = dist.upper();341    RealType result = 0; // of checks.342    if(false == detail::check_uniform("boost::math::median(const uniform_distribution<%1%>&)", lower, upper, &result, Policy()))343    {344      return result;345    }346    return (lower + upper) / 2; //347  }348  template <class RealType, class Policy>349  BOOST_MATH_GPU_ENABLED inline RealType skewness(const uniform_distribution<RealType, Policy>& dist)350  {351    RealType lower = dist.lower();352    RealType upper = dist.upper();353    RealType result = 0; // of checks.354    if(false == detail::check_uniform("boost::math::skewness(const uniform_distribution<%1%>&)",lower, upper, &result, Policy()))355    {356      return result;357    }358    return 0;359  } // RealType skewness(const uniform_distribution<RealType, Policy>& dist)360 361  template <class RealType, class Policy>362  BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const uniform_distribution<RealType, Policy>& dist)363  {364    RealType lower = dist.lower();365    RealType upper = dist.upper();366    RealType result = 0;  // of checks.367    if(false == detail::check_uniform("boost::math::kurtosis_excess(const uniform_distribution<%1%>&)", lower, upper, &result, Policy()))368    {369      return result;370    }371    return static_cast<RealType>(-6)/5; //  -6/5 = -1.2;372  } // RealType kurtosis_excess(const uniform_distribution<RealType, Policy>& dist)373 374  template <class RealType, class Policy>375  BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const uniform_distribution<RealType, Policy>& dist)376  {377    return kurtosis_excess(dist) + 3;378  }379 380  template <class RealType, class Policy>381  BOOST_MATH_GPU_ENABLED inline RealType entropy(const uniform_distribution<RealType, Policy>& dist)382  {383    BOOST_MATH_STD_USING384    return log(dist.upper() - dist.lower());385  }386 387} // namespace math388} // namespace boost389 390// This include must be at the end, *after* the accessors391// for this distribution have been defined, in order to392// keep compilers that support two-phase lookup happy.393#include <boost/math/distributions/detail/derived_accessors.hpp>394 395#endif // BOOST_STATS_UNIFORM_HPP396 397 398 399