MATHLIB User Guide
MATHLIB_atan2_scalar.h
Go to the documentation of this file.
1 /* ======================================================================== *
2  * MATHLIB -- TI Floating-Point Math Function Library *
3  * *
4  * *
5  * Copyright (C) 2011 Texas Instruments Incorporated - https://www.ti.com/ *
6  * *
7  * *
8  * Redistribution and use in source and binary forms, with or without *
9  * modification, are permitted provided that the following conditions *
10  * are met: *
11  * *
12  * Redistributions of source code must retain the above copyright *
13  * notice, this list of conditions and the following disclaimer. *
14  * *
15  * Redistributions in binary form must reproduce the above copyright *
16  * notice, this list of conditions and the following disclaimer in the *
17  * documentation and/or other materials provided with the *
18  * distribution. *
19  * *
20  * Neither the name of Texas Instruments Incorporated nor the names of *
21  * its contributors may be used to endorse or promote products derived *
22  * from this software without specific prior written permission. *
23  * *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
25  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *
26  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR *
27  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT *
28  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *
29  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
30  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, *
31  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY *
32  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
33  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE *
34  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
35  * ======================================================================== */
36 
37 /* =========================================================================== */
38 /* atan2sp_i.h - single and double precision floating point arctangent two arguement */
39 /* optimized inlined C implementation (w/ intrinsics) */
40 /* =========================================================================== */
41 
42 #ifndef ATAN2SP_I_H_
43 #define ATAN2SP_I_H_ 1
44 
45 #include "../common/MATHLIB_utility.h"
46 #include <c6x_migration.h>
47 #include <stdbool.h>
48 
49 typedef bool t_bool;
50 #define TRUE ((t_bool) true)
51 #define FALSE ((t_bool) false)
52 
53 static double ti_math_vTable[4] = {0.00000000000000000000, 0.52359877559829887308, 1.57079632679489661923,
54  1.04719755119659774615};
55 
56 static inline float divspMod_atan2spi(float a, float b);
57 static inline float atan2f_sr1i_atan2spi(float g1, float pih, t_bool s, t_bool bn, t_bool an);
58 
59 #ifndef __cplusplus /* FOR PROTECTION PURPOSE - C++ NOT SUPPORTED. */
60 #pragma CODE_SECTION(divspMod_atan2spi, ".text:optci");
61 #endif
62 
63 /* Pull in inline for divsp */
64 static inline float divspMod_atan2spi(float a, float b) { return cmn_DIVSP(b, a); }
65 
66 #ifndef __cplusplus /* FOR PROTECTION PURPOSE - C++ NOT SUPPORTED. */
67 #pragma CODE_SECTION(atan2f_sr1i_atan2spi, ".text:optci");
68 #endif
69 
70 static inline float atan2f_sr1i_atan2spi(float g1, float pih, t_bool s, t_bool bn, t_bool an)
71 {
72  float coef;
73  float g2;
74  float g4;
75  float g6;
76  float g8;
77  float g10;
78  float g12;
79  float pol;
80  float tmp1;
81  float tmp2;
82  float c1 = 0.00230158202f;
83  float c2 = -0.01394551000f;
84  float c3 = 0.03937087815f;
85  float c4 = -0.07235669163f;
86  float c5 = 0.10521499322f;
87  float c6 = -0.14175076797f;
88  float c7 = 0.19989300877f;
89  float c8 = -0.33332930041f;
90 
91  /* get coef based on the flags */
92  coef = pih;
93  if (s == FALSE) {
94  coef = 3.1415927f;
95  }
96 
97  /* a & b have not been swapped, and b is negative*/
98  if ((s == FALSE) && (bn == FALSE)) {
99  coef = 0.0f;
100  }
101 
102  /* MISRA requires explicit checks, != FALSE is faster than == TRUE*/
103  if (an != FALSE) {
104  coef = -coef;
105  }
106 
107  /* calculate polynomial */
108  g2 = g1 * g1;
109  g4 = g2 * g2;
110  g6 = g2 * g4;
111  g8 = g4 * g4;
112  g10 = g6 * g4;
113  g12 = g8 * g4;
114 
115  tmp1 = (c5 * g8) + (c6 * g6) + (c7 * g4) + (c8 * g2);
116  tmp2 = (((c1 * g4) + (c2 * g2) + c3) * g12) + (c4 * g10);
117 
118  pol = tmp1 + tmp2;
119  pol = (pol * g1) + g1;
120 
121  /* MISRA requires explicit checks, != FALSE is faster than == TRUE*/
122  return ((s != FALSE) ? (coef - pol) : (coef + pol));
123 }
124 
125 /* Pull in inline for divdp */
126 static inline double divdpMod_atan2dpi(double a, double b) { return cmn_DIVDP(a, b); }
127 
128 static inline double atandpMod_atan2dpi(double a)
129 {
130  double p0 = -1.3688768894191926929e+1;
131  double p1 = -2.0505855195861651981e+1;
132  double p2 = -8.4946240351320683534e+0;
133  double p3 = -8.3758299368150059274e-1;
134  double q0 = 4.1066306682575781263e+1;
135  double q1 = 8.6157349597130242515e+1;
136  double q2 = 5.9578436142597344465e+1;
137  double q3 = 1.5024001160028576121e+1;
138  double sqrt3 = 1.7320508075688772935e+0;
139  double iims3 = 2.6794919243112270647e-1;
140  double F, G, H, R, RN, RD;
141  int N, Sign;
142 
143  Sign = 0;
144  F = a;
145  N = 0;
146 
147  if (F < 0.0) {
148  F = -F;
149  Sign = 1;
150  }
151 
152  if (F > 1.0) {
153  F = divdpMod_atan2dpi(1.0, F);
154  N = 2;
155  }
156 
157  if (F > iims3) {
158  N = N + 1;
159  F = divdpMod_atan2dpi((F * sqrt3) - 1.0, F + sqrt3);
160  }
161 
162  H = F;
163  H = _fabs(H);
164 
165  G = H * H;
166  RN = ((((((p3 * G) + p2) * G) + p1) * G) + p0) * G;
167  RD = ((((((G + q3) * G) + q2) * G) + q1) * G) + q0;
168  R = divdpMod_atan2dpi(RN, RD);
169 
170  F = F + (F * R);
171 
172  if (N > 1) {
173  F = -F;
174  }
175 
176  H = F + ti_math_vTable[N];
177 
178  if (Sign == 1) {
179  H = -H;
180  }
181 
182  return (H);
183 }
184 
185 #ifndef __cplusplus /* FOR PROTECTION PURPOSE - C++ NOT SUPPORTED. */
186 #pragma CODE_SECTION(atan2sp_i, ".text:optci");
187 #endif
188 
189 template <typename T> static inline T MATHLIB_atan2_scalar_ci(T a, T b);
190 
191 template <> inline float MATHLIB_atan2_scalar_ci<float>(float a, float b)
192 {
193  float g, x, y;
194  float res;
195  float temp;
196  float pih = 1.570796327f;
197  float pi = 3.141592741f;
198  float Max = 3.402823466E+38f;
199  t_bool an;
200  t_bool bn;
201  t_bool s = FALSE;
202 
203  x = a;
204  y = b;
205  an = (a < 0.0f) ? TRUE : FALSE; /* flag for a negative */
206  bn = (b < 0.0f) ? TRUE : FALSE; /* flag for b negative */
207 
208  /* swap a and b before calling division sub routine if a > b */
209  if (_fabsf(a) > _fabsf(b)) {
210  temp = b;
211  b = a;
212  a = temp;
213  s = TRUE; /* swap flag */
214  }
215 
216  g = divspMod_atan2spi(b, a);
217 
218  /* do polynomial estimation */
219  res = atan2f_sr1i_atan2spi(g, pih, s, bn, an);
220 
221  /* switch the returns so that the answer is equivalent */
222  if (x == 0.0f) {
223  res = y >= 0.0f ? 0.0f : pi;
224  }
225 
226 #if 0
227  /* As the values of a and b are getting swapped the value of g is never going
228  to be out of range [-1, 1]. Hence following condition will never hit*/
229  if (g > Max) {
230  res = pih;
231  }
232  if (g < -Max) {
233  res = -pih;
234  }
235 #else
236  /* Mathematically when y=0, value of res should be + / - pi depending on the sign of x
237  This condition can be used insed of checking g value. */
238  if (y == 0.0f && x > 0) {
239  res = pih;
240  }
241  if (y == 0.0f && x < 0) {
242  res = -pih;
243  }
244 #endif
245 
246  return (res);
247 }
248 
249 template <> inline double MATHLIB_atan2_scalar_ci<double>(double a, double b)
250 {
251  double HalfPI = 1.57079632679489661923;
252  double MATHLIB_PI = 3.14159265358979323846;
253  double Maxv = 1.7976931348623157e+308;
254  double X, Y, Z, W, res;
255 
256  Y = a;
257  X = b;
258 
259  Z = divdpMod_atan2dpi(Y, X);
260 
261  W = atandpMod_atan2dpi(Z);
262 
263  res = W;
264 
265  if (X < 0.0) {
266  res = MATHLIB_PI + W;
267  if (W > 0.0) {
268  res = W - MATHLIB_PI;
269  }
270  }
271 
272  if (X == 0.0f) {
273  res = Y > 0.0f ? HalfPI : -HalfPI;
274  }
275 
276  if (Y == 0.0f) {
277  res = X >= 0.0f ? 0.0 : MATHLIB_PI;
278  }
279 
280  if (Z > Maxv) {
281  res = HalfPI;
282  }
283 
284  if (Z < -Maxv) {
285  res = -HalfPI;
286  }
287 
288  return (res);
289 }
290 
291 extern "C" {
292 static inline float MATHLIB_atan2_scalar_sp(float a, float b)
293 {
294  float result = MATHLIB_atan2_scalar_ci<float>(a, b);
295  return result;
296 }
297 
298 static inline double MATHLIB_atan2_scalar_dp(double a, double b)
299 {
300  double result = MATHLIB_atan2_scalar_ci<double>(a, b);
301  return result;
302 }
303 }
304 
305 #endif /* ATAN2SP_I_H_ */
306 
307 /* ======================================================================== */
308 /* End of file: atan2sp_i.h */
309 /* ======================================================================== */
double MATHLIB_atan2_scalar_ci< double >(double a, double b)
static float atan2f_sr1i_atan2spi(float g1, float pih, t_bool s, t_bool bn, t_bool an)
float MATHLIB_atan2_scalar_ci< float >(float a, float b)
#define TRUE
#define FALSE
static double ti_math_vTable[4]
static float MATHLIB_atan2_scalar_sp(float a, float b)
static double atandpMod_atan2dpi(double a)
bool t_bool
static double MATHLIB_atan2_scalar_dp(double a, double b)
static float divspMod_atan2spi(float a, float b)
static double divdpMod_atan2dpi(double a, double b)
static T MATHLIB_atan2_scalar_ci(T a, T b)
bool t_bool
static float cmn_DIVSP(float a, float b)
static double cmn_DIVDP(double a, double b)