Replace 32 bit unsigned with 64 bits

This commit is contained in:
Matt Borland 2023-05-23 10:52:50 +02:00
parent 0a222f6e92
commit f968bec20f
No known key found for this signature in database
GPG Key ID: 1FC9FE1989F22A0B
3 changed files with 46 additions and 31 deletions

View File

@ -16,6 +16,7 @@
#include <boost/math/distributions/detail/hypergeometric_cdf.hpp>
#include <boost/math/distributions/detail/hypergeometric_quantile.hpp>
#include <boost/math/special_functions/fpclassify.hpp>
#include <cstdint>
namespace boost { namespace math {
@ -26,7 +27,7 @@ namespace boost { namespace math {
typedef RealType value_type;
typedef Policy policy_type;
hypergeometric_distribution(unsigned r, unsigned n, unsigned N) // Constructor. r=defective/failures/success, n=trials/draws, N=total population.
hypergeometric_distribution(std::uint64_t r, std::uint64_t n, std::uint64_t N) // Constructor. r=defective/failures/success, n=trials/draws, N=total population.
: m_n(n), m_N(N), m_r(r)
{
static const char* function = "boost::math::hypergeometric_distribution<%1%>::hypergeometric_distribution";
@ -34,17 +35,17 @@ namespace boost { namespace math {
check_params(function, &ret);
}
// Accessor functions.
unsigned total()const
std::uint64_t total() const
{
return m_N;
}
unsigned defective()const // successes/failures/events
std::uint64_t defective() const // successes/failures/events
{
return m_r;
}
unsigned sample_count()const
std::uint64_t sample_count()const
{
return m_n;
}
@ -65,9 +66,9 @@ namespace boost { namespace math {
}
return true;
}
bool check_x(unsigned x, const char* function, RealType* result)const
bool check_x(std::uint64_t x, const char* function, RealType* result)const
{
if(x < static_cast<unsigned>((std::max)(0, static_cast<int>(m_n + m_r) - static_cast<int>(m_N))))
if(x < static_cast<std::uint64_t>((std::max)(INT64_C(0), static_cast<std::int64_t>(m_n + m_r) - static_cast<std::int64_t>(m_N))))
{
*result = boost::math::policies::raise_domain_error<RealType>(
function, "Random variable out of range: must be > 0 and > m + r - N but got %1%", static_cast<RealType>(x), Policy());
@ -84,40 +85,40 @@ namespace boost { namespace math {
private:
// Data members:
unsigned m_n; // number of items picked or drawn.
unsigned m_N; // number of "total" items.
unsigned m_r; // number of "defective/successes/failures/events items.
std::uint64_t m_n; // number of items picked or drawn.
std::uint64_t m_N; // number of "total" items.
std::uint64_t m_r; // number of "defective/successes/failures/events items.
}; // class hypergeometric_distribution
typedef hypergeometric_distribution<double> hypergeometric;
template <class RealType, class Policy>
inline const std::pair<unsigned, unsigned> range(const hypergeometric_distribution<RealType, Policy>& dist)
inline const std::pair<std::uint64_t, std::uint64_t> range(const hypergeometric_distribution<RealType, Policy>& dist)
{ // Range of permissible values for random variable x.
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable:4267)
#endif
unsigned r = dist.defective();
unsigned n = dist.sample_count();
unsigned N = dist.total();
unsigned l = static_cast<unsigned>((std::max)(0, static_cast<int>(n + r) - static_cast<int>(N)));
unsigned u = (std::min)(r, n);
return std::pair<unsigned, unsigned>(l, u);
std::uint64_t r = dist.defective();
std::uint64_t n = dist.sample_count();
std::uint64_t N = dist.total();
std::uint64_t l = static_cast<std::uint64_t>((std::max)(INT64_C(0), static_cast<std::int64_t>(n + r) - static_cast<std::int64_t>(N)));
std::uint64_t u = (std::min)(r, n);
return std::pair<std::uint64_t, std::uint64_t>(l, u);
#ifdef _MSC_VER
# pragma warning(pop)
#endif
}
template <class RealType, class Policy>
inline const std::pair<unsigned, unsigned> support(const hypergeometric_distribution<RealType, Policy>& d)
inline const std::pair<std::uint64_t, std::uint64_t> support(const hypergeometric_distribution<RealType, Policy>& d)
{
return range(d);
}
template <class RealType, class Policy>
inline RealType pdf(const hypergeometric_distribution<RealType, Policy>& dist, const unsigned& x)
inline RealType pdf(const hypergeometric_distribution<RealType, Policy>& dist, const std::uint64_t& x)
{
static const char* function = "boost::math::pdf(const hypergeometric_distribution<%1%>&, const %1%&)";
RealType result = 0;
@ -136,7 +137,7 @@ namespace boost { namespace math {
BOOST_MATH_STD_USING
static const char* function = "boost::math::pdf(const hypergeometric_distribution<%1%>&, const %1%&)";
RealType r = static_cast<RealType>(x);
unsigned u = itrunc(r, typename policies::normalise<Policy, policies::rounding_error<policies::ignore_error> >::type());
auto u = lltrunc(r, typename policies::normalise<Policy, policies::rounding_error<policies::ignore_error> >::type());
if(u != r)
{
return boost::math::policies::raise_domain_error<RealType>(
@ -146,7 +147,7 @@ namespace boost { namespace math {
}
template <class RealType, class Policy>
inline RealType cdf(const hypergeometric_distribution<RealType, Policy>& dist, const unsigned& x)
inline RealType cdf(const hypergeometric_distribution<RealType, Policy>& dist, const std::uint64_t& x)
{
static const char* function = "boost::math::cdf(const hypergeometric_distribution<%1%>&, const %1%&)";
RealType result = 0;
@ -165,7 +166,7 @@ namespace boost { namespace math {
BOOST_MATH_STD_USING
static const char* function = "boost::math::cdf(const hypergeometric_distribution<%1%>&, const %1%&)";
RealType r = static_cast<RealType>(x);
unsigned u = itrunc(r, typename policies::normalise<Policy, policies::rounding_error<policies::ignore_error> >::type());
auto u = lltrunc(r, typename policies::normalise<Policy, policies::rounding_error<policies::ignore_error> >::type());
if(u != r)
{
return boost::math::policies::raise_domain_error<RealType>(
@ -175,7 +176,7 @@ namespace boost { namespace math {
}
template <class RealType, class Policy>
inline RealType cdf(const complemented2_type<hypergeometric_distribution<RealType, Policy>, unsigned>& c)
inline RealType cdf(const complemented2_type<hypergeometric_distribution<RealType, Policy>, std::uint64_t>& c)
{
static const char* function = "boost::math::cdf(const hypergeometric_distribution<%1%>&, const %1%&)";
RealType result = 0;
@ -194,7 +195,7 @@ namespace boost { namespace math {
BOOST_MATH_STD_USING
static const char* function = "boost::math::cdf(const hypergeometric_distribution<%1%>&, const %1%&)";
RealType r = static_cast<RealType>(c.param);
unsigned u = itrunc(r, typename policies::normalise<Policy, policies::rounding_error<policies::ignore_error> >::type());
std::uint64_t u = lltrunc(r, typename policies::normalise<Policy, policies::rounding_error<policies::ignore_error> >::type());
if(u != r)
{
return boost::math::policies::raise_domain_error<RealType>(
@ -208,11 +209,14 @@ namespace boost { namespace math {
{
BOOST_MATH_STD_USING // for ADL of std functions
// Checking function argument
RealType result = 0;
// Checking function argument
RealType result = 0;
const char* function = "boost::math::quantile(const hypergeometric_distribution<%1%>&, %1%)";
if (false == dist.check_params(function, &result)) return result;
if(false == detail::check_probability(function, p, &result, Policy())) return result;
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.defective(), dist.sample_count(), dist.total(), Policy()));
} // quantile
@ -225,8 +229,10 @@ namespace boost { namespace math {
// Checking function argument
RealType result = 0;
const char* function = "quantile(const complemented2_type<hypergeometric_distribution<%1%>, %1%>&)";
if (false == c.dist.check_params(function, &result)) return result;
if(false == detail::check_probability(function, c.param, &result, Policy())) return result;
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.defective(), c.dist.sample_count(), c.dist.total(), Policy()));
} // quantile

View File

@ -8,6 +8,15 @@
// (5) are commented out as they are too close to numeric_limits<double>::min(), to expect
// our implementation to cope :-(
//
#ifdef _MSC_VER
#pragma warning (disable:4127 4512)
#elif __GNUC__ >= 5
# pragma GCC diagnostic ignored "-Woverflow"
#elif defined(__clang__)
# pragma clang diagnostic ignored "-Wliteral-range"
#endif
#define SC_(x) static_cast<typename table_type<T>::type>(BOOST_JOIN(x, L))
static const std::array<std::array<T, 7>, 1542-5> hypergeometric_dist_data2 = {{
{{ SC_(3.0), SC_(3.0), SC_(4.0), SC_(3.0), SC_(0.25), SC_(1.0), SC_(0.0) }},

View File

@ -470,8 +470,8 @@ void test_spots(RealType /*T*/, const char* type_name)
test_spot(40, 70, 89, 170, static_cast<T>(0.0721901023798991), static_cast<T>(0.885447799131944), static_cast<T>(1 - 0.885447799131944), tolerance);
boost::math::hypergeometric_distribution<RealType> d(50, 200, 500);
BOOST_CHECK_EQUAL(range(d).first, 0u);
BOOST_CHECK_EQUAL(range(d).second, 50u);
BOOST_CHECK_EQUAL(range(d).first, UINT64_C(0));
BOOST_CHECK_EQUAL(range(d).second, UINT64_C(50));
BOOST_CHECK_CLOSE(mean(d), static_cast<RealType>(20), tolerance);
BOOST_CHECK_CLOSE(mode(d), static_cast<RealType>(20), tolerance);
// Test values and code revised to correct kurtosis using Mathematica algorithm and test values.