File indexing completed on 2025-01-30 10:25:47
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 #ifndef VC_COMMON_MATH_H_
0029 #define VC_COMMON_MATH_H_
0030
0031 #define Vc_COMMON_MATH_H_INTERNAL 1
0032
0033 #include "trigonometric.h"
0034
0035 #include "const.h"
0036 #include "macros.h"
0037
0038 namespace Vc_VERSIONED_NAMESPACE
0039 {
0040
0041 template <class T, class Abi>
0042 SimdArray<int, Vector<T, Abi>::size()> fpclassify(const Vector<T, Abi> &x)
0043 {
0044 return SimdArray<int, Vector<T, Abi>::size()>(
0045 [&](std::size_t i) { return std::fpclassify(x[i]); });
0046 }
0047 template <class T, size_t N> SimdArray<int, N> fpclassify(const SimdArray<T, N> &x)
0048 {
0049 return SimdArray<int, N>([&](std::size_t i) { return std::fpclassify(x[i]); });
0050 }
0051
0052 #ifdef Vc_IMPL_SSE
0053
0054 #include "logarithm.h"
0055 #include "exponential.h"
0056 #ifdef Vc_IMPL_AVX
0057 inline AVX::double_v exp(AVX::double_v _x)
0058 {
0059 AVX::Vector<double> x = _x;
0060 typedef AVX::Vector<double> V;
0061 typedef V::Mask M;
0062 typedef AVX::Const<double> C;
0063
0064 const M overflow = x > Vc::Detail::doubleConstant< 1, 0x0006232bdd7abcd2ull, 9>();
0065 const M underflow = x < Vc::Detail::doubleConstant<-1, 0x0006232bdd7abcd2ull, 9>();
0066
0067 V px = floor(C::log2_e() * x + 0.5);
0068 __m128i tmp = _mm256_cvttpd_epi32(px.data());
0069 const SimdArray<int, V::Size> n = SSE::int_v{tmp};
0070 x -= px * C::ln2_large();
0071 x -= px * C::ln2_small();
0072
0073 const double P[] = {
0074 Vc::Detail::doubleConstant<1, 0x000089cdd5e44be8ull, -13>(),
0075 Vc::Detail::doubleConstant<1, 0x000f06d10cca2c7eull, -6>(),
0076 Vc::Detail::doubleConstant<1, 0x0000000000000000ull, 0>()
0077 };
0078 const double Q[] = {
0079 Vc::Detail::doubleConstant<1, 0x00092eb6bc365fa0ull, -19>(),
0080 Vc::Detail::doubleConstant<1, 0x0004ae39b508b6c0ull, -9>(),
0081 Vc::Detail::doubleConstant<1, 0x000d17099887e074ull, -3>(),
0082 Vc::Detail::doubleConstant<1, 0x0000000000000000ull, 1>()
0083 };
0084 const V x2 = x * x;
0085 px = x * ((P[0] * x2 + P[1]) * x2 + P[2]);
0086 x = px / ((((Q[0] * x2 + Q[1]) * x2 + Q[2]) * x2 + Q[3]) - px);
0087 x = V::One() + 2.0 * x;
0088
0089 x = ldexp(x, n);
0090
0091 x(overflow) = std::numeric_limits<double>::infinity();
0092 x.setZero(underflow);
0093
0094 return x;
0095 }
0096 #endif
0097
0098 inline SSE::double_v exp(SSE::double_v::AsArg _x) {
0099 SSE::Vector<double> x = _x;
0100 typedef SSE::Vector<double> V;
0101 typedef V::Mask M;
0102 typedef SSE::Const<double> C;
0103
0104 const M overflow = x > Vc::Detail::doubleConstant< 1, 0x0006232bdd7abcd2ull, 9>();
0105 const M underflow = x < Vc::Detail::doubleConstant<-1, 0x0006232bdd7abcd2ull, 9>();
0106
0107 V px = floor(C::log2_e() * x + 0.5);
0108 SimdArray<int, V::Size> n;
0109 _mm_storel_epi64(reinterpret_cast<__m128i *>(&n), _mm_cvttpd_epi32(px.data()));
0110 x -= px * C::ln2_large();
0111 x -= px * C::ln2_small();
0112
0113 const double P[] = {
0114 Vc::Detail::doubleConstant<1, 0x000089cdd5e44be8ull, -13>(),
0115 Vc::Detail::doubleConstant<1, 0x000f06d10cca2c7eull, -6>(),
0116 Vc::Detail::doubleConstant<1, 0x0000000000000000ull, 0>()
0117 };
0118 const double Q[] = {
0119 Vc::Detail::doubleConstant<1, 0x00092eb6bc365fa0ull, -19>(),
0120 Vc::Detail::doubleConstant<1, 0x0004ae39b508b6c0ull, -9>(),
0121 Vc::Detail::doubleConstant<1, 0x000d17099887e074ull, -3>(),
0122 Vc::Detail::doubleConstant<1, 0x0000000000000000ull, 1>()
0123 };
0124 const V x2 = x * x;
0125 px = x * ((P[0] * x2 + P[1]) * x2 + P[2]);
0126 x = px / ((((Q[0] * x2 + Q[1]) * x2 + Q[2]) * x2 + Q[3]) - px);
0127 x = V::One() + 2.0 * x;
0128
0129 x = ldexp(x, n);
0130
0131 x(overflow) = std::numeric_limits<double>::infinity();
0132 x.setZero(underflow);
0133
0134 return x;
0135 }
0136
0137 #endif
0138 }
0139
0140 #undef Vc_COMMON_MATH_H_INTERNAL
0141
0142 #endif