cos_pi.hpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  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_COS_PI_HPP
  7. #define BOOST_MATH_COS_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 <boost/math/tools/numeric_limits.hpp>
  16. #include <boost/math/special_functions/math_fwd.hpp>
  17. #include <boost/math/special_functions/trunc.hpp>
  18. #include <boost/math/tools/promotion.hpp>
  19. #include <boost/math/constants/constants.hpp>
  20. namespace boost{ namespace math{ namespace detail{
  21. template <class T, class Policy>
  22. BOOST_MATH_GPU_ENABLED T cos_pi_imp(T x, const Policy&)
  23. {
  24. BOOST_MATH_STD_USING // ADL of std names
  25. // cos of pi*x:
  26. bool invert = false;
  27. if(fabs(x) < T(0.25))
  28. return cos(constants::pi<T>() * x);
  29. if(x < 0)
  30. {
  31. x = -x;
  32. }
  33. T rem = floor(x);
  34. if(abs(floor(rem/2)*2 - rem) > boost::math::numeric_limits<T>::epsilon())
  35. {
  36. invert = !invert;
  37. }
  38. rem = x - rem;
  39. if(rem > 0.5f)
  40. {
  41. rem = 1 - rem;
  42. invert = !invert;
  43. }
  44. if(rem == 0.5f)
  45. return 0;
  46. if(rem > 0.25f)
  47. {
  48. rem = 0.5f - rem;
  49. rem = sin(constants::pi<T>() * rem);
  50. }
  51. else
  52. rem = cos(constants::pi<T>() * rem);
  53. return invert ? T(-rem) : rem;
  54. }
  55. } // namespace detail
  56. template <class T, class Policy>
  57. BOOST_MATH_GPU_ENABLED inline typename tools::promote_args<T>::type cos_pi(T x, const Policy&)
  58. {
  59. typedef typename tools::promote_args<T>::type result_type;
  60. typedef typename policies::evaluation<result_type, Policy>::type value_type;
  61. typedef typename policies::normalise<
  62. Policy,
  63. policies::promote_float<false>,
  64. policies::promote_double<false>,
  65. policies::discrete_quantile<>,
  66. policies::assert_undefined<>,
  67. // We want to ignore overflows since the result is in [-1,1] and the
  68. // check slows the code down considerably.
  69. policies::overflow_error<policies::ignore_error> >::type forwarding_policy;
  70. return policies::checked_narrowing_cast<result_type, forwarding_policy>(boost::math::detail::cos_pi_imp<value_type>(x, forwarding_policy()), "cos_pi");
  71. }
  72. template <class T>
  73. BOOST_MATH_GPU_ENABLED inline typename tools::promote_args<T>::type cos_pi(T x)
  74. {
  75. return boost::math::cos_pi(x, policies::policy<>());
  76. }
  77. } // namespace math
  78. } // namespace boost
  79. #else // Special handling for NVRTC
  80. namespace boost {
  81. namespace math {
  82. template <typename T>
  83. BOOST_MATH_GPU_ENABLED auto cos_pi(T x)
  84. {
  85. return ::cospi(x);
  86. }
  87. template <>
  88. BOOST_MATH_GPU_ENABLED auto cos_pi(float x)
  89. {
  90. return ::cospif(x);
  91. }
  92. template <typename T, typename Policy>
  93. BOOST_MATH_GPU_ENABLED auto cos_pi(T x, const Policy&)
  94. {
  95. return ::cospi(x);
  96. }
  97. template <typename Policy>
  98. BOOST_MATH_GPU_ENABLED auto cos_pi(float x, const Policy&)
  99. {
  100. return ::cospif(x);
  101. }
  102. } // namespace math
  103. } // namespace boost
  104. #endif // BOOST_MATH_HAS_NVRTC
  105. #endif