Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Logpdf support #762

Merged
merged 20 commits into from
Apr 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,6 @@ Makefile
**CTestTestfile.cmake
DartConfiguration.tcl
cmake-build-debug/*
.cmake/*
build.ninja
.ninja*
1 change: 1 addition & 0 deletions include/boost/math/distributions/arcsine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#ifndef BOOST_MATH_DIST_ARCSINE_HPP
#define BOOST_MATH_DIST_ARCSINE_HPP

#include <cmath>
#include <boost/math/distributions/fwd.hpp>
#include <boost/math/distributions/complement.hpp> // complements.
#include <boost/math/distributions/detail/common_error_handling.hpp> // error checks.
Expand Down
38 changes: 7 additions & 31 deletions include/boost/math/distributions/chi_squared.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ template <class RealType = double, class Policy = policies::policy<> >
class chi_squared_distribution
{
public:
typedef RealType value_type;
typedef Policy policy_type;
using value_type = RealType;
using policy_type = Policy;

chi_squared_distribution(RealType i) : m_df(i)
explicit chi_squared_distribution(RealType i) : m_df(i)
{
RealType result;
detail::check_df(
Expand All @@ -53,7 +53,7 @@ class chi_squared_distribution
RealType m_df; // degrees of freedom is a positive real number.
}; // class chi_squared_distribution

typedef chi_squared_distribution<double> chi_squared;
using chi_squared = chi_squared_distribution<double>;

#ifdef __cpp_deduction_guides
template <class RealType>
Expand All @@ -66,7 +66,7 @@ chi_squared_distribution(RealType)->chi_squared_distribution<typename boost::mat
#endif

template <class RealType, class Policy>
inline const std::pair<RealType, RealType> range(const chi_squared_distribution<RealType, Policy>& /*dist*/)
inline std::pair<RealType, RealType> range(const chi_squared_distribution<RealType, Policy>& /*dist*/)
{ // Range of permissible values for random variable x.
if (std::numeric_limits<RealType>::has_infinity)
{
Expand All @@ -84,7 +84,7 @@ inline const std::pair<RealType, RealType> range(const chi_squared_distribution<
#endif

template <class RealType, class Policy>
inline const std::pair<RealType, RealType> support(const chi_squared_distribution<RealType, Policy>& /*dist*/)
inline std::pair<RealType, RealType> support(const chi_squared_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.
return std::pair<RealType, RealType>(static_cast<RealType>(0), tools::max_value<RealType>()); // 0 to + infinity.
Expand Down Expand Up @@ -224,17 +224,6 @@ inline RealType mode(const chi_squared_distribution<RealType, Policy>& dist)
{
RealType df = dist.degrees_of_freedom();
static const char* function = "boost::math::mode(const chi_squared_distribution<%1%>&)";
// Most sources only define mode for df >= 2,
// but for 0 <= df <= 2, the pdf maximum actually occurs at random variate = 0;
// So one could extend the definition of mode thus:
//if(df < 0)
//{
// return policies::raise_domain_error<RealType>(
// function,
// "Chi-Squared distribution only has a mode for degrees of freedom >= 0, but got degrees of freedom = %1%.",
// df, Policy());
//}
//return (df <= 2) ? 0 : df - 2;

if(df < 2)
return policies::raise_domain_error<RealType>(
Expand All @@ -244,25 +233,12 @@ inline RealType mode(const chi_squared_distribution<RealType, Policy>& dist)
return df - 2;
}

//template <class RealType, class Policy>
//inline RealType median(const chi_squared_distribution<RealType, Policy>& dist)
//{ // Median is given by Quantile[dist, 1/2]
// RealType df = dist.degrees_of_freedom();
// if(df <= 1)
// return tools::domain_error<RealType>(
// BOOST_CURRENT_FUNCTION,
// "The Chi-Squared distribution only has a mode for degrees of freedom >= 2, but got degrees of freedom = %1%.",
// df);
// return df - RealType(2)/3;
//}
// Now implemented via quantile(half) in derived accessors.

template <class RealType, class Policy>
inline RealType skewness(const chi_squared_distribution<RealType, Policy>& dist)
{
BOOST_MATH_STD_USING // For ADL
RealType df = dist.degrees_of_freedom();
return sqrt (8 / df); // == 2 * sqrt(2 / df);
return sqrt (8 / df);
}

template <class RealType, class Policy>
Expand Down
7 changes: 7 additions & 0 deletions include/boost/math/distributions/detail/derived_accessors.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,13 @@ inline typename Distribution::value_type pdf(const Distribution& dist, const Rea
return pdf(dist, static_cast<value_type>(x));
}
template <class Distribution, class RealType>
inline typename Distribution::value_type logpdf(const Distribution& dist, const RealType& x)
{
using std::log;
typedef typename Distribution::value_type value_type;
return log(pdf(dist, static_cast<value_type>(x)));
}
template <class Distribution, class RealType>
inline typename Distribution::value_type cdf(const Distribution& dist, const RealType& x)
{
typedef typename Distribution::value_type value_type;
Expand Down
30 changes: 24 additions & 6 deletions include/boost/math/distributions/exponential.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ template <class RealType = double, class Policy = policies::policy<> >
class exponential_distribution
{
public:
typedef RealType value_type;
typedef Policy policy_type;
using value_type = RealType;
using policy_type = Policy;

exponential_distribution(RealType l_lambda = 1)
explicit exponential_distribution(RealType l_lambda = 1)
: m_lambda(l_lambda)
{
RealType err;
Expand All @@ -76,15 +76,15 @@ class exponential_distribution
RealType m_lambda;
};

typedef exponential_distribution<double> exponential;
using exponential = exponential_distribution<double>;

#ifdef __cpp_deduction_guides
template <class RealType>
exponential_distribution(RealType)->exponential_distribution<typename boost::math::tools::promote_args<RealType>::type>;
#endif

template <class RealType, class Policy>
inline const std::pair<RealType, RealType> range(const exponential_distribution<RealType, Policy>& /*dist*/)
inline std::pair<RealType, RealType> range(const exponential_distribution<RealType, Policy>& /*dist*/)
{ // Range of permissible values for random variable x.
if (std::numeric_limits<RealType>::has_infinity)
{
Expand All @@ -98,7 +98,7 @@ inline const std::pair<RealType, RealType> range(const exponential_distribution<
}

template <class RealType, class Policy>
inline const std::pair<RealType, RealType> support(const exponential_distribution<RealType, Policy>& /*dist*/)
inline std::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;
Expand Down Expand Up @@ -127,6 +127,24 @@ inline RealType pdf(const exponential_distribution<RealType, Policy>& dist, cons
return result;
} // pdf

template <class RealType, class Policy>
inline RealType logpdf(const exponential_distribution<RealType, Policy>& dist, const RealType& x)
{
BOOST_MATH_STD_USING // for ADL of std functions

static const char* function = "boost::math::logpdf(const exponential_distribution<%1%>&, %1%)";

RealType lambda = dist.lambda();
RealType result = -std::numeric_limits<RealType>::infinity();
if(0 == detail::verify_lambda(function, lambda, &result, Policy()))
return result;
if(0 == detail::verify_exp_x(function, x, &result, Policy()))
return result;

result = log(lambda) - lambda * x;
return result;
} // logpdf

template <class RealType, class Policy>
inline RealType cdf(const exponential_distribution<RealType, Policy>& dist, const RealType& x)
{
Expand Down
40 changes: 33 additions & 7 deletions include/boost/math/distributions/extreme_value.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ template <class RealType = double, class Policy = policies::policy<> >
class extreme_value_distribution
{
public:
typedef RealType value_type;
typedef Policy policy_type;
using value_type = RealType;
using policy_type = Policy;

extreme_value_distribution(RealType a = 0, RealType b = 1)
explicit extreme_value_distribution(RealType a = 0, RealType b = 1)
: m_a(a), m_b(b)
{
RealType err;
Expand All @@ -68,10 +68,11 @@ class extreme_value_distribution
RealType scale()const { return m_b; }

private:
RealType m_a, m_b;
RealType m_a;
RealType m_b;
};

typedef extreme_value_distribution<double> extreme_value;
using extreme_value = extreme_value_distribution<double>;

#ifdef __cpp_deduction_guides
template <class RealType>
Expand All @@ -81,7 +82,7 @@ extreme_value_distribution(RealType,RealType)->extreme_value_distribution<typena
#endif

template <class RealType, class Policy>
inline const std::pair<RealType, RealType> range(const extreme_value_distribution<RealType, Policy>& /*dist*/)
inline std::pair<RealType, RealType> range(const extreme_value_distribution<RealType, Policy>& /*dist*/)
{ // Range of permissible values for random variable x.
using boost::math::tools::max_value;
return std::pair<RealType, RealType>(
Expand All @@ -90,7 +91,7 @@ inline const std::pair<RealType, RealType> range(const extreme_value_distributio
}

template <class RealType, class Policy>
inline const std::pair<RealType, RealType> support(const extreme_value_distribution<RealType, Policy>& /*dist*/)
inline std::pair<RealType, RealType> support(const extreme_value_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;
Expand Down Expand Up @@ -122,6 +123,31 @@ inline RealType pdf(const extreme_value_distribution<RealType, Policy>& dist, co
return result;
} // pdf

template <class RealType, class Policy>
inline RealType logpdf(const extreme_value_distribution<RealType, Policy>& dist, const RealType& x)
{
BOOST_MATH_STD_USING // for ADL of std functions

static const char* function = "boost::math::logpdf(const extreme_value_distribution<%1%>&, %1%)";

RealType a = dist.location();
RealType b = dist.scale();
RealType result = -std::numeric_limits<RealType>::infinity();
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;
if(e < tools::log_max_value<RealType>())
result = log(1/b) + e - exp(e);
// else.... result *must* be zero since exp(e) is infinite...
return result;
} // logpdf

template <class RealType, class Policy>
inline RealType cdf(const extreme_value_distribution<RealType, Policy>& dist, const RealType& x)
{
Expand Down
38 changes: 33 additions & 5 deletions include/boost/math/distributions/gamma.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <boost/math/distributions/complement.hpp>

#include <utility>
#include <type_traits>

namespace boost{ namespace math
{
Expand Down Expand Up @@ -71,10 +72,10 @@ template <class RealType = double, class Policy = policies::policy<> >
class gamma_distribution
{
public:
typedef RealType value_type;
typedef Policy policy_type;
using value_type = RealType;
using policy_type = Policy;

gamma_distribution(RealType l_shape, RealType l_scale = 1)
explicit gamma_distribution(RealType l_shape, RealType l_scale = 1)
: m_shape(l_shape), m_scale(l_scale)
{
RealType result;
Expand Down Expand Up @@ -108,14 +109,14 @@ gamma_distribution(RealType,RealType)->gamma_distribution<typename boost::math::
#endif

template <class RealType, class Policy>
inline const std::pair<RealType, RealType> range(const gamma_distribution<RealType, Policy>& /* dist */)
inline std::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 std::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>());
}

template <class RealType, class Policy>
inline const std::pair<RealType, RealType> support(const gamma_distribution<RealType, Policy>& /* dist */)
inline std::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;
Expand Down Expand Up @@ -147,6 +148,33 @@ inline RealType pdf(const gamma_distribution<RealType, Policy>& dist, const Real
return result;
} // pdf

template <class RealType, class Policy>
inline RealType logpdf(const gamma_distribution<RealType, Policy>& dist, const RealType& x)
{
BOOST_MATH_STD_USING // for ADL of std functions
using boost::math::lgamma;

static const char* function = "boost::math::logpdf(const gamma_distribution<%1%>&, %1%)";

RealType k = dist.shape();
RealType theta = dist.scale();

RealType result = -std::numeric_limits<RealType>::infinity();
if(false == detail::check_gamma(function, theta, k, &result, Policy()))
return result;
if(false == detail::check_gamma_x(function, x, &result, Policy()))
return result;

if(x == 0)
{
return std::numeric_limits<RealType>::quiet_NaN();
}

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

return result;
} // logpdf

template <class RealType, class Policy>
inline RealType cdf(const gamma_distribution<RealType, Policy>& dist, const RealType& x)
{
Expand Down
Loading