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,,