Back to home page

EIC code displayed by LXR

 
 

    


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

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