129 lines · plain
1// Copyright (c) 2007 John Maddock2// Copyright (c) 2024 Matt Borland3// Use, modification and distribution are subject to the4// Boost Software License, Version 1.0. (See accompanying file5// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)6 7#ifndef BOOST_MATH_COS_PI_HPP8#define BOOST_MATH_COS_PI_HPP9 10#ifdef _MSC_VER11#pragma once12#endif13 14#include <boost/math/tools/config.hpp>15 16#ifndef BOOST_MATH_HAS_NVRTC17 18#include <cmath>19#include <limits>20#include <boost/math/tools/numeric_limits.hpp>21#include <boost/math/special_functions/math_fwd.hpp>22#include <boost/math/special_functions/trunc.hpp>23#include <boost/math/tools/promotion.hpp>24#include <boost/math/constants/constants.hpp>25 26namespace boost{ namespace math{ namespace detail{27 28template <class T, class Policy>29BOOST_MATH_GPU_ENABLED T cos_pi_imp(T x, const Policy&)30{31 BOOST_MATH_STD_USING // ADL of std names32 // cos of pi*x:33 bool invert = false;34 if(fabs(x) < T(0.25))35 return cos(constants::pi<T>() * x);36 37 if(x < 0)38 {39 x = -x;40 }41 T rem = floor(x);42 if(abs(floor(rem/2)*2 - rem) > boost::math::numeric_limits<T>::epsilon())43 {44 invert = !invert;45 }46 rem = x - rem;47 if(rem > 0.5f)48 {49 rem = 1 - rem;50 invert = !invert;51 }52 if(rem == 0.5f)53 return 0;54 55 if(rem > 0.25f)56 {57 rem = 0.5f - rem;58 rem = sin(constants::pi<T>() * rem);59 }60 else61 rem = cos(constants::pi<T>() * rem);62 return invert ? T(-rem) : rem;63}64 65} // namespace detail66 67template <class T, class Policy>68BOOST_MATH_GPU_ENABLED inline typename tools::promote_args<T>::type cos_pi(T x, const Policy&)69{70 typedef typename tools::promote_args<T>::type result_type;71 typedef typename policies::evaluation<result_type, Policy>::type value_type;72 typedef typename policies::normalise<73 Policy,74 policies::promote_float<false>,75 policies::promote_double<false>,76 policies::discrete_quantile<>,77 policies::assert_undefined<>,78 // We want to ignore overflows since the result is in [-1,1] and the 79 // check slows the code down considerably.80 policies::overflow_error<policies::ignore_error> >::type forwarding_policy;81 return policies::checked_narrowing_cast<result_type, forwarding_policy>(boost::math::detail::cos_pi_imp<value_type>(x, forwarding_policy()), "cos_pi");82}83 84template <class T>85BOOST_MATH_GPU_ENABLED inline typename tools::promote_args<T>::type cos_pi(T x)86{87 return boost::math::cos_pi(x, policies::policy<>());88}89 90} // namespace math91} // namespace boost92 93#else // Special handling for NVRTC94 95namespace boost {96namespace math {97 98template <typename T>99BOOST_MATH_GPU_ENABLED auto cos_pi(T x)100{101 return ::cospi(x);102}103 104template <>105BOOST_MATH_GPU_ENABLED auto cos_pi(float x)106{107 return ::cospif(x);108}109 110template <typename T, typename Policy>111BOOST_MATH_GPU_ENABLED auto cos_pi(T x, const Policy&)112{113 return ::cospi(x);114}115 116template <typename Policy>117BOOST_MATH_GPU_ENABLED auto cos_pi(float x, const Policy&)118{119 return ::cospif(x);120}121 122} // namespace math123} // namespace boost124 125#endif // BOOST_MATH_HAS_NVRTC126 127#endif128 129