[Boost-bugs] [Boost C++ Libraries] #9042: boost::math, cdf(complement(normal_distribution<>(...)) fails to catch invalid scale and location parameters

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