From 6ccd6e1cf4dbd865e7855498ea410b75c8c51b6f Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Sat, 5 May 2012 18:50:17 +0900 Subject: [PATCH] add sprout::cbrt, hypot, fmax, fmin, fdim fix sprout::pow case x==0 --- sprout/math/cbrt.hpp | 47 +++++++++++++++++++++++++++++ sprout/math/constants.hpp | 33 +++++++++++++-------- sprout/math/{abs.hpp => fabs.hpp} | 6 ++-- sprout/math/fdim.hpp | 48 ++++++++++++++++++++++++++++++ sprout/math/fmax.hpp | 48 ++++++++++++++++++++++++++++++ sprout/math/fmin.hpp | 48 ++++++++++++++++++++++++++++++ sprout/math/hypot.hpp | 49 +++++++++++++++++++++++++++++++ sprout/math/operations.hpp | 5 +++- sprout/math/pow.hpp | 4 ++- sprout/math/power.hpp | 2 ++ 10 files changed, 273 insertions(+), 17 deletions(-) create mode 100644 sprout/math/cbrt.hpp rename sprout/math/{abs.hpp => fabs.hpp} (90%) create mode 100644 sprout/math/fdim.hpp create mode 100644 sprout/math/fmax.hpp create mode 100644 sprout/math/fmin.hpp create mode 100644 sprout/math/hypot.hpp diff --git a/sprout/math/cbrt.hpp b/sprout/math/cbrt.hpp new file mode 100644 index 00000000..4bcb6a6c --- /dev/null +++ b/sprout/math/cbrt.hpp @@ -0,0 +1,47 @@ +#ifndef SPROUT_MATH_CBRT_HPP +#define SPROUT_MATH_CBRT_HPP + +#include +#include +#include +#include +#include +#if SPROUT_USE_BUILTIN_CMATH_FUNCTION +# include +#endif + +namespace sprout { + namespace math { + namespace detail { + template< + typename FloatType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR FloatType + cbrt(FloatType x) { + return x < 0 ? -sprout::math::detail::pow(-x, sprout::math::third()) + : sprout::math::detail::pow(x, sprout::math::third()) + ; + } + + template< + typename IntType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR double + cbrt(IntType x) { + return sprout::math::detail::cbrt(static_cast(x)); + } + } // namespace detail + +# if SPROUT_USE_BUILTIN_CMATH_FUNCTION + using std::cbrt; +# else + using sprout::math::detail::cbrt; +# endif + } // namespace math + + using sprout::math::cbrt; +} // namespace sprout + +#endif // #ifndef SPROUT_MATH_CBRT_HPP diff --git a/sprout/math/constants.hpp b/sprout/math/constants.hpp index 272b1418..1a258c64 100644 --- a/sprout/math/constants.hpp +++ b/sprout/math/constants.hpp @@ -7,35 +7,46 @@ namespace sprout { namespace math { // // pi + // half_pi + // quarter_pi // template inline SPROUT_CONSTEXPR T pi() { return 3.141592653589793238462643383279502884197169399375105820974944L; } - // - // half_pi - // template inline SPROUT_CONSTEXPR T half_pi() { return 1.570796326794896619231321691639751442098584699687552910487472L; } - // - // quarter_pi - // template inline SPROUT_CONSTEXPR T quarter_pi() { return 0.785398163397448309615660845819875721049292349843776455243736L; } // + // half + // third + // twothirds + // + template + inline SPROUT_CONSTEXPR T half() { + return 0.5L; + } + template + inline SPROUT_CONSTEXPR T third() { + return 0.3333333333333333333333333333333333333333333333333333333333333333333333L; + } + template + inline SPROUT_CONSTEXPR T twothirds() { + return 0.6666666666666666666666666666666666666666666666666666666666666666666666L; + } + // // root_two + // half_root_two // template inline SPROUT_CONSTEXPR T root_two() { return 1.414213562373095048801688724209698078569671875376948073L; } - // - // half_root_two - // template inline SPROUT_CONSTEXPR T half_root_two() { return 0.70710678118654752440084436210484903928483593756084L; @@ -49,14 +60,12 @@ namespace sprout { } // // ln_ten + // ln_two // template inline SPROUT_CONSTEXPR T ln_ten() { return 2.302585092994045684017991454684364207601101488628772976L; } - // - // ln_two - // template inline SPROUT_CONSTEXPR T ln_two() { return 0.693147180559945309417232121458176568075500134360255254L; diff --git a/sprout/math/abs.hpp b/sprout/math/fabs.hpp similarity index 90% rename from sprout/math/abs.hpp rename to sprout/math/fabs.hpp index fcc5ed71..606ed855 100644 --- a/sprout/math/abs.hpp +++ b/sprout/math/fabs.hpp @@ -1,5 +1,5 @@ -#ifndef SPROUT_MATH_ABS_HPP -#define SPROUT_MATH_ABS_HPP +#ifndef SPROUT_MATH_FABS_HPP +#define SPROUT_MATH_FABS_HPP #include #include @@ -64,4 +64,4 @@ namespace sprout { using sprout::math::fabs; } // namespace sprout -#endif // #ifndef SPROUT_MATH_ABS_HPP +#endif // #ifndef SPROUT_MATH_FABS_HPP diff --git a/sprout/math/fdim.hpp b/sprout/math/fdim.hpp new file mode 100644 index 00000000..c995f8f3 --- /dev/null +++ b/sprout/math/fdim.hpp @@ -0,0 +1,48 @@ +#ifndef SPROUT_MATH_FDIM_HPP +#define SPROUT_MATH_FDIM_HPP + +#include +#include +#include +#include +#if SPROUT_USE_BUILTIN_CMATH_FUNCTION +# include +#endif + +namespace sprout { + namespace math { + namespace detail { + template< + typename FloatType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR FloatType + fdim(FloatType x, FloatType y) { + return x > y ? x - y : 0; + } + + template< + typename ArithmeticType1, + typename ArithmeticType2, + typename sprout::enabler_if< + std::is_arithmetic::value && std::is_arithmetic::value + >::type = sprout::enabler + > + inline SPROUT_CONSTEXPR typename sprout::math::float_promote::type + fdim(ArithmeticType1 x, ArithmeticType2 y) { + typedef typename sprout::math::float_promote::type type; + return sprout::math::detail::fdim(static_cast(x), static_cast(y)); + } + } // namespace detail + +# if SPROUT_USE_BUILTIN_CMATH_FUNCTION + using std::fdim; +# else + using sprout::math::detail::fdim; +# endif + } // namespace math + + using sprout::math::fdim; +} // namespace sprout + +#endif // #ifndef SPROUT_MATH_FDIM_HPP diff --git a/sprout/math/fmax.hpp b/sprout/math/fmax.hpp new file mode 100644 index 00000000..7b06755d --- /dev/null +++ b/sprout/math/fmax.hpp @@ -0,0 +1,48 @@ +#ifndef SPROUT_MATH_FMAX_HPP +#define SPROUT_MATH_FMAX_HPP + +#include +#include +#include +#include +#if SPROUT_USE_BUILTIN_CMATH_FUNCTION +# include +#endif + +namespace sprout { + namespace math { + namespace detail { + template< + typename FloatType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR FloatType + fmax(FloatType x, FloatType y) { + return x < y ? y : x; + } + + template< + typename ArithmeticType1, + typename ArithmeticType2, + typename sprout::enabler_if< + std::is_arithmetic::value && std::is_arithmetic::value + >::type = sprout::enabler + > + inline SPROUT_CONSTEXPR typename sprout::math::float_promote::type + fmax(ArithmeticType1 x, ArithmeticType2 y) { + typedef typename sprout::math::float_promote::type type; + return sprout::math::detail::fmax(static_cast(x), static_cast(y)); + } + } // namespace detail + +# if SPROUT_USE_BUILTIN_CMATH_FUNCTION + using std::fmax; +# else + using sprout::math::detail::fmax; +# endif + } // namespace math + + using sprout::math::fmax; +} // namespace sprout + +#endif // #ifndef SPROUT_MATH_FMAX_HPP diff --git a/sprout/math/fmin.hpp b/sprout/math/fmin.hpp new file mode 100644 index 00000000..0fb53263 --- /dev/null +++ b/sprout/math/fmin.hpp @@ -0,0 +1,48 @@ +#ifndef SPROUT_MATH_FMIN_HPP +#define SPROUT_MATH_FMIN_HPP + +#include +#include +#include +#include +#if SPROUT_USE_BUILTIN_CMATH_FUNCTION +# include +#endif + +namespace sprout { + namespace math { + namespace detail { + template< + typename FloatType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR FloatType + fmin(FloatType x, FloatType y) { + return x > y ? y : x; + } + + template< + typename ArithmeticType1, + typename ArithmeticType2, + typename sprout::enabler_if< + std::is_arithmetic::value && std::is_arithmetic::value + >::type = sprout::enabler + > + inline SPROUT_CONSTEXPR typename sprout::math::float_promote::type + fmin(ArithmeticType1 x, ArithmeticType2 y) { + typedef typename sprout::math::float_promote::type type; + return sprout::math::detail::fmin(static_cast(x), static_cast(y)); + } + } // namespace detail + +# if SPROUT_USE_BUILTIN_CMATH_FUNCTION + using std::fmin; +# else + using sprout::math::detail::fmin; +# endif + } // namespace math + + using sprout::math::fmin; +} // namespace sprout + +#endif // #ifndef SPROUT_MATH_FMIN_HPP diff --git a/sprout/math/hypot.hpp b/sprout/math/hypot.hpp new file mode 100644 index 00000000..12967e1a --- /dev/null +++ b/sprout/math/hypot.hpp @@ -0,0 +1,49 @@ +#ifndef SPROUT_MATH_HYPOT_HPP +#define SPROUT_MATH_HYPOT_HPP + +#include +#include +#include +#include +#include +#if SPROUT_USE_BUILTIN_CMATH_FUNCTION +# include +#endif + +namespace sprout { + namespace math { + namespace detail { + template< + typename FloatType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR FloatType + hypot(FloatType x, FloatType y) { + return sprout::math::detail::sqrt(x * x + y * y); + } + + template< + typename ArithmeticType1, + typename ArithmeticType2, + typename sprout::enabler_if< + std::is_arithmetic::value && std::is_arithmetic::value + >::type = sprout::enabler + > + inline SPROUT_CONSTEXPR typename sprout::math::float_promote::type + hypot(ArithmeticType1 x, ArithmeticType2 y) { + typedef typename sprout::math::float_promote::type type; + return sprout::math::detail::hypot(static_cast(x), static_cast(y)); + } + } // namespace detail + +# if SPROUT_USE_BUILTIN_CMATH_FUNCTION + using std::hypot; +# else + using sprout::math::detail::hypot; +# endif + } // namespace math + + using sprout::math::hypot; +} // namespace sprout + +#endif // #ifndef SPROUT_MATH_HYPOT_HPP diff --git a/sprout/math/operations.hpp b/sprout/math/operations.hpp index b8ae419d..df845bd9 100644 --- a/sprout/math/operations.hpp +++ b/sprout/math/operations.hpp @@ -1,6 +1,9 @@ #ifndef SPROUT_MATH_OPERATIONS_HPP #define SPROUT_MATH_OPERATIONS_HPP -#include +#include +#include +#include +#include #endif // #ifndef SPROUT_MATH_OPERATIONS_HPP diff --git a/sprout/math/pow.hpp b/sprout/math/pow.hpp index 635eb66a..d762787e 100644 --- a/sprout/math/pow.hpp +++ b/sprout/math/pow.hpp @@ -21,7 +21,9 @@ namespace sprout { > inline SPROUT_CONSTEXPR FloatType pow(FloatType x, FloatType y) { - return sprout::math::detail::exp(y * sprout::math::detail::log(x)); + return x == 0 && y > 0 ? FloatType(0) + : sprout::math::detail::exp(y * sprout::math::detail::log(x)) + ; } template< diff --git a/sprout/math/power.hpp b/sprout/math/power.hpp index ebcd6e55..4ebd1266 100644 --- a/sprout/math/power.hpp +++ b/sprout/math/power.hpp @@ -2,6 +2,8 @@ #define SPROUT_MATH_POWER_HPP #include +#include #include +#include #endif // #ifndef SPROUT_MATH_POWER_HPP