21 #if defined(VC_IMPL_SSE) || defined(VC_IMPL_AVX)
34 template<
typename T>
static Vc_ALWAYS_INLINE Vector<T> cosSeries(
const Vector<T> &x)
37 const Vector<T> x2 = x *
x;
38 return ((C::cosCoeff(2) * x2 +
39 C::cosCoeff(1)) * x2 +
40 C::cosCoeff(0)) * (x2 *
x2)
45 typedef Const<double>
C;
47 return (((((C::cosCoeff(5) * x2 +
48 C::cosCoeff(4)) * x2 +
49 C::cosCoeff(3)) * x2 +
50 C::cosCoeff(2)) * x2 +
51 C::cosCoeff(1)) * x2 +
52 C::cosCoeff(0)) * (x2 *
x2)
55 template<
typename T>
static Vc_ALWAYS_INLINE Vector<T> sinSeries(
const Vector<T> &x)
58 const Vector<T> x2 = x *
x;
59 return ((C::sinCoeff(2) * x2 +
60 C::sinCoeff(1)) * x2 +
61 C::sinCoeff(0)) * (x2 *
x)
66 typedef Const<double>
C;
68 return (((((C::sinCoeff(5) * x2 +
69 C::sinCoeff(4)) * x2 +
70 C::sinCoeff(3)) * x2 +
71 C::sinCoeff(2)) * x2 +
72 C::sinCoeff(1)) * x2 +
73 C::sinCoeff(0)) * (x2 *
x)
76 template<
typename V>
struct signed_integer {
typedef int_v type; };
79 template<
typename _T,
typename IV>
static Vc_ALWAYS_INLINE Vector<_T> foldInput(
const Vector<_T> &_x, IV &quadrant)
85 #if defined(VC_IMPL_FMA4) || defined(VC_IMPL_FMA)
86 quadrant =
static_cast<IV
>(x * C::_4_pi() +
V::One());
87 quadrant &= ~IV
::One();
89 quadrant =
static_cast<IV
>(x * C::_4_pi());
90 quadrant += quadrant &
IV::One();
92 const V y =
static_cast<V
>(quadrant);
95 return ((x - y * C::_pi_4_hi()) - y * C::_pi_4_rem1()) - y * C::_pi_4_rem2();
100 typedef Const<double>
C;
103 V y =
trunc(x / C::_pi_4());
104 V z = y -
trunc(y * C::_1_16()) * C::_16();
105 quadrant =
static_cast<int_v>(z);
108 y(static_cast<double_m>(mask)) +=
V::One();
113 return ((x - y * C::_pi_4_hi()) - y * C::_pi_4_rem1()) - y * C::_pi_4_rem2();
135 typedef Vector<_T> V;
136 typedef typename V::Mask M;
140 const V z = foldInput(_x, quadrant);
141 const M sign = (_x < V::Zero()) ^ static_cast<M>(quadrant > 3);
142 quadrant(quadrant > 3) -= 4;
145 y(quadrant ==
IV::One() || quadrant == 2) = cosSeries(z);
157 const V x = foldInput(_x, quadrant);
158 sign ^=
static_cast<M
>(quadrant > 3);
159 quadrant(quadrant > 3) -= 4;
162 y(static_cast<M>(quadrant ==
int_v::One() || quadrant == 2)) = cosSeries(x);
167 typedef Vector<_T> V;
168 typedef typename V::Mask M;
172 const V x = foldInput(_x, quadrant);
173 M sign = quadrant > 3;
174 quadrant(quadrant > 3) -= 4;
178 y(quadrant ==
IV::One() || quadrant == 2) = sinSeries(x);
188 const V x = foldInput(_x, quadrant);
189 M sign =
static_cast<M
>(quadrant > 3);
190 quadrant(quadrant > 3) -= 4;
191 sign ^=
static_cast<M
>(quadrant >
int_v::One());
194 y(static_cast<M>(quadrant ==
int_v::One() || quadrant == 2)) = sinSeries(x);
199 typedef Vector<_T> V;
200 typedef typename V::Mask M;
204 const V x = foldInput(_x, quadrant);
205 M sign =
static_cast<M
>(quadrant > 3);
206 quadrant(quadrant > 3) -= 4;
208 const V cos_s = cosSeries(x);
209 const V sin_s = sinSeries(x);
212 c(static_cast<M>(quadrant ==
IV::One() || quadrant == 2)) = sin_s;
213 c(sign ^ static_cast<M>(quadrant >
IV::One())) = -
c;
217 s(static_cast<M>(quadrant ==
IV::One() || quadrant == 2)) = cos_s;
218 s(sign ^ static_cast<M>(_x <
V::Zero())) = -s;
226 const V x = foldInput(_x, quadrant);
227 M sign =
static_cast<M
>(quadrant > 3);
228 quadrant(quadrant > 3) -= 4;
230 const V cos_s = cosSeries(x);
231 const V sin_s = sinSeries(x);
234 c(static_cast<M>(quadrant ==
int_v::One() || quadrant == 2)) = sin_s;
239 s(static_cast<M>(quadrant ==
int_v::One() || quadrant == 2)) = cos_s;
240 s(sign ^ static_cast<M>(_x <
V::Zero())) = -s;
245 typedef Vector<_T> V;
246 typedef typename V::Mask M;
248 const M &negative = _x <
V::Zero();
250 const V &a =
abs(_x);
251 const M outOfRange = a >
V::One();
252 const M &small = a < C::smallAsinInput();
253 const M >_0_5 = a > C::_1_2();
256 z(gt_0_5) = (
V::One() -
a) * C::_1_2();
258 z = ((((C::asinCoeff0(0) * z
259 + C::asinCoeff0(1)) * z
260 + C::asinCoeff0(2)) * z
261 + C::asinCoeff0(3)) * z
262 + C::asinCoeff0(4)) * z * x
264 z(gt_0_5) = C::_pi_2() - (z + z);
267 z.setQnan(outOfRange);
272 typedef Const<double>
C;
276 const M negative = _x <
V::Zero();
279 const M outOfRange = a >
V::One();
280 const M small = a < C::smallAsinInput();
281 const M large = a > C::largeAsinInput();
284 const V r = (((C::asinCoeff0(0) * zz + C::asinCoeff0(1)) * zz + C::asinCoeff0(2)) * zz +
285 C::asinCoeff0(3)) * zz + C::asinCoeff0(4);
286 const V s = (((zz + C::asinCoeff1(0)) * zz + C::asinCoeff1(1)) * zz +
287 C::asinCoeff1(2)) * zz + C::asinCoeff1(3);
288 V sqrtzz =
sqrt(zz + zz);
289 V z = C::_pi_4() - sqrtzz;
290 z -= sqrtzz * (zz * r / s) - C::_pi_2_rem();
294 const V p = ((((C::asinCoeff2(0) * a2 + C::asinCoeff2(1)) * a2 + C::asinCoeff2(2)) * a2 +
295 C::asinCoeff2(3)) * a2 + C::asinCoeff2(4)) * a2 + C::asinCoeff2(5);
296 const V q = ((((a2 + C::asinCoeff3(0)) * a2 + C::asinCoeff3(1)) * a2 +
297 C::asinCoeff3(2)) * a2 + C::asinCoeff3(3)) * a2 + C::asinCoeff3(4);
298 z(!large) = a * (a2 * p /
q) + a;
302 z.setQnan(outOfRange);
308 typedef Vector<_T> V;
309 typedef typename V::Mask M;
311 const M >_tan_3pi_8 = x > C::atanThrsHi();
312 const M >_tan_pi_8 = x > C::atanThrsLo() && !gt_tan_3pi_8;
314 y(gt_tan_3pi_8) = C::_pi_2();
315 y(gt_tan_pi_8) = C::_pi_4();
319 y += (((C::atanP(0) * x2
322 - C::atanP(3)) * x2 * x
325 y.setQnan(
isnan(_x));
329 typedef Const<double>
C;
338 const M large = x > C::atanThrsHi();
339 const M gt_06 = x > C::atanThrsLo();
343 y(gt_06) = C::_pi_4();
344 y(large) = C::_pi_2();
346 const V p = (((C::atanP(0) * z + C::atanP(1)) * z + C::atanP(2)) * z + C::atanP(3)) * z + C::atanP(4);
347 const V q = ((((z + C::atanQ(0)) * z + C::atanQ(1)) * z + C::atanQ(2)) * z + C::atanQ(3)) * z + C::atanQ(4);
350 V morebits = C::_pi_2_rem();
351 morebits(!large) *= C::_1_2();
352 z(gt_06) += morebits;
355 ret.setQnan(
isnan(_x));
360 typedef Vector<_T> V;
361 typedef typename V::Mask M;
363 const M xZero = x ==
V::Zero();
364 const M yZero = y ==
V::Zero();
365 const M xMinusZero = xZero && x.isNegative();
370 V a = C::_pi().copySign(y);
375 _x(yInf) =
V::One().copySign(x);
380 a.setZero(xZero && yZero);
383 a(xMinusZero) += C::_pi().copySign(y);
386 a(xZero && yNeg) = -C::_pi_2();
389 a(xInf && yInf) += C::_pi_4().copySign(x ^ ~y);
400 typedef Const<double>
C;
404 const M xZero = x ==
V::Zero();
405 const M yZero = y ==
V::Zero();
406 const M xMinusZero = xZero && x.isNegative();
411 V a = V(C::_pi()).copySign(y);
416 _x(yInf) =
V::One().copySign(x);
421 a.setZero(xZero && yZero);
424 a(xMinusZero) += C::_pi().copySign(y);
427 a(xZero && yNeg) = -C::_pi_2();
430 a(xInf && yInf) += C::_pi_4().copySign(x ^ ~y);
VECTOR_NAMESPACE::sfloat_v sfloat_v
Namespace for new ROOT classes and functions.
static Vc_ALWAYS_INLINE float_v trunc(float_v::AsArg v)
static Vector< T > cos(const Vector< T > &_x)
static Vc_ALWAYS_INLINE Vector< T >::Mask isfinite(const Vector< T > &x)
VECTOR_NAMESPACE::short_v short_v
static const double x2[5]
static Vc_ALWAYS_INLINE Vector< T > abs(const Vector< T > &x)
static Vector< T > asin(const Vector< T > &_x)
static Vector< T > atan(const Vector< T > &_x)
VECTOR_NAMESPACE::int_v int_v
VECTOR_NAMESPACE::double_v double_v
static void sincos(const Vector< T > &_x, Vector< T > *_sin, Vector< T > *_cos)
static Vector< T > atan2(const Vector< T > &y, const Vector< T > &x)
VECTOR_NAMESPACE::float_v float_v
static Vector< T > sin(const Vector< T > &_x)