id summary reporter owner description type status milestone component version severity resolution keywords cc 9126 Logistic distribution pdf() and cdf(complement()) fail to catch invalid scale and location parameters Paul McClellan Paul A. Bristow "This issue is related to '''Ticket #9042''' In '''boost/math/distributions/logistic.hpp''': {{{ template inline RealType pdf(const logistic_distribution& 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()) return 0; exp_term = exp(exp_term); if((exp_term * scale > 1) && (exp_term > tools::max_value() / (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 inline RealType cdf(const logistic_distribution& 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()) return 0; if(power < -tools::log_max_value()) return 1; return 1 / (1 + exp(power)); } }}} The same issue exists with the complementary cdf: {{{ template inline RealType cdf(const complemented2_type, 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()) return 0; if(power < -tools::log_max_value()) return 1; return 1 / (1 + exp(power)); } }}}" Bugs closed Boost 1.55.0 math Boost 1.54.0 Problem fixed