sin_pi.hpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. // Copyright (c) 2007 John Maddock
  2. // Copyright (c) 2024 Matt Borland
  3. // Use, modification and distribution are subject to the
  4. // Boost Software License, Version 1.0. (See accompanying file
  5. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. #ifndef BOOST_MATH_SIN_PI_HPP
  7. #define BOOST_MATH_SIN_PI_HPP
  8. #ifdef _MSC_VER
  9. #pragma once
  10. #endif
  11. #include <boost/math/tools/config.hpp>
  12. #ifndef BOOST_MATH_HAS_NVRTC
  13. #include <cmath>
  14. #include <limits>
  15. #include <type_traits>
  16. #include <boost/math/tools/numeric_limits.hpp>
  17. #include <boost/math/special_functions/math_fwd.hpp>
  18. #include <boost/math/special_functions/trunc.hpp>
  19. #include <boost/math/tools/promotion.hpp>
  20. #include <boost/math/constants/constants.hpp>
  21. namespace boost{ namespace math{ namespace detail{
  22. template <class T, class Policy>
  23. BOOST_MATH_GPU_ENABLED inline T sin_pi_imp(T x, const Policy&)
  24. {
  25. BOOST_MATH_STD_USING // ADL of std names
  26. // sin of pi*x:
  27. if(x < T(0.5))
  28. return sin(constants::pi<T>() * x);
  29. bool invert;
  30. if(x < 1)
  31. {
  32. invert = true;
  33. x = -x;
  34. }
  35. else
  36. invert = false;
  37. T rem = floor(x);
  38. if(abs(floor(rem/2)*2 - rem) > boost::math::numeric_limits<T>::epsilon())
  39. {
  40. invert = !invert;
  41. }
  42. rem = x - rem;
  43. if(rem > 0.5f)
  44. rem = 1 - rem;
  45. if(rem == 0.5f)
  46. return static_cast<T>(invert ? -1 : 1);
  47. rem = sin(constants::pi<T>() * rem);
  48. return invert ? T(-rem) : rem;
  49. }
  50. template <class T, class Policy>
  51. BOOST_MATH_GPU_ENABLED inline T sin_pi_dispatch(T x, const Policy& pol)
  52. {
  53. if (x < T(0))
  54. {
  55. return -sin_pi_imp(T(-x), pol);
  56. }
  57. else
  58. {
  59. return sin_pi_imp(T(x), pol);
  60. }
  61. }
  62. } // namespace detail
  63. template <class T, class Policy>
  64. BOOST_MATH_GPU_ENABLED inline typename tools::promote_args<T>::type sin_pi(T x, const Policy&)
  65. {
  66. typedef typename tools::promote_args<T>::type result_type;
  67. typedef typename policies::evaluation<result_type, Policy>::type value_type;
  68. typedef typename policies::normalise<
  69. Policy,
  70. policies::promote_float<false>,
  71. policies::promote_double<false>,
  72. policies::discrete_quantile<>,
  73. policies::assert_undefined<>,
  74. // We want to ignore overflows since the result is in [-1,1] and the
  75. // check slows the code down considerably.
  76. policies::overflow_error<policies::ignore_error> >::type forwarding_policy;
  77. return policies::checked_narrowing_cast<result_type, forwarding_policy>(boost::math::detail::sin_pi_dispatch<value_type>(x, forwarding_policy()), "sin_pi");
  78. }
  79. template <class T>
  80. inline typename tools::promote_args<T>::type sin_pi(T x)
  81. {
  82. return boost::math::sin_pi(x, policies::policy<>());
  83. }
  84. } // namespace math
  85. } // namespace boost
  86. #else // Special handling for NVRTC
  87. namespace boost {
  88. namespace math {
  89. template <typename T>
  90. BOOST_MATH_GPU_ENABLED auto sin_pi(T x)
  91. {
  92. return ::sinpi(x);
  93. }
  94. template <>
  95. BOOST_MATH_GPU_ENABLED auto sin_pi(float x)
  96. {
  97. return ::sinpif(x);
  98. }
  99. template <typename T, typename Policy>
  100. BOOST_MATH_GPU_ENABLED auto sin_pi(T x, const Policy&)
  101. {
  102. return ::sinpi(x);
  103. }
  104. template <typename Policy>
  105. BOOST_MATH_GPU_ENABLED auto sin_pi(float x, const Policy&)
  106. {
  107. return ::sinpif(x);
  108. }
  109. } // namespace math
  110. } // namespace boost
  111. #endif // BOOST_MATH_HAS_NVRTC
  112. #endif