1 #ifndef DataFormats_Math_FastMath_h
2 #define DataFormats_Math_FastMath_h
8 # include <emmintrin.h>
16 _mm_store_ss( &out, _mm_rsqrt_ss( _mm_load_ss( &in ) ) );
18 return out * (1.5f - 0.5f * in * out *
out);
28 namespace fastmath_details {
29 const double _2pi = (2.0 * 3.1415926535897932384626434);
40 inline std::pair<float,float>
atan2r(
float y_,
float x_,
bool overR=
false) {
41 using namespace fastmath_details;
42 float mag2 = x_ * x_ + y_ * y_;
43 if(!(
mag2 > 0)) {
return std::pair<float,float>(0.f,0.f); }
47 unsigned int flags = 0;
54 if (y_ < 0 ) {
flags |= 4; y_ = -y_; }
55 if (x_ < 0 ) {
flags |= 2; x_ = -x_; }
58 x = rinv * y_;
y = rinv * x_; yp.f +=
y;
61 x = rinv * x_;
y = rinv * y_; yp.f +=
y;
63 int ind = (yp.i & 0x01FF) * 2;
65 float* asbuf = (
float*)(
atanbuf_ + ind);
66 float sv = yp.f - 32768.f;
71 float asvd = 6.f + sv * sv; sv *= float(1.0
f / 6.0
f);
72 float th = asv + asvd * sv;
75 if (
flags & 4) { th = -th; }
76 return std::pair<float,float>(th,overR ? rinv : rinv*
mag2);
82 inline std::pair<double, double>
atan2r(
double y_,
double x_,
bool overR=
false) {
83 using namespace fastmath_details;
85 double mag2 = x_ * x_ + y_ * y_;
86 if(!(
mag2 > 0)) {
return std::pair<double, double>(0.,0.); }
90 unsigned int flags = 0;
92 const double _2p43 = 65536.0 * 65536.0 * 2048.0;
99 if (y_ < 0) {
flags |= 4; y_ = -y_; }
100 if (x_ < 0) {
flags |= 2; x_ = -x_; }
103 x = rinv * y_;
y = rinv * x_; yp.d +=
y;
106 x = rinv * x_;
y = rinv * y_; yp.d +=
y;
109 int ind = (yp.i[0] & 0x03FF) * 2;
111 double* dasbuf = (
double*)(
datanbuf_ + ind);
112 double sv = yp.d - _2p43;
113 double cv = dasbuf[0];
114 double asv = dasbuf[1];
115 sv =
y *
cv -
x * sv;
118 double asvd = 6 + sv * sv; sv *= double(1.0 / 6.0);
119 double th = asv + asvd * sv;
122 if (
flags & 4) { th = -th; }
123 return std::pair<double,double>(th,overR ? rinv : r_);
129 std::pair<T,T> por =
atan2r(y,x,
true);
std::vector< Variable::Flags > flags
T mag2() const
The vector magnitude squared. Equivalent to vec.dot(vec)
std::pair< T, T > etaphi(T x, T y, T z)
std::pair< float, float > atan2r(float y_, float x_, bool overR=false)