From 28f22ab73dbd7e1b8820688ddf9f63f6be88ebdd Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Fri, 4 May 2012 23:23:39 +0900 Subject: [PATCH] add sprout::asin, acos, pow --- sprout/math/acos.hpp | 45 ++++++++++++++++++ sprout/math/asin.hpp | 88 ++++++++++++++++++++++++++++++++++ sprout/math/pow.hpp | 89 +++++++++++++++++++++++++++++++++++ sprout/math/power.hpp | 1 + sprout/math/trigonometric.hpp | 2 + 5 files changed, 225 insertions(+) create mode 100644 sprout/math/acos.hpp create mode 100644 sprout/math/asin.hpp create mode 100644 sprout/math/pow.hpp diff --git a/sprout/math/acos.hpp b/sprout/math/acos.hpp new file mode 100644 index 00000000..405564dc --- /dev/null +++ b/sprout/math/acos.hpp @@ -0,0 +1,45 @@ +#ifndef SPROUT_MATH_ACOS_HPP +#define SPROUT_MATH_ACOS_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 + acos(FloatType x) { + return sprout::math::half_pi() - sprout::math::detail::asin(x); + } + + template< + typename IntType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR double + acos(IntType x) { + return sprout::math::detail::acos(static_cast(x)); + } + } // namespace detail + +# if SPROUT_USE_BUILTIN_CMATH_FUNCTION + using std::acos; +# else + using sprout::math::detail::acos; +# endif + } // namespace math + + using sprout::math::acos; +} // namespace sprout + +#endif // #ifndef SPROUT_MATH_ACOS_HPP diff --git a/sprout/math/asin.hpp b/sprout/math/asin.hpp new file mode 100644 index 00000000..f97b043f --- /dev/null +++ b/sprout/math/asin.hpp @@ -0,0 +1,88 @@ +#ifndef SPROUT_MATH_ASIN_HPP +#define SPROUT_MATH_ASIN_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#if SPROUT_USE_BUILTIN_CMATH_FUNCTION +# include +#endif + +namespace sprout { + namespace math { + namespace detail { + template + inline SPROUT_CONSTEXPR T + asin_impl_2(T x, T tmp, std::size_t n, T x2n1, T _4n) { + return 2 * n > sprout::math::factorial_limit() ? tmp + : sprout::math::detail::asin_impl_2( + x, + tmp + sprout::math::factorial(2 * n) + / _4n / sprout::math::factorial(n) / sprout::math::factorial(n) / (2 * n + 1) + * x2n1 + , + n + 1, + x2n1 * x * x, + _4n * 4 + ) + ; + } + template + inline SPROUT_CONSTEXPR T + asin_impl_1(T x) { + return sprout::math::detail::asin_impl_2( + x, + x, + 1, + x * x * x, + T(4) + ); + } + template + inline SPROUT_CONSTEXPR T + asin_impl(T x) { + return x > sprout::math::half_root_two() + ? sprout::math::half_pi() - sprout::math::detail::asin_impl_1(sprout::math::detail::sqrt(1 - x * x)) + : sprout::math::detail::asin_impl_1(x) + ; + } + + template< + typename FloatType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR FloatType + asin(FloatType x) { + typedef double type; + return x > 1 || x < -1 ? std::numeric_limits::quiet_NaN() + : x < 0 ? -static_cast(sprout::math::detail::asin_impl(static_cast(-x))) + : static_cast(sprout::math::detail::asin_impl(static_cast(x))) + ; + } + + template< + typename IntType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR double + asin(IntType x) { + return sprout::math::detail::asin(static_cast(x)); + } + } // namespace detail + +# if SPROUT_USE_BUILTIN_CMATH_FUNCTION + using std::asin; +# else + using sprout::math::detail::asin; +# endif + } // namespace math + + using sprout::math::asin; +} // namespace sprout + +#endif // #ifndef SPROUT_MATH_ASIN_HPP diff --git a/sprout/math/pow.hpp b/sprout/math/pow.hpp new file mode 100644 index 00000000..841ec18a --- /dev/null +++ b/sprout/math/pow.hpp @@ -0,0 +1,89 @@ +#ifndef SPROUT_MATH_POW_HPP +#define SPROUT_MATH_POW_HPP + +#include +#include +#include +#include +#include +#include +#if SPROUT_USE_BUILTIN_CMATH_FUNCTION +# include +#endif + +namespace sprout { + namespace math { + namespace detail { + template + struct pow_promoted {}; + template + struct pow_promoted< + X, + Y, + typename std::enable_if< + std::is_arithmetic::value && std::is_arithmetic::value + && (std::is_same::value || std::is_same::value) + >::type + > { + public: + typedef long double type; + }; + template + struct pow_promoted< + X, + Y, + typename std::enable_if< + std::is_arithmetic::value && std::is_arithmetic::value + && !(std::is_same::value || std::is_same::value) + >::type + > { + public: + typedef double type; + }; + } // namespace detail + // + // pow_promoted + // + template + struct pow_promoted + : public sprout::math::detail::pow_promoted< + typename std::remove_cv::type, + typename std::remove_cv::type + > + {}; + + namespace detail { + template< + typename FloatType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR FloatType + pow(FloatType x, FloatType y) { + return sprout::math::detail::exp(y * sprout::math::detail::log(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::pow_promoted::type + pow(ArithmeticType1 x, ArithmeticType2 y) { + typedef typename sprout::math::pow_promoted::type type; + return sprout::math::detail::pow(static_cast(x), static_cast(y)); + } + } // namespace detail + +# if SPROUT_USE_BUILTIN_CMATH_FUNCTION + using std::pow; +# else + using sprout::math::detail::pow; +# endif + } // namespace math + + using sprout::math::pow; +} // namespace sprout + +#endif // #ifndef SPROUT_MATH_POW_HPP diff --git a/sprout/math/power.hpp b/sprout/math/power.hpp index ab356abd..ebcd6e55 100644 --- a/sprout/math/power.hpp +++ b/sprout/math/power.hpp @@ -2,5 +2,6 @@ #define SPROUT_MATH_POWER_HPP #include +#include #endif // #ifndef SPROUT_MATH_POWER_HPP diff --git a/sprout/math/trigonometric.hpp b/sprout/math/trigonometric.hpp index e4203bfa..299062a1 100644 --- a/sprout/math/trigonometric.hpp +++ b/sprout/math/trigonometric.hpp @@ -4,6 +4,8 @@ #include #include #include +#include +#include #include #endif // #ifndef SPROUT_MATH_TRIGONOMETRIC_HPP