Subject: [Boost-bugs] [Boost C++ Libraries] #9042: boost::math, cdf(complement(normal_distribution<>(...)) fails to catch invalid scale and location parameters
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2013-08-24 06:06:27
#9042: boost::math, cdf(complement(normal_distribution<>(...)) fails to catch
invalid scale and location parameters
--------------------------------------+-------------------------
Reporter: Paul McClellan <paulm@â¦> | Owner: johnmaddock
Type: Bugs | Status: new
Milestone: To Be Determined | Component: math
Version: Boost 1.54.0 | Severity: Problem
Keywords: |
--------------------------------------+-------------------------
In boost/math/distributions/normal.hpp:
{{{
template <class RealType, class Policy>
inline RealType cdf(const complemented2_type<normal_distribution<RealType,
Policy>, RealType>& c)
{
BOOST_MATH_STD_USING // for ADL of std functions
RealType sd = c.dist.standard_deviation();
RealType mean = c.dist.mean();
RealType x = c.param;
static const char* function = "boost::math::cdf(const
complement(normal_distribution<%1%>&), %1%)";
if((boost::math::isinf)(x))
{
if(x < 0) return 1; // cdf complement -infinity is unity.
return 0; // cdf complement +infinity is zero
}
// These produce MSVC 4127 warnings, so the above used instead.
//if(std::numeric_limits<RealType>::has_infinity && x ==
std::numeric_limits<RealType>::infinity())
//{ // cdf complement +infinity is zero.
// return 0;
//}
//if(std::numeric_limits<RealType>::has_infinity && x ==
-std::numeric_limits<RealType>::infinity())
//{ // cdf complement -infinity is unity.
// return 1;
//}
RealType result = 0;
if(false == detail::check_scale(function, sd, &result, Policy()))
return result;
if(false == detail::check_location(function, mean, &result, Policy()))
return result;
if(false == detail::check_x(function, x, &result, Policy()))
return result;
RealType diff = (x - mean) / (sd * constants::root_two<RealType>());
result = boost::math::erfc(diff, Policy()) / 2;
return result;
} // cdf complement
}}}
The test if((boost::math::isinf)(x)) occurs before check_scale() or
check_location() is called, returning 1 or 0 for infinite x, even if sd or
mean are invalid.
The calls to check_scale() and check_location() should be moved up just
before the test if((boost::math::isinf)(x)).
See, for example, how the tests are ordered here:
{{{
template <class RealType, class Policy>
inline RealType cdf(const normal_distribution<RealType, Policy>& dist,
const RealType& x)
{
BOOST_MATH_STD_USING // for ADL of std functions
RealType sd = dist.standard_deviation();
RealType mean = dist.mean();
static const char* function = "boost::math::cdf(const
normal_distribution<%1%>&, %1%)";
RealType result = 0;
if(false == detail::check_scale(function, sd, &result, Policy()))
{
return result;
}
if(false == detail::check_location(function, mean, &result, Policy()))
{
return result;
}
if((boost::math::isinf)(x))
{
if(x < 0) return 0; // -infinity
return 1; // + infinity
}
// These produce MSVC 4127 warnings, so the above used instead.
//if(std::numeric_limits<RealType>::has_infinity && x ==
std::numeric_limits<RealType>::infinity())
//{ // cdf +infinity is unity.
// return 1;
//}
//if(std::numeric_limits<RealType>::has_infinity && x ==
-std::numeric_limits<RealType>::infinity())
//{ // cdf -infinity is zero.
// return 0;
//}
if(false == detail::check_x(function, x, &result, Policy()))
{
return result;
}
RealType diff = (x - mean) / (sd * constants::root_two<RealType>());
result = boost::math::erfc(-diff, Policy()) / 2;
return result;
} // cdf
}}}
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/9042> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:13 UTC