add math::lgamma

This commit is contained in:
bolero-MURAKAMI 2013-04-23 19:03:03 +09:00
parent a55c430f09
commit 5f40808f75
58 changed files with 323 additions and 116 deletions

View file

@ -57,7 +57,7 @@ namespace sprout {
template<typename Outdirected> template<typename Outdirected>
SPROUT_CONSTEXPR typename std::iterator_traits<Outdirected>::value_type SPROUT_CONSTEXPR typename std::iterator_traits<Outdirected>::value_type
operator()(Outdirected const& x) const { operator()(Outdirected const& x) const {
return calc(x, d_ + depth_ * sprout::math::sin(sprout::math::two_pi<Value>() * rate_ * x.index() / samples_per_sec_)); return calc(x, d_ + depth_ * sprout::sin(sprout::math::two_pi<Value>() * rate_ * x.index() / samples_per_sec_));
} }
}; };

View file

@ -21,8 +21,8 @@ namespace sprout {
public: public:
SPROUT_CONSTEXPR T SPROUT_CONSTEXPR T
operator()(T const& x) const { operator()(T const& x) const {
return x >= 0 ? sprout::math::atan(x) / sprout::math::half_pi<T>() return x >= 0 ? sprout::atan(x) / sprout::math::half_pi<T>()
: sprout::math::atan(x) / sprout::math::half_pi<T>() / 10 : sprout::atan(x) / sprout::math::half_pi<T>() / 10
; ;
} }
}; };

View file

@ -56,7 +56,7 @@ namespace sprout {
template<typename Outdirected> template<typename Outdirected>
SPROUT_CONSTEXPR typename std::iterator_traits<Outdirected>::value_type SPROUT_CONSTEXPR typename std::iterator_traits<Outdirected>::value_type
operator()(Outdirected const& x) const { operator()(Outdirected const& x) const {
return calc(x, d_ + depth_ * sprout::math::sin(sprout::math::two_pi<Value>() * rate_ * x.index() / samples_per_sec_)); return calc(x, d_ + depth_ * sprout::sin(sprout::math::two_pi<Value>() * rate_ * x.index() / samples_per_sec_));
} }
}; };

View file

@ -21,7 +21,7 @@ namespace sprout {
inline SPROUT_CONSTEXPR std::size_t inline SPROUT_CONSTEXPR std::size_t
float_hash_value_impl_4(T v, int exp, std::size_t seed, std::size_t length, std::size_t i = 0) { float_hash_value_impl_4(T v, int exp, std::size_t seed, std::size_t length, std::size_t i = 0) {
return i != length ? sprout::detail::float_hash_value_impl_4( return i != length ? sprout::detail::float_hash_value_impl_4(
sprout::math::ldexp(v - static_cast<T>(static_cast<std::size_t>(v)), std::numeric_limits<std::size_t>::digits), sprout::ldexp(v - static_cast<T>(static_cast<std::size_t>(v)), std::numeric_limits<std::size_t>::digits),
exp, sprout::detail::hash_float_combine(seed, static_cast<std::size_t>(v)), exp, sprout::detail::hash_float_combine(seed, static_cast<std::size_t>(v)),
length, i + 1 length, i + 1
) )
@ -32,7 +32,7 @@ namespace sprout {
inline SPROUT_CONSTEXPR std::size_t inline SPROUT_CONSTEXPR std::size_t
float_hash_value_impl_3(T v, int exp) { float_hash_value_impl_3(T v, int exp) {
return sprout::detail::float_hash_value_impl_4( return sprout::detail::float_hash_value_impl_4(
sprout::math::ldexp(v - static_cast<T>(static_cast<std::size_t>(v)), std::numeric_limits<std::size_t>::digits), sprout::ldexp(v - static_cast<T>(static_cast<std::size_t>(v)), std::numeric_limits<std::size_t>::digits),
exp, static_cast<std::size_t>(v), exp, static_cast<std::size_t>(v),
(std::numeric_limits<T>::digits * sprout::detail::static_log2<std::numeric_limits<T>::radix>::value + std::numeric_limits<std::size_t>::digits - 1) (std::numeric_limits<T>::digits * sprout::detail::static_log2<std::numeric_limits<T>::radix>::value + std::numeric_limits<std::size_t>::digits - 1)
/ std::numeric_limits<std::size_t>::digits / std::numeric_limits<std::size_t>::digits
@ -41,7 +41,7 @@ namespace sprout {
template<typename T> template<typename T>
inline SPROUT_CONSTEXPR std::size_t inline SPROUT_CONSTEXPR std::size_t
float_hash_value_impl_2(T v, int exp) { float_hash_value_impl_2(T v, int exp) {
return sprout::detail::float_hash_value_impl_3(sprout::math::ldexp(v, std::numeric_limits<std::size_t>::digits), exp); return sprout::detail::float_hash_value_impl_3(sprout::ldexp(v, std::numeric_limits<std::size_t>::digits), exp);
} }
template<typename T, typename P> template<typename T, typename P>
inline SPROUT_CONSTEXPR std::size_t inline SPROUT_CONSTEXPR std::size_t
@ -70,7 +70,7 @@ namespace sprout {
template<typename T> template<typename T>
inline SPROUT_CONSTEXPR std::size_t inline SPROUT_CONSTEXPR std::size_t
float_hash_value(T v) { float_hash_value(T v) {
return sprout::detail::float_hash_value_1(v, sprout::math::fpclassify(v)); return sprout::detail::float_hash_value_1(v, sprout::fpclassify(v));
} }
} // namespace detail } // namespace detail
} // namespace sprout } // namespace sprout

View file

@ -20,7 +20,7 @@ namespace sprout {
acos(FloatType x) { acos(FloatType x) {
return x == 1 ? FloatType(0) return x == 1 ? FloatType(0)
: x > 1 || x < -1 ? std::numeric_limits<FloatType>::quiet_NaN() : x > 1 || x < -1 ? std::numeric_limits<FloatType>::quiet_NaN()
: sprout::math::half_pi<FloatType>() - sprout::math::asin(x) : sprout::math::half_pi<FloatType>() - sprout::asin(x)
; ;
} }

View file

@ -21,7 +21,7 @@ namespace sprout {
return x == 1 ? FloatType(0) return x == 1 ? FloatType(0)
: x < 1 ? std::numeric_limits<FloatType>::quiet_NaN() : x < 1 ? std::numeric_limits<FloatType>::quiet_NaN()
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity() : x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: sprout::math::log(x + sprout::math::sqrt(x * x - 1)) : sprout::log(x + sprout::sqrt(x * x - 1))
; ;
} }

View file

@ -21,7 +21,7 @@ namespace sprout {
return x == 0 ? FloatType(0) return x == 0 ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity() : x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity() : x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity()
: sprout::math::log(x + sprout::math::sqrt(x * x + 1)) : sprout::log(x + sprout::sqrt(x * x + 1))
; ;
} }

View file

@ -34,8 +34,8 @@ namespace sprout {
: FloatType(0) : FloatType(0)
: y == std::numeric_limits<FloatType>::infinity() ? sprout::math::half_pi<FloatType>() : y == std::numeric_limits<FloatType>::infinity() ? sprout::math::half_pi<FloatType>()
: y == -std::numeric_limits<FloatType>::infinity() ? -sprout::math::half_pi<FloatType>() : y == -std::numeric_limits<FloatType>::infinity() ? -sprout::math::half_pi<FloatType>()
: x < 0 ? sprout::math::atan(y / x) + (y < 0 ? -1 : 1) * sprout::math::pi<FloatType>() : x < 0 ? sprout::atan(y / x) + (y < 0 ? -1 : 1) * sprout::math::pi<FloatType>()
: sprout::math::atan(y / x) : sprout::atan(y / x)
; ;
} }

View file

@ -21,7 +21,7 @@ namespace sprout {
: x == 1 ? std::numeric_limits<FloatType>::infinity() : x == 1 ? std::numeric_limits<FloatType>::infinity()
: x == -1 ? -std::numeric_limits<FloatType>::infinity() : x == -1 ? -std::numeric_limits<FloatType>::infinity()
: x > 1 || x < -1 ? std::numeric_limits<FloatType>::quiet_NaN() : x > 1 || x < -1 ? std::numeric_limits<FloatType>::quiet_NaN()
: sprout::math::log((1 + x) / (1 - x)) / 2 : sprout::log((1 + x) / (1 - x)) / 2
; ;
} }

View file

@ -21,8 +21,8 @@ namespace sprout {
return x == 0 ? FloatType(0) return x == 0 ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity() : x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity() : x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity()
: x < 0 ? -sprout::math::pow(-x, sprout::math::third<FloatType>()) : x < 0 ? -sprout::pow(-x, sprout::math::third<FloatType>())
: sprout::math::pow(x, sprout::math::third<FloatType>()) : sprout::pow(x, sprout::math::third<FloatType>())
; ;
} }

View file

@ -34,7 +34,7 @@ namespace sprout {
template<typename T> template<typename T>
inline SPROUT_CONSTEXPR T inline SPROUT_CONSTEXPR T
erf_impl(T x2, T a) { erf_impl(T x2, T a) {
return T(1) - sprout::math::exp(-x2 / (T(1) + a * x2) * (sprout::math::quarter_pi<T>() + a * x2)); return T(1) - sprout::exp(-x2 / (T(1) + a * x2) * (sprout::math::quarter_pi<T>() + a * x2));
} }
template< template<
typename FloatType, typename FloatType,

View file

@ -18,7 +18,7 @@ namespace sprout {
erfc(FloatType x) { erfc(FloatType x) {
return x == std::numeric_limits<FloatType>::infinity() ? FloatType(0) return x == std::numeric_limits<FloatType>::infinity() ? FloatType(0)
: x == -std::numeric_limits<FloatType>::infinity() ? FloatType(2) : x == -std::numeric_limits<FloatType>::infinity() ? FloatType(2)
: FloatType(1) - sprout::math::erf(x) : FloatType(1) - sprout::erf(x)
; ;
} }

View file

@ -20,7 +20,7 @@ namespace sprout {
return x == 0 ? FloatType(1) return x == 0 ? FloatType(1)
: x == -std::numeric_limits<FloatType>::infinity() ? FloatType(0) : x == -std::numeric_limits<FloatType>::infinity() ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity() : x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: sprout::math::exp(x * sprout::math::ln_ten<FloatType>()) : sprout::exp(x * sprout::math::ln_ten<FloatType>())
; ;
} }

View file

@ -21,7 +21,7 @@ namespace sprout {
return x == 0 ? FloatType(1) return x == 0 ? FloatType(1)
: x == -std::numeric_limits<FloatType>::infinity() ? FloatType(0) : x == -std::numeric_limits<FloatType>::infinity() ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity() : x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: sprout::math::exp(x * sprout::math::ln_two<FloatType>()) : sprout::exp(x * sprout::math::ln_two<FloatType>())
; ;
} }

View file

@ -21,7 +21,7 @@ namespace sprout {
return x == 0 ? FloatType(0) return x == 0 ? FloatType(0)
: x == -std::numeric_limits<FloatType>::infinity() ? FloatType(-1) : x == -std::numeric_limits<FloatType>::infinity() ? FloatType(-1)
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity() : x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: sprout::math::exp(x) - FloatType(1) : sprout::exp(x) - FloatType(1)
; ;
} }

View file

@ -18,7 +18,7 @@ namespace sprout {
inline SPROUT_CONSTEXPR int inline SPROUT_CONSTEXPR int
float2_exponent(FloatType x) { float2_exponent(FloatType x) {
return x == 0 ? 0 return x == 0 ? 0
: sprout::math::ilogb2(x) + 1 : sprout::ilogb2(x) + 1
; ;
} }

View file

@ -22,7 +22,7 @@ namespace sprout {
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity() : x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity() : x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity()
: x == std::numeric_limits<FloatType>::quiet_NaN() ? std::numeric_limits<FloatType>::quiet_NaN() : x == std::numeric_limits<FloatType>::quiet_NaN() ? std::numeric_limits<FloatType>::quiet_NaN()
: x / sprout::detail::pow_n(FloatType(2), sprout::math::float2_exponent(x)) : x / sprout::detail::pow_n(FloatType(2), sprout::float2_exponent(x))
; ;
} }

View file

@ -18,7 +18,7 @@ namespace sprout {
inline SPROUT_CONSTEXPR int inline SPROUT_CONSTEXPR int
float_exponent(FloatType x) { float_exponent(FloatType x) {
return x == 0 ? 0 return x == 0 ? 0
: sprout::math::ilogb(x) + 1 : sprout::ilogb(x) + 1
; ;
} }

View file

@ -31,7 +31,7 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR sprout::pair<FloatType, int> inline SPROUT_CONSTEXPR sprout::pair<FloatType, int>
float_sig_exp(FloatType x) { float_sig_exp(FloatType x) {
return sprout::math::detail::float_sig_exp_impl(x, sprout::math::float_exponent(x)); return sprout::math::detail::float_sig_exp_impl(x, sprout::float_exponent(x));
} }
template< template<

View file

@ -22,7 +22,7 @@ namespace sprout {
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity() : x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity() : x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity()
: x == std::numeric_limits<FloatType>::quiet_NaN() ? std::numeric_limits<FloatType>::quiet_NaN() : x == std::numeric_limits<FloatType>::quiet_NaN() ? std::numeric_limits<FloatType>::quiet_NaN()
: x / sprout::detail::pow_n(FloatType(std::numeric_limits<FloatType>::radix), sprout::math::float_exponent(x)) : x / sprout::detail::pow_n(FloatType(std::numeric_limits<FloatType>::radix), sprout::float_exponent(x))
; ;
} }

View file

@ -22,7 +22,7 @@ namespace sprout {
? std::numeric_limits<FloatType>::quiet_NaN() ? std::numeric_limits<FloatType>::quiet_NaN()
: x == 0 ? FloatType(0) : x == 0 ? FloatType(0)
: y == std::numeric_limits<FloatType>::infinity() || y == -std::numeric_limits<FloatType>::infinity() ? x : y == std::numeric_limits<FloatType>::infinity() || y == -std::numeric_limits<FloatType>::infinity() ? x
: x - sprout::math::trunc(x / y) * y : x - sprout::trunc(x / y) * y
; ;
} }

View file

@ -20,9 +20,9 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR int inline SPROUT_CONSTEXPR int
fpclassify(FloatType x) { fpclassify(FloatType x) {
return sprout::math::isnan(x) ? FP_NAN return sprout::isnan(x) ? FP_NAN
: sprout::math::isinf(x) ? FP_INFINITE : sprout::isinf(x) ? FP_INFINITE
: sprout::math::iszero(x) ? FP_ZERO : sprout::iszero(x) ? FP_ZERO
: sprout::math::detail::issubnormal_or_zero(x) ? FP_SUBNORMAL : sprout::math::detail::issubnormal_or_zero(x) ? FP_SUBNORMAL
: FP_NORMAL : FP_NORMAL
; ;

View file

@ -28,7 +28,7 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR sprout::pair<FloatType, FloatType> inline SPROUT_CONSTEXPR sprout::pair<FloatType, FloatType>
frac_int(FloatType x) { frac_int(FloatType x) {
return sprout::math::detail::frac_int_impl(x, sprout::math::integer_part(x)); return sprout::math::detail::frac_int_impl(x, sprout::integer_part(x));
} }
template< template<

View file

@ -19,7 +19,7 @@ namespace sprout {
fractional_part(FloatType x) { fractional_part(FloatType x) {
return x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity() ? FloatType(0) return x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity() ? FloatType(0)
: x == std::numeric_limits<FloatType>::quiet_NaN() ? std::numeric_limits<FloatType>::quiet_NaN() : x == std::numeric_limits<FloatType>::quiet_NaN() ? std::numeric_limits<FloatType>::quiet_NaN()
: x - sprout::math::integer_part(x) : x - sprout::integer_part(x)
; ;
} }

View file

@ -3,5 +3,6 @@
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/math/tgamma.hpp> #include <sprout/math/tgamma.hpp>
#include <sprout/math/lgamma.hpp>
#endif // #ifndef SPROUT_MATH_GAMMA_HPP #endif // #ifndef SPROUT_MATH_GAMMA_HPP

View file

@ -246,6 +246,8 @@ namespace sprout {
return sprout::math::gcd_evaluator<IntType>().operator()(a, b); return sprout::math::gcd_evaluator<IntType>().operator()(a, b);
} }
} // namespace math } // namespace math
} // namespace boost
using sprout::math::gcd;
} // namespace sprout
#endif // #ifndef SPROUT_MATH_GCD_HPP #endif // #ifndef SPROUT_MATH_GCD_HPP

View file

@ -19,13 +19,13 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR FloatType inline SPROUT_CONSTEXPR FloatType
hypot(FloatType x, FloatType y) { hypot(FloatType x, FloatType y) {
return y == 0 ? sprout::math::fabs(x) return y == 0 ? sprout::fabs(x)
: x == 0 ? sprout::math::fabs(y) : x == 0 ? sprout::fabs(y)
: y == std::numeric_limits<FloatType>::infinity() || y == -std::numeric_limits<FloatType>::infinity() : y == std::numeric_limits<FloatType>::infinity() || y == -std::numeric_limits<FloatType>::infinity()
? std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity() : x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity()
? std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: sprout::math::sqrt(x * x + y * y) : sprout::sqrt(x * x + y * y)
; ;
} }

View file

@ -32,7 +32,7 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR To inline SPROUT_CONSTEXPR To
iceil(FloatType x) { iceil(FloatType x) {
return sprout::math::detail::iceil_impl<To>(sprout::math::ceil(x)); return sprout::math::detail::iceil_impl<To>(sprout::ceil(x));
} }
#else #else
template<typename To, typename FloatType> template<typename To, typename FloatType>

View file

@ -32,7 +32,7 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR To inline SPROUT_CONSTEXPR To
ifloor(FloatType x) { ifloor(FloatType x) {
return sprout::math::detail::ifloor_impl<To>(sprout::math::floor(x)); return sprout::math::detail::ifloor_impl<To>(sprout::floor(x));
} }
#else #else
template<typename To, typename FloatType> template<typename To, typename FloatType>

View file

@ -21,10 +21,10 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR int inline SPROUT_CONSTEXPR int
ilogb(FloatType x) { ilogb(FloatType x) {
return sprout::math::iszero(x) ? FP_ILOGB0 return sprout::iszero(x) ? FP_ILOGB0
: sprout::math::isinf(x) ? INT_MAX : sprout::isinf(x) ? INT_MAX
: sprout::math::isnan(x) ? FP_ILOGBNAN : sprout::isnan(x) ? FP_ILOGBNAN
: static_cast<int>(sprout::math::logb(x)) : static_cast<int>(sprout::logb(x))
; ;
} }

View file

@ -26,7 +26,7 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR int inline SPROUT_CONSTEXPR int
ilogb2(FloatType x) { ilogb2(FloatType x) {
return sprout::math::ilogb(x); return sprout::ilogb(x);
} }
template< template<
@ -35,7 +35,7 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR int inline SPROUT_CONSTEXPR int
ilogb2(IntType x) { ilogb2(IntType x) {
return sprout::math::ilogb(x); return sprout::ilogb(x);
} }
#else #else
template< template<
@ -44,10 +44,10 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR int inline SPROUT_CONSTEXPR int
ilogb2(FloatType x) { ilogb2(FloatType x) {
return sprout::math::iszero(x) ? FP_ILOGB0 return sprout::iszero(x) ? FP_ILOGB0
: sprout::math::isinf(x) ? INT_MAX : sprout::isinf(x) ? INT_MAX
: sprout::math::isnan(x) ? FP_ILOGBNAN : sprout::isnan(x) ? FP_ILOGBNAN
: static_cast<int>(sprout::math::logb2(x)) : static_cast<int>(sprout::logb2(x))
; ;
} }

View file

@ -20,7 +20,7 @@ namespace sprout {
return x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity() return x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity() : x == -std::numeric_limits<FloatType>::infinity() ? -std::numeric_limits<FloatType>::infinity()
: x == std::numeric_limits<FloatType>::quiet_NaN() ? std::numeric_limits<FloatType>::quiet_NaN() : x == std::numeric_limits<FloatType>::quiet_NaN() ? std::numeric_limits<FloatType>::quiet_NaN()
: sprout::math::trunc(x) : sprout::trunc(x)
; ;
} }

View file

@ -32,7 +32,7 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR To inline SPROUT_CONSTEXPR To
iround(FloatType x) { iround(FloatType x) {
return sprout::math::detail::iround_impl<To>(sprout::math::round(x)); return sprout::math::detail::iround_impl<To>(sprout::round(x));
} }
#else #else
template<typename To, typename FloatType> template<typename To, typename FloatType>

View file

@ -17,8 +17,8 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR int inline SPROUT_CONSTEXPR int
isfinite(FloatType x) { isfinite(FloatType x) {
return !sprout::math::isnan(x) return !sprout::isnan(x)
&& !sprout::math::isinf(x) && !sprout::isinf(x)
; ;
} }
} // namespace detail } // namespace detail

View file

@ -18,8 +18,8 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR int inline SPROUT_CONSTEXPR int
isnormal(FloatType x) { isnormal(FloatType x) {
return !sprout::math::isnan(x) return !sprout::isnan(x)
&& !sprout::math::isinf(x) && !sprout::isinf(x)
&& !sprout::math::detail::issubnormal_or_zero(x) && !sprout::math::detail::issubnormal_or_zero(x)
; ;
} }

View file

@ -28,7 +28,7 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR int inline SPROUT_CONSTEXPR int
issubnormal(FloatType x) { issubnormal(FloatType x) {
return !sprout::math::iszero(x) return !sprout::iszero(x)
&& sprout::math::detail::issubnormal_or_zero(x) && sprout::math::detail::issubnormal_or_zero(x)
; ;
} }

View file

@ -30,7 +30,7 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR To inline SPROUT_CONSTEXPR To
itrunc(FloatType x) { itrunc(FloatType x) {
return sprout::math::detail::itrunc_impl<To>(sprout::math::trunc(x)); return sprout::math::detail::itrunc_impl<To>(sprout::trunc(x));
} }
#else #else
template< template<

View file

@ -105,6 +105,8 @@ namespace sprout {
return sprout::math::lcm_evaluator<IntType>().operator()(a, b); return sprout::math::lcm_evaluator<IntType>().operator()(a, b);
} }
} // namespace math } // namespace math
} // namespace boost
using sprout::math::lcm;
} // namespace sprout
#endif // #ifndef SPROUT_MATH_LCM_HPP #endif // #ifndef SPROUT_MATH_LCM_HPP

210
sprout/math/lgamma.hpp Normal file
View file

@ -0,0 +1,210 @@
#ifndef SPROUT_MATH_LGAMMA_HPP
#define SPROUT_MATH_LGAMMA_HPP
#include <limits>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/math/detail/config.hpp>
#include <sprout/math/detail/float_compute.hpp>
#include <sprout/math/constants.hpp>
#include <sprout/math/factorial.hpp>
#include <sprout/math/log.hpp>
#include <sprout/math/sin.hpp>
#include <sprout/math/abs.hpp>
#include <sprout/math/itrunc.hpp>
#include <sprout/type_traits/enabler_if.hpp>
namespace sprout {
namespace math {
namespace detail {
template<typename T>
inline SPROUT_CONSTEXPR T
lgamma_impl_3(T x, T y) {
return x < 0 ? sprout::log(sprout::math::pi<T>() / sprout::abs(x * sprout::sin(x * sprout::math::pi<T>()))) - y
: y
;
}
template<typename T>
inline SPROUT_CONSTEXPR T
lgamma_impl_2_d_1(T x, T w, T v, T t) {
return sprout::math::detail::lgamma_impl_3(
x,
(((((-0.00163312359200500807 * t + 8.3644533703385956e-4) * t + -5.9518947575728181e-4) * t
+ 7.9365057505415415e-4) * t + -0.00277777777735463043) * t + 0.08333333333333309869) * v + 0.91893853320467274178
+ ((w - T(0.5)) * sprout::log(w) - w)
);
}
template<typename T>
inline SPROUT_CONSTEXPR T
lgamma_impl_2_d(T x, T w, T v) {
return sprout::math::detail::lgamma_impl_2_d_1(x, w, v, v * v);
}
template<typename T>
inline SPROUT_CONSTEXPR T
lgamma_impl_2_c_1(T x, T w, T t, int k) {
return sprout::math::detail::lgamma_impl_3(
x,
k == 0 ? (((((((((((
1.16333640008e-8 * t + -8.33156123568e-8) * t
+ 3.832869977018e-7) * t + -1.5814047847688e-6) * t + 6.50106723241e-6) * t
+ -2.74514060128677e-5) * t + 1.209015360925566e-4) * t + -5.666333178228163e-4) * t
+ 0.0029294103665559733) * t + -0.0180340086069185819) * t + 0.1651788780501166204) * t
+ 1.1031566406452431944) * t + 1.2009736023470742248
: k == 1 ? (((((((((((
1.3842760642e-9 * t + -6.9417501176e-9) * t
+ 3.42976459827e-8) * t + -1.785317236779e-7) * t + 9.525947257118e-7) * t
+ -5.2483007560905e-6) * t + 3.02364659535708e-5) * t + -1.858396115473822e-4) * t
+ 0.0012634378559425382) * t + -0.0102594702201954322) * t + 0.1243625515195050218) * t
+ 1.3888709263595291174) * t + 2.4537365708424422209
: k == 2 ? (((((((((((
1.298977078e-10 * t + -8.02957489e-10) * t
+ 4.945484615e-9) * t + -3.17563534834e-8) * t + 2.092136698089e-7) * t
+ -1.4252023958462e-6) * t + 1.01652510114008e-5) * t + -7.74550502862323e-5) * t
+ 6.537746948291078e-4) * t + -0.006601491253552183) * t + 0.0996711934948138193) * t
+ 1.6110931485817511402) * t + 3.9578139676187162939
: k == 3 ? (((((((((((
1.83995642e-11 * t + -1.353537034e-10) * t
+ 9.984676809e-10) * t + -7.6346363974e-9) * t + 5.99311464148e-8) * t
+ -4.868554120177e-7) * t + 4.1441957716669e-6) * t + -3.77160856623282e-5) * t
+ 3.805693126824884e-4) * t + -0.0045979851178130194) * t + 0.0831422678749791178) * t
+ 1.7929113303999329439) * t + 5.6625620598571415285
: (((((((((((
3.4858778e-12 * t + -2.97587783e-11) * t
+ 2.557677575e-10) * t + -2.2705728282e-9) * t + 2.0702499245e-8) * t
+ -1.954426390917e-7) * t + 1.9343161886722e-6) * t + -2.0479024910257e-5) * t
+ 2.405181940241215e-4) * t + -0.0033842087561074799) * t + 0.0713079483483518997) * t
+ 1.9467574842460867884) * t + 7.5343642367587329552
);
}
template<typename T>
inline SPROUT_CONSTEXPR T
lgamma_impl_2_c(T x, T w, int k) {
return sprout::math::detail::lgamma_impl_2_c_1(x, w, w - (static_cast<T>(k) + 3.5), k);
}
template<typename T>
inline SPROUT_CONSTEXPR T
lgamma_impl_2_b_2(T x, T w, T t, int k) {
return sprout::math::detail::lgamma_impl_3(
x,
k == 0 ? ((((((((((((
-4.587497028e-11 * t + 1.902363396e-10) * t
+ 8.6377323367e-10) * t + 1.15513678861e-8) * t + -2.556403058605e-8) * t
+ -1.5236723372486e-7) * t + -3.1680510638574e-6) * t + 1.22903704923381e-6) * t
+ 2.334372474572637e-5) * t + 0.00111544038088797696) * t + 0.00344717051723468982) * t
+ 0.03198287045148788384) * t + -0.32705333652955399526) * t + 0.40120442440953927615
: k == 1 ? ((((((((((((
-5.184290387e-11 * t + -8.3355121068e-10) * t
+ -2.56167239813e-9) * t + 1.455875381397e-8) * t + 1.3512178394703e-7) * t
+ 2.9898826810905e-7) * t + -3.58107254612779e-6) * t + -2.445260816156224e-5) * t
+ -4.417127762011821e-5) * t + 0.00112859455189416567) * t + 0.00804694454346728197) * t
+ 0.04919775747126691372) * t + -0.24818372840948854178) * t + 0.11071780856646862561
: k == 2 ? ((((((((((((
3.0279161576e-10 * t + 1.60742167357e-9) * t
+ -4.05596009522e-9) * t + -5.089259920266e-8) * t + -2.029496209743e-8) * t
+ 1.35130272477793e-6) * t + 3.91430041115376e-6) * t + -2.871505678061895e-5) * t
+ -2.3052137536922035e-4) * t + 4.5534656385400747e-4) * t + 0.01153444585593040046) * t
+ 0.07924014651650476036) * t + -0.12152192626936502982) * t + -0.07916438300260539592
: k == 3 ? ((((((((((((
-5.091914958e-10 * t + -1.15274986907e-9) * t
+ 1.237873512188e-8) * t + 2.937383549209e-8) * t + -3.0621450667958e-7) * t
+ -7.7409414949954e-7) * t + 8.16753874325579e-6) * t + 2.412433382517375e-5) * t
+ -2.60612176060637e-4) * t + -9.1000087658659231e-4) * t + 0.01068093850598380797) * t
+ 0.11395654404408482305) * t + 0.07209569059984075595) * t + -0.10971041451764266684
: k == 4 ? ((((((((((((
4.0119897187e-10 * t + -1.3224526679e-10) * t
+ -1.002723190355e-8) * t + 2.569249716518e-8) * t + 2.0336011868466e-7) * t
+ -1.1809768272606e-6) * t + -3.00660303810663e-6) * t + 4.402212897757763e-5) * t
+ -1.462405876235375e-5) * t + -0.0016487379559600128) * t + 0.00513927520866443706) * t
+ 0.13843580753590579416) * t + 0.32730190978254056722) * t + 0.08588339725978624973
: k == 5 ? ((((((((((((
-1.5413428348e-10 * t + 6.4905779353e-10) * t
+ 1.60702811151e-9) * t + -2.655645793815e-8) * t + 7.619544277956e-8) * t
+ 4.7604380765353e-7) * t + -4.90748870866195e-6) * t + 8.21513040821212e-6) * t
+ 1.4804944070262948e-4) * t + -0.00122152255762163238) * t + -8.7425289205498532e-4) * t
+ 0.1443870369965796831) * t + 0.61315889733595543766) * t + 0.55513708159976477557
: ((((((((((((
1.049740243e-11 * t + -2.5832017855e-10) * t
+ 1.39591845075e-9) * t + -2.1177278325e-10) * t + -5.082950464905e-8) * t
+ 3.7801785193343e-7) * t + -7.3982266659145e-7) * t + -1.088918441519888e-5) * t
+ 1.2491810452478905e-4) * t + -4.9171790705139895e-4) * t + -0.0042570708944826646) * t
+ 0.13595080378472757216) * t + 0.89518356003149514744) * t + 1.31073912535196238583
);
}
template<typename T>
inline SPROUT_CONSTEXPR T
lgamma_impl_2_b_1(T x, T w, T t, int k) {
return sprout::math::detail::lgamma_impl_2_b_2(x, w, t - (static_cast<T>(k) - T(3.5)), k);
}
template<typename T>
inline SPROUT_CONSTEXPR T
lgamma_impl_2_b(T x, T w, T t) {
return sprout::math::detail::lgamma_impl_2_b_1(x, w, t, sprout::itrunc(t) + 4);
}
template<typename T>
inline SPROUT_CONSTEXPR T
lgamma_impl_2_a(T x, T w, int k) {
return sprout::math::detail::lgamma_impl_3(
x,
-sprout::log(
k == 0 ? ((((((((((
9.967270908702825e-5 * w + -1.9831672170162227e-4) * w
+ -0.00117085315349625822) * w + 0.00722012810948319552) * w + -0.0096221300936780297) * w
+ -0.04219772092994235254) * w + 0.16653861065243609743) * w + -0.04200263501129018037) * w
+ -0.65587807152061930091) * w + 0.57721566490153514421) * w + 0.99999999999999999764) * w
: ((((((((((
4.67209725901142e-5 * w + -6.812300803992063e-5) * w
+ -0.00132531159076610073) * w + 0.0073352117810720277) * w + -0.00968095666383935949) * w
+ -0.0421764281187354028) * w + 0.16653313644244428256) * w + -0.04200165481709274859) * w
+ -0.65587818792782740945) * w + 0.57721567315209190522) * w + 0.99999999973565236061) * w
)
);
}
template<typename T>
inline SPROUT_CONSTEXPR T
lgamma_impl_1(T x, T w) {
return w < T(0.5) ? sprout::math::detail::lgamma_impl_2_a(x, w, w < T(0.25) ? 0 : 1)
: w < T(3.5) ? sprout::math::detail::lgamma_impl_2_b(x, w, w - T(4.5) / (w + T(0.5)))
: w < T(8) ? sprout::math::detail::lgamma_impl_2_c(x, w, sprout::itrunc(w) - 3)
: sprout::math::detail::lgamma_impl_2_d(x, w, T(1) / w)
;
}
template<typename T>
inline SPROUT_CONSTEXPR T
lgamma_impl(T x) {
return sprout::math::detail::lgamma_impl_1(x, x < 0 ? -x : x);
}
template<
typename FloatType,
typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR FloatType
lgamma(FloatType x) {
typedef typename sprout::math::detail::float_compute<FloatType>::type type;
return x == 1 ? FloatType(0)
: x == 2 ? FloatType(0)
: x <= 0 && x == std::trunc(x) ? std::numeric_limits<FloatType>::infinity()
: x == -std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: static_cast<FloatType>(sprout::math::detail::lgamma_impl(static_cast<type>(x)))
;
}
template<
typename IntType,
typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR double
lgamma(IntType x) {
return sprout::math::detail::lgamma(static_cast<double>(x));
}
} // namespace detail
using NS_SPROUT_MATH_DETAIL::lgamma;
} // namespace math
using sprout::math::lgamma;
} // namespace sprout
#endif // #ifndef SPROUT_MATH_LGAMMA_HPP

View file

@ -16,7 +16,7 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR long long inline SPROUT_CONSTEXPR long long
llround(FloatType x) { llround(FloatType x) {
return sprout::math::iround<long long>(x); return sprout::iround<long long>(x);
} }
template< template<
@ -25,7 +25,7 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR long long inline SPROUT_CONSTEXPR long long
llround(IntType x) { llround(IntType x) {
return sprout::math::iround<long long>(x); return sprout::iround<long long>(x);
} }
} // namespace detail } // namespace detail

View file

@ -30,7 +30,7 @@ namespace sprout {
log_impl(T x) { log_impl(T x) {
return !(x > sprout::math::root_two<T>()) return !(x > sprout::math::root_two<T>())
? sprout::math::detail::log_impl_1(x - 1, 1, sprout::math::factorial_limit<T>() + 1) ? sprout::math::detail::log_impl_1(x - 1, 1, sprout::math::factorial_limit<T>() + 1)
: 2 * sprout::math::detail::log_impl(sprout::math::sqrt(x)) : 2 * sprout::math::detail::log_impl(sprout::sqrt(x))
; ;
} }

View file

@ -22,7 +22,7 @@ namespace sprout {
: x == 1 ? FloatType(0) : x == 1 ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity() : x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: x < 0 ? std::numeric_limits<FloatType>::quiet_NaN() : x < 0 ? std::numeric_limits<FloatType>::quiet_NaN()
: sprout::math::log(x) / sprout::math::ln_ten<FloatType>() : sprout::log(x) / sprout::math::ln_ten<FloatType>()
; ;
} }

View file

@ -21,7 +21,7 @@ namespace sprout {
: x == -1 ? -std::numeric_limits<FloatType>::infinity() : x == -1 ? -std::numeric_limits<FloatType>::infinity()
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity() : x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: x < -1 ? std::numeric_limits<FloatType>::quiet_NaN() : x < -1 ? std::numeric_limits<FloatType>::quiet_NaN()
: sprout::math::log(1 + x) : sprout::log(1 + x)
; ;
} }

View file

@ -22,7 +22,7 @@ namespace sprout {
: x == 1 ? FloatType(0) : x == 1 ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity() : x == std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: x < 0 ? std::numeric_limits<FloatType>::quiet_NaN() : x < 0 ? std::numeric_limits<FloatType>::quiet_NaN()
: sprout::math::log(x) / sprout::math::ln_two<FloatType>() : sprout::log(x) / sprout::math::ln_two<FloatType>()
; ;
} }

View file

@ -18,9 +18,9 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR FloatType inline SPROUT_CONSTEXPR FloatType
log_a(FloatType x, FloatType y) { log_a(FloatType x, FloatType y) {
return x == 2 ? sprout::math::log(y) / sprout::math::ln_two<FloatType>() return x == 2 ? sprout::log(y) / sprout::math::ln_two<FloatType>()
: x == 10 ? sprout::math::log(y) / sprout::math::ln_ten<FloatType>() : x == 10 ? sprout::log(y) / sprout::math::ln_ten<FloatType>()
: sprout::math::log(y) / sprout::math::log(x) : sprout::log(y) / sprout::log(x)
; ;
} }

View file

@ -80,7 +80,7 @@ namespace sprout {
inline SPROUT_CONSTEXPR T inline SPROUT_CONSTEXPR T
logb_impl(T x, T exp) { logb_impl(T x, T exp) {
return sprout::math::detail::logb_impl_1( return sprout::math::detail::logb_impl_1(
x, sprout::detail::pow_n(T(std::numeric_limits<T>::radix), sprout::math::itrunc<std::intmax_t>(exp)), exp x, sprout::detail::pow_n(T(std::numeric_limits<T>::radix), sprout::itrunc<std::intmax_t>(exp)), exp
); );
} }
@ -93,8 +93,8 @@ namespace sprout {
return x == 0 ? -std::numeric_limits<FloatType>::infinity() return x == 0 ? -std::numeric_limits<FloatType>::infinity()
: x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity() : x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity()
? std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: x < 0 ? sprout::math::detail::logb_impl(-x, sprout::math::trunc(sprout::math::log_a(FloatType(std::numeric_limits<FloatType>::radix), -x))) : x < 0 ? sprout::math::detail::logb_impl(-x, sprout::trunc(sprout::log_a(FloatType(std::numeric_limits<FloatType>::radix), -x)))
: sprout::math::detail::logb_impl(x, sprout::math::trunc(sprout::math::log_a(FloatType(std::numeric_limits<FloatType>::radix), x))) : sprout::math::detail::logb_impl(x, sprout::trunc(sprout::log_a(FloatType(std::numeric_limits<FloatType>::radix), x)))
; ;
} }

View file

@ -27,7 +27,7 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR FloatType inline SPROUT_CONSTEXPR FloatType
logb2(FloatType x) { logb2(FloatType x) {
return sprout::math::logb(x); return sprout::logb(x);
} }
template< template<
@ -36,7 +36,7 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR double inline SPROUT_CONSTEXPR double
logb2(IntType x) { logb2(IntType x) {
return sprout::math::logb(x); return sprout::logb(x);
} }
#else #else
template<typename T> template<typename T>
@ -104,7 +104,7 @@ namespace sprout {
inline SPROUT_CONSTEXPR T inline SPROUT_CONSTEXPR T
logb2_impl(T x, T exp) { logb2_impl(T x, T exp) {
return sprout::math::detail::logb2_impl_1( return sprout::math::detail::logb2_impl_1(
x, sprout::detail::pow_n(T(2), sprout::math::itrunc<std::intmax_t>(exp)), exp x, sprout::detail::pow_n(T(2), sprout::itrunc<std::intmax_t>(exp)), exp
); );
} }
@ -117,8 +117,8 @@ namespace sprout {
return x == 0 ? -std::numeric_limits<FloatType>::infinity() return x == 0 ? -std::numeric_limits<FloatType>::infinity()
: x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity() : x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity()
? std::numeric_limits<FloatType>::infinity() ? std::numeric_limits<FloatType>::infinity()
: x < 0 ? sprout::math::detail::logb2_impl(-x, sprout::math::trunc(sprout::math::log_a(FloatType(2), -x))) : x < 0 ? sprout::math::detail::logb2_impl(-x, sprout::trunc(sprout::log_a(FloatType(2), -x)))
: sprout::math::detail::logb2_impl(x, sprout::math::trunc(sprout::math::log_a(FloatType(2), x))) : sprout::math::detail::logb2_impl(x, sprout::trunc(sprout::log_a(FloatType(2), x)))
; ;
} }

View file

@ -16,7 +16,7 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR long inline SPROUT_CONSTEXPR long
lround(FloatType x) { lround(FloatType x) {
return sprout::math::iround<long>(x); return sprout::iround<long>(x);
} }
template< template<
@ -25,7 +25,7 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR long inline SPROUT_CONSTEXPR long
lround(IntType x) { lround(IntType x) {
return sprout::math::iround<long>(x); return sprout::iround<long>(x);
} }
} // namespace detail } // namespace detail

View file

@ -23,27 +23,27 @@ namespace sprout {
return x == 0 return x == 0
? y < 0 ? std::numeric_limits<FloatType>::infinity() ? y < 0 ? std::numeric_limits<FloatType>::infinity()
: y > 0 ? FloatType(0) : y > 0 ? FloatType(0)
: sprout::math::exp(y * sprout::math::log(x)) : sprout::exp(y * sprout::log(x))
: x == -1 && (y == std::numeric_limits<FloatType>::infinity() || y == -std::numeric_limits<FloatType>::infinity()) ? FloatType(1) : x == -1 && (y == std::numeric_limits<FloatType>::infinity() || y == -std::numeric_limits<FloatType>::infinity()) ? FloatType(1)
: x == 1 ? FloatType(1) : x == 1 ? FloatType(1)
: y == 0 ? FloatType(1) : y == 0 ? FloatType(1)
: y == -std::numeric_limits<FloatType>::infinity() : y == -std::numeric_limits<FloatType>::infinity()
? x < 1 && x > -1 ? std::numeric_limits<FloatType>::infinity() ? x < 1 && x > -1 ? std::numeric_limits<FloatType>::infinity()
: x > 1 || x < -1 ? FloatType(0) : x > 1 || x < -1 ? FloatType(0)
: sprout::math::exp(y * sprout::math::log(x)) : sprout::exp(y * sprout::log(x))
: y == std::numeric_limits<FloatType>::infinity() : y == std::numeric_limits<FloatType>::infinity()
? x < 1 && x > -1 ? FloatType(0) ? x < 1 && x > -1 ? FloatType(0)
: x > 1 || x < -1 ? std::numeric_limits<FloatType>::infinity() : x > 1 || x < -1 ? std::numeric_limits<FloatType>::infinity()
: sprout::math::exp(y * sprout::math::log(x)) : sprout::exp(y * sprout::log(x))
: x == -std::numeric_limits<FloatType>::infinity() : x == -std::numeric_limits<FloatType>::infinity()
? y < 0 ? FloatType(0) ? y < 0 ? FloatType(0)
: y > 0 ? std::numeric_limits<FloatType>::infinity() : y > 0 ? std::numeric_limits<FloatType>::infinity()
: sprout::math::exp(y * sprout::math::log(x)) : sprout::exp(y * sprout::log(x))
: x == std::numeric_limits<FloatType>::infinity() : x == std::numeric_limits<FloatType>::infinity()
? y < 0 ? FloatType(0) ? y < 0 ? FloatType(0)
: y > 0 ? std::numeric_limits<FloatType>::infinity() : y > 0 ? std::numeric_limits<FloatType>::infinity()
: sprout::math::exp(y * sprout::math::log(x)) : sprout::exp(y * sprout::log(x))
: sprout::math::exp(y * sprout::math::log(x)) : sprout::exp(y * sprout::log(x))
; ;
} }

View file

@ -24,7 +24,7 @@ namespace sprout {
? std::numeric_limits<FloatType>::quiet_NaN() ? std::numeric_limits<FloatType>::quiet_NaN()
: x == 0 ? FloatType(0) : x == 0 ? FloatType(0)
: y == std::numeric_limits<FloatType>::infinity() || y == -std::numeric_limits<FloatType>::infinity() ? FloatType(0) : y == std::numeric_limits<FloatType>::infinity() || y == -std::numeric_limits<FloatType>::infinity() ? FloatType(0)
: sprout::math::iround<R>(x / y) : sprout::iround<R>(x / y)
; ;
} }

View file

@ -32,7 +32,7 @@ namespace sprout {
> >
inline SPROUT_CONSTEXPR sprout::pair<FloatType, R> inline SPROUT_CONSTEXPR sprout::pair<FloatType, R>
rem_quo(FloatType x, FloatType y) { rem_quo(FloatType x, FloatType y) {
return sprout::math::detail::rem_quo_impl(x, y, sprout::math::quotient(x, y)); return sprout::math::detail::rem_quo_impl(x, y, sprout::quotient(x, y));
} }
template< template<

View file

@ -23,7 +23,7 @@ namespace sprout {
? std::numeric_limits<FloatType>::quiet_NaN() ? std::numeric_limits<FloatType>::quiet_NaN()
: x == 0 ? FloatType(0) : x == 0 ? FloatType(0)
: y == std::numeric_limits<FloatType>::infinity() || y == -std::numeric_limits<FloatType>::infinity() ? x : y == std::numeric_limits<FloatType>::infinity() || y == -std::numeric_limits<FloatType>::infinity() ? x
: x - sprout::math::round(x / y) * y : x - sprout::round(x / y) * y
; ;
} }

View file

@ -21,7 +21,7 @@ namespace sprout {
return x == 0 ? FloatType(0) return x == 0 ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity() : x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity()
? std::numeric_limits<FloatType>::quiet_NaN() ? std::numeric_limits<FloatType>::quiet_NaN()
: -sprout::math::cos(x + sprout::math::half_pi<FloatType>()) : -sprout::cos(x + sprout::math::half_pi<FloatType>())
; ;
} }

View file

@ -21,7 +21,7 @@ namespace sprout {
return x == 0 ? FloatType(0) return x == 0 ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity() : x == std::numeric_limits<FloatType>::infinity() || x == -std::numeric_limits<FloatType>::infinity()
? std::numeric_limits<FloatType>::quiet_NaN() ? std::numeric_limits<FloatType>::quiet_NaN()
: sprout::math::sin(x) / sprout::math::cos(x) : sprout::sin(x) / sprout::cos(x)
; ;
} }

View file

@ -21,7 +21,7 @@ namespace sprout {
return x == 0 ? FloatType(0) return x == 0 ? FloatType(0)
: x == std::numeric_limits<FloatType>::infinity() ? FloatType(1) : x == std::numeric_limits<FloatType>::infinity() ? FloatType(1)
: x == -std::numeric_limits<FloatType>::infinity() ? FloatType(-1) : x == -std::numeric_limits<FloatType>::infinity() ? FloatType(-1)
: sprout::math::sinh(x) / sprout::math::cosh(x) : sprout::sinh(x) / sprout::cosh(x)
; ;
} }

View file

@ -68,27 +68,19 @@ namespace sprout {
} }
template<typename T> template<typename T>
inline SPROUT_CONSTEXPR T inline SPROUT_CONSTEXPR T
tgamma_impl_2_pos(T x, T y, T t) { tgamma_impl_2_pos_rec(T x, T y, T t) {
return t == 0 ? std::numeric_limits<T>::infinity() return t == 0 ? std::numeric_limits<T>::infinity()
: (x - T(1)) / y / t : (x - T(1)) / y / t
; ;
} }
template<typename T> template<typename T>
inline SPROUT_CONSTEXPR T inline SPROUT_CONSTEXPR T
tgamma_impl_2_neg(T x, T y, T t) {
return t == 0 ? T(0)
: T(1) / y * t
;
}
template<typename T>
inline SPROUT_CONSTEXPR T
tgamma_impl_1(T x, int n) { tgamma_impl_1(T x, int n) {
return n == 1 ? (x - T(1)) / sprout::math::detail::tgamma_impl_y(x - (n + 2)) return n == 1 ? (x - T(1)) / sprout::math::detail::tgamma_impl_y(x - (n + 2))
: n == 0 ? T(1) / sprout::math::detail::tgamma_impl_y(x - (n + 2)) : n == 0 ? T(1) / sprout::math::detail::tgamma_impl_y(x - (n + 2))
: n == static_cast<int>(sprout::math::factorial_limit<T>()) : n == static_cast<int>(sprout::math::factorial_limit<T>())
? sprout::math::detail::tgamma_impl_2_pos(x, sprout::math::detail::tgamma_impl_y(x - (n + 2)), sprout::math::detail::tgamma_impl_t_pos_rec(x, 2, n + 1)) ? sprout::math::detail::tgamma_impl_2_pos_rec(x, sprout::math::detail::tgamma_impl_y(x - (n + 2)), sprout::math::detail::tgamma_impl_t_pos_rec(x, 2, n + 1))
: n == -static_cast<int>(sprout::math::factorial_limit<T>()) : n == -static_cast<int>(sprout::math::factorial_limit<T>())
// ? sprout::math::detail::tgamma_impl_2_neg(x, sprout::math::detail::tgamma_impl_y(x - (n + 2)), sprout::math::detail::tgamma_impl_t_neg_rec(x, 0, -n))
? T(1) / sprout::math::detail::tgamma_impl_y(x - (n + 2)) * sprout::math::detail::tgamma_impl_t_neg_rec(x, 0, -n) ? T(1) / sprout::math::detail::tgamma_impl_y(x - (n + 2)) * sprout::math::detail::tgamma_impl_t_neg_rec(x, 0, -n)
: n > 1 ? (x - T(1)) / sprout::math::detail::tgamma_impl_y(x - (n + 2)) * sprout::math::detail::tgamma_impl_t_pos(x, 2, n + 1) : n > 1 ? (x - T(1)) / sprout::math::detail::tgamma_impl_y(x - (n + 2)) * sprout::math::detail::tgamma_impl_t_pos(x, 2, n + 1)
: T(1) / sprout::math::detail::tgamma_impl_y(x - (n + 2)) / sprout::math::detail::tgamma_impl_t_neg(x, 0, -n) : T(1) / sprout::math::detail::tgamma_impl_y(x - (n + 2)) / sprout::math::detail::tgamma_impl_t_neg(x, 0, -n)
@ -100,7 +92,7 @@ namespace sprout {
return sprout::math::detail::tgamma_impl_1( return sprout::math::detail::tgamma_impl_1(
x, x,
sprout::clamp( sprout::clamp(
sprout::math::iround(x - T(2)), sprout::iround(x - T(2)),
-static_cast<int>(sprout::math::factorial_limit<T>()), -static_cast<int>(sprout::math::factorial_limit<T>()),
static_cast<int>(sprout::math::factorial_limit<T>()) static_cast<int>(sprout::math::factorial_limit<T>())
) )

View file

@ -53,7 +53,7 @@ namespace sprout {
{ {
return rational_add_impl_3( return rational_add_impl_3(
rhs, rhs,
sprout::math::gcd(num, g), den, num sprout::gcd(num, g), den, num
); );
} }
template<typename IntType> template<typename IntType>
@ -86,7 +86,7 @@ namespace sprout {
operator+(sprout::rational<IntType> const& lhs, sprout::rational<IntType> const& rhs) { operator+(sprout::rational<IntType> const& lhs, sprout::rational<IntType> const& rhs) {
return sprout::detail::rational_add_impl( return sprout::detail::rational_add_impl(
lhs, rhs, lhs, rhs,
sprout::math::gcd(lhs.denominator(), rhs.denominator()) sprout::gcd(lhs.denominator(), rhs.denominator())
); );
} }
template<typename IntType> template<typename IntType>
@ -122,7 +122,7 @@ namespace sprout {
{ {
return rational_sub_impl_3( return rational_sub_impl_3(
rhs, rhs,
sprout::math::gcd(num, g), den, num sprout::gcd(num, g), den, num
); );
} }
template<typename IntType> template<typename IntType>
@ -155,7 +155,7 @@ namespace sprout {
operator-(sprout::rational<IntType> const& lhs, sprout::rational<IntType> const& rhs) { operator-(sprout::rational<IntType> const& lhs, sprout::rational<IntType> const& rhs) {
return sprout::detail::rational_sub_impl( return sprout::detail::rational_sub_impl(
lhs, rhs, lhs, rhs,
sprout::math::gcd(lhs.denominator(), rhs.denominator()) sprout::gcd(lhs.denominator(), rhs.denominator())
); );
} }
template<typename IntType> template<typename IntType>
@ -189,8 +189,8 @@ namespace sprout {
operator*(sprout::rational<IntType> const& lhs, sprout::rational<IntType> const& rhs) { operator*(sprout::rational<IntType> const& lhs, sprout::rational<IntType> const& rhs) {
return sprout::detail::rational_mul_impl( return sprout::detail::rational_mul_impl(
lhs, rhs, lhs, rhs,
sprout::math::gcd(lhs.numerator(), rhs.denominator()), sprout::gcd(lhs.numerator(), rhs.denominator()),
sprout::math::gcd(rhs.numerator(), lhs.denominator()) sprout::gcd(rhs.numerator(), lhs.denominator())
); );
} }
template<typename IntType> template<typename IntType>
@ -238,8 +238,8 @@ namespace sprout {
: lhs.numerator() == IntType(0) ? lhs : lhs.numerator() == IntType(0) ? lhs
: sprout::detail::rational_div_impl( : sprout::detail::rational_div_impl(
lhs, rhs, lhs, rhs,
sprout::math::gcd(lhs.numerator(), rhs.numerator()), sprout::gcd(lhs.numerator(), rhs.numerator()),
sprout::math::gcd(rhs.denominator(), lhs.denominator()) sprout::gcd(rhs.denominator(), lhs.denominator())
) )
; ;
} }

View file

@ -71,7 +71,7 @@ namespace sprout {
static SPROUT_CONSTEXPR IntType normalize_g(IntType num, IntType den) { static SPROUT_CONSTEXPR IntType normalize_g(IntType num, IntType den) {
return den == 0 ? throw sprout::bad_rational() return den == 0 ? throw sprout::bad_rational()
: num == 0 ? den : num == 0 ? den
: normalize_g_1(den, sprout::math::gcd(num, den)) : normalize_g_1(den, sprout::gcd(num, den))
; ;
} }
private: private:
@ -111,26 +111,26 @@ namespace sprout {
} }
rational& operator+=(rational const& rhs) { rational& operator+=(rational const& rhs) {
IntType g = sprout::math::gcd(den_, rhs.den_); IntType g = sprout::gcd(den_, rhs.den_);
den_ /= g; den_ /= g;
num_ = num_ * (rhs.den_ / g) + rhs.num_ * den_; num_ = num_ * (rhs.den_ / g) + rhs.num_ * den_;
g = sprout::math::gcd(num_, g); g = sprout::gcd(num_, g);
num_ /= g; num_ /= g;
den_ *= rhs.den_ / g; den_ *= rhs.den_ / g;
return *this; return *this;
} }
rational& operator-=(rational const& rhs) { rational& operator-=(rational const& rhs) {
IntType g = sprout::math::gcd(den_, rhs.den_); IntType g = sprout::gcd(den_, rhs.den_);
den_ /= g; den_ /= g;
num_ = num_ * (rhs.den_ / g) - rhs.num_ * den_; num_ = num_ * (rhs.den_ / g) - rhs.num_ * den_;
g = sprout::math::gcd(num_, g); g = sprout::gcd(num_, g);
num_ /= g; num_ /= g;
den_ *= rhs.den_ / g; den_ *= rhs.den_ / g;
return *this; return *this;
} }
rational& operator*=(rational const& rhs) { rational& operator*=(rational const& rhs) {
IntType gcd1 = sprout::math::gcd(num_, rhs.den_); IntType gcd1 = sprout::gcd(num_, rhs.den_);
IntType gcd2 = sprout::math::gcd(rhs.num_, den_); IntType gcd2 = sprout::gcd(rhs.num_, den_);
num_ =(num_ / gcd1) * (rhs.num_ / gcd2); num_ =(num_ / gcd1) * (rhs.num_ / gcd2);
den_ =(den_ / gcd2) * (rhs.den_ / gcd1); den_ =(den_ / gcd2) * (rhs.den_ / gcd1);
return *this; return *this;
@ -142,8 +142,8 @@ namespace sprout {
if (num_ == IntType(0)) { if (num_ == IntType(0)) {
return *this; return *this;
} }
IntType gcd1 = sprout::math::gcd(num_, rhs.num_); IntType gcd1 = sprout::gcd(num_, rhs.num_);
IntType gcd2 = sprout::math::gcd(rhs.den_, den_); IntType gcd2 = sprout::gcd(rhs.den_, den_);
num_ =(num_ / gcd1) * (rhs.den_ / gcd2); num_ =(num_ / gcd1) * (rhs.den_ / gcd2);
den_ =(den_ / gcd2) * (rhs.num_ / gcd1); den_ =(den_ / gcd2) * (rhs.num_ / gcd1);
if (den_ < IntType(0)) { if (den_ < IntType(0)) {