File indexing completed on 2025-09-17 08:35:29
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_MATH_DISTRIBUTIONS_LOGISTIC
0009 #define BOOST_MATH_DISTRIBUTIONS_LOGISTIC
0010
0011 #include <boost/math/tools/config.hpp>
0012 #include <boost/math/tools/numeric_limits.hpp>
0013 #include <boost/math/tools/tuple.hpp>
0014 #include <boost/math/tools/precision.hpp>
0015 #include <boost/math/distributions/fwd.hpp>
0016 #include <boost/math/distributions/detail/common_error_handling.hpp>
0017 #include <boost/math/distributions/complement.hpp>
0018 #include <boost/math/special_functions/log1p.hpp>
0019 #include <boost/math/constants/constants.hpp>
0020 #include <boost/math/policies/policy.hpp>
0021 #include <boost/math/policies/error_handling.hpp>
0022
0023 namespace boost { namespace math {
0024
0025 template <class RealType = double, class Policy = policies::policy<> >
0026 class logistic_distribution
0027 {
0028 public:
0029 typedef RealType value_type;
0030 typedef Policy policy_type;
0031
0032 BOOST_MATH_GPU_ENABLED logistic_distribution(RealType l_location=0, RealType l_scale=1)
0033 : m_location(l_location), m_scale(l_scale)
0034 {
0035 constexpr auto function = "boost::math::logistic_distribution<%1%>::logistic_distribution";
0036
0037 RealType result;
0038 detail::check_scale(function, l_scale, &result, Policy());
0039 detail::check_location(function, l_location, &result, Policy());
0040 }
0041
0042 BOOST_MATH_GPU_ENABLED RealType scale()const
0043 {
0044 return m_scale;
0045 }
0046
0047 BOOST_MATH_GPU_ENABLED RealType location()const
0048 {
0049 return m_location;
0050 }
0051 private:
0052
0053 RealType m_location;
0054 RealType m_scale;
0055 };
0056
0057
0058 typedef logistic_distribution<double> logistic;
0059
0060 #ifdef __cpp_deduction_guides
0061 template <class RealType>
0062 logistic_distribution(RealType)->logistic_distribution<typename boost::math::tools::promote_args<RealType>::type>;
0063 template <class RealType>
0064 logistic_distribution(RealType,RealType)->logistic_distribution<typename boost::math::tools::promote_args<RealType>::type>;
0065 #endif
0066
0067 template <class RealType, class Policy>
0068 BOOST_MATH_GPU_ENABLED inline const boost::math::pair<RealType, RealType> range(const logistic_distribution<RealType, Policy>& )
0069 {
0070 using boost::math::tools::max_value;
0071 return boost::math::pair<RealType, RealType>(
0072 boost::math::numeric_limits<RealType>::has_infinity ? -boost::math::numeric_limits<RealType>::infinity() : -max_value<RealType>(),
0073 boost::math::numeric_limits<RealType>::has_infinity ? boost::math::numeric_limits<RealType>::infinity() : max_value<RealType>());
0074 }
0075
0076 template <class RealType, class Policy>
0077 BOOST_MATH_GPU_ENABLED inline const boost::math::pair<RealType, RealType> support(const logistic_distribution<RealType, Policy>& )
0078 {
0079
0080 using boost::math::tools::max_value;
0081 return boost::math::pair<RealType, RealType>(-max_value<RealType>(), max_value<RealType>());
0082 }
0083
0084 template <class RealType, class Policy>
0085 BOOST_MATH_GPU_ENABLED inline RealType pdf(const logistic_distribution<RealType, Policy>& dist, const RealType& x)
0086 {
0087 constexpr auto function = "boost::math::pdf(const logistic_distribution<%1%>&, %1%)";
0088 RealType scale = dist.scale();
0089 RealType location = dist.location();
0090 RealType result = 0;
0091
0092 if(false == detail::check_scale(function, scale , &result, Policy()))
0093 {
0094 return result;
0095 }
0096 if(false == detail::check_location(function, location, &result, Policy()))
0097 {
0098 return result;
0099 }
0100
0101 if((boost::math::isinf)(x))
0102 {
0103 return 0;
0104 }
0105
0106 if(false == detail::check_x(function, x, &result, Policy()))
0107 {
0108 return result;
0109 }
0110
0111 BOOST_MATH_STD_USING
0112 RealType exp_term = (location - x) / scale;
0113 if(fabs(exp_term) > tools::log_max_value<RealType>())
0114 return 0;
0115 exp_term = exp(exp_term);
0116 if((exp_term * scale > 1) && (exp_term > tools::max_value<RealType>() / (scale * exp_term)))
0117 return 1 / (scale * exp_term);
0118 return (exp_term) / (scale * (1 + exp_term) * (1 + exp_term));
0119 }
0120
0121 template <class RealType, class Policy>
0122 BOOST_MATH_GPU_ENABLED inline RealType cdf(const logistic_distribution<RealType, Policy>& dist, const RealType& x)
0123 {
0124 RealType scale = dist.scale();
0125 RealType location = dist.location();
0126 RealType result = 0;
0127 constexpr auto function = "boost::math::cdf(const logistic_distribution<%1%>&, %1%)";
0128 if(false == detail::check_scale(function, scale, &result, Policy()))
0129 {
0130 return result;
0131 }
0132 if(false == detail::check_location(function, location, &result, Policy()))
0133 {
0134 return result;
0135 }
0136
0137 if((boost::math::isinf)(x))
0138 {
0139 if(x < 0) return 0;
0140 return 1;
0141 }
0142
0143 if(false == detail::check_x(function, x, &result, Policy()))
0144 {
0145 return result;
0146 }
0147 BOOST_MATH_STD_USING
0148 RealType power = (location - x) / scale;
0149 if(power > tools::log_max_value<RealType>())
0150 return 0;
0151 if(power < -tools::log_max_value<RealType>())
0152 return 1;
0153 return 1 / (1 + exp(power));
0154 }
0155
0156 template <class RealType, class Policy>
0157 BOOST_MATH_GPU_ENABLED inline RealType logcdf(const logistic_distribution<RealType, Policy>& dist, const RealType& x)
0158 {
0159 RealType scale = dist.scale();
0160 RealType location = dist.location();
0161 RealType result = 0;
0162 constexpr auto function = "boost::math::cdf(const logistic_distribution<%1%>&, %1%)";
0163 if(false == detail::check_scale(function, scale, &result, Policy()))
0164 {
0165 return result;
0166 }
0167 if(false == detail::check_location(function, location, &result, Policy()))
0168 {
0169 return result;
0170 }
0171
0172 if((boost::math::isinf)(x))
0173 {
0174 if(x < 0)
0175 {
0176 return 0;
0177 }
0178 return 1;
0179 }
0180
0181 if(false == detail::check_x(function, x, &result, Policy()))
0182 {
0183 return result;
0184 }
0185 BOOST_MATH_STD_USING
0186 RealType power = (location - x) / scale;
0187 if(power > tools::log_max_value<RealType>())
0188 {
0189 return 0;
0190 }
0191 if(power < -tools::log_max_value<RealType>())
0192 {
0193 return 1;
0194 }
0195
0196 return -log1p(exp(power));
0197 }
0198
0199 template <class RealType, class Policy>
0200 BOOST_MATH_GPU_ENABLED inline RealType quantile(const logistic_distribution<RealType, Policy>& dist, const RealType& p)
0201 {
0202 BOOST_MATH_STD_USING
0203 RealType location = dist.location();
0204 RealType scale = dist.scale();
0205
0206 constexpr auto function = "boost::math::quantile(const logistic_distribution<%1%>&, %1%)";
0207
0208 RealType result = 0;
0209 if(false == detail::check_scale(function, scale, &result, Policy()))
0210 return result;
0211 if(false == detail::check_location(function, location, &result, Policy()))
0212 return result;
0213 if(false == detail::check_probability(function, p, &result, Policy()))
0214 return result;
0215
0216 if(p == 0)
0217 {
0218 return -policies::raise_overflow_error<RealType>(function,"probability argument is 0, must be >0 and <1",Policy());
0219 }
0220 if(p == 1)
0221 {
0222 return policies::raise_overflow_error<RealType>(function,"probability argument is 1, must be >0 and <1",Policy());
0223 }
0224
0225
0226
0227
0228
0229
0230
0231
0232 return location - scale * log((1 - p) / p);
0233 }
0234
0235 template <class RealType, class Policy>
0236 BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type<logistic_distribution<RealType, Policy>, RealType>& c)
0237 {
0238 BOOST_MATH_STD_USING
0239 RealType location = c.dist.location();
0240 RealType scale = c.dist.scale();
0241 RealType x = c.param;
0242 constexpr auto function = "boost::math::cdf(const complement(logistic_distribution<%1%>&), %1%)";
0243
0244 RealType result = 0;
0245 if(false == detail::check_scale(function, scale, &result, Policy()))
0246 {
0247 return result;
0248 }
0249 if(false == detail::check_location(function, location, &result, Policy()))
0250 {
0251 return result;
0252 }
0253 if((boost::math::isinf)(x))
0254 {
0255 if(x < 0) return 1;
0256 return 0;
0257 }
0258 if(false == detail::check_x(function, x, &result, Policy()))
0259 {
0260 return result;
0261 }
0262 RealType power = (x - location) / scale;
0263 if(power > tools::log_max_value<RealType>())
0264 return 0;
0265 if(power < -tools::log_max_value<RealType>())
0266 return 1;
0267 return 1 / (1 + exp(power));
0268 }
0269
0270 template <class RealType, class Policy>
0271 BOOST_MATH_GPU_ENABLED inline RealType logcdf(const complemented2_type<logistic_distribution<RealType, Policy>, RealType>& c)
0272 {
0273 BOOST_MATH_STD_USING
0274 RealType location = c.dist.location();
0275 RealType scale = c.dist.scale();
0276 RealType x = c.param;
0277 constexpr auto function = "boost::math::cdf(const complement(logistic_distribution<%1%>&), %1%)";
0278
0279 RealType result = 0;
0280 if(false == detail::check_scale(function, scale, &result, Policy()))
0281 {
0282 return result;
0283 }
0284 if(false == detail::check_location(function, location, &result, Policy()))
0285 {
0286 return result;
0287 }
0288 if((boost::math::isinf)(x))
0289 {
0290 if(x < 0) return 1;
0291 return 0;
0292 }
0293 if(false == detail::check_x(function, x, &result, Policy()))
0294 {
0295 return result;
0296 }
0297 RealType power = (x - location) / scale;
0298 if(power > tools::log_max_value<RealType>())
0299 return 0;
0300 if(power < -tools::log_max_value<RealType>())
0301 return 1;
0302
0303 return -log1p(exp(power));
0304 }
0305
0306 template <class RealType, class Policy>
0307 BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type<logistic_distribution<RealType, Policy>, RealType>& c)
0308 {
0309 BOOST_MATH_STD_USING
0310 RealType scale = c.dist.scale();
0311 RealType location = c.dist.location();
0312 constexpr auto function = "boost::math::quantile(const complement(logistic_distribution<%1%>&), %1%)";
0313 RealType result = 0;
0314 if(false == detail::check_scale(function, scale, &result, Policy()))
0315 return result;
0316 if(false == detail::check_location(function, location, &result, Policy()))
0317 return result;
0318 RealType q = c.param;
0319 if(false == detail::check_probability(function, q, &result, Policy()))
0320 return result;
0321 using boost::math::tools::max_value;
0322
0323 if(q == 1)
0324 {
0325 return -policies::raise_overflow_error<RealType>(function,"probability argument is 1, but must be >0 and <1",Policy());
0326 }
0327 if(q == 0)
0328 {
0329 return policies::raise_overflow_error<RealType>(function,"probability argument is 0, but must be >0 and <1",Policy());
0330 }
0331
0332
0333 return location + scale * log((1 - q) / q);
0334
0335
0336
0337
0338
0339
0340 }
0341
0342 template <class RealType, class Policy>
0343 BOOST_MATH_GPU_ENABLED inline RealType mean(const logistic_distribution<RealType, Policy>& dist)
0344 {
0345 return dist.location();
0346 }
0347
0348 template <class RealType, class Policy>
0349 BOOST_MATH_GPU_ENABLED inline RealType variance(const logistic_distribution<RealType, Policy>& dist)
0350 {
0351 BOOST_MATH_STD_USING
0352 RealType scale = dist.scale();
0353 return boost::math::constants::pi<RealType>()*boost::math::constants::pi<RealType>()*scale*scale/3;
0354 }
0355
0356 template <class RealType, class Policy>
0357 BOOST_MATH_GPU_ENABLED inline RealType mode(const logistic_distribution<RealType, Policy>& dist)
0358 {
0359 return dist.location();
0360 }
0361
0362 template <class RealType, class Policy>
0363 BOOST_MATH_GPU_ENABLED inline RealType median(const logistic_distribution<RealType, Policy>& dist)
0364 {
0365 return dist.location();
0366 }
0367 template <class RealType, class Policy>
0368 BOOST_MATH_GPU_ENABLED inline RealType skewness(const logistic_distribution<RealType, Policy>& )
0369 {
0370 return 0;
0371 }
0372
0373 template <class RealType, class Policy>
0374 BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const logistic_distribution<RealType, Policy>& )
0375 {
0376 return static_cast<RealType>(6)/5;
0377 }
0378
0379 template <class RealType, class Policy>
0380 BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const logistic_distribution<RealType, Policy>& dist)
0381 {
0382 return kurtosis_excess(dist) + 3;
0383 }
0384
0385 template <class RealType, class Policy>
0386 BOOST_MATH_GPU_ENABLED inline RealType entropy(const logistic_distribution<RealType, Policy>& dist)
0387 {
0388 using std::log;
0389 return 2 + log(dist.scale());
0390 }
0391 }}
0392
0393
0394
0395 #include <boost/math/distributions/detail/derived_accessors.hpp>
0396
0397 #endif