Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
b7e93c4
Initial implementation with arcsine testing
JacobHass8 May 29, 2026
8c2f4fc
Deleted bernoulli tests
JacobHass8 May 29, 2026
55b7cd0
Fixed bugs in test_dist_helpers and arcsine distribution
JacobHass8 May 30, 2026
1b4d33b
Added invalid parameter construction function
JacobHass8 May 30, 2026
89eaaab
Added bernoulli distribution
JacobHass8 May 31, 2026
db113bb
Added beta distribution
JacobHass8 May 31, 2026
8c38d3a
Added binomial distribution
JacobHass8 May 31, 2026
eabc1ac
Added infinite support and cauchy dist
JacobHass8 May 31, 2026
12f40d4
Added exponential distribution
JacobHass8 May 31, 2026
37dfe2d
Changed signature of test_invalid_support; added f distribution
JacobHass8 May 31, 2026
2280c01
Added more tests for fisher distribution
JacobHass8 May 31, 2026
3007654
Added gamma distribution
JacobHass8 May 31, 2026
8a9cfec
Added geometric distribution
JacobHass8 May 31, 2026
3df106a
Reverted gamma distribution
JacobHass8 Jun 1, 2026
f4360d6
Changed gamma support to [0, inf)
JacobHass8 Jun 1, 2026
328fe17
Added some tests for gamma distribution
JacobHass8 Jun 1, 2026
54d899f
Added inverse gamma dist
JacobHass8 Jun 1, 2026
028bd48
Reverted some of the tests
JacobHass8 Jun 1, 2026
709bb08
Reverted more inverse gamma tests
JacobHass8 Jun 1, 2026
46585c0
Added inverse gaussian tests
JacobHass8 Jun 1, 2026
3df8049
Added more geometric dist tests
JacobHass8 Jun 1, 2026
12e19d4
Added hyperexponential tests
JacobHass8 Jun 1, 2026
3d00920
Added hypergeometric tests
JacobHass8 Jun 2, 2026
08cdb17
test_hypergeometric_dist.cpp
JacobHass8 Jun 2, 2026
b76ff8c
Fixed c++14 is_constructible_v
JacobHass8 Jun 13, 2026
778e118
Macos fix
JacobHass8 Jun 13, 2026
a31c6f2
Added macos debugging info
JacobHass8 Jun 13, 2026
7202c5e
Another macos fix?
JacobHass8 Jun 13, 2026
0de31d5
Added try catch for debugging
JacobHass8 Jun 13, 2026
82a2ffd
Deleted failing hypergeometric test; input -1 coerced to uint
JacobHass8 Jun 14, 2026
4cf0dd6
Changed inverse gamma support to [0, inf)
JacobHass8 Jun 19, 2026
686cfe2
Hit all inverse gamma
JacobHass8 Jun 19, 2026
0ca5957
Added more inverse gamma tests
JacobHass8 Jun 19, 2026
39c250a
Fixed real_concept tests
JacobHass8 Jun 30, 2026
2431ddb
Added boost license
JacobHass8 Jul 1, 2026
8363bbb
Added macros from test_out_of_range
JacobHass8 Jul 1, 2026
7755cb2
Hopefully fixed constexpr bugs
JacobHass8 Jul 1, 2026
901cbb7
Deleted windows macros
JacobHass8 Jul 1, 2026
48c0e4b
Tried to implement BOOST_MATH_IF_CONSTEXPR
JacobHass8 Jul 1, 2026
d43d0ec
Reverted constexpr
JacobHass8 Jul 1, 2026
6902ae7
Got rid of macros
JacobHass8 Jul 1, 2026
a5ed0b9
Added new lineat end of file
JacobHass8 Jul 1, 2026
6b5c74f
Remove uses of naked if constexpr
mborland Jul 1, 2026
e880139
Disable test with mandatory throw
mborland Jul 1, 2026
cfcaa89
Use SFINAE
mborland Jul 2, 2026
fe2a4d8
Initializer list .data() isn't available in libc++
mborland Jul 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions include/boost/math/distributions/arcsine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,11 +229,11 @@ namespace boost
// Special cases:
if (p == 0)
{
return 0;
return x_min;
}
if (p == 1)
{
return 1;
return x_max;
}
using boost::math::constants::half_pi;
RealType sin2hpip = sin(half_pi<RealType>() * p);
Expand All @@ -247,11 +247,11 @@ namespace boost
// Special cases:
if (q == 1)
{
return 0;
return x_min;
}
if (q == 0)
{
return 1;
return x_max;
}
// Naive RealType p = 1 - q; result = sin(half_pi<RealType>() * p); loses accuracy, so use a cos alternative instead.
//result = cos(half_pi<RealType>() * q); // for arcsine(0,1)
Expand Down
64 changes: 64 additions & 0 deletions include/boost/math/distributions/detail/common_error_handling.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,70 @@ BOOST_MATH_GPU_ENABLED inline bool check_finite(
return true;
}

template <class RealType, class Policy>
BOOST_MATH_GPU_ENABLED inline bool check_inverse_gamma_shape(
const char* function, // inverse_gamma
RealType shape, // shape aka alpha
RealType* result, // to update, perhaps with NaN
const Policy& pol)
{ // Sources say shape argument must be > 0
// but seems logical to allow shape zero as special case,
// returning pdf and cdf zero (but not < 0).
// (Functions like mean, variance with other limits on shape are checked
// in version including an operator & limit below).
if((shape < 0) || !(boost::math::isfinite)(shape))
{
*result = policies::raise_domain_error<RealType>(
function,
"Shape parameter is %1%, but must be >= 0 !", shape, pol);
return false;
}
return true;
} //bool check_inverse_gamma_shape

template <class RealType, class Policy>
BOOST_MATH_GPU_ENABLED inline bool check_inverse_gamma_x(
const char* function,
RealType const& x,
RealType* result, const Policy& pol)
{
if((x < 0) || !(boost::math::isfinite)(x))
{
*result = policies::raise_domain_error<RealType>(
function,
"Random variate is %1% but must be >= 0 !", x, pol);
return false;
}
return true;
}

template <class RealType, class Policy>
BOOST_MATH_GPU_ENABLED inline bool check_inverse_gamma_x_positive(
const char* function,
RealType const& x,
RealType* result, const Policy& pol)
{
if((x < 0) || (boost::math::isnan)(x))
{
*result = policies::raise_domain_error<RealType>(
function,
"Random variate is %1% but must be >= 0 !", x, pol);
return false;
}
return true;
}

template <class RealType, class Policy>
BOOST_MATH_GPU_ENABLED inline bool check_inverse_gamma(
const char* function, // TODO swap these over, so shape is first.
RealType scale, // scale aka beta
RealType shape, // shape aka alpha
RealType* result, const Policy& pol)
{
return check_scale(function, scale, result, pol)
&& check_inverse_gamma_shape(function, shape, result, pol);
} // bool check_inverse_gamma

} // namespace detail
} // namespace math
} // namespace boost
Expand Down
22 changes: 9 additions & 13 deletions include/boost/math/distributions/exponential.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,15 @@ template <class RealType, class Policy>
BOOST_MATH_GPU_ENABLED inline boost::math::pair<RealType, RealType> support(const exponential_distribution<RealType, Policy>& /*dist*/)
{ // Range of supported values for random variable x.
// This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
using boost::math::tools::max_value;
using boost::math::tools::min_value;
return boost::math::pair<RealType, RealType>(min_value<RealType>(), max_value<RealType>());
// min_value<RealType>() to avoid a discontinuity at x = 0.
BOOST_MATH_IF_CONSTEXPR (boost::math::numeric_limits<RealType>::has_infinity)
{
return boost::math::pair<RealType, RealType>(static_cast<RealType>(0), boost::math::numeric_limits<RealType>::infinity()); // - to + infinity.
}
else
{ // Can only use max_value.
using boost::math::tools::max_value;
return boost::math::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>()); // - to + max.
}
}

template <class RealType, class Policy>
Expand All @@ -128,9 +133,6 @@ BOOST_MATH_GPU_ENABLED inline RealType pdf(const exponential_distribution<RealTy
return result;
if(0 == detail::verify_exp_x(function, x, &result, Policy()))
return result;
// Workaround for VC11/12 bug:
if ((boost::math::isinf)(x))
return 0;
result = lambda * exp(-lambda * x);
return result;
} // pdf
Expand Down Expand Up @@ -225,9 +227,6 @@ BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type<exponential_
return result;
if(0 == detail::verify_exp_x(function, c.param, &result, Policy()))
return result;
// Workaround for VC11/12 bug:
if (c.param >= tools::max_value<RealType>())
return 0;
result = exp(-c.param * lambda);

return result;
Expand All @@ -246,9 +245,6 @@ BOOST_MATH_GPU_ENABLED inline RealType logcdf(const complemented2_type<exponenti
return result;
if(0 == detail::verify_exp_x(function, c.param, &result, Policy()))
return result;
// Workaround for VC11/12 bug:
if (c.param >= tools::max_value<RealType>())
return 0;
result = -c.param * lambda;

return result;
Expand Down
28 changes: 14 additions & 14 deletions include/boost/math/distributions/fisher_f.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,10 @@ BOOST_MATH_GPU_ENABLED inline RealType cdf(const fisher_f_distribution<RealType,
RealType df2 = dist.degrees_of_freedom2();
// Error check:
RealType error_result = 0;
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))
Expand Down Expand Up @@ -201,10 +201,10 @@ BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type<fisher_f_dis
RealType x = c.param;
// Error check:
RealType error_result = 0;
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))
Expand Down Expand Up @@ -260,10 +260,10 @@ BOOST_MATH_GPU_ENABLED inline RealType mean(const fisher_f_distribution<RealType
RealType df2 = dist.degrees_of_freedom2();
// Error check:
RealType error_result = 0;
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(df2 <= 2)
{
Expand All @@ -281,10 +281,10 @@ BOOST_MATH_GPU_ENABLED inline RealType variance(const fisher_f_distribution<Real
RealType df2 = dist.degrees_of_freedom2();
// Error check:
RealType error_result = 0;
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(df2 <= 4)
{
Expand All @@ -302,10 +302,10 @@ BOOST_MATH_GPU_ENABLED inline RealType mode(const fisher_f_distribution<RealType
RealType df2 = dist.degrees_of_freedom2();
// Error check:
RealType error_result = 0;
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(df1 <= 2)
{
Expand Down Expand Up @@ -333,10 +333,10 @@ BOOST_MATH_GPU_ENABLED inline RealType skewness(const fisher_f_distribution<Real
RealType df2 = dist.degrees_of_freedom2();
// Error check:
RealType error_result = 0;
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(df2 <= 6)
{
Expand Down Expand Up @@ -364,10 +364,10 @@ BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const fisher_f_distributi
RealType df2 = dist.degrees_of_freedom2();
// Error check:
RealType error_result = 0;
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(df2 <= 8)
{
Expand Down
71 changes: 61 additions & 10 deletions include/boost/math/distributions/gamma.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,22 @@ BOOST_MATH_GPU_ENABLED inline bool check_gamma_x(
return true;
}

template <class RealType, class Policy>
BOOST_MATH_GPU_ENABLED inline bool check_gamma_x_positive(
const char* function,
RealType const& x,
RealType* result, const Policy& pol)
{
if((x < 0) || (boost::math::isnan)(x))
{
*result = policies::raise_domain_error<RealType>(
function,
"Random variate is %1% but must be >= 0 !", x, pol);
return false;
}
return true;
}

template <class RealType, class Policy>
BOOST_MATH_GPU_ENABLED inline bool check_gamma(
const char* function,
Expand Down Expand Up @@ -112,17 +128,30 @@ gamma_distribution(RealType,RealType)->gamma_distribution<typename boost::math::
template <class RealType, class Policy>
BOOST_MATH_GPU_ENABLED inline boost::math::pair<RealType, RealType> range(const gamma_distribution<RealType, Policy>& /* dist */)
{ // Range of permissible values for random variable x.
using boost::math::tools::max_value;
return boost::math::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>());
BOOST_MATH_IF_CONSTEXPR (boost::math::numeric_limits<RealType>::has_infinity)
{
return boost::math::pair<RealType, RealType>(static_cast<RealType>(0), boost::math::numeric_limits<RealType>::infinity()); // 0 to + infinity.
}
else
{
using boost::math::tools::max_value;
return boost::math::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>()); // 0 to + max
}
}

template <class RealType, class Policy>
BOOST_MATH_GPU_ENABLED inline boost::math::pair<RealType, RealType> support(const gamma_distribution<RealType, Policy>& /* dist */)
{ // Range of supported values for random variable x.
// This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
using boost::math::tools::max_value;
using boost::math::tools::min_value;
return boost::math::pair<RealType, RealType>(min_value<RealType>(), max_value<RealType>());
BOOST_MATH_IF_CONSTEXPR (boost::math::numeric_limits<RealType>::has_infinity)
{
return boost::math::pair<RealType, RealType>(static_cast<RealType>(0), boost::math::numeric_limits<RealType>::infinity()); // 0 to + infinity.
}
else
{
using boost::math::tools::max_value;
return boost::math::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>()); // 0 to + max
}
}

template <class RealType, class Policy>
Expand All @@ -138,13 +167,18 @@ BOOST_MATH_GPU_ENABLED inline RealType pdf(const gamma_distribution<RealType, Po
RealType result = 0;
if(false == detail::check_gamma(function, scale, shape, &result, Policy()))
return result;
if(false == detail::check_gamma_x(function, x, &result, Policy()))
if(false == detail::check_gamma_x_positive(function, x, &result, Policy()))
return result;

if(x == 0)
{
return 0;
}
if ((boost::math::isinf)(x))
{
return 0;
}

result = gamma_p_derivative(shape, x / scale, Policy()) / scale;
return result;
} // pdf
Expand All @@ -168,9 +202,8 @@ BOOST_MATH_GPU_ENABLED inline RealType logpdf(const gamma_distribution<RealType,

if(x == 0)
{
return boost::math::numeric_limits<RealType>::quiet_NaN();
return policies::raise_domain_error<RealType>(function, "Random variate is %1% but must be > 0 !", x, Policy());;
}

result = -k*log(theta) + (k-1)*log(x) - lgamma(k) - (x/theta);

return result;
Expand All @@ -189,8 +222,17 @@ BOOST_MATH_GPU_ENABLED inline RealType cdf(const gamma_distribution<RealType, Po
RealType result = 0;
if(false == detail::check_gamma(function, scale, shape, &result, Policy()))
return result;
if(false == detail::check_gamma_x(function, x, &result, Policy()))
if(false == detail::check_gamma_x_positive(function, x, &result, Policy()))
return result;

if(x == 0)
{
return 0;
}
if ((boost::math::isinf)(x))
{
return 1;
}

result = boost::math::gamma_p(shape, x / scale, Policy());
return result;
Expand Down Expand Up @@ -233,9 +275,18 @@ BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type<gamma_distri
RealType result = 0;
if(false == detail::check_gamma(function, scale, shape, &result, Policy()))
return result;
if(false == detail::check_gamma_x(function, c.param, &result, Policy()))
if(false == detail::check_gamma_x_positive(function, c.param, &result, Policy()))
return result;

if(c.param == 0)
{
return 1;
}
if ((boost::math::isinf)(c.param))
{
return 0;
}

result = gamma_q(shape, c.param / scale, Policy());

return result;
Expand Down
Loading
Loading