diff options
Diffstat (limited to 'boost/math/distributions')
-rw-r--r-- | boost/math/distributions/bernoulli.hpp | 2 | ||||
-rw-r--r-- | boost/math/distributions/binomial.hpp | 2 | ||||
-rw-r--r-- | boost/math/distributions/detail/hypergeometric_pdf.hpp | 2 | ||||
-rw-r--r-- | boost/math/distributions/detail/hypergeometric_quantile.hpp | 46 | ||||
-rw-r--r-- | boost/math/distributions/exponential.hpp | 4 | ||||
-rw-r--r-- | boost/math/distributions/extreme_value.hpp | 4 | ||||
-rw-r--r-- | boost/math/distributions/fisher_f.hpp | 4 | ||||
-rw-r--r-- | boost/math/distributions/geometric.hpp | 2 | ||||
-rw-r--r-- | boost/math/distributions/hypergeometric.hpp | 44 | ||||
-rw-r--r-- | boost/math/distributions/inverse_gaussian.hpp | 15 | ||||
-rw-r--r-- | boost/math/distributions/negative_binomial.hpp | 2 | ||||
-rw-r--r-- | boost/math/distributions/non_central_beta.hpp | 6 | ||||
-rw-r--r-- | boost/math/distributions/non_central_chi_squared.hpp | 58 | ||||
-rw-r--r-- | boost/math/distributions/non_central_t.hpp | 4 | ||||
-rw-r--r-- | boost/math/distributions/rayleigh.hpp | 2 | ||||
-rw-r--r-- | boost/math/distributions/skew_normal.hpp | 18 | ||||
-rw-r--r-- | boost/math/distributions/triangular.hpp | 12 | ||||
-rw-r--r-- | boost/math/distributions/uniform.hpp | 21 |
18 files changed, 162 insertions, 86 deletions
diff --git a/boost/math/distributions/bernoulli.hpp b/boost/math/distributions/bernoulli.hpp index 1355eda229..09b8a0a3e1 100644 --- a/boost/math/distributions/bernoulli.hpp +++ b/boost/math/distributions/bernoulli.hpp @@ -89,7 +89,7 @@ namespace boost template <class RealType, class Policy> inline bool check_dist_and_prob(const char* function, RealType p, RealType prob, RealType* result, const Policy& /* pol */) { - if(check_dist(function, p, result, Policy(), typename policies::method_error_check<Policy>::type()) && detail::check_probability(function, prob, result, Policy()) == false) + if((check_dist(function, p, result, Policy(), typename policies::method_error_check<Policy>::type()) && detail::check_probability(function, prob, result, Policy())) == false) { return false; } diff --git a/boost/math/distributions/binomial.hpp b/boost/math/distributions/binomial.hpp index a48c89c5b9..620bf9b121 100644 --- a/boost/math/distributions/binomial.hpp +++ b/boost/math/distributions/binomial.hpp @@ -155,7 +155,7 @@ namespace boost template <class RealType, class Policy> inline bool check_dist_and_prob(const char* function, const RealType& N, RealType p, RealType prob, RealType* result, const Policy& pol) { - if(check_dist(function, N, p, result, pol) && detail::check_probability(function, prob, result, pol) == false) + if((check_dist(function, N, p, result, pol) && detail::check_probability(function, prob, result, pol)) == false) return false; return true; } diff --git a/boost/math/distributions/detail/hypergeometric_pdf.hpp b/boost/math/distributions/detail/hypergeometric_pdf.hpp index 1e6a5ca20d..4364266514 100644 --- a/boost/math/distributions/detail/hypergeometric_pdf.hpp +++ b/boost/math/distributions/detail/hypergeometric_pdf.hpp @@ -311,7 +311,7 @@ T hypergeometric_pdf_prime_loop_imp(hypergeometric_pdf_prime_loop_data& data, hy } if(prime_powers) { - T p = integer_power<T>(data.current_prime, prime_powers); + T p = integer_power<T>(static_cast<T>(data.current_prime), prime_powers); if((p > 1) && (tools::max_value<T>() / p < result.value)) { // diff --git a/boost/math/distributions/detail/hypergeometric_quantile.hpp b/boost/math/distributions/detail/hypergeometric_quantile.hpp index a855a4a777..2cdee23c10 100644 --- a/boost/math/distributions/detail/hypergeometric_quantile.hpp +++ b/boost/math/distributions/detail/hypergeometric_quantile.hpp @@ -130,6 +130,29 @@ unsigned hypergeometric_quantile_imp(T p, T q, unsigned r, unsigned n, unsigned unsigned x = base; result = hypergeometric_pdf<T>(x, r, n, N, pol); T diff = result; + if (diff == 0) + { + ++x; + // We want to skip through x values as fast as we can until we start getting non-zero values, + // otherwise we're just making lots of expensive PDF calls: + T log_pdf = boost::math::lgamma(static_cast<T>(n + 1), pol) + + boost::math::lgamma(static_cast<T>(r + 1), pol) + + boost::math::lgamma(static_cast<T>(N - n + 1), pol) + + boost::math::lgamma(static_cast<T>(N - r + 1), pol) + - boost::math::lgamma(static_cast<T>(N + 1), pol) + - boost::math::lgamma(static_cast<T>(x + 1), pol) + - boost::math::lgamma(static_cast<T>(n - x + 1), pol) + - boost::math::lgamma(static_cast<T>(r - x + 1), pol) + - boost::math::lgamma(static_cast<T>(N - n - r + x + 1), pol); + while (log_pdf < tools::log_min_value<T>()) + { + log_pdf += -log(static_cast<T>(x + 1)) + log(static_cast<T>(n - x)) + log(static_cast<T>(r - x)) - log(static_cast<T>(N - n - r + x + 1)); + ++x; + } + // By the time we get here, log_pdf may be fairly inaccurate due to + // roundoff errors, get a fresh PDF calculation before proceding: + diff = hypergeometric_pdf<T>(x, r, n, N, pol); + } while(result < p) { diff = (diff > tools::min_value<T>() * 8) @@ -155,6 +178,29 @@ unsigned hypergeometric_quantile_imp(T p, T q, unsigned r, unsigned n, unsigned unsigned x = lim; result = 0; T diff = hypergeometric_pdf<T>(x, r, n, N, pol); + if (diff == 0) + { + // We want to skip through x values as fast as we can until we start getting non-zero values, + // otherwise we're just making lots of expensive PDF calls: + --x; + T log_pdf = boost::math::lgamma(static_cast<T>(n + 1), pol) + + boost::math::lgamma(static_cast<T>(r + 1), pol) + + boost::math::lgamma(static_cast<T>(N - n + 1), pol) + + boost::math::lgamma(static_cast<T>(N - r + 1), pol) + - boost::math::lgamma(static_cast<T>(N + 1), pol) + - boost::math::lgamma(static_cast<T>(x + 1), pol) + - boost::math::lgamma(static_cast<T>(n - x + 1), pol) + - boost::math::lgamma(static_cast<T>(r - x + 1), pol) + - boost::math::lgamma(static_cast<T>(N - n - r + x + 1), pol); + while (log_pdf < tools::log_min_value<T>()) + { + log_pdf += log(static_cast<T>(x)) - log(static_cast<T>(n - x + 1)) - log(static_cast<T>(r - x + 1)) + log(static_cast<T>(N - n - r + x)); + --x; + } + // By the time we get here, log_pdf may be fairly inaccurate due to + // roundoff errors, get a fresh PDF calculation before proceding: + diff = hypergeometric_pdf<T>(x, r, n, N, pol); + } while(result + diff / 2 < q) { result += diff; diff --git a/boost/math/distributions/exponential.hpp b/boost/math/distributions/exponential.hpp index bfe7e6b4ac..05c49374ed 100644 --- a/boost/math/distributions/exponential.hpp +++ b/boost/math/distributions/exponential.hpp @@ -117,7 +117,7 @@ inline RealType pdf(const exponential_distribution<RealType, Policy>& dist, cons return result; // Workaround for VC11/12 bug: if ((boost::math::isinf)(x)) - return 0; + return 0; result = lambda * exp(-lambda * x); return result; } // pdf @@ -178,7 +178,7 @@ inline RealType cdf(const complemented2_type<exponential_distribution<RealType, return result; // Workaround for VC11/12 bug: if (c.param >= tools::max_value<RealType>()) - return 0; + return 0; result = exp(-c.param * lambda); return result; diff --git a/boost/math/distributions/extreme_value.hpp b/boost/math/distributions/extreme_value.hpp index 4c6b710cbd..cb86de6612 100644 --- a/boost/math/distributions/extreme_value.hpp +++ b/boost/math/distributions/extreme_value.hpp @@ -100,12 +100,12 @@ inline RealType pdf(const extreme_value_distribution<RealType, Policy>& dist, co RealType a = dist.location(); RealType b = dist.scale(); RealType result = 0; - if((boost::math::isinf)(x)) - return 0.0f; if(0 == detail::verify_scale_b(function, b, &result, Policy())) return result; if(0 == detail::check_finite(function, a, &result, Policy())) return result; + if((boost::math::isinf)(x)) + return 0.0f; if(0 == detail::check_x(function, x, &result, Policy())) return result; RealType e = (a - x) / b; diff --git a/boost/math/distributions/fisher_f.hpp b/boost/math/distributions/fisher_f.hpp index 9e259bcc96..798db2fa75 100644 --- a/boost/math/distributions/fisher_f.hpp +++ b/boost/math/distributions/fisher_f.hpp @@ -78,10 +78,10 @@ RealType pdf(const fisher_f_distribution<RealType, Policy>& dist, const RealType // Error check: RealType error_result = 0; static const char* function = "boost::math::pdf(fisher_f_distribution<%1%> const&, %1%)"; - if(false == detail::check_df( + if(false == (detail::check_df( function, df1, &error_result, Policy()) && detail::check_df( - function, df2, &error_result, Policy())) + function, df2, &error_result, Policy()))) return error_result; if((x < 0) || !(boost::math::isfinite)(x)) diff --git a/boost/math/distributions/geometric.hpp b/boost/math/distributions/geometric.hpp index 88947d6c57..6c9713eadd 100644 --- a/boost/math/distributions/geometric.hpp +++ b/boost/math/distributions/geometric.hpp @@ -105,7 +105,7 @@ namespace boost template <class RealType, class Policy> inline bool check_dist_and_prob(const char* function, RealType p, RealType prob, RealType* result, const Policy& pol) { - if(check_dist(function, p, result, pol) && detail::check_probability(function, prob, result, pol) == false) + if((check_dist(function, p, result, pol) && detail::check_probability(function, prob, result, pol)) == false) { return false; } diff --git a/boost/math/distributions/hypergeometric.hpp b/boost/math/distributions/hypergeometric.hpp index 5d1ebc7388..21449638d9 100644 --- a/boost/math/distributions/hypergeometric.hpp +++ b/boost/math/distributions/hypergeometric.hpp @@ -41,12 +41,12 @@ namespace boost { namespace math { unsigned defective()const { - return m_n; + return m_r; } unsigned sample_count()const { - return m_r; + return m_n; } bool check_params(const char* function, RealType* result)const @@ -84,9 +84,9 @@ namespace boost { namespace math { private: // Data members: - unsigned m_n; // number of "defective" items + unsigned m_n; // number of items picked unsigned m_N; // number of "total" items - unsigned m_r; // number of items picked + unsigned m_r; // number of "defective" items }; // class hypergeometric_distribution @@ -99,8 +99,8 @@ namespace boost { namespace math { # pragma warning(push) # pragma warning(disable:4267) #endif - unsigned r = dist.sample_count(); - unsigned n = dist.defective(); + unsigned r = dist.defective(); + unsigned n = dist.sample_count(); unsigned N = dist.total(); unsigned l = static_cast<unsigned>((std::max)(0, (int)(n + r) - (int)(N))); unsigned u = (std::min)(r, n); @@ -127,7 +127,7 @@ namespace boost { namespace math { return result; return boost::math::detail::hypergeometric_pdf<RealType>( - x, dist.sample_count(), dist.defective(), dist.total(), Policy()); + x, dist.defective(), dist.sample_count(), dist.total(), Policy()); } template <class RealType, class Policy, class U> @@ -156,7 +156,7 @@ namespace boost { namespace math { return result; return boost::math::detail::hypergeometric_cdf<RealType>( - x, dist.sample_count(), dist.defective(), dist.total(), false, Policy()); + x, dist.defective(), dist.sample_count(), dist.total(), false, Policy()); } template <class RealType, class Policy, class U> @@ -185,7 +185,7 @@ namespace boost { namespace math { return result; return boost::math::detail::hypergeometric_cdf<RealType>( - c.param, c.dist.sample_count(), c.dist.defective(), c.dist.total(), true, Policy()); + c.param, c.dist.defective(), c.dist.sample_count(), c.dist.total(), true, Policy()); } template <class RealType, class Policy, class U> @@ -214,7 +214,7 @@ namespace boost { namespace math { if (false == dist.check_params(function, &result)) return result; if(false == detail::check_probability(function, p, &result, Policy())) return result; - return static_cast<RealType>(detail::hypergeometric_quantile(p, RealType(1 - p), dist.sample_count(), dist.defective(), dist.total(), Policy())); + return static_cast<RealType>(detail::hypergeometric_quantile(p, RealType(1 - p), dist.defective(), dist.sample_count(), dist.total(), Policy())); } // quantile template <class RealType, class Policy> @@ -228,30 +228,30 @@ namespace boost { namespace math { if (false == c.dist.check_params(function, &result)) return result; if(false == detail::check_probability(function, c.param, &result, Policy())) return result; - return static_cast<RealType>(detail::hypergeometric_quantile(RealType(1 - c.param), c.param, c.dist.sample_count(), c.dist.defective(), c.dist.total(), Policy())); + return static_cast<RealType>(detail::hypergeometric_quantile(RealType(1 - c.param), c.param, c.dist.defective(), c.dist.sample_count(), c.dist.total(), Policy())); } // quantile template <class RealType, class Policy> inline RealType mean(const hypergeometric_distribution<RealType, Policy>& dist) { - return static_cast<RealType>(dist.sample_count() * dist.defective()) / dist.total(); + return static_cast<RealType>(dist.defective() * dist.sample_count()) / dist.total(); } // RealType mean(const hypergeometric_distribution<RealType, Policy>& dist) template <class RealType, class Policy> inline RealType variance(const hypergeometric_distribution<RealType, Policy>& dist) { - RealType r = static_cast<RealType>(dist.sample_count()); - RealType n = static_cast<RealType>(dist.defective()); + RealType r = static_cast<RealType>(dist.defective()); + RealType n = static_cast<RealType>(dist.sample_count()); RealType N = static_cast<RealType>(dist.total()); - return r * (n / N) * (1 - n / N) * (N - r) / (N - 1); + return n * r * (N - r) * (N - n) / (N * N * (N - 1)); } // RealType variance(const hypergeometric_distribution<RealType, Policy>& dist) template <class RealType, class Policy> inline RealType mode(const hypergeometric_distribution<RealType, Policy>& dist) { BOOST_MATH_STD_USING - RealType r = static_cast<RealType>(dist.sample_count()); - RealType n = static_cast<RealType>(dist.defective()); + RealType r = static_cast<RealType>(dist.defective()); + RealType n = static_cast<RealType>(dist.sample_count()); RealType N = static_cast<RealType>(dist.total()); return floor((r + 1) * (n + 1) / (N + 2)); } @@ -260,17 +260,17 @@ namespace boost { namespace math { inline RealType skewness(const hypergeometric_distribution<RealType, Policy>& dist) { BOOST_MATH_STD_USING - RealType r = static_cast<RealType>(dist.sample_count()); - RealType n = static_cast<RealType>(dist.defective()); + RealType r = static_cast<RealType>(dist.defective()); + RealType n = static_cast<RealType>(dist.sample_count()); RealType N = static_cast<RealType>(dist.total()); - return (N - 2 * n) * sqrt(N - 1) * (N - 2 * r) / (sqrt(n * r * (N - n) * (N - r)) * (N - 2)); + return (N - 2 * r) * sqrt(N - 1) * (N - 2 * n) / (sqrt(n * r * (N - r) * (N - n)) * (N - 2)); } // RealType skewness(const hypergeometric_distribution<RealType, Policy>& dist) template <class RealType, class Policy> inline RealType kurtosis_excess(const hypergeometric_distribution<RealType, Policy>& dist) { - RealType r = static_cast<RealType>(dist.sample_count()); - RealType n = static_cast<RealType>(dist.defective()); + RealType r = static_cast<RealType>(dist.defective()); + RealType n = static_cast<RealType>(dist.sample_count()); RealType N = static_cast<RealType>(dist.total()); RealType t1 = N * N * (N - 1) / (r * (N - 2) * (N - 3) * (N - r)); RealType t2 = (N * (N + 1) - 6 * N * (N - r)) / (n * (N - n)) diff --git a/boost/math/distributions/inverse_gaussian.hpp b/boost/math/distributions/inverse_gaussian.hpp index eeca12ad48..e3aa4e0650 100644 --- a/boost/math/distributions/inverse_gaussian.hpp +++ b/boost/math/distributions/inverse_gaussian.hpp @@ -82,6 +82,7 @@ public: RealType result; detail::check_scale(function, l_scale, &result, Policy()); detail::check_location(function, l_mean, &result, Policy()); + detail::check_x_gt0(function, l_mean, &result, Policy()); } RealType mean()const @@ -146,6 +147,10 @@ inline RealType pdf(const inverse_gaussian_distribution<RealType, Policy>& dist, { return result; } + if(false == detail::check_x_gt0(function, mean, &result, Policy())) + { + return result; + } if(false == detail::check_positive_x(function, x, &result, Policy())) { return result; @@ -179,6 +184,10 @@ inline RealType cdf(const inverse_gaussian_distribution<RealType, Policy>& dist, { return result; } + if (false == detail::check_x_gt0(function, mean, &result, Policy())) + { + return result; + } if(false == detail::check_positive_x(function, x, &result, Policy())) { return result; @@ -322,6 +331,8 @@ inline RealType quantile(const inverse_gaussian_distribution<RealType, Policy>& return result; if(false == detail::check_location(function, mean, &result, Policy())) return result; + if (false == detail::check_x_gt0(function, mean, &result, Policy())) + return result; if(false == detail::check_probability(function, p, &result, Policy())) return result; if (p == 0) @@ -380,6 +391,8 @@ inline RealType cdf(const complemented2_type<inverse_gaussian_distribution<RealT return result; if(false == detail::check_location(function, mean, &result, Policy())) return result; + if (false == detail::check_x_gt0(function, mean, &result, Policy())) + return result; if(false == detail::check_positive_x(function, x, &result, Policy())) return result; @@ -412,6 +425,8 @@ inline RealType quantile(const complemented2_type<inverse_gaussian_distribution< return result; if(false == detail::check_location(function, mean, &result, Policy())) return result; + if (false == detail::check_x_gt0(function, mean, &result, Policy())) + return result; RealType q = c.param; if(false == detail::check_probability(function, q, &result, Policy())) return result; diff --git a/boost/math/distributions/negative_binomial.hpp b/boost/math/distributions/negative_binomial.hpp index ca5723fa7d..3b4de4062f 100644 --- a/boost/math/distributions/negative_binomial.hpp +++ b/boost/math/distributions/negative_binomial.hpp @@ -124,7 +124,7 @@ namespace boost template <class RealType, class Policy> inline bool check_dist_and_prob(const char* function, const RealType& r, RealType p, RealType prob, RealType* result, const Policy& pol) { - if(check_dist(function, r, p, result, pol) && detail::check_probability(function, prob, result, pol) == false) + if((check_dist(function, r, p, result, pol) && detail::check_probability(function, prob, result, pol)) == false) { return false; } diff --git a/boost/math/distributions/non_central_beta.hpp b/boost/math/distributions/non_central_beta.hpp index 6e699e509f..aa66ecec0d 100644 --- a/boost/math/distributions/non_central_beta.hpp +++ b/boost/math/distributions/non_central_beta.hpp @@ -515,7 +515,11 @@ namespace boost T non_central_beta_pdf(T a, T b, T lam, T x, T y, const Policy& pol) { BOOST_MATH_STD_USING - using namespace boost::math; + // + // Special cases: + // + if((x == 0) || (y == 0)) + return 0; // // Variables come first: // diff --git a/boost/math/distributions/non_central_chi_squared.hpp b/boost/math/distributions/non_central_chi_squared.hpp index 88933c1956..97f87ed4c0 100644 --- a/boost/math/distributions/non_central_chi_squared.hpp +++ b/boost/math/distributions/non_central_chi_squared.hpp @@ -73,7 +73,7 @@ namespace boost // int k = iround(lambda, pol); // Forwards and backwards Poisson weights: - T poisf = boost::math::gamma_p_derivative(1 + k, lambda, pol); + T poisf = boost::math::gamma_p_derivative(static_cast<T>(1 + k), lambda, pol); T poisb = poisf * k / lambda; // Initial forwards central chi squared term: T gamf = boost::math::gamma_q(del + k, y, pol); @@ -225,7 +225,7 @@ namespace boost // Central chi squared term for backward iteration: T gamkb = gamkf; // Forwards Poisson weight: - T poiskf = gamma_p_derivative(k+1, del, pol); + T poiskf = gamma_p_derivative(static_cast<T>(k+1), del, pol); // Backwards Poisson weight: T poiskb = poiskf; // Forwards gamma function recursion term: @@ -295,7 +295,7 @@ namespace boost T l2 = lambda / 2; T sum = 0; int k = itrunc(l2); - T pois = gamma_p_derivative(k + 1, l2, pol) * gamma_p_derivative(n2 + k, x2); + T pois = gamma_p_derivative(static_cast<T>(k + 1), l2, pol) * gamma_p_derivative(static_cast<T>(n2 + k), x2); if(pois == 0) return 0; T poisb = pois; @@ -334,7 +334,7 @@ namespace boost BOOST_MATH_STD_USING value_type result; if(l == 0) - result = cdf(boost::math::chi_squared_distribution<RealType, Policy>(k), x); + return invert == false ? cdf(boost::math::chi_squared_distribution<RealType, Policy>(k), x) : cdf(complement(boost::math::chi_squared_distribution<RealType, Policy>(k), x)); else if(x > k + l) { // Complement is the smaller of the two: @@ -442,7 +442,7 @@ namespace boost // noncentral chi squared", Biometrika 46: 364. // See also: // "A comparison of approximations to percentiles of the noncentral chi2-distribution", - // Hardeo Sahai and Mario Miguel Ojeda, Revista de Matematica: Teoria y Aplicaciones 2003 10(1–2) : 57–76. + // Hardeo Sahai and Mario Miguel Ojeda, Revista de Matematica: Teoria y Aplicaciones 2003 10(1-2) : 57-76. // Note that the latter reference refers to an approximation of the CDF, when they really mean the quantile. // value_type b = -(l * l) / (k + 3 * l); @@ -693,18 +693,18 @@ namespace boost static RealType find_degrees_of_freedom(RealType lam, RealType x, RealType p) { const char* function = "non_central_chi_squared<%1%>::find_degrees_of_freedom"; - typedef typename policies::evaluation<RealType, Policy>::type value_type; + typedef typename policies::evaluation<RealType, Policy>::type eval_type; typedef typename policies::normalise< Policy, policies::promote_float<false>, policies::promote_double<false>, policies::discrete_quantile<>, policies::assert_undefined<> >::type forwarding_policy; - value_type result = detail::find_degrees_of_freedom( - static_cast<value_type>(lam), - static_cast<value_type>(x), - static_cast<value_type>(p), - static_cast<value_type>(1-p), + eval_type result = detail::find_degrees_of_freedom( + static_cast<eval_type>(lam), + static_cast<eval_type>(x), + static_cast<eval_type>(p), + static_cast<eval_type>(1-p), forwarding_policy()); return policies::checked_narrowing_cast<RealType, forwarding_policy>( result, @@ -714,18 +714,18 @@ namespace boost static RealType find_degrees_of_freedom(const complemented3_type<A,B,C>& c) { const char* function = "non_central_chi_squared<%1%>::find_degrees_of_freedom"; - typedef typename policies::evaluation<RealType, Policy>::type value_type; + typedef typename policies::evaluation<RealType, Policy>::type eval_type; typedef typename policies::normalise< Policy, policies::promote_float<false>, policies::promote_double<false>, policies::discrete_quantile<>, policies::assert_undefined<> >::type forwarding_policy; - value_type result = detail::find_degrees_of_freedom( - static_cast<value_type>(c.dist), - static_cast<value_type>(c.param1), - static_cast<value_type>(1-c.param2), - static_cast<value_type>(c.param2), + eval_type result = detail::find_degrees_of_freedom( + static_cast<eval_type>(c.dist), + static_cast<eval_type>(c.param1), + static_cast<eval_type>(1-c.param2), + static_cast<eval_type>(c.param2), forwarding_policy()); return policies::checked_narrowing_cast<RealType, forwarding_policy>( result, @@ -734,18 +734,18 @@ namespace boost static RealType find_non_centrality(RealType v, RealType x, RealType p) { const char* function = "non_central_chi_squared<%1%>::find_non_centrality"; - typedef typename policies::evaluation<RealType, Policy>::type value_type; + typedef typename policies::evaluation<RealType, Policy>::type eval_type; typedef typename policies::normalise< Policy, policies::promote_float<false>, policies::promote_double<false>, policies::discrete_quantile<>, policies::assert_undefined<> >::type forwarding_policy; - value_type result = detail::find_non_centrality( - static_cast<value_type>(v), - static_cast<value_type>(x), - static_cast<value_type>(p), - static_cast<value_type>(1-p), + eval_type result = detail::find_non_centrality( + static_cast<eval_type>(v), + static_cast<eval_type>(x), + static_cast<eval_type>(p), + static_cast<eval_type>(1-p), forwarding_policy()); return policies::checked_narrowing_cast<RealType, forwarding_policy>( result, @@ -755,18 +755,18 @@ namespace boost static RealType find_non_centrality(const complemented3_type<A,B,C>& c) { const char* function = "non_central_chi_squared<%1%>::find_non_centrality"; - typedef typename policies::evaluation<RealType, Policy>::type value_type; + typedef typename policies::evaluation<RealType, Policy>::type eval_type; typedef typename policies::normalise< Policy, policies::promote_float<false>, policies::promote_double<false>, policies::discrete_quantile<>, policies::assert_undefined<> >::type forwarding_policy; - value_type result = detail::find_non_centrality( - static_cast<value_type>(c.dist), - static_cast<value_type>(c.param1), - static_cast<value_type>(1-c.param2), - static_cast<value_type>(c.param2), + eval_type result = detail::find_non_centrality( + static_cast<eval_type>(c.dist), + static_cast<eval_type>(c.param1), + static_cast<eval_type>(1-c.param2), + static_cast<eval_type>(c.param2), forwarding_policy()); return policies::checked_narrowing_cast<RealType, forwarding_policy>( result, diff --git a/boost/math/distributions/non_central_t.hpp b/boost/math/distributions/non_central_t.hpp index df7a58e575..718453b657 100644 --- a/boost/math/distributions/non_central_t.hpp +++ b/boost/math/distributions/non_central_t.hpp @@ -90,7 +90,7 @@ namespace boost betaf -= xtermf; T term = poisf * betaf; sum += term; - if((fabs(last_term) > fabs(term)) && (fabs(term/sum) < errtol)) + if((fabs(last_term) >= fabs(term)) && (fabs(term/sum) < errtol)) break; last_term = term; ++count; @@ -358,7 +358,7 @@ namespace boost s = boost::math::sign(pzero - q); if(s != boost::math::sign(guess)) { - guess = s; + guess = static_cast<T>(s); } value_type result = detail::generic_quantile( diff --git a/boost/math/distributions/rayleigh.hpp b/boost/math/distributions/rayleigh.hpp index 01f38c0b01..744733a9fa 100644 --- a/boost/math/distributions/rayleigh.hpp +++ b/boost/math/distributions/rayleigh.hpp @@ -182,7 +182,7 @@ inline RealType cdf(const complemented2_type<rayleigh_distribution<RealType, Pol RealType ea = x * x / (2 * sigma * sigma); // Fix for VC11/12 x64 bug in exp(float): if (ea >= tools::max_value<RealType>()) - return 0; + return 0; result = exp(-ea); return result; } // cdf complement diff --git a/boost/math/distributions/skew_normal.hpp b/boost/math/distributions/skew_normal.hpp index 98348e59bb..f348347ede 100644 --- a/boost/math/distributions/skew_normal.hpp +++ b/boost/math/distributions/skew_normal.hpp @@ -122,15 +122,6 @@ namespace boost{ namespace math{ const RealType shape = dist.shape(); static const char* function = "boost::math::pdf(const skew_normal_distribution<%1%>&, %1%)"; - if((boost::math::isinf)(x)) - { - return 0; // pdf + and - infinity is zero. - } - // Below produces MSVC 4127 warnings, so the above used instead. - //if(std::numeric_limits<RealType>::has_infinity && abs(x) == std::numeric_limits<RealType>::infinity()) - //{ // pdf + and - infinity is zero. - // return 0; - //} RealType result = 0; if(false == detail::check_scale(function, scale, &result, Policy())) @@ -145,6 +136,15 @@ namespace boost{ namespace math{ { return result; } + if((boost::math::isinf)(x)) + { + return 0; // pdf + and - infinity is zero. + } + // Below produces MSVC 4127 warnings, so the above used instead. + //if(std::numeric_limits<RealType>::has_infinity && abs(x) == std::numeric_limits<RealType>::infinity()) + //{ // pdf + and - infinity is zero. + // return 0; + //} if(false == detail::check_x(function, x, &result, Policy())) { return result; diff --git a/boost/math/distributions/triangular.hpp b/boost/math/distributions/triangular.hpp index 78ef0df744..1e49a38faf 100644 --- a/boost/math/distributions/triangular.hpp +++ b/boost/math/distributions/triangular.hpp @@ -8,6 +8,12 @@ #define BOOST_STATS_TRIANGULAR_HPP // http://mathworld.wolfram.com/TriangularDistribution.html +// Note that the 'constructors' defined by Wolfram are difference from those here, +// for example +// N[variance[triangulardistribution{1, +2}, 1.5], 50] computes +// 0.041666666666666666666666666666666666666666666666667 +// TriangularDistribution{1, +2}, 1.5 is the analog of triangular_distribution(1, 1.5, 2) + // http://en.wikipedia.org/wiki/Triangular_distribution #include <boost/math/distributions/fwd.hpp> @@ -449,7 +455,7 @@ namespace boost{ namespace math } RealType lower = dist.lower(); RealType upper = dist.upper(); - if (mode < (upper - lower) / 2) + if (mode >= (upper + lower) / 2) { return lower + sqrt((upper - lower) * (mode - lower)) / constants::root_two<RealType>(); } @@ -475,7 +481,9 @@ namespace boost{ namespace math return result; } return root_two<RealType>() * (lower + upper - 2 * mode) * (2 * lower - upper - mode) * (lower - 2 * upper + mode) / - (5 * pow((lower * lower + upper + upper + mode * mode - lower * upper - lower * mode - upper * mode), RealType(3)/RealType(2))); + (5 * pow((lower * lower + upper * upper + mode * mode + - lower * upper - lower * mode - upper * mode), RealType(3)/RealType(2))); + // #11768: Skewness formula for triangular distribution is incorrect - corrected 29 Oct 2015 for release 1.61. } // RealType skewness(const triangular_distribution<RealType, Policy>& dist) template <class RealType, class Policy> diff --git a/boost/math/distributions/uniform.hpp b/boost/math/distributions/uniform.hpp index a20597a66a..856c144e36 100644 --- a/boost/math/distributions/uniform.hpp +++ b/boost/math/distributions/uniform.hpp @@ -269,15 +269,18 @@ namespace boost{ namespace math return result; } if(false == detail::check_probability("boost::math::quantile(const uniform_distribution<%1%>&, %1%)", q, &result, Policy())) - if(q == 0) - { - return lower; - } - if(q == 1) - { - return upper; - } - return -q * (upper - lower) + upper; + { + return result; + } + if(q == 0) + { + return upper; + } + if(q == 1) + { + return lower; + } + return -q * (upper - lower) + upper; } // RealType quantile(const complemented2_type<uniform_distribution<RealType, Policy>, RealType>& c) template <class RealType, class Policy> |