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