Skip to content

Commit 466cf6b

Browse files
Simplify the formula for the CDF of the Cauchy distribution.
The Cauchy CDF function may be expressed as atan2(1, -x)/pi.
1 parent 933faf4 commit 466cf6b

File tree

2 files changed

+38
-22
lines changed

2 files changed

+38
-22
lines changed

include/boost/math/distributions/cauchy.hpp

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -45,23 +45,11 @@ BOOST_MATH_GPU_ENABLED RealType cdf_imp(const cauchy_distribution<RealType, Poli
4545
//
4646
// This calculates the cdf of the Cauchy distribution and/or its complement.
4747
//
48-
// The usual formula for the Cauchy cdf is:
48+
// This implementation uses the formula
4949
//
50-
// cdf = 0.5 + atan(x)/pi
50+
// cdf = atan2(1, -x)/pi
5151
//
52-
// But that suffers from cancellation error as x -> -INF.
53-
//
54-
// Recall that for x < 0:
55-
//
56-
// atan(x) = -pi/2 - atan(1/x)
57-
//
58-
// Substituting into the above we get:
59-
//
60-
// CDF = -atan(1/x)/pi ; x < 0
61-
//
62-
// So the procedure is to calculate the cdf for -fabs(x)
63-
// using the above formula, and then subtract from 1 when required
64-
// to get the result.
52+
// where x is the standardized (i.e. shifted and scaled) domain variable.
6553
//
6654
BOOST_MATH_STD_USING // for ADL of std functions
6755
constexpr auto function = "boost::math::cdf(cauchy<%1%>&, %1%)";
@@ -99,13 +87,8 @@ BOOST_MATH_GPU_ENABLED RealType cdf_imp(const cauchy_distribution<RealType, Poli
9987
{ // Catches x == NaN
10088
return result;
10189
}
102-
RealType mx = -fabs((x - location) / scale); // scale is > 0
103-
if(mx > -tools::epsilon<RealType>() / 8)
104-
{ // special case first: x extremely close to location.
105-
return static_cast<RealType>(0.5f);
106-
}
107-
result = -atan(1 / mx) / constants::pi<RealType>();
108-
return (((x > location) != complement) ? 1 - result : result);
90+
RealType x_std = static_cast<RealType>((complement) ? 1 : -1)*(x - location) / scale;
91+
return atan2(static_cast<RealType>(1), x_std) / constants::pi<RealType>();
10992
} // cdf
11093

11194
template <class RealType, class Policy>

test/test_cauchy.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,22 @@ void test_spots(RealType T)
124124
static_cast<RealType>(-10.0)), // x
125125
static_cast<RealType>(0.031725517430553569514977118601302L), // probability.
126126
tolerance); // %
127+
BOOST_CHECK_CLOSE(
128+
::boost::math::cdf(
129+
cauchy_distribution<RealType>(),
130+
static_cast<RealType>(-15000000.0)),
131+
static_cast<RealType>(0.000000021220659078919346664504384865488560725L),
132+
tolerance); // %
133+
BOOST_CHECK_CLOSE(
134+
// Test the CDF at the most extreme floating point value of the left tail.
135+
// For an input x of this magnitude, the reference value is 1/|x|/pi.
136+
::boost::math::cdf(
137+
cauchy_distribution<RealType>(),
138+
-boost::math::tools::max_value<RealType>()),
139+
static_cast<RealType>(1)
140+
/ boost::math::tools::max_value<RealType>()
141+
/ boost::math::constants::pi<RealType>(),
142+
tolerance); // %
127143

128144
//
129145
// Complements:
@@ -188,6 +204,23 @@ void test_spots(RealType T)
188204
static_cast<RealType>(-10.0))), // x
189205
static_cast<RealType>(0.9682744825694464304850228813987L), // probability.
190206
tolerance); // %
207+
BOOST_CHECK_CLOSE(
208+
::boost::math::cdf(
209+
complement(cauchy_distribution<RealType>(),
210+
static_cast<RealType>(15000000.0))),
211+
static_cast<RealType>(0.000000021220659078919346664504384865488560725L),
212+
tolerance); // %
213+
BOOST_CHECK_CLOSE(
214+
// Test the complemented CDF at the most extreme floating point value
215+
// of the right tail. For an input x of this magnitude, the reference
216+
// value is 1/x/pi.
217+
::boost::math::cdf(
218+
complement(cauchy_distribution<RealType>(),
219+
boost::math::tools::max_value<RealType>())),
220+
static_cast<RealType>(1)
221+
/ boost::math::tools::max_value<RealType>()
222+
/ boost::math::constants::pi<RealType>(),
223+
tolerance); // %
191224

192225
//
193226
// Quantiles:

0 commit comments

Comments
 (0)