brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.4 KiB · 56dc6e9 Raw
398 lines · plain
1// Copyright 2008 Gautam Sewani2// Copyright 2024 Matt Borland3// Use, modification and distribution are subject to the4// Boost Software License, Version 1.0.5// (See accompanying file LICENSE_1_0.txt6// or copy at http://www.boost.org/LICENSE_1_0.txt)7 8#ifndef BOOST_MATH_DISTRIBUTIONS_LOGISTIC9#define BOOST_MATH_DISTRIBUTIONS_LOGISTIC10 11#include <boost/math/tools/config.hpp>12#include <boost/math/tools/numeric_limits.hpp>13#include <boost/math/tools/tuple.hpp>14#include <boost/math/tools/precision.hpp>15#include <boost/math/distributions/fwd.hpp>16#include <boost/math/distributions/detail/common_error_handling.hpp>17#include <boost/math/distributions/complement.hpp>18#include <boost/math/special_functions/log1p.hpp>19#include <boost/math/constants/constants.hpp>20#include <boost/math/policies/policy.hpp>21#include <boost/math/policies/error_handling.hpp>22 23namespace boost { namespace math { 24 25    template <class RealType = double, class Policy = policies::policy<> >26    class logistic_distribution27    {28    public:29      typedef RealType value_type;30      typedef Policy policy_type;31      32      BOOST_MATH_GPU_ENABLED logistic_distribution(RealType l_location=0, RealType l_scale=1) // Constructor.33        : m_location(l_location), m_scale(l_scale) 34      {35        constexpr auto function = "boost::math::logistic_distribution<%1%>::logistic_distribution";36        37        RealType result;38        detail::check_scale(function, l_scale, &result, Policy());39        detail::check_location(function, l_location, &result, Policy());40      }41      // Accessor functions.42      BOOST_MATH_GPU_ENABLED RealType scale()const43      {44        return m_scale;45      }46      47      BOOST_MATH_GPU_ENABLED RealType location()const48      {49        return m_location;50      }51    private:52      // Data members:53      RealType m_location;  // distribution location aka mu.54      RealType m_scale;  // distribution scale aka s.55    }; // class logistic_distribution56    57    58    typedef logistic_distribution<double> logistic;59 60    #ifdef __cpp_deduction_guides61    template <class RealType>62    logistic_distribution(RealType)->logistic_distribution<typename boost::math::tools::promote_args<RealType>::type>;63    template <class RealType>64    logistic_distribution(RealType,RealType)->logistic_distribution<typename boost::math::tools::promote_args<RealType>::type>;65    #endif66 67    template <class RealType, class Policy>68    BOOST_MATH_GPU_ENABLED inline const boost::math::pair<RealType, RealType> range(const logistic_distribution<RealType, Policy>& /* dist */)69    { // Range of permissible values for random variable x.70      using boost::math::tools::max_value;71      return boost::math::pair<RealType, RealType>(72         boost::math::numeric_limits<RealType>::has_infinity ? -boost::math::numeric_limits<RealType>::infinity() : -max_value<RealType>(), 73         boost::math::numeric_limits<RealType>::has_infinity ? boost::math::numeric_limits<RealType>::infinity() : max_value<RealType>());74    }75    76    template <class RealType, class Policy>77    BOOST_MATH_GPU_ENABLED inline const boost::math::pair<RealType, RealType> support(const logistic_distribution<RealType, Policy>& /* dist */)78    { // Range of supported values for random variable x.79      // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.80      using boost::math::tools::max_value;81      return boost::math::pair<RealType, RealType>(-max_value<RealType>(), max_value<RealType>()); // - to + infinity82    }83     84    template <class RealType, class Policy>85    BOOST_MATH_GPU_ENABLED inline RealType pdf(const logistic_distribution<RealType, Policy>& dist, const RealType& x)86    {87       constexpr auto function = "boost::math::pdf(const logistic_distribution<%1%>&, %1%)";88       RealType scale = dist.scale();89       RealType location = dist.location();90       RealType result = 0;91 92       if(false == detail::check_scale(function, scale , &result, Policy()))93       {94          return result;95       }96       if(false == detail::check_location(function, location, &result, Policy()))97       {98          return result;99       }100 101       if((boost::math::isinf)(x))102       {103          return 0; // pdf + and - infinity is zero.104       }105 106       if(false == detail::check_x(function, x, &result, Policy()))107       {108          return result;109       }110 111       BOOST_MATH_STD_USING112       RealType exp_term = (location - x) / scale;113       if(fabs(exp_term) > tools::log_max_value<RealType>())114          return 0;115       exp_term = exp(exp_term);116       if((exp_term * scale > 1) && (exp_term > tools::max_value<RealType>() / (scale * exp_term)))117          return 1 / (scale * exp_term);118       return (exp_term) / (scale * (1 + exp_term) * (1 + exp_term));119    } 120    121    template <class RealType, class Policy>122    BOOST_MATH_GPU_ENABLED inline RealType cdf(const logistic_distribution<RealType, Policy>& dist, const RealType& x)123    {124       RealType scale = dist.scale();125       RealType location = dist.location();126       RealType result = 0; // of checks.127       constexpr auto function = "boost::math::cdf(const logistic_distribution<%1%>&, %1%)";128       if(false == detail::check_scale(function, scale, &result, Policy()))129       {130          return result;131       }132       if(false == detail::check_location(function, location, &result, Policy()))133       {134          return result;135       }136 137       if((boost::math::isinf)(x))138       {139          if(x < 0) return 0; // -infinity140          return 1; // + infinity141       }142 143       if(false == detail::check_x(function, x, &result, Policy()))144       {145          return result;146       }147       BOOST_MATH_STD_USING148       RealType power = (location - x) / scale;149       if(power > tools::log_max_value<RealType>())150          return 0;151       if(power < -tools::log_max_value<RealType>())152          return 1;153       return 1 / (1 + exp(power)); 154    }155 156    template <class RealType, class Policy>157    BOOST_MATH_GPU_ENABLED inline RealType logcdf(const logistic_distribution<RealType, Policy>& dist, const RealType& x)158    {159       RealType scale = dist.scale();160       RealType location = dist.location();161       RealType result = 0; // of checks.162       constexpr auto function = "boost::math::cdf(const logistic_distribution<%1%>&, %1%)";163       if(false == detail::check_scale(function, scale, &result, Policy()))164       {165          return result;166       }167       if(false == detail::check_location(function, location, &result, Policy()))168       {169          return result;170       }171 172       if((boost::math::isinf)(x))173       {174          if(x < 0) 175          {176            return 0; // -infinity177          }178          return 1; // + infinity179       }180 181       if(false == detail::check_x(function, x, &result, Policy()))182       {183          return result;184       }185       BOOST_MATH_STD_USING186       RealType power = (location - x) / scale;187       if(power > tools::log_max_value<RealType>())188       {189          return 0;190       }191       if(power < -tools::log_max_value<RealType>())192       {193          return 1;194       }195 196       return -log1p(exp(power));197    } 198    199    template <class RealType, class Policy>200    BOOST_MATH_GPU_ENABLED inline RealType quantile(const logistic_distribution<RealType, Policy>& dist, const RealType& p)201    {202       BOOST_MATH_STD_USING203       RealType location = dist.location();204       RealType scale = dist.scale();205 206       constexpr auto function = "boost::math::quantile(const logistic_distribution<%1%>&, %1%)";207 208       RealType result = 0;209       if(false == detail::check_scale(function, scale, &result, Policy()))210          return result;211       if(false == detail::check_location(function, location, &result, Policy()))212          return result;213       if(false == detail::check_probability(function, p, &result, Policy()))214          return result;215 216       if(p == 0)217       {218          return -policies::raise_overflow_error<RealType>(function,"probability argument is 0, must be >0 and <1",Policy());219       }220       if(p == 1)221       {222          return policies::raise_overflow_error<RealType>(function,"probability argument is 1, must be >0 and <1",Policy());223       }224       //Expressions to try225       //return location+scale*log(p/(1-p));226       //return location+scale*log1p((2*p-1)/(1-p));227 228       //return location - scale*log( (1-p)/p);229       //return location - scale*log1p((1-2*p)/p);230 231       //return -scale*log(1/p-1) + location;232       return location - scale * log((1 - p) / p);233     } // RealType quantile(const logistic_distribution<RealType, Policy>& dist, const RealType& p)234    235    template <class RealType, class Policy>236    BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type<logistic_distribution<RealType, Policy>, RealType>& c)237    {238       BOOST_MATH_STD_USING239       RealType location = c.dist.location();240       RealType scale = c.dist.scale();241       RealType x = c.param;242       constexpr auto function = "boost::math::cdf(const complement(logistic_distribution<%1%>&), %1%)";243 244       RealType result = 0;245       if(false == detail::check_scale(function, scale, &result, Policy()))246       {247          return result;248       }249       if(false == detail::check_location(function, location, &result, Policy()))250       {251          return result;252       }253       if((boost::math::isinf)(x))254       {255          if(x < 0) return 1; // cdf complement -infinity is unity.256          return 0; // cdf complement +infinity is zero.257       }258       if(false == detail::check_x(function, x, &result, Policy()))259       {260          return result;261       }262       RealType power = (x - location) / scale;263       if(power > tools::log_max_value<RealType>())264          return 0;265       if(power < -tools::log_max_value<RealType>())266          return 1;267       return 1 / (1 + exp(power)); 268    } 269 270    template <class RealType, class Policy>271    BOOST_MATH_GPU_ENABLED inline RealType logcdf(const complemented2_type<logistic_distribution<RealType, Policy>, RealType>& c)272    {273       BOOST_MATH_STD_USING274       RealType location = c.dist.location();275       RealType scale = c.dist.scale();276       RealType x = c.param;277       constexpr auto function = "boost::math::cdf(const complement(logistic_distribution<%1%>&), %1%)";278 279       RealType result = 0;280       if(false == detail::check_scale(function, scale, &result, Policy()))281       {282          return result;283       }284       if(false == detail::check_location(function, location, &result, Policy()))285       {286          return result;287       }288       if((boost::math::isinf)(x))289       {290          if(x < 0) return 1; // cdf complement -infinity is unity.291          return 0; // cdf complement +infinity is zero.292       }293       if(false == detail::check_x(function, x, &result, Policy()))294       {295          return result;296       }297       RealType power = (x - location) / scale;298       if(power > tools::log_max_value<RealType>())299          return 0;300       if(power < -tools::log_max_value<RealType>())301          return 1;302       303       return -log1p(exp(power));304    }  305 306    template <class RealType, class Policy>307    BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type<logistic_distribution<RealType, Policy>, RealType>& c)308    {309       BOOST_MATH_STD_USING310       RealType scale = c.dist.scale();311       RealType location = c.dist.location();312       constexpr auto function = "boost::math::quantile(const complement(logistic_distribution<%1%>&), %1%)";313       RealType result = 0;314       if(false == detail::check_scale(function, scale, &result, Policy()))315          return result;316       if(false == detail::check_location(function, location, &result, Policy()))317          return result;318       RealType q = c.param;319       if(false == detail::check_probability(function, q, &result, Policy()))320          return result;321       using boost::math::tools::max_value;322 323       if(q == 1)324       {325          return -policies::raise_overflow_error<RealType>(function,"probability argument is 1, but must be >0 and <1",Policy());326       }327       if(q == 0)328       {329          return policies::raise_overflow_error<RealType>(function,"probability argument is 0, but must be >0 and <1",Policy());330       }331       //Expressions to try 332       //return location+scale*log((1-q)/q);333       return location + scale * log((1 - q) / q);334 335       //return location-scale*log(q/(1-q));336       //return location-scale*log1p((2*q-1)/(1-q));337 338       //return location+scale*log(1/q-1);339       //return location+scale*log1p(1/q-2);340    } 341    342    template <class RealType, class Policy>343    BOOST_MATH_GPU_ENABLED inline RealType mean(const logistic_distribution<RealType, Policy>& dist)344    {345      return dist.location();346    } // RealType mean(const logistic_distribution<RealType, Policy>& dist)347    348    template <class RealType, class Policy>349    BOOST_MATH_GPU_ENABLED inline RealType variance(const logistic_distribution<RealType, Policy>& dist)350    {351      BOOST_MATH_STD_USING352      RealType scale = dist.scale();353      return boost::math::constants::pi<RealType>()*boost::math::constants::pi<RealType>()*scale*scale/3;354    } // RealType variance(const logistic_distribution<RealType, Policy>& dist)355    356    template <class RealType, class Policy>357    BOOST_MATH_GPU_ENABLED inline RealType mode(const logistic_distribution<RealType, Policy>& dist)358    {359      return dist.location();360    }361    362    template <class RealType, class Policy>363    BOOST_MATH_GPU_ENABLED inline RealType median(const logistic_distribution<RealType, Policy>& dist)364    {365      return dist.location();366    }367    template <class RealType, class Policy>368    BOOST_MATH_GPU_ENABLED inline RealType skewness(const logistic_distribution<RealType, Policy>& /*dist*/)369    {370      return 0;371    } // RealType skewness(const logistic_distribution<RealType, Policy>& dist)372    373    template <class RealType, class Policy>374    BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const logistic_distribution<RealType, Policy>& /*dist*/)375    {376      return static_cast<RealType>(6)/5; 377    } // RealType kurtosis_excess(const logistic_distribution<RealType, Policy>& dist)378 379    template <class RealType, class Policy>380    BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const logistic_distribution<RealType, Policy>& dist)381    {382      return kurtosis_excess(dist) + 3;383    } // RealType kurtosis_excess(const logistic_distribution<RealType, Policy>& dist)384 385    template <class RealType, class Policy>386    BOOST_MATH_GPU_ENABLED inline RealType entropy(const logistic_distribution<RealType, Policy>& dist)387    {388       using std::log;389       return 2 + log(dist.scale());390    }391  }}392 393 394// Must come at the end:395#include <boost/math/distributions/detail/derived_accessors.hpp>396 397#endif // BOOST_MATH_DISTRIBUTIONS_LOGISTIC398