diff --git a/sprout/cmath.hpp b/sprout/cmath.hpp index 1568cb14..446929f0 100644 --- a/sprout/cmath.hpp +++ b/sprout/cmath.hpp @@ -2,6 +2,6 @@ #define SPROUT_CMATH_HPP #include -#include +#include #endif // #ifndef SPROUT_CMATH_HPP diff --git a/sprout/math/cosh.hpp b/sprout/math/cosh.hpp new file mode 100644 index 00000000..359a46bd --- /dev/null +++ b/sprout/math/cosh.hpp @@ -0,0 +1,64 @@ +#ifndef SPROUT_MATH_COSH_HPP +#define SPROUT_MATH_COSH_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 + cosh_impl(T x, T tmp, std::size_t n, T x2n) { + return 2 * n > sprout::math::factorial_limit() ? tmp + : sprout::math::detail::cosh_impl( + x, + tmp + 1 / sprout::math::factorial(2 * n) * x2n, + n + 1, + x2n * x * x + ) + ; + } + + template< + typename FloatType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR FloatType + cosh(FloatType x) { + typedef double type; + return static_cast(sprout::math::detail::cosh_impl( + static_cast(x), + type(1), + 1, + static_cast(x) * static_cast(x) + )); + } + + template< + typename IntType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR double + cosh(IntType x) { + return sprout::math::detail::cosh(static_cast(x)); + } + } // namespace detail + +# if SPROUT_USE_BUILTIN_CMATH_FUNCTION + using std::cosh; +# else + using sprout::math::detail::cosh; +# endif + } // namespace math + + using sprout::math::cosh; +} // namespace sprout + +#endif // #ifndef SPROUT_MATH_COSH_HPP diff --git a/sprout/math/functions.hpp b/sprout/math/functions.hpp new file mode 100644 index 00000000..8e5462fe --- /dev/null +++ b/sprout/math/functions.hpp @@ -0,0 +1,9 @@ +#ifndef SPROUT_MATH_FUNCTIONS_HPP +#define SPROUT_MATH_FUNCTIONS_HPP + +#include +#include +#include +#include + +#endif // #ifndef SPROUT_MATH_FUNCTIONS_HPP diff --git a/sprout/math/hyperbolic.hpp b/sprout/math/hyperbolic.hpp new file mode 100644 index 00000000..32ae4216 --- /dev/null +++ b/sprout/math/hyperbolic.hpp @@ -0,0 +1,8 @@ +#ifndef SPROUT_MATH_HYPERBOLIC_HPP +#define SPROUT_MATH_HYPERBOLIC_HPP + +#include +#include +#include + +#endif // #ifndef SPROUT_MATH_HYPERBOLIC_HPP diff --git a/sprout/math/power.hpp b/sprout/math/power.hpp new file mode 100644 index 00000000..ab356abd --- /dev/null +++ b/sprout/math/power.hpp @@ -0,0 +1,6 @@ +#ifndef SPROUT_MATH_POWER_HPP +#define SPROUT_MATH_POWER_HPP + +#include + +#endif // #ifndef SPROUT_MATH_POWER_HPP diff --git a/sprout/math/sinh.hpp b/sprout/math/sinh.hpp new file mode 100644 index 00000000..b2ae1750 --- /dev/null +++ b/sprout/math/sinh.hpp @@ -0,0 +1,64 @@ +#ifndef SPROUT_MATH_SINH_HPP +#define SPROUT_MATH_SINH_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 + sinh_impl(T x, T tmp, std::size_t n, T x2n1) { + return 2 * n + 1 > sprout::math::factorial_limit() ? tmp + : sprout::math::detail::sinh_impl( + x, + tmp + 1 / sprout::math::factorial(2 * n + 1) * x2n1, + n + 1, + x2n1 * x * x + ) + ; + } + + template< + typename FloatType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR FloatType + sinh(FloatType x) { + typedef double type; + return static_cast(sprout::math::detail::sinh_impl( + static_cast(x), + static_cast(x), + 1, + static_cast(x) * static_cast(x) * static_cast(x) + )); + } + + template< + typename IntType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR double + sinh(IntType x) { + return sprout::math::detail::sinh(static_cast(x)); + } + } // namespace detail + +# if SPROUT_USE_BUILTIN_CMATH_FUNCTION + using std::sinh; +# else + using sprout::math::detail::sinh; +# endif + } // namespace math + + using sprout::math::sinh; +} // namespace sprout + +#endif // #ifndef SPROUT_MATH_SINH_HPP diff --git a/sprout/math/sqrt.hpp b/sprout/math/sqrt.hpp new file mode 100644 index 00000000..76405e0d --- /dev/null +++ b/sprout/math/sqrt.hpp @@ -0,0 +1,72 @@ +#ifndef SPROUT_MATH_SQRT_HPP +#define SPROUT_MATH_SQRT_HPP + +#include +#include +#include +#include +#if SPROUT_USE_BUILTIN_CMATH_FUNCTION +# include +#endif + +namespace sprout { + namespace math { + namespace detail { + template + inline SPROUT_CONSTEXPR T + sqrt_impl_1(T x, T s, T s2) { + return !(s < s2) ? s2 + : sprout::math::detail::sqrt_impl_1( + x, + (x / s + s) / 2, + s + ) + ; + } + template + inline SPROUT_CONSTEXPR T + sqrt_impl(T x, T s) { + return sprout::math::detail::sqrt_impl_1( + x, + (x / s + s) / 2, + s + ) + ; + } + + template< + typename FloatType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR FloatType + sqrt(FloatType x) { + typedef double type; + return x < 0 ? std::numeric_limits::quiet_NaN() + : x == 0 ? type(0) + : static_cast(sprout::math::detail::sqrt_impl( + static_cast(x), + x > 1 ? static_cast(x) : type(1) + )); + } + + template< + typename IntType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR double + sqrt(IntType x) { + return sprout::math::detail::sqrt(static_cast(x)); + } + } // namespace detail + +# if SPROUT_USE_BUILTIN_CMATH_FUNCTION + using std::sqrt; +# else + using sprout::math::detail::sqrt; +# endif + } // namespace math + + using sprout::math::sqrt; +} // namespace sprout + +#endif // #ifndef SPROUT_MATH_SQRT_HPP diff --git a/sprout/math/tanh.hpp b/sprout/math/tanh.hpp new file mode 100644 index 00000000..fe63a32b --- /dev/null +++ b/sprout/math/tanh.hpp @@ -0,0 +1,45 @@ +#ifndef SPROUT_MATH_TANH_HPP +#define SPROUT_MATH_TANH_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 + tanh(FloatType x) { + return sprout::math::detail::sinh(x) / sprout::math::detail::cosh(x); + } + + template< + typename IntType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR double + tanh(IntType x) { + return sprout::math::detail::tanh(static_cast(x)); + } + } // namespace detail + +# if SPROUT_USE_BUILTIN_CMATH_FUNCTION + using std::tanh; +# else + using sprout::math::detail::tanh; +# endif + } // namespace math + + using sprout::math::tanh; +} // namespace sprout + +#endif // #ifndef SPROUT_MATH_TANH_HPP