cos_pi.hpp 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. // Copyright (c) 2007 John Maddock
  2. // Use, modification and distribution are subject to the
  3. // Boost Software License, Version 1.0. (See accompanying file
  4. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef BOOST_MATH_COS_PI_HPP
  6. #define BOOST_MATH_COS_PI_HPP
  7. #ifdef _MSC_VER
  8. #pragma once
  9. #endif
  10. #include <cmath>
  11. #include <limits>
  12. #include <boost/math/special_functions/math_fwd.hpp>
  13. #include <boost/math/tools/config.hpp>
  14. #include <boost/math/special_functions/trunc.hpp>
  15. #include <boost/math/tools/promotion.hpp>
  16. #include <boost/math/constants/constants.hpp>
  17. namespace boost{ namespace math{ namespace detail{
  18. template <class T, class Policy>
  19. T cos_pi_imp(T x, const Policy&)
  20. {
  21. BOOST_MATH_STD_USING // ADL of std names
  22. // cos of pi*x:
  23. bool invert = false;
  24. if(fabs(x) < T(0.25))
  25. return cos(constants::pi<T>() * x);
  26. if(x < 0)
  27. {
  28. x = -x;
  29. }
  30. T rem = floor(x);
  31. if(abs(floor(rem/2)*2 - rem) > std::numeric_limits<T>::epsilon())
  32. {
  33. invert = !invert;
  34. }
  35. rem = x - rem;
  36. if(rem > 0.5f)
  37. {
  38. rem = 1 - rem;
  39. invert = !invert;
  40. }
  41. if(rem == 0.5f)
  42. return 0;
  43. if(rem > 0.25f)
  44. {
  45. rem = 0.5f - rem;
  46. rem = sin(constants::pi<T>() * rem);
  47. }
  48. else
  49. rem = cos(constants::pi<T>() * rem);
  50. return invert ? T(-rem) : rem;
  51. }
  52. } // namespace detail
  53. template <class T, class Policy>
  54. inline typename tools::promote_args<T>::type cos_pi(T x, const Policy&)
  55. {
  56. typedef typename tools::promote_args<T>::type result_type;
  57. typedef typename policies::evaluation<result_type, Policy>::type value_type;
  58. typedef typename policies::normalise<
  59. Policy,
  60. policies::promote_float<false>,
  61. policies::promote_double<false>,
  62. policies::discrete_quantile<>,
  63. policies::assert_undefined<>,
  64. // We want to ignore overflows since the result is in [-1,1] and the
  65. // check slows the code down considerably.
  66. policies::overflow_error<policies::ignore_error> >::type forwarding_policy;
  67. return policies::checked_narrowing_cast<result_type, forwarding_policy>(boost::math::detail::cos_pi_imp<value_type>(x, forwarding_policy()), "cos_pi");
  68. }
  69. template <class T>
  70. inline typename tools::promote_args<T>::type cos_pi(T x)
  71. {
  72. return boost::math::cos_pi(x, policies::policy<>());
  73. }
  74. } // namespace math
  75. } // namespace boost
  76. #endif