Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-16 08:38:14

0001 //  Copyright John Maddock 2006.
0002 //  Copyright Paul A. Bristow 2006.
0003 //  Copyright Matt Borland 2024.
0004 //  Use, modification and distribution are subject to the
0005 //  Boost Software License, Version 1.0. (See accompanying file
0006 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 
0008 // TODO deal with infinity as special better - or remove.
0009 //
0010 
0011 #ifndef BOOST_STATS_UNIFORM_HPP
0012 #define BOOST_STATS_UNIFORM_HPP
0013 
0014 // http://www.itl.nist.gov/div898/handbook/eda/section3/eda3668.htm
0015 // http://mathworld.wolfram.com/UniformDistribution.html
0016 // http://documents.wolfram.com/calculationcenter/v2/Functions/ListsMatrices/Statistics/UniformDistribution.html
0017 // http://en.wikipedia.org/wiki/Uniform_distribution_%28continuous%29
0018 
0019 #include <boost/math/tools/config.hpp>
0020 #include <boost/math/tools/tuple.hpp>
0021 #include <boost/math/distributions/fwd.hpp>
0022 #include <boost/math/distributions/detail/common_error_handling.hpp>
0023 #include <boost/math/distributions/complement.hpp>
0024 
0025 namespace boost{ namespace math
0026 {
0027   namespace detail
0028   {
0029     template <class RealType, class Policy>
0030     BOOST_MATH_GPU_ENABLED inline bool check_uniform_lower(
0031       const char* function,
0032       RealType lower,
0033       RealType* result, const Policy& pol)
0034     {
0035       if((boost::math::isfinite)(lower))
0036       { // any finite value is OK.
0037         return true;
0038       }
0039       else
0040       { // Not finite.
0041         *result = policies::raise_domain_error<RealType>(
0042           function,
0043           "Lower parameter is %1%, but must be finite!", lower, pol);
0044         return false;
0045       }
0046     } // bool check_uniform_lower(
0047 
0048     template <class RealType, class Policy>
0049     BOOST_MATH_GPU_ENABLED inline bool check_uniform_upper(
0050       const char* function,
0051       RealType upper,
0052       RealType* result, const Policy& pol)
0053     {
0054       if((boost::math::isfinite)(upper))
0055       { // Any finite value is OK.
0056         return true;
0057       }
0058       else
0059       { // Not finite.
0060         *result = policies::raise_domain_error<RealType>(
0061           function,
0062           "Upper parameter is %1%, but must be finite!", upper, pol);
0063         return false;
0064       }
0065     } // bool check_uniform_upper(
0066 
0067     template <class RealType, class Policy>
0068     BOOST_MATH_GPU_ENABLED inline bool check_uniform_x(
0069       const char* function,
0070       RealType const& x,
0071       RealType* result, const Policy& pol)
0072     {
0073       if((boost::math::isfinite)(x))
0074       { // Any finite value is OK
0075         return true;
0076       }
0077       else
0078       { // Not finite..
0079         *result = policies::raise_domain_error<RealType>(
0080           function,
0081           "x parameter is %1%, but must be finite!", x, pol);
0082         return false;
0083       }
0084     } // bool check_uniform_x
0085 
0086     template <class RealType, class Policy>
0087     BOOST_MATH_GPU_ENABLED inline bool check_uniform(
0088       const char* function,
0089       RealType lower,
0090       RealType upper,
0091       RealType* result, const Policy& pol)
0092     {
0093       if((check_uniform_lower(function, lower, result, pol) == false)
0094         || (check_uniform_upper(function, upper, result, pol) == false))
0095       {
0096         return false;
0097       }
0098       else if (lower >= upper) // If lower == upper then 1 / (upper-lower) = 1/0 = +infinity!
0099       { // upper and lower have been checked before, so must be lower >= upper.
0100         *result = policies::raise_domain_error<RealType>(
0101           function,
0102           "lower parameter is %1%, but must be less than upper!", lower, pol);
0103         return false;
0104       }
0105       else
0106       { // All OK,
0107         return true;
0108       }
0109     } // bool check_uniform(
0110 
0111   } // namespace detail
0112 
0113   template <class RealType = double, class Policy = policies::policy<> >
0114   class uniform_distribution
0115   {
0116   public:
0117     typedef RealType value_type;
0118     typedef Policy policy_type;
0119 
0120     BOOST_MATH_GPU_ENABLED uniform_distribution(RealType l_lower = 0, RealType l_upper = 1) // Constructor.
0121       : m_lower(l_lower), m_upper(l_upper) // Default is standard uniform distribution.
0122     {
0123       RealType result;
0124       detail::check_uniform("boost::math::uniform_distribution<%1%>::uniform_distribution", l_lower, l_upper, &result, Policy());
0125     }
0126     // Accessor functions.
0127     BOOST_MATH_GPU_ENABLED RealType lower()const
0128     {
0129       return m_lower;
0130     }
0131 
0132     BOOST_MATH_GPU_ENABLED RealType upper()const
0133     {
0134       return m_upper;
0135     }
0136   private:
0137     // Data members:
0138     RealType m_lower;  // distribution lower aka a.
0139     RealType m_upper;  // distribution upper aka b.
0140   }; // class uniform_distribution
0141 
0142   typedef uniform_distribution<double> uniform;
0143 
0144   #ifdef __cpp_deduction_guides
0145   template <class RealType>
0146   uniform_distribution(RealType)->uniform_distribution<typename boost::math::tools::promote_args<RealType>::type>;
0147   template <class RealType>
0148   uniform_distribution(RealType,RealType)->uniform_distribution<typename boost::math::tools::promote_args<RealType>::type>;
0149   #endif
0150 
0151   template <class RealType, class Policy>
0152   BOOST_MATH_GPU_ENABLED inline const boost::math::pair<RealType, RealType> range(const uniform_distribution<RealType, Policy>& /* dist */)
0153   { // Range of permissible values for random variable x.
0154      using boost::math::tools::max_value;
0155      return boost::math::pair<RealType, RealType>(-max_value<RealType>(), max_value<RealType>()); // - to + 'infinity'.
0156      // Note RealType infinity is NOT permitted, only max_value.
0157   }
0158 
0159   template <class RealType, class Policy>
0160   BOOST_MATH_GPU_ENABLED inline const boost::math::pair<RealType, RealType> support(const uniform_distribution<RealType, Policy>& dist)
0161   { // Range of supported values for random variable x.
0162      // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
0163      using boost::math::tools::max_value;
0164      return boost::math::pair<RealType, RealType>(dist.lower(),  dist.upper());
0165   }
0166 
0167   template <class RealType, class Policy>
0168   BOOST_MATH_GPU_ENABLED inline RealType pdf(const uniform_distribution<RealType, Policy>& dist, const RealType& x)
0169   {
0170     RealType lower = dist.lower();
0171     RealType upper = dist.upper();
0172     RealType result = 0; // of checks.
0173     if(false == detail::check_uniform("boost::math::pdf(const uniform_distribution<%1%>&, %1%)", lower, upper, &result, Policy()))
0174     {
0175       return result;
0176     }
0177     if(false == detail::check_uniform_x("boost::math::pdf(const uniform_distribution<%1%>&, %1%)", x, &result, Policy()))
0178     {
0179       return result;
0180     }
0181 
0182     if((x < lower) || (x > upper) )
0183     {
0184       return 0;
0185     }
0186     else
0187     {
0188       return 1 / (upper - lower);
0189     }
0190   } // RealType pdf(const uniform_distribution<RealType, Policy>& dist, const RealType& x)
0191 
0192   template <class RealType, class Policy>
0193   BOOST_MATH_GPU_ENABLED inline RealType cdf(const uniform_distribution<RealType, Policy>& dist, const RealType& x)
0194   {
0195     RealType lower = dist.lower();
0196     RealType upper = dist.upper();
0197     RealType result = 0; // of checks.
0198     if(false == detail::check_uniform("boost::math::cdf(const uniform_distribution<%1%>&, %1%)",lower, upper, &result, Policy()))
0199     {
0200       return result;
0201     }
0202     if(false == detail::check_uniform_x("boost::math::cdf(const uniform_distribution<%1%>&, %1%)", x, &result, Policy()))
0203     {
0204       return result;
0205     }
0206     if (x < lower)
0207     {
0208       return 0;
0209     }
0210     if (x > upper)
0211     {
0212       return 1;
0213     }
0214     return (x - lower) / (upper - lower); // lower <= x <= upper
0215   } // RealType cdf(const uniform_distribution<RealType, Policy>& dist, const RealType& x)
0216 
0217   template <class RealType, class Policy>
0218   BOOST_MATH_GPU_ENABLED inline RealType quantile(const uniform_distribution<RealType, Policy>& dist, const RealType& p)
0219   {
0220     RealType lower = dist.lower();
0221     RealType upper = dist.upper();
0222     RealType result = 0; // of checks
0223     if(false == detail::check_uniform("boost::math::quantile(const uniform_distribution<%1%>&, %1%)",lower, upper, &result, Policy()))
0224     {
0225       return result;
0226     }
0227     if(false == detail::check_probability("boost::math::quantile(const uniform_distribution<%1%>&, %1%)", p, &result, Policy()))
0228     {
0229       return result;
0230     }
0231     if(p == 0)
0232     {
0233       return lower;
0234     }
0235     if(p == 1)
0236     {
0237       return upper;
0238     }
0239     return p * (upper - lower) + lower;
0240   } // RealType quantile(const uniform_distribution<RealType, Policy>& dist, const RealType& p)
0241 
0242   template <class RealType, class Policy>
0243   BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type<uniform_distribution<RealType, Policy>, RealType>& c)
0244   {
0245     RealType lower = c.dist.lower();
0246     RealType upper = c.dist.upper();
0247     RealType x = c.param;
0248     RealType result = 0; // of checks.
0249     if(false == detail::check_uniform("boost::math::cdf(const uniform_distribution<%1%>&, %1%)", lower, upper, &result, Policy()))
0250     {
0251       return result;
0252     }
0253     if(false == detail::check_uniform_x("boost::math::cdf(const uniform_distribution<%1%>&, %1%)", x, &result, Policy()))
0254     {
0255       return result;
0256     }
0257     if (x < lower)
0258     {
0259       return 1;
0260     }
0261     if (x > upper)
0262     {
0263       return 0;
0264     }
0265     return (upper - x) / (upper - lower);
0266   } // RealType cdf(const complemented2_type<uniform_distribution<RealType, Policy>, RealType>& c)
0267 
0268   template <class RealType, class Policy>
0269   BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type<uniform_distribution<RealType, Policy>, RealType>& c)
0270   {
0271     RealType lower = c.dist.lower();
0272     RealType upper = c.dist.upper();
0273     RealType q = c.param;
0274     RealType result = 0; // of checks.
0275     if(false == detail::check_uniform("boost::math::quantile(const uniform_distribution<%1%>&, %1%)", lower, upper, &result, Policy()))
0276     {
0277       return result;
0278     }
0279     if(false == detail::check_probability("boost::math::quantile(const uniform_distribution<%1%>&, %1%)", q, &result, Policy()))
0280     {
0281        return result;
0282     }
0283     if(q == 0)
0284     {
0285        return upper;
0286     }
0287     if(q == 1)
0288     {
0289        return lower;
0290     }
0291     return -q * (upper - lower) + upper;
0292   } // RealType quantile(const complemented2_type<uniform_distribution<RealType, Policy>, RealType>& c)
0293 
0294   template <class RealType, class Policy>
0295   BOOST_MATH_GPU_ENABLED inline RealType mean(const uniform_distribution<RealType, Policy>& dist)
0296   {
0297     RealType lower = dist.lower();
0298     RealType upper = dist.upper();
0299     RealType result = 0;  // of checks.
0300     if(false == detail::check_uniform("boost::math::mean(const uniform_distribution<%1%>&)", lower, upper, &result, Policy()))
0301     {
0302       return result;
0303     }
0304     return (lower + upper ) / 2;
0305   } // RealType mean(const uniform_distribution<RealType, Policy>& dist)
0306 
0307   template <class RealType, class Policy>
0308   BOOST_MATH_GPU_ENABLED inline RealType variance(const uniform_distribution<RealType, Policy>& dist)
0309   {
0310     RealType lower = dist.lower();
0311     RealType upper = dist.upper();
0312     RealType result = 0; // of checks.
0313     if(false == detail::check_uniform("boost::math::variance(const uniform_distribution<%1%>&)", lower, upper, &result, Policy()))
0314     {
0315       return result;
0316     }
0317     return (upper - lower) * ( upper - lower) / 12;
0318     // for standard uniform = 0.833333333333333333333333333333333333333333;
0319   } // RealType variance(const uniform_distribution<RealType, Policy>& dist)
0320 
0321   template <class RealType, class Policy>
0322   BOOST_MATH_GPU_ENABLED inline RealType mode(const uniform_distribution<RealType, Policy>& dist)
0323   {
0324     RealType lower = dist.lower();
0325     RealType upper = dist.upper();
0326     RealType result = 0; // of checks.
0327     if(false == detail::check_uniform("boost::math::mode(const uniform_distribution<%1%>&)", lower, upper, &result, Policy()))
0328     {
0329       return result;
0330     }
0331     result = lower; // Any value [lower, upper] but arbitrarily choose lower.
0332     return result;
0333   }
0334 
0335   template <class RealType, class Policy>
0336   BOOST_MATH_GPU_ENABLED inline RealType median(const uniform_distribution<RealType, Policy>& dist)
0337   {
0338     RealType lower = dist.lower();
0339     RealType upper = dist.upper();
0340     RealType result = 0; // of checks.
0341     if(false == detail::check_uniform("boost::math::median(const uniform_distribution<%1%>&)", lower, upper, &result, Policy()))
0342     {
0343       return result;
0344     }
0345     return (lower + upper) / 2; //
0346   }
0347   template <class RealType, class Policy>
0348   BOOST_MATH_GPU_ENABLED inline RealType skewness(const uniform_distribution<RealType, Policy>& dist)
0349   {
0350     RealType lower = dist.lower();
0351     RealType upper = dist.upper();
0352     RealType result = 0; // of checks.
0353     if(false == detail::check_uniform("boost::math::skewness(const uniform_distribution<%1%>&)",lower, upper, &result, Policy()))
0354     {
0355       return result;
0356     }
0357     return 0;
0358   } // RealType skewness(const uniform_distribution<RealType, Policy>& dist)
0359 
0360   template <class RealType, class Policy>
0361   BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const uniform_distribution<RealType, Policy>& dist)
0362   {
0363     RealType lower = dist.lower();
0364     RealType upper = dist.upper();
0365     RealType result = 0;  // of checks.
0366     if(false == detail::check_uniform("boost::math::kurtosis_excess(const uniform_distribution<%1%>&)", lower, upper, &result, Policy()))
0367     {
0368       return result;
0369     }
0370     return static_cast<RealType>(-6)/5; //  -6/5 = -1.2;
0371   } // RealType kurtosis_excess(const uniform_distribution<RealType, Policy>& dist)
0372 
0373   template <class RealType, class Policy>
0374   BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const uniform_distribution<RealType, Policy>& dist)
0375   {
0376     return kurtosis_excess(dist) + 3;
0377   }
0378 
0379   template <class RealType, class Policy>
0380   BOOST_MATH_GPU_ENABLED inline RealType entropy(const uniform_distribution<RealType, Policy>& dist)
0381   {
0382     BOOST_MATH_STD_USING
0383     return log(dist.upper() - dist.lower());
0384   }
0385 
0386 } // namespace math
0387 } // namespace boost
0388 
0389 // This include must be at the end, *after* the accessors
0390 // for this distribution have been defined, in order to
0391 // keep compilers that support two-phase lookup happy.
0392 #include <boost/math/distributions/detail/derived_accessors.hpp>
0393 
0394 #endif // BOOST_STATS_UNIFORM_HPP
0395 
0396 
0397