File indexing completed on 2025-01-18 09:54:48
0001
0002
0003
0004
0005
0006
0007
0008 #pragma once
0009
0010 #include <cmath>
0011 #include <cstdint>
0012
0013 namespace celeritas
0014 {
0015 namespace detail
0016 {
0017
0018
0019
0020
0021
0022
0023
0024
0025 inline void sincospi_impl(double a, double* sptr, double* cptr)
0026 {
0027 double c, r, s, t, az;
0028 std::int64_t i;
0029
0030 az = a * 0.0;
0031
0032 a = (std::fabs(a) < 9.0071992547409920e+15) ? a : az;
0033
0034 r = std::nearbyint(a + a);
0035 i = static_cast<std::int64_t>(r);
0036 t = std::fma(-0.5, r, a);
0037
0038 s = t * t;
0039
0040 r = -1.0369917389758117e-4;
0041 r = std::fma(r, s, 1.9294935641298806e-3);
0042 r = std::fma(r, s, -2.5806887942825395e-2);
0043 r = std::fma(r, s, 2.3533063028328211e-1);
0044 r = std::fma(r, s, -1.3352627688538006e+0);
0045 r = std::fma(r, s, 4.0587121264167623e+0);
0046 r = std::fma(r, s, -4.9348022005446790e+0);
0047 c = std::fma(r, s, 1.0000000000000000e+0);
0048
0049 r = 4.6151442520157035e-4;
0050 r = std::fma(r, s, -7.3700183130883555e-3);
0051 r = std::fma(r, s, 8.2145868949323936e-2);
0052 r = std::fma(r, s, -5.9926452893214921e-1);
0053 r = std::fma(r, s, 2.5501640398732688e+0);
0054 r = std::fma(r, s, -5.1677127800499516e+0);
0055 s = s * t;
0056 r = r * s;
0057 s = std::fma(t, 3.1415926535897931e+0, r);
0058
0059 if (i & 2)
0060 {
0061 s = 0.0 - s;
0062 c = 0.0 - c;
0063 }
0064 if (i & 1)
0065 {
0066 t = 0.0 - s;
0067 s = c;
0068 c = t;
0069 }
0070
0071 if (a == std::floor(a))
0072 s = az;
0073 *sptr = s;
0074 *cptr = c;
0075 }
0076
0077
0078
0079
0080
0081
0082
0083
0084 inline void sincospi_impl(float a, float* sptr, float* cptr)
0085 {
0086
0087
0088 using namespace std;
0089
0090 float az, t, c, r, s;
0091 int32_t i;
0092
0093 az = a * 0.0f;
0094
0095 a = (fabsf(a) < 0x1.0p24f) ? a : az;
0096 r = nearbyintf(a + a);
0097 i = static_cast<int32_t>(r);
0098 t = fmaf(-0.5f, r, a);
0099
0100 s = t * t;
0101
0102 r = 0x1.d9e000p-3f;
0103 r = fmaf(r, s, -0x1.55c400p+0f);
0104 r = fmaf(r, s, 0x1.03c1cep+2f);
0105 r = fmaf(r, s, -0x1.3bd3ccp+2f);
0106 c = fmaf(r, s, 0x1.000000p+0f);
0107
0108 r = -0x1.310000p-1f;
0109 r = fmaf(r, s, 0x1.46737ep+1f);
0110 r = fmaf(r, s, -0x1.4abbfep+2f);
0111 r = (t * s) * r;
0112 s = fmaf(t, 0x1.921fb6p+1f, r);
0113 if (i & 2)
0114 {
0115 s = 0.0f - s;
0116 c = 0.0f - c;
0117 }
0118 if (i & 1)
0119 {
0120 t = 0.0f - s;
0121 s = c;
0122 c = t;
0123 }
0124
0125 if (a == floorf(a))
0126 s = az;
0127 *sptr = s;
0128 *cptr = c;
0129 }
0130
0131
0132
0133 template<class T>
0134 CELER_FORCEINLINE T sinpi_impl(T v)
0135 {
0136 T result;
0137 T unused;
0138 sincospi_impl(v, &result, &unused);
0139 return result;
0140 }
0141
0142
0143
0144 template<class T>
0145 CELER_FORCEINLINE T cospi_impl(T v)
0146 {
0147 T unused;
0148 T result;
0149 sincospi_impl(v, &unused, &result);
0150 return result;
0151 }
0152
0153
0154
0155 template<class T>
0156 CELER_FORCEINLINE void sincos_impl(T x, T* sptr, T* cptr)
0157 {
0158 *sptr = std::sin(x);
0159 *cptr = std::cos(x);
0160 }
0161
0162
0163
0164 CELER_FORCEINLINE void sincospif(float x, float* sptr, float* cptr)
0165 {
0166 return sincospi_impl(x, sptr, cptr);
0167 }
0168
0169 CELER_FORCEINLINE void sincosf(float x, float* sptr, float* cptr)
0170 {
0171 return sincos_impl(x, sptr, cptr);
0172 }
0173
0174 CELER_FORCEINLINE float sinpif(float x)
0175 {
0176 return sinpi_impl(x);
0177 }
0178
0179 CELER_FORCEINLINE float cospif(float x)
0180 {
0181 return cospi_impl(x);
0182 }
0183
0184 CELER_FORCEINLINE void sincospi(double x, double* sptr, double* cptr)
0185 {
0186 return sincospi_impl(x, sptr, cptr);
0187 }
0188
0189 CELER_FORCEINLINE void sincos(double x, double* sptr, double* cptr)
0190 {
0191 return sincos_impl(x, sptr, cptr);
0192 }
0193
0194 CELER_FORCEINLINE double sinpi(double x)
0195 {
0196 return sinpi_impl(x);
0197 }
0198
0199 CELER_FORCEINLINE double cospi(double x)
0200 {
0201 return cospi_impl(x);
0202 }
0203
0204
0205 }
0206 }