Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/HeuristicLab.ExtLibs/HeuristicLab.NativeInterpreter/0.1/NativeInterpreter-0.1/lib/vdt/atan.h @ 16724

Last change on this file since 16724 was 16269, checked in by bburlacu, 6 years ago

#2958: Add C++ source code

File size: 3.8 KB
Line 
1/*
2 * atan.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: Jun 23, 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 ATAN_H_
28#define ATAN_H_
29
30#include "vdtcore_common.h"
31
32namespace vdt{
33
34namespace details{
35const double T3PO8 = 2.41421356237309504880;
36const double MOREBITSO2 = MOREBITS * 0.5;
37
38inline double get_atan_px(const double x2){
39
40  const double PX1atan = -8.750608600031904122785E-1;
41  const double PX2atan = -1.615753718733365076637E1;
42  const double PX3atan = -7.500855792314704667340E1;
43  const double PX4atan = -1.228866684490136173410E2;
44  const double PX5atan = -6.485021904942025371773E1;
45
46  double px = PX1atan;
47  px *= x2;
48  px += PX2atan;
49  px *= x2;
50  px += PX3atan;
51  px *= x2;
52  px += PX4atan;
53  px *= x2;
54  px += PX5atan;
55
56  return px;
57}
58
59
60inline double get_atan_qx(const double x2){
61  const double QX1atan = 2.485846490142306297962E1;
62  const double QX2atan = 1.650270098316988542046E2;
63  const double QX3atan = 4.328810604912902668951E2;
64  const double QX4atan = 4.853903996359136964868E2;
65  const double QX5atan = 1.945506571482613964425E2;
66
67  double qx=x2;
68  qx += QX1atan;
69  qx *=x2;
70  qx += QX2atan;
71  qx *=x2;
72  qx += QX3atan;
73  qx *=x2;
74  qx += QX4atan;
75  qx *=x2;
76  qx += QX5atan;
77
78  return qx;
79}
80
81}
82
83
84
85/// Fast Atan implementation double precision
86inline double fast_atan(double x){
87
88  /* make argument positive and save the sign */
89  const uint64_t sign_mask = details::getSignMask(x);
90  x=std::fabs(x);
91
92  /* range reduction */
93  const double originalx=x;
94
95  double y = details::PIO4;
96  double factor = details::MOREBITSO2;
97  x = (x-1.0) / (x+1.0);
98
99  if( originalx > details::T3PO8 ) {
100    y = details::PIO2;
101    factor = details::MOREBITS;
102    x = -1.0 / originalx ;
103  }
104  if ( originalx <= 0.66 ) {
105    y = 0.;
106    factor = 0.;
107    x = originalx;
108  }
109
110  const double x2 = x * x;
111
112  const double px = details::get_atan_px(x2);
113  const double qx = details::get_atan_qx(x2);
114
115  //double res = y +x * x2 * px / qx + x +factor;
116
117  const double poq=px / qx;
118
119  double res = x * x2 * poq + x;
120  res+=y;
121
122  res+=factor;
123
124  return details::dpORuint64(res,sign_mask);
125}
126
127//------------------------------------------------------------------------------
128/// Fast Atan implementation single precision
129inline float fast_atanf( float xx ) {
130
131  const uint32_t sign_mask = details::getSignMask(xx);
132
133  float x= std::fabs(xx);
134  const float x0=x;
135  float y=0.0f;
136
137  /* range reduction */
138  if( x0 > 0.4142135623730950f ){ // * tan pi/8
139    x = (x0-1.0f)/(x0+1.0f);
140    y = details::PIO4F;
141  }
142  if( x0 > 2.414213562373095f ){  // tan 3pi/8
143    x = -( 1.0f/x0 );
144    y = details::PIO2F;
145  }
146
147
148  const float x2 = x * x;
149  y +=
150      ((( 8.05374449538e-2f * x2
151          - 1.38776856032E-1f) * x2
152          + 1.99777106478E-1f) * x2
153          - 3.33329491539E-1f) * x2 * x
154          + x;
155
156  return details::spORuint32(y,sign_mask);
157}
158
159//------------------------------------------------------------------------------
160
161}// end of vdt
162
163#endif // end of atan
Note: See TracBrowser for help on using the repository browser.