137 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_SIN_PI_HPP8#define BOOST_MATH_SIN_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 <type_traits>21#include <boost/math/tools/numeric_limits.hpp>22#include <boost/math/special_functions/math_fwd.hpp>23#include <boost/math/special_functions/trunc.hpp>24#include <boost/math/tools/promotion.hpp>25#include <boost/math/constants/constants.hpp>26 27namespace boost{ namespace math{ namespace detail{28 29template <class T, class Policy>30BOOST_MATH_GPU_ENABLED inline T sin_pi_imp(T x, const Policy&)31{32 BOOST_MATH_STD_USING // ADL of std names33 // sin of pi*x:34 if(x < T(0.5))35 return sin(constants::pi<T>() * x);36 bool invert;37 if(x < 1)38 {39 invert = true;40 x = -x;41 }42 else43 invert = false;44 45 T rem = floor(x);46 if(abs(floor(rem/2)*2 - rem) > boost::math::numeric_limits<T>::epsilon())47 {48 invert = !invert;49 }50 rem = x - rem;51 if(rem > 0.5f)52 rem = 1 - rem;53 if(rem == 0.5f)54 return static_cast<T>(invert ? -1 : 1);55 56 rem = sin(constants::pi<T>() * rem);57 return invert ? T(-rem) : rem;58}59 60template <class T, class Policy>61BOOST_MATH_GPU_ENABLED inline T sin_pi_dispatch(T x, const Policy& pol)62{63 if (x < T(0))64 {65 return -sin_pi_imp(T(-x), pol);66 }67 else68 {69 return sin_pi_imp(T(x), pol);70 }71}72 73} // namespace detail74 75template <class T, class Policy>76BOOST_MATH_GPU_ENABLED inline typename tools::promote_args<T>::type sin_pi(T x, const Policy&)77{78 typedef typename tools::promote_args<T>::type result_type;79 typedef typename policies::evaluation<result_type, Policy>::type value_type;80 typedef typename policies::normalise<81 Policy,82 policies::promote_float<false>,83 policies::promote_double<false>,84 policies::discrete_quantile<>,85 policies::assert_undefined<>,86 // We want to ignore overflows since the result is in [-1,1] and the 87 // check slows the code down considerably.88 policies::overflow_error<policies::ignore_error> >::type forwarding_policy;89 return policies::checked_narrowing_cast<result_type, forwarding_policy>(boost::math::detail::sin_pi_dispatch<value_type>(x, forwarding_policy()), "sin_pi");90}91 92template <class T>93inline typename tools::promote_args<T>::type sin_pi(T x)94{95 return boost::math::sin_pi(x, policies::policy<>());96}97 98} // namespace math99} // namespace boost100 101#else // Special handling for NVRTC102 103namespace boost {104namespace math {105 106template <typename T>107BOOST_MATH_GPU_ENABLED auto sin_pi(T x)108{109 return ::sinpi(x);110}111 112template <>113BOOST_MATH_GPU_ENABLED auto sin_pi(float x)114{115 return ::sinpif(x);116}117 118template <typename T, typename Policy>119BOOST_MATH_GPU_ENABLED auto sin_pi(T x, const Policy&)120{121 return ::sinpi(x);122}123 124template <typename Policy>125BOOST_MATH_GPU_ENABLED auto sin_pi(float x, const Policy&)126{127 return ::sinpif(x);128}129 130} // namespace math131} // namespace boost132 133#endif // BOOST_MATH_HAS_NVRTC134 135#endif136 137