Logo ROOT   6.08/07
Reference Guide
atan2.h
Go to the documentation of this file.
1 /*
2  * atan2.h
3  * The basic idea is to exploit Pade polynomials.
4  * A lot of ideas were inspired by the cephes math library (by Stephen L. Moshier
5  * moshier@na-net.ornl.gov) as well as actual code.
6  * The Cephes library can be found here: http://www.netlib.org/cephes/
7  *
8  * Created on: Sept 20, 2012
9  * Author: Danilo Piparo, Thomas Hauth, Vincenzo Innocente
10  */
11 
12 /*
13  * VDT is free software: you can redistribute it and/or modify
14  * it under the terms of the GNU Lesser Public License as published by
15  * the Free Software Foundation, either version 3 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU Lesser Public License for more details.
22  *
23  * You should have received a copy of the GNU Lesser Public License
24  * along with this program. If not, see <http://www.gnu.org/licenses/>.
25  */
26 
27 #ifndef ATAN2_H_
28 #define ATAN2_H_
29 
30 #include "vdtcore_common.h"
31 #include "atan.h"
32 
33 namespace vdt{
34 
35 inline double fast_atan2( double y, double x ) {
36  // move in first octant
37  double xx = std::fabs(x);
38  double yy = std::fabs(y);
39  double tmp (0.0);
40  if (yy>xx) {
41  tmp = yy;
42  yy=xx; xx=tmp;
43  tmp=1.;
44  }
45 
46  // To avoid the fpe, we protect against /0.
47  const double oneIfXXZero = (xx==0.);
48  double t=yy/(xx+oneIfXXZero);
49  double z=t;
50 
51  double s = details::PIO4;
52  double factor = details::MOREBITSO2;
53  t = (t-1.0) / (t+1.0);
54 
55  if( z > details::T3PO8 ) {
56  s = details::PIO2;
57  factor = details::MOREBITS;
58  t = -1.0 / z ;
59  }
60  if ( z <= 0.66 ) {
61  s = 0.;
62  factor = 0.;
63  t = z;
64  }
65 
66  const double t2 = t * t;
67 
68  const double px = details::get_atan_px(t2);
69  const double qx = details::get_atan_qx(t2);
70 
71  //double res = y +x * x2 * px / qx + x +factor;
72 
73  const double poq=px / qx;
74 
75  double ret = t * t2 * poq + t;
76  ret+=s;
77 
78  ret+=factor;
79 
80  // Here we put the result to 0 if xx was 0, if not nothing happens!
81  ret*= (1.-oneIfXXZero);
82 
83  // move back in place
84  if (y==0) ret=0.0;
85  if (tmp!=0) ret = details::PIO2 - ret;
86  if (x<0) ret = details::PI - ret;
87  if (y<0) ret = -ret;
88 
89 
90  return ret;
91 }
92 
93 inline float fast_atan2f( float y, float x ) {
94 
95  // move in first octant
96  float xx = std::fabs(x);
97  float yy = std::fabs(y);
98  float tmp (0.0f);
99  if (yy>xx) {
100  tmp = yy;
101  yy=xx; xx=tmp;
102  tmp =1.f;
103  }
104 
105  // To avoid the fpe, we protect against /0.
106  const float oneIfXXZero = (xx==0.f);
107 
108  float t=yy/(xx/*+oneIfXXZero*/);
109  float z=t;
110  if( t > 0.4142135623730950f ) // * tan pi/8
111  z = (t-1.0f)/(t+1.0f);
112 
113  //printf("%e %e %e %e\n",yy,xx,t,z);
114  float z2 = z * z;
115 
116  float ret =(((( 8.05374449538e-2f * z2
117  - 1.38776856032E-1f) * z2
118  + 1.99777106478E-1f) * z2
119  - 3.33329491539E-1f) * z2 * z
120  + z );
121 
122  // Here we put the result to 0 if xx was 0, if not nothing happens!
123  ret*= (1.f - oneIfXXZero);
124 
125  // move back in place
126  if (y==0.f) ret=0.f;
127  if( t > 0.4142135623730950f ) ret += details::PIO4F;
128  if (tmp!=0) ret = details::PIO2F - ret;
129  if (x<0.f) ret = details::PIF - ret;
130  if (y<0.f) ret = -ret;
131 
132  return ret;
133 
134 }
135 
136 
137 
138 //------------------------------------------------------------------------------
139 // // Vector signatures
140 //
141 // void atan2v(const uint32_t size, double const * __restrict__ iarray, double const * __restrict__ iarray2, double* __restrict__ oarray);
142 // void fast_atan2v(const uint32_t size, double const * __restrict__ iarray, double const * __restrict__ iarray2, double* __restrict__ oarray);
143 // void atan2fv(const uint32_t size, float const * __restrict__ iarray, float const * __restrict__ iarray2, float* __restrict__ oarray);
144 // void fast_atan2fv(const uint32_t size, float const * __restrict__ iarray, float const * __restrict__ iarray2, float* __restrict__ oarray);
145 
146 } // end namespace vdt
147 
148 
149 #endif
double get_atan_px(const double x2)
Definition: atan.h:38
const double PIO2
const float PIO4F
Double_t x[n]
Definition: legend1.C:17
const float PIO2F
const double PIO4
VecExpr< UnaryOp< Fabs< T >, VecExpr< A, T, D >, T >, T, D > fabs(const VecExpr< A, T, D > &rhs)
Double_t E()
Definition: TMath.h:54
const double MOREBITS
double f(double x)
const double PI
Double_t y[n]
Definition: legend1.C:17
Definition: asin.h:32
you should not use this method at all Int_t Int_t z
Definition: TRolke.cxx:630
double get_atan_qx(const double x2)
Definition: atan.h:60
const float PIF
double fast_atan2(double y, double x)
Definition: atan2.h:35
float fast_atan2f(float y, float x)
Definition: atan2.h:93
const double MOREBITSO2
Definition: atan.h:36
const double T3PO8
Definition: atan.h:35