mirror of
https://github.com/bolero-MURAKAMI/Sprout.git
synced 2025-01-21 20:36:37 +00:00
add math::lgamma
This commit is contained in:
parent
a55c430f09
commit
5f40808f75
58 changed files with 323 additions and 116 deletions
|
@ -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_));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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_));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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))
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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))
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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>())
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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>())
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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>())
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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))
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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<
|
||||||
|
|
|
@ -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))
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
;
|
;
|
||||||
|
|
|
@ -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<
|
||||||
|
|
|
@ -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)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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))
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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))
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<
|
||||||
|
|
|
@ -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
210
sprout/math/lgamma.hpp
Normal 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
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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))
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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>()
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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>()
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)))
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)))
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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))
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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<
|
||||||
|
|
|
@ -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
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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>())
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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>())
|
||||||
)
|
)
|
||||||
|
|
|
@ -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())
|
||||||
)
|
)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
Loading…
Reference in a new issue