annotate DEPENDENCIES/generic/include/boost/math/distributions/cauchy.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 // Copyright John Maddock 2006, 2007.
Chris@16 2 // Copyright Paul A. Bristow 2007.
Chris@16 3
Chris@16 4 // Use, modification and distribution are subject to the
Chris@16 5 // Boost Software License, Version 1.0. (See accompanying file
Chris@16 6 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 7
Chris@16 8 #ifndef BOOST_STATS_CAUCHY_HPP
Chris@16 9 #define BOOST_STATS_CAUCHY_HPP
Chris@16 10
Chris@16 11 #ifdef _MSC_VER
Chris@16 12 #pragma warning(push)
Chris@16 13 #pragma warning(disable : 4127) // conditional expression is constant
Chris@16 14 #endif
Chris@16 15
Chris@16 16 #include <boost/math/distributions/fwd.hpp>
Chris@16 17 #include <boost/math/constants/constants.hpp>
Chris@16 18 #include <boost/math/distributions/complement.hpp>
Chris@16 19 #include <boost/math/distributions/detail/common_error_handling.hpp>
Chris@16 20 #include <boost/config/no_tr1/cmath.hpp>
Chris@16 21
Chris@16 22 #include <utility>
Chris@16 23
Chris@16 24 namespace boost{ namespace math
Chris@16 25 {
Chris@16 26
Chris@16 27 template <class RealType, class Policy>
Chris@16 28 class cauchy_distribution;
Chris@16 29
Chris@16 30 namespace detail
Chris@16 31 {
Chris@16 32
Chris@16 33 template <class RealType, class Policy>
Chris@16 34 RealType cdf_imp(const cauchy_distribution<RealType, Policy>& dist, const RealType& x, bool complement)
Chris@16 35 {
Chris@16 36 //
Chris@16 37 // This calculates the cdf of the Cauchy distribution and/or its complement.
Chris@16 38 //
Chris@16 39 // The usual formula for the Cauchy cdf is:
Chris@16 40 //
Chris@16 41 // cdf = 0.5 + atan(x)/pi
Chris@16 42 //
Chris@16 43 // But that suffers from cancellation error as x -> -INF.
Chris@16 44 //
Chris@16 45 // Recall that for x < 0:
Chris@16 46 //
Chris@16 47 // atan(x) = -pi/2 - atan(1/x)
Chris@16 48 //
Chris@16 49 // Substituting into the above we get:
Chris@16 50 //
Chris@16 51 // CDF = -atan(1/x) ; x < 0
Chris@16 52 //
Chris@16 53 // So the proceedure is to calculate the cdf for -fabs(x)
Chris@16 54 // using the above formula, and then subtract from 1 when required
Chris@16 55 // to get the result.
Chris@16 56 //
Chris@16 57 BOOST_MATH_STD_USING // for ADL of std functions
Chris@16 58 static const char* function = "boost::math::cdf(cauchy<%1%>&, %1%)";
Chris@16 59 RealType result = 0;
Chris@16 60 RealType location = dist.location();
Chris@16 61 RealType scale = dist.scale();
Chris@16 62 if(false == detail::check_location(function, location, &result, Policy()))
Chris@16 63 {
Chris@16 64 return result;
Chris@16 65 }
Chris@16 66 if(false == detail::check_scale(function, scale, &result, Policy()))
Chris@16 67 {
Chris@16 68 return result;
Chris@16 69 }
Chris@16 70 if(std::numeric_limits<RealType>::has_infinity && x == std::numeric_limits<RealType>::infinity())
Chris@16 71 { // cdf +infinity is unity.
Chris@16 72 return static_cast<RealType>((complement) ? 0 : 1);
Chris@16 73 }
Chris@16 74 if(std::numeric_limits<RealType>::has_infinity && x == -std::numeric_limits<RealType>::infinity())
Chris@16 75 { // cdf -infinity is zero.
Chris@16 76 return static_cast<RealType>((complement) ? 1 : 0);
Chris@16 77 }
Chris@16 78 if(false == detail::check_x(function, x, &result, Policy()))
Chris@16 79 { // Catches x == NaN
Chris@16 80 return result;
Chris@16 81 }
Chris@16 82 RealType mx = -fabs((x - location) / scale); // scale is > 0
Chris@16 83 if(mx > -tools::epsilon<RealType>() / 8)
Chris@16 84 { // special case first: x extremely close to location.
Chris@16 85 return 0.5;
Chris@16 86 }
Chris@16 87 result = -atan(1 / mx) / constants::pi<RealType>();
Chris@16 88 return (((x > location) != complement) ? 1 - result : result);
Chris@16 89 } // cdf
Chris@16 90
Chris@16 91 template <class RealType, class Policy>
Chris@16 92 RealType quantile_imp(
Chris@16 93 const cauchy_distribution<RealType, Policy>& dist,
Chris@16 94 const RealType& p,
Chris@16 95 bool complement)
Chris@16 96 {
Chris@16 97 // This routine implements the quantile for the Cauchy distribution,
Chris@16 98 // the value p may be the probability, or its complement if complement=true.
Chris@16 99 //
Chris@16 100 // The procedure first performs argument reduction on p to avoid error
Chris@16 101 // when calculating the tangent, then calulates the distance from the
Chris@16 102 // mid-point of the distribution. This is either added or subtracted
Chris@16 103 // from the location parameter depending on whether `complement` is true.
Chris@16 104 //
Chris@16 105 static const char* function = "boost::math::quantile(cauchy<%1%>&, %1%)";
Chris@16 106 BOOST_MATH_STD_USING // for ADL of std functions
Chris@16 107
Chris@16 108 RealType result = 0;
Chris@16 109 RealType location = dist.location();
Chris@16 110 RealType scale = dist.scale();
Chris@16 111 if(false == detail::check_location(function, location, &result, Policy()))
Chris@16 112 {
Chris@16 113 return result;
Chris@16 114 }
Chris@16 115 if(false == detail::check_scale(function, scale, &result, Policy()))
Chris@16 116 {
Chris@16 117 return result;
Chris@16 118 }
Chris@16 119 if(false == detail::check_probability(function, p, &result, Policy()))
Chris@16 120 {
Chris@16 121 return result;
Chris@16 122 }
Chris@16 123 // Special cases:
Chris@16 124 if(p == 1)
Chris@16 125 {
Chris@16 126 return (complement ? -1 : 1) * policies::raise_overflow_error<RealType>(function, 0, Policy());
Chris@16 127 }
Chris@16 128 if(p == 0)
Chris@16 129 {
Chris@16 130 return (complement ? 1 : -1) * policies::raise_overflow_error<RealType>(function, 0, Policy());
Chris@16 131 }
Chris@16 132
Chris@16 133 RealType P = p - floor(p); // argument reduction of p:
Chris@16 134 if(P > 0.5)
Chris@16 135 {
Chris@16 136 P = P - 1;
Chris@16 137 }
Chris@16 138 if(P == 0.5) // special case:
Chris@16 139 {
Chris@16 140 return location;
Chris@16 141 }
Chris@16 142 result = -scale / tan(constants::pi<RealType>() * P);
Chris@16 143 return complement ? RealType(location - result) : RealType(location + result);
Chris@16 144 } // quantile
Chris@16 145
Chris@16 146 } // namespace detail
Chris@16 147
Chris@16 148 template <class RealType = double, class Policy = policies::policy<> >
Chris@16 149 class cauchy_distribution
Chris@16 150 {
Chris@16 151 public:
Chris@16 152 typedef RealType value_type;
Chris@16 153 typedef Policy policy_type;
Chris@16 154
Chris@16 155 cauchy_distribution(RealType l_location = 0, RealType l_scale = 1)
Chris@16 156 : m_a(l_location), m_hg(l_scale)
Chris@16 157 {
Chris@16 158 static const char* function = "boost::math::cauchy_distribution<%1%>::cauchy_distribution";
Chris@16 159 RealType result;
Chris@16 160 detail::check_location(function, l_location, &result, Policy());
Chris@16 161 detail::check_scale(function, l_scale, &result, Policy());
Chris@16 162 } // cauchy_distribution
Chris@16 163
Chris@16 164 RealType location()const
Chris@16 165 {
Chris@16 166 return m_a;
Chris@16 167 }
Chris@16 168 RealType scale()const
Chris@16 169 {
Chris@16 170 return m_hg;
Chris@16 171 }
Chris@16 172
Chris@16 173 private:
Chris@16 174 RealType m_a; // The location, this is the median of the distribution.
Chris@16 175 RealType m_hg; // The scale )or shape), this is the half width at half height.
Chris@16 176 };
Chris@16 177
Chris@16 178 typedef cauchy_distribution<double> cauchy;
Chris@16 179
Chris@16 180 template <class RealType, class Policy>
Chris@16 181 inline const std::pair<RealType, RealType> range(const cauchy_distribution<RealType, Policy>&)
Chris@16 182 { // Range of permissible values for random variable x.
Chris@16 183 if (std::numeric_limits<RealType>::has_infinity)
Chris@16 184 {
Chris@16 185 return std::pair<RealType, RealType>(-std::numeric_limits<RealType>::infinity(), std::numeric_limits<RealType>::infinity()); // - to + infinity.
Chris@16 186 }
Chris@16 187 else
Chris@16 188 { // Can only use max_value.
Chris@16 189 using boost::math::tools::max_value;
Chris@16 190 return std::pair<RealType, RealType>(-max_value<RealType>(), max_value<RealType>()); // - to + max.
Chris@16 191 }
Chris@16 192 }
Chris@16 193
Chris@16 194 template <class RealType, class Policy>
Chris@16 195 inline const std::pair<RealType, RealType> support(const cauchy_distribution<RealType, Policy>& )
Chris@16 196 { // Range of supported values for random variable x.
Chris@16 197 // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
Chris@16 198 if (std::numeric_limits<RealType>::has_infinity)
Chris@16 199 {
Chris@16 200 return std::pair<RealType, RealType>(-std::numeric_limits<RealType>::infinity(), std::numeric_limits<RealType>::infinity()); // - to + infinity.
Chris@16 201 }
Chris@16 202 else
Chris@16 203 { // Can only use max_value.
Chris@16 204 using boost::math::tools::max_value;
Chris@16 205 return std::pair<RealType, RealType>(-tools::max_value<RealType>(), max_value<RealType>()); // - to + max.
Chris@16 206 }
Chris@16 207 }
Chris@16 208
Chris@16 209 template <class RealType, class Policy>
Chris@16 210 inline RealType pdf(const cauchy_distribution<RealType, Policy>& dist, const RealType& x)
Chris@16 211 {
Chris@16 212 BOOST_MATH_STD_USING // for ADL of std functions
Chris@16 213
Chris@16 214 static const char* function = "boost::math::pdf(cauchy<%1%>&, %1%)";
Chris@16 215 RealType result = 0;
Chris@16 216 RealType location = dist.location();
Chris@16 217 RealType scale = dist.scale();
Chris@16 218 if(false == detail::check_scale("boost::math::pdf(cauchy<%1%>&, %1%)", scale, &result, Policy()))
Chris@16 219 {
Chris@16 220 return result;
Chris@16 221 }
Chris@16 222 if(false == detail::check_location("boost::math::pdf(cauchy<%1%>&, %1%)", location, &result, Policy()))
Chris@16 223 {
Chris@16 224 return result;
Chris@16 225 }
Chris@16 226 if((boost::math::isinf)(x))
Chris@16 227 {
Chris@16 228 return 0; // pdf + and - infinity is zero.
Chris@16 229 }
Chris@16 230 // These produce MSVC 4127 warnings, so the above used instead.
Chris@16 231 //if(std::numeric_limits<RealType>::has_infinity && abs(x) == std::numeric_limits<RealType>::infinity())
Chris@16 232 //{ // pdf + and - infinity is zero.
Chris@16 233 // return 0;
Chris@16 234 //}
Chris@16 235
Chris@16 236 if(false == detail::check_x(function, x, &result, Policy()))
Chris@16 237 { // Catches x = NaN
Chris@16 238 return result;
Chris@16 239 }
Chris@16 240
Chris@16 241 RealType xs = (x - location) / scale;
Chris@16 242 result = 1 / (constants::pi<RealType>() * scale * (1 + xs * xs));
Chris@16 243 return result;
Chris@16 244 } // pdf
Chris@16 245
Chris@16 246 template <class RealType, class Policy>
Chris@16 247 inline RealType cdf(const cauchy_distribution<RealType, Policy>& dist, const RealType& x)
Chris@16 248 {
Chris@16 249 return detail::cdf_imp(dist, x, false);
Chris@16 250 } // cdf
Chris@16 251
Chris@16 252 template <class RealType, class Policy>
Chris@16 253 inline RealType quantile(const cauchy_distribution<RealType, Policy>& dist, const RealType& p)
Chris@16 254 {
Chris@16 255 return detail::quantile_imp(dist, p, false);
Chris@16 256 } // quantile
Chris@16 257
Chris@16 258 template <class RealType, class Policy>
Chris@16 259 inline RealType cdf(const complemented2_type<cauchy_distribution<RealType, Policy>, RealType>& c)
Chris@16 260 {
Chris@16 261 return detail::cdf_imp(c.dist, c.param, true);
Chris@16 262 } // cdf complement
Chris@16 263
Chris@16 264 template <class RealType, class Policy>
Chris@16 265 inline RealType quantile(const complemented2_type<cauchy_distribution<RealType, Policy>, RealType>& c)
Chris@16 266 {
Chris@16 267 return detail::quantile_imp(c.dist, c.param, true);
Chris@16 268 } // quantile complement
Chris@16 269
Chris@16 270 template <class RealType, class Policy>
Chris@16 271 inline RealType mean(const cauchy_distribution<RealType, Policy>&)
Chris@16 272 { // There is no mean:
Chris@16 273 typedef typename Policy::assert_undefined_type assert_type;
Chris@16 274 BOOST_STATIC_ASSERT(assert_type::value == 0);
Chris@16 275
Chris@16 276 return policies::raise_domain_error<RealType>(
Chris@16 277 "boost::math::mean(cauchy<%1%>&)",
Chris@16 278 "The Cauchy distribution does not have a mean: "
Chris@16 279 "the only possible return value is %1%.",
Chris@16 280 std::numeric_limits<RealType>::quiet_NaN(), Policy());
Chris@16 281 }
Chris@16 282
Chris@16 283 template <class RealType, class Policy>
Chris@16 284 inline RealType variance(const cauchy_distribution<RealType, Policy>& /*dist*/)
Chris@16 285 {
Chris@16 286 // There is no variance:
Chris@16 287 typedef typename Policy::assert_undefined_type assert_type;
Chris@16 288 BOOST_STATIC_ASSERT(assert_type::value == 0);
Chris@16 289
Chris@16 290 return policies::raise_domain_error<RealType>(
Chris@16 291 "boost::math::variance(cauchy<%1%>&)",
Chris@16 292 "The Cauchy distribution does not have a variance: "
Chris@16 293 "the only possible return value is %1%.",
Chris@16 294 std::numeric_limits<RealType>::quiet_NaN(), Policy());
Chris@16 295 }
Chris@16 296
Chris@16 297 template <class RealType, class Policy>
Chris@16 298 inline RealType mode(const cauchy_distribution<RealType, Policy>& dist)
Chris@16 299 {
Chris@16 300 return dist.location();
Chris@16 301 }
Chris@16 302
Chris@16 303 template <class RealType, class Policy>
Chris@16 304 inline RealType median(const cauchy_distribution<RealType, Policy>& dist)
Chris@16 305 {
Chris@16 306 return dist.location();
Chris@16 307 }
Chris@16 308 template <class RealType, class Policy>
Chris@16 309 inline RealType skewness(const cauchy_distribution<RealType, Policy>& /*dist*/)
Chris@16 310 {
Chris@16 311 // There is no skewness:
Chris@16 312 typedef typename Policy::assert_undefined_type assert_type;
Chris@16 313 BOOST_STATIC_ASSERT(assert_type::value == 0);
Chris@16 314
Chris@16 315 return policies::raise_domain_error<RealType>(
Chris@16 316 "boost::math::skewness(cauchy<%1%>&)",
Chris@16 317 "The Cauchy distribution does not have a skewness: "
Chris@16 318 "the only possible return value is %1%.",
Chris@16 319 std::numeric_limits<RealType>::quiet_NaN(), Policy()); // infinity?
Chris@16 320 }
Chris@16 321
Chris@16 322 template <class RealType, class Policy>
Chris@16 323 inline RealType kurtosis(const cauchy_distribution<RealType, Policy>& /*dist*/)
Chris@16 324 {
Chris@16 325 // There is no kurtosis:
Chris@16 326 typedef typename Policy::assert_undefined_type assert_type;
Chris@16 327 BOOST_STATIC_ASSERT(assert_type::value == 0);
Chris@16 328
Chris@16 329 return policies::raise_domain_error<RealType>(
Chris@16 330 "boost::math::kurtosis(cauchy<%1%>&)",
Chris@16 331 "The Cauchy distribution does not have a kurtosis: "
Chris@16 332 "the only possible return value is %1%.",
Chris@16 333 std::numeric_limits<RealType>::quiet_NaN(), Policy());
Chris@16 334 }
Chris@16 335
Chris@16 336 template <class RealType, class Policy>
Chris@16 337 inline RealType kurtosis_excess(const cauchy_distribution<RealType, Policy>& /*dist*/)
Chris@16 338 {
Chris@16 339 // There is no kurtosis excess:
Chris@16 340 typedef typename Policy::assert_undefined_type assert_type;
Chris@16 341 BOOST_STATIC_ASSERT(assert_type::value == 0);
Chris@16 342
Chris@16 343 return policies::raise_domain_error<RealType>(
Chris@16 344 "boost::math::kurtosis_excess(cauchy<%1%>&)",
Chris@16 345 "The Cauchy distribution does not have a kurtosis: "
Chris@16 346 "the only possible return value is %1%.",
Chris@16 347 std::numeric_limits<RealType>::quiet_NaN(), Policy());
Chris@16 348 }
Chris@16 349
Chris@16 350 } // namespace math
Chris@16 351 } // namespace boost
Chris@16 352
Chris@16 353 #ifdef _MSC_VER
Chris@16 354 #pragma warning(pop)
Chris@16 355 #endif
Chris@16 356
Chris@16 357 // This include must be at the end, *after* the accessors
Chris@16 358 // for this distribution have been defined, in order to
Chris@16 359 // keep compilers that support two-phase lookup happy.
Chris@16 360 #include <boost/math/distributions/detail/derived_accessors.hpp>
Chris@16 361
Chris@16 362 #endif // BOOST_STATS_CAUCHY_HPP