[Boost-bugs] [Boost C++ Libraries] #9126: Logistic distribution pdf() and cdf(complement()) fail to catch invalid scale and location parameters

Subject: [Boost-bugs] [Boost C++ Libraries] #9126: Logistic distribution pdf() and cdf(complement()) fail to catch invalid scale and location parameters
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2013-09-18 02:20:00


#9126: Logistic distribution pdf() and cdf(complement()) fail 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: |
--------------------------------------+-------------------------
 This issue is related to '''Ticket #9042'''

 In '''boost/math/distributions/logistic.hpp''':

 {{{
     template <class RealType, class Policy>
     inline RealType pdf(const logistic_distribution<RealType, Policy>&
 dist, const RealType& x)
     {
        RealType scale = dist.scale();
        RealType location = dist.location();

        static const char* function = "boost::math::pdf(const
 logistic_distribution<%1%>&, %1%)";
        if((boost::math::isinf)(x))
        {
           return 0; // pdf + and - infinity is zero.
        }

        RealType result = 0;
        if(false == detail::check_scale(function, scale , &result,
 Policy()))
        {
           return result;
        }
        if(false == detail::check_location(function, location, &result,
 Policy()))
        {
           return result;
        }
        if(false == detail::check_x(function, x, &result, Policy()))
        {
           return result;
        }

        BOOST_MATH_STD_USING
        RealType exp_term = (location - x) / scale;
        if(fabs(exp_term) > tools::log_max_value<RealType>())
           return 0;
        exp_term = exp(exp_term);
        if((exp_term * scale > 1) && (exp_term >
 tools::max_value<RealType>() / (scale * exp_term)))
           return 1 / (scale * exp_term);
        return (exp_term) / (scale * (1 + exp_term) * (1 + exp_term));
     }
 }}}

 The test if((boost::math::isinf)(x)) occurs before check_scale() or
 check_location() is called, returning 0 for infinite x, even if scale or
 location 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 logistic_distribution<RealType, Policy>&
 dist, const RealType& x)
     {
        RealType scale = dist.scale();
        RealType location = dist.location();
        RealType result = 0; // of checks.
        static const char* function = "boost::math::cdf(const
 logistic_distribution<%1%>&, %1%)";
        if(false == detail::check_scale(function, scale, &result,
 Policy()))
        {
           return result;
        }
        if(false == detail::check_location(function, location, &result,
 Policy()))
        {
           return result;
        }

        if((boost::math::isinf)(x))
        {
           if(x < 0) return 0; // -infinity
           return 1; // + infinity
        }

        if(false == detail::check_x(function, x, &result, Policy()))
        {
           return result;
        }
        BOOST_MATH_STD_USING
        RealType power = (location - x) / scale;
        if(power > tools::log_max_value<RealType>())
           return 0;
        if(power < -tools::log_max_value<RealType>())
           return 1;
        return 1 / (1 + exp(power));
     }
  }}}

 The same issue exists with the complementary cdf:

 {{{
     template <class RealType, class Policy>
     inline RealType cdf(const
 complemented2_type<logistic_distribution<RealType, Policy>, RealType>& c)
     {
        BOOST_MATH_STD_USING
        RealType location = c.dist.location();
        RealType scale = c.dist.scale();
        RealType x = c.param;
        static const char* function = "boost::math::cdf(const
 complement(logistic_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
        }
        RealType result = 0;
        if(false == detail::check_scale(function, scale, &result,
 Policy()))
           return result;
        if(false == detail::check_location(function, location, &result,
 Policy()))
           return result;
        if(false == detail::check_x(function, x, &result, Policy()))
           return result;
        RealType power = (x - location) / scale;
        if(power > tools::log_max_value<RealType>())
           return 0;
        if(power < -tools::log_max_value<RealType>())
           return 1;
        return 1 / (1 + exp(power));
     }
 }}}

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/9126>
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:14 UTC