diff --git a/sprout/math/constants.hpp b/sprout/math/constants.hpp index a743395c..da7de011 100644 --- a/sprout/math/constants.hpp +++ b/sprout/math/constants.hpp @@ -19,6 +19,13 @@ namespace sprout { inline SPROUT_CONSTEXPR T pi_div_two() { return 1.570796326794896619231321691639751442098584699687552910487472L; } + // + // root_two + // + template + inline SPROUT_CONSTEXPR T root_two() { + return 1.414213562373095048801688724209698078569671875376948073L; + } } // namespace math } // namespace sprout diff --git a/sprout/math/cos.hpp b/sprout/math/cos.hpp index 3b0443b8..aaace216 100644 --- a/sprout/math/cos.hpp +++ b/sprout/math/cos.hpp @@ -19,7 +19,7 @@ namespace sprout { return 2 * n > sprout::math::factorial_limit() ? tmp : sprout::math::detail::cos_impl( x, - tmp + (n % 2 ? -1 : 1) / sprout::math::factorial(2 * n) * x2n, + tmp + (n % 2 ? -1 : 1) * x2n / sprout::math::factorial(2 * n), n + 1, x2n * x * x ) diff --git a/sprout/math/cosh.hpp b/sprout/math/cosh.hpp index 359a46bd..ff205d2a 100644 --- a/sprout/math/cosh.hpp +++ b/sprout/math/cosh.hpp @@ -19,7 +19,7 @@ namespace sprout { return 2 * n > sprout::math::factorial_limit() ? tmp : sprout::math::detail::cosh_impl( x, - tmp + 1 / sprout::math::factorial(2 * n) * x2n, + tmp + x2n / sprout::math::factorial(2 * n), n + 1, x2n * x * x ) diff --git a/sprout/math/exp.hpp b/sprout/math/exp.hpp new file mode 100644 index 00000000..78acbb01 --- /dev/null +++ b/sprout/math/exp.hpp @@ -0,0 +1,64 @@ +#ifndef SPROUT_MATH_EXP_HPP +#define SPROUT_MATH_EXP_HPP + +#include +#include +#include +#include +#include +#if SPROUT_USE_BUILTIN_CMATH_FUNCTION +# include +#endif + +namespace sprout { + namespace math { + namespace detail { + template + inline SPROUT_CONSTEXPR T + exp_impl(T x, T tmp, std::size_t n, T xn) { + return n > sprout::math::factorial_limit() ? tmp + : sprout::math::detail::exp_impl( + x, + tmp + xn / sprout::math::factorial(n), + n + 1, + xn * x + ) + ; + } + + template< + typename FloatType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR FloatType + exp(FloatType x) { + typedef double type; + return static_cast(sprout::math::detail::exp_impl( + static_cast(x), + type(1), + 1, + static_cast(x) + )); + } + + template< + typename IntType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR double + exp(IntType x) { + return sprout::math::detail::exp(static_cast(x)); + } + } // namespace detail + +# if SPROUT_USE_BUILTIN_CMATH_FUNCTION + using std::exp; +# else + using sprout::math::detail::exp; +# endif + } // namespace math + + using sprout::math::exp; +} // namespace sprout + +#endif // #ifndef SPROUT_MATH_EXP_HPP diff --git a/sprout/math/exponential.hpp b/sprout/math/exponential.hpp new file mode 100644 index 00000000..b441aee3 --- /dev/null +++ b/sprout/math/exponential.hpp @@ -0,0 +1,7 @@ +#ifndef SPROUT_MATH_EXPONENTIAL_HPP +#define SPROUT_MATH_EXPONENTIAL_HPP + +#include +#include + +#endif // #ifndef SPROUT_MATH_EXPONENTIAL_HPP diff --git a/sprout/math/functions.hpp b/sprout/math/functions.hpp index 8e5462fe..5d984352 100644 --- a/sprout/math/functions.hpp +++ b/sprout/math/functions.hpp @@ -2,6 +2,7 @@ #define SPROUT_MATH_FUNCTIONS_HPP #include +#include #include #include #include diff --git a/sprout/math/log.hpp b/sprout/math/log.hpp new file mode 100644 index 00000000..a59fb3d9 --- /dev/null +++ b/sprout/math/log.hpp @@ -0,0 +1,81 @@ +#ifndef SPROUT_MATH_LOG_HPP +#define SPROUT_MATH_LOG_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 + log_impl_2(T x, T tmp, std::size_t n, T xn) { + return n > sprout::math::factorial_limit() ? tmp + : sprout::math::detail::log_impl_2( + x, + tmp + (n % 2 ? 1 : -1) * xn / n, + n + 1, + xn * x + ) + ; + } + template + inline SPROUT_CONSTEXPR T + log_impl_1(T x) { + return sprout::math::detail::log_impl_2( + x, + x, + 2, + x * x + ); + } + template + inline SPROUT_CONSTEXPR T + log_impl(T x) { + return !(x > sprout::math::root_two()) ? sprout::math::detail::log_impl_1(x - 1) + : 2 * sprout::math::detail::log_impl(sprout::math::detail::sqrt(x)) + ; + } + + template< + typename FloatType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR FloatType + log(FloatType x) { + typedef double type; + return !(x > 0) ? -std::numeric_limits::infinity() + : static_cast(sprout::math::detail::log_impl(x)) + ; + } + + template< + typename IntType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR double + log(IntType x) { + return sprout::math::detail::log(static_cast(x)); + } + } // namespace detail + +# if SPROUT_USE_BUILTIN_CMATH_FUNCTION + using std::log; +# else + using sprout::math::detail::log; +# endif + } // namespace math + + using sprout::math::log; +} // namespace sprout + +#endif // #ifndef SPROUT_MATH_LOG_HPP diff --git a/sprout/math/sinh.hpp b/sprout/math/sinh.hpp index b2ae1750..741a6b32 100644 --- a/sprout/math/sinh.hpp +++ b/sprout/math/sinh.hpp @@ -19,7 +19,7 @@ namespace sprout { return 2 * n + 1 > sprout::math::factorial_limit() ? tmp : sprout::math::detail::sinh_impl( x, - tmp + 1 / sprout::math::factorial(2 * n + 1) * x2n1, + tmp + x2n1 / sprout::math::factorial(2 * n + 1), n + 1, x2n1 * x * x )