mirror of
https://github.com/boostorg/math.git
synced 2026-01-19 04:22:09 +00:00
Improve performance of sin_pi and cos_pi:
Use a static_cast to int when available for parity checking as it's much faster than itrunc. Don't check for overflows in the result, since we know the result is in [-1,1].
This commit is contained in:
@@ -33,7 +33,7 @@ T cos_pi_imp(T x, const Policy& pol)
|
||||
x = -x;
|
||||
}
|
||||
T rem = floor(x);
|
||||
if(itrunc(rem, pol) & 1)
|
||||
if(iconvert(rem, pol) & 1)
|
||||
invert = !invert;
|
||||
rem = x - rem;
|
||||
if(rem > 0.5f)
|
||||
@@ -66,7 +66,10 @@ inline typename tools::promote_args<T>::type cos_pi(T x, const Policy&)
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
policies::discrete_quantile<>,
|
||||
policies::assert_undefined<> >::type forwarding_policy;
|
||||
policies::assert_undefined<>,
|
||||
// We want to igore overflows since the result is in [-1,1] and the
|
||||
// check slows the code down considerably.
|
||||
policies::overflow_error<policies::ignore_error> >::type forwarding_policy;
|
||||
return policies::checked_narrowing_cast<result_type, forwarding_policy>(boost::math::detail::cos_pi_imp<value_type>(x, forwarding_policy()), "cos_pi");
|
||||
}
|
||||
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
namespace boost{ namespace math{ namespace detail{
|
||||
|
||||
template <class T, class Policy>
|
||||
T sin_pi_imp(T x, const Policy& pol)
|
||||
inline T sin_pi_imp(T x, const Policy& pol)
|
||||
{
|
||||
BOOST_MATH_STD_USING // ADL of std names
|
||||
if(x < 0)
|
||||
return -sin_pi(-x);
|
||||
return -sin_pi_imp(T(-x), pol);
|
||||
// sin of pi*x:
|
||||
bool invert;
|
||||
if(x < 0.5)
|
||||
@@ -38,7 +38,7 @@ T sin_pi_imp(T x, const Policy& pol)
|
||||
invert = false;
|
||||
|
||||
T rem = floor(x);
|
||||
if(itrunc(rem, pol) & 1)
|
||||
if(iconvert(rem, pol) & 1)
|
||||
invert = !invert;
|
||||
rem = x - rem;
|
||||
if(rem > 0.5f)
|
||||
@@ -62,8 +62,11 @@ inline typename tools::promote_args<T>::type sin_pi(T x, const Policy&)
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
policies::discrete_quantile<>,
|
||||
policies::assert_undefined<> >::type forwarding_policy;
|
||||
return policies::checked_narrowing_cast<result_type, forwarding_policy>(boost::math::detail::sin_pi_imp<value_type>(x, forwarding_policy()), "cos_pi");
|
||||
policies::assert_undefined<>,
|
||||
// We want to igore overflows since the result is in [-1,1] and the
|
||||
// check slows the code down considerably.
|
||||
policies::overflow_error<policies::ignore_error> >::type forwarding_policy;
|
||||
return policies::checked_narrowing_cast<result_type, forwarding_policy>(boost::math::detail::sin_pi_imp<value_type>(x, forwarding_policy()), "sin_pi");
|
||||
}
|
||||
|
||||
template <class T>
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
#include <boost/math/tools/config.hpp>
|
||||
#include <boost/math/policies/error_handling.hpp>
|
||||
#include <boost/math/special_functions/fpclassify.hpp>
|
||||
#include <boost/type_traits/is_constructible.hpp>
|
||||
#include <boost/core/enable_if.hpp>
|
||||
|
||||
namespace boost{ namespace math{ namespace detail{
|
||||
|
||||
@@ -106,6 +108,55 @@ inline boost::long_long_type lltrunc(const T& v)
|
||||
|
||||
#endif
|
||||
|
||||
template <class T, class Policy>
|
||||
inline typename boost::enable_if_c<boost::is_constructible<int, T>::value, int>::type
|
||||
iconvert(const T& v, const Policy&)
|
||||
{
|
||||
return static_cast<int>(v);
|
||||
}
|
||||
|
||||
template <class T, class Policy>
|
||||
inline typename boost::disable_if_c<boost::is_constructible<int, T>::value, int>::type
|
||||
iconvert(const T& v, const Policy& pol)
|
||||
{
|
||||
using boost::math::itrunc;
|
||||
return itrunc(v, pol);
|
||||
}
|
||||
|
||||
template <class T, class Policy>
|
||||
inline typename boost::enable_if_c<boost::is_constructible<long, T>::value, long>::type
|
||||
lconvert(const T& v, const Policy&)
|
||||
{
|
||||
return static_cast<long>(v);
|
||||
}
|
||||
|
||||
template <class T, class Policy>
|
||||
inline typename boost::disable_if_c<boost::is_constructible<long, T>::value, long>::type
|
||||
lconvert(const T& v, const Policy& pol)
|
||||
{
|
||||
using boost::math::ltrunc;
|
||||
return ltrunc(v, pol);
|
||||
}
|
||||
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
|
||||
template <class T, class Policy>
|
||||
inline typename boost::enable_if_c<boost::is_constructible<boost::long_long_type, T>::value, boost::long_long_type>::type
|
||||
llconvertert(const T& v, const Policy&)
|
||||
{
|
||||
return static_cast<boost::long_long_type>(v);
|
||||
}
|
||||
|
||||
template <class T, class Policy>
|
||||
inline typename boost::disable_if_c<boost::is_constructible<boost::long_long_type, T>::value, boost::long_long_type>::type
|
||||
llconvertert(const T& v, const Policy& pol)
|
||||
{
|
||||
using boost::math::lltrunc;
|
||||
return lltrunc(v, pol);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}} // namespaces
|
||||
|
||||
#endif // BOOST_MATH_TRUNC_HPP
|
||||
|
||||
Reference in New Issue
Block a user