MATHLIB User Guide
MATHLIB_atan2.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *
11  * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the
14  * distribution.
15  *
16  * Neither the name of Texas Instruments Incorporated nor the names of
17  * its contributors may be used to endorse or promote products derived
18  * from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  ******************************************************************************/
33 
34 #include <cstdint>
35 #define ELEMENT_COUNT(x) c7x::element_count_of<x>::value
36 
37 /******************************************************************************/
38 /* */
39 /* Includes */
40 /* */
41 /******************************************************************************/
42 
43 #include "MATHLIB_atan2_scalar.h"
44 #include "MATHLIB_ilut.h"
45 #include "MATHLIB_lut.h"
46 #include "MATHLIB_permute.h"
47 #include "MATHLIB_types.h"
48 #include "MATHLIB_utility.h"
49 #include <cstddef>
50 #include <limits>
51 
52 /******************************************************************************/
53 /* */
54 /* MATHLIB_atan2 */
55 /* */
56 /******************************************************************************/
57 
58 // this method performs a/b division for atan2 computation
59 template <typename vecType> static inline vecType divspMod_atan2_i(vecType a, vecType b);
60 
61 template <> inline c7x::float_vec divspMod_atan2_i<c7x::float_vec>(c7x::float_vec a, c7x::float_vec b)
62 {
63  typedef typename c7x::make_full_vector<float>::type vecType;
64 
65  vecType res_fVec, r0, d0, d1, p0_Vec, p1_Vec, Two;
66 
67  Two = (vecType) 2.0;
68 
69  p0_Vec = __recip(b);
70  d0 = p0_Vec * b;
71  r0 = p0_Vec;
72 
73  p1_Vec = Two - d0;
74  d1 = r0 * p1_Vec;
75 
76  res_fVec = a * d1;
77 
78  return res_fVec;
79 }
80 
81 // this method constructs the polynomial estimation for atan2 computation
82 template <typename vecType, typename vecBool>
83 static inline vecType atan22f_sr1i_atan2_i(vecType g1, vecType pih, vecBool s, vecBool bn, vecBool an);
84 
85 template <>
86 inline c7x::float_vec atan22f_sr1i_atan2_i<c7x::float_vec, c7x::char_vec>(c7x::float_vec g1,
87  c7x::float_vec pih,
88  c7x::char_vec s,
89  c7x::char_vec bn,
90  c7x::char_vec an)
91 {
92 
93  /*************************************************************************************/
94  /* Create and assign values for constants and variables for polynomial approximation */
95  /*************************************************************************************/
96  c7x::float_vec coef_vec, negativeCoef, pi_vec, polVec, Zero_vec, G2, G4, G6, G8, G10, G12, tmp1_vec, tmp2_vec, C1,
97  C2, C3, C4, C5, C6, C7, C8, Res, res_minus, res_plus;
98  c7x::char_vec false_vec;
99 
100  false_vec = (c7x::char_vec) 0;
101  Zero_vec = (c7x::float_vec) 0.0;
102  pi_vec = (c7x::float_vec) 3.1415927;
103  // pih = (c7x::float_vec) 1.57079632679;
104 
105  C1 = (c7x::float_vec) 0.00230158202;
106  C2 = (c7x::float_vec) -0.01394551000;
107  C3 = (c7x::float_vec) 0.03937087815;
108  C4 = (c7x::float_vec) -0.07235669163;
109  C5 = (c7x::float_vec) 0.10521499322;
110  C6 = (c7x::float_vec) -0.14175076797;
111  C7 = (c7x::float_vec) 0.19989300877;
112  C8 = (c7x::float_vec) -0.33332930041;
113 
114  coef_vec = pih;
115 
116  // get coef_vec based on the flags
117  // check 'swap' flag
118  // if (s == false_vec) {
119  // coef_vec = pi_vec;
120  // }
121  __vpred cmp_swap = __cmp_eq_pred(s, false_vec);
122  coef_vec = __select(cmp_swap, pi_vec, coef_vec);
123  // if ((s == false_vec) && (bn == false_vec)) {
124  // coef_vec = 0.0f;
125 
126  __vpred cmp_negb = __cmp_eq_pred(bn, false_vec);
127  __vpred and_negB_swap = __and(cmp_negb, cmp_swap);
128 
129  coef_vec = __select(and_negB_swap, Zero_vec, coef_vec);
130 
131  // check if input to atan2_i is negative
132  // if (an != false_vec) {
133  // coef_vec = -coef_vec;
134  // }
135  negativeCoef = -coef_vec;
136  __vpred cmp_sign = __cmp_eq_pred(an, false_vec);
137  coef_vec = __select(cmp_sign, coef_vec, negativeCoef);
138 
139  // calculate polynomial
140  G2 = g1 * g1;
141  G4 = G2 * G2;
142  G6 = G2 * G4;
143  G8 = G4 * G4;
144  G10 = G6 * G4;
145  G12 = G8 * G4;
146 
147  tmp1_vec = ((C5 * G8) + (C6 * G6)) + ((C7 * G4) + (C8 * G2));
148  tmp2_vec = ((((C1 * G4) + (C2 * G2)) + C3) * G12) + (C4 * G10);
149 
150  polVec = tmp1_vec + tmp2_vec;
151  polVec = (polVec * g1) + g1;
152 
153  // return ((s != false_vec) ? (coef_vec - polVec) : (coef_vec + polVec));
154  res_minus = coef_vec - polVec;
155  res_plus = coef_vec + polVec;
156  __vpred cmp_res = __cmp_eq_pred(s, false_vec);
157  Res = __select(cmp_res, res_plus, res_minus);
158 
159  return Res;
160 }
161 
162 // this method performs arc-tangent2 computation of input vector
163 template <typename T> static inline void MATHLIB_atan2_vector(size_t length, T *pSrc0, T *pSrc1, T *pDst);
164 
165 template <> inline void MATHLIB_atan2_vector<float>(size_t length, float *pSrc0, float *pSrc1, float *pDst)
166 {
167 
168  // variables
169  size_t numBlocks = 0; // compute loop's iteration count
170  size_t remNumBlocks = 0; // when numBlocks is not a multiple of SIMD width
171 
172  // derive c7x vector type from template typename
173  typedef typename c7x::make_full_vector<float>::type vec;
174  __SE_TEMPLATE_v1 se0Params = __gen_SE_TEMPLATE_v1();
175  __SA_TEMPLATE_v1 sa0Params = __gen_SA_TEMPLATE_v1();
176 
177  MATHLIB_SE0SA01DSequentialInit(&se0Params, &sa0Params, length, pSrc0, pDst);
178 
179  // calculate compute loop's iteration counter
180  numBlocks = length / c7x::element_count_of<vec>::value;
181  remNumBlocks = length % c7x::element_count_of<vec>::value;
182  if (remNumBlocks) {
183  numBlocks++;
184  }
185 
186  // open SE0, SE1, and SA0 for reading and writing operands
187  MATHLIB_SE0SE1SA0Open(&se0Params, &sa0Params, pSrc0, pSrc1);
188 
189  /***********************************************************************/
190  /* Create and assign values for constants employed on atan2 computation */
191  /***********************************************************************/
192  vec g, res_fvec, Zero, temp, abs_a, abs_b;
193  c7x::char_vec an, bn, s, TRUE_vec, FALSE_vec;
194  vec pih = (vec) 1.570796327;
195  vec pi_Vec = (vec) 3.141592741;
196  vec MAX = std::numeric_limits<float>::max();
197 
198  TRUE_vec = (c7x::char_vec) 1;
199  FALSE_vec = (c7x::char_vec) 0;
200  Zero = (vec) 0.0;
201 
202  // compute loop to perform vector atan2
203  for (size_t i = 0; i < numBlocks; i++) {
204  vec a = c7x::strm_eng<0, vec>::get_adv();
205  vec b = c7x::strm_eng<1, vec>::get_adv();
206 
207  vec x = a;
208  vec y = b;
209 
210  /* if (i == 0) { */
211  /* x.print(); */
212  /* y.print(); */
213  /* } */
214 
215  s = FALSE_vec;
216  __vpred cmp_negA = __cmp_lt_pred(a, Zero);
217  an = __select(cmp_negA, TRUE_vec, FALSE_vec);
218  __vpred cmp_negB = __cmp_lt_pred(b, Zero);
219  bn = __select(cmp_negB, TRUE_vec, FALSE_vec);
220 
221  // swap a and b before calling division sub routine if a > b
222  // if (_fabsf(a) > _fabsf(b) {
223  // temp = b;
224  // b = a;
225  // a = temp;
226  // s = TRUE_vec;
227  // }
228 
229  abs_a = __abs(a);
230  abs_b = __abs(b);
231 
232  __vpred cmp_AgtB = __cmp_lt_pred(abs_b, abs_a);
233  temp = __select(cmp_AgtB, b, Zero);
234  b = __select(cmp_AgtB, a, b);
235  a = __select(cmp_AgtB, temp, a);
236  s = __select(cmp_AgtB, TRUE_vec, s);
237  /***********************************************************************/
238  /* Division computation for atan2 */
239  /***********************************************************************/
240  g = divspMod_atan2_i<vec>(a, b);
241 
242  /***********************************************************************/
243  /* Polynomial computation for atan2 */
244  /***********************************************************************/
245  res_fvec = atan22f_sr1i_atan2_i<vec, c7x::char_vec>(g, pih, s, bn, an);
246 
247  /***********************************************************************/
248  /* Bounds Checking */
249  /***********************************************************************/
250 
251  // if (x == 0.0f) {
252  // res_fvec = y >= 0.0f ? 0.0f : pi_Vec;
253  // }
254 
255  __vpred cmp_zeroX = __cmp_eq_pred(x, Zero);
256 
257  __vpred cmp_zeroY = __cmp_le_pred(Zero, y);
258  vec resY = __select(cmp_zeroY, Zero, pi_Vec);
259 
260  res_fvec = __select(cmp_zeroX, resY, res_fvec);
261 
262  // if (g > MAX) {
263 
264  // res_fvec = pih;
265  // }
266 
267  __vpred gMax = __cmp_lt_pred(MAX, g);
268  res_fvec = __select(gMax, pih, res_fvec);
269 
270  // if (g < -MAX) {
271  // res_fvec = -pih;
272  // }
273 
274  vec MIN = -MAX;
275  vec negativepih = -pih;
276 
277  __vpred gMin = __cmp_lt_pred(g, MIN);
278  res_fvec = __select(gMin, negativepih, res_fvec);
279 
280  vec outVec = res_fvec;
281 
282  __vpred tmp = c7x::strm_agen<0, vec>::get_vpred();
283  vec *addr = c7x::strm_agen<0, vec>::get_adv(pDst);
284  __vstore_pred(tmp, addr, outVec);
285  }
286 
288 
289  return;
290 }
291 
292 template <> inline c7x::double_vec divspMod_atan2_i<c7x::double_vec>(c7x::double_vec a, c7x::double_vec b)
293 {
294  c7x::double_vec Two = (c7x::double_vec)(2.0f);
295  c7x::double_vec X_vec;
296  X_vec = __recip(b);
297  X_vec = X_vec * (Two - (b * X_vec));
298  X_vec = X_vec * (Two - (b * X_vec));
299  X_vec = X_vec * (Two - (b * X_vec));
300  X_vec = a * X_vec;
301 
302  return X_vec;
303 }
304 
305 template <typename T>
306 static inline void atandpMod_atan2dpi_dp(__SE_TEMPLATE_v1 *restrict se0Params,
307  __SA_TEMPLATE_v1 *restrict sa0Params,
308  size_t length,
309  T *restrict pSrc0,
310  T *restrict pDst)
311 {
312  // variables
313  size_t numBlocks = 0; // compute loop's iteration count
314  size_t remNumBlocks = 0; // when numBlocks is not a multiple of SIMD width
315 
316  // derive c7x vector type from template typename
317  typedef typename c7x::make_full_vector<T>::type vec;
318  typedef typename c7x::make_full_vector<long>::type vecLong;
319 
320  // calculate compute loop's iteration counter
321  numBlocks = length / c7x::element_count_of<vec>::value;
322  remNumBlocks = length % c7x::element_count_of<vec>::value;
323  if (remNumBlocks) {
324  numBlocks++;
325  }
326 
327  // open SE0, SE1, and SA0 for reading and writing operands
328  MATHLIB_SE0SA0Open(se0Params, sa0Params, pDst);
329 
330  vec p0_vec = (vec) (-1.3688768894191926929e+1);
331  vec p1_vec = (vec) (-2.0505855195861651981e+1);
332  vec p2_vec = (vec) (-8.4946240351320683534e+0);
333  vec p3_vec = (vec) (-8.3758299368150059274e-1);
334  vec q0_vec = (vec) (4.1066306682575781263e+1);
335  vec q1_vec = (vec) (8.6157349597130242515e+1);
336  vec q2_vec = (vec) (5.9578436142597344465e+1);
337  vec q3_vec = (vec) (1.5024001160028576121e+1);
338  vec sqrt3 = (vec) (1.7320508075688772935e+0);
339  vec iims3 = (vec) (2.6794919243112270647e-1);
340  vec zero = (vec) (0.0);
341  vec n_one = (vec) (-1.0);
342  vec p_one = (vec) (1.0);
343 
344  vec F, G, H, R, RN, RD;
345 
346  vecLong N, Sign;
347 
348  vecLong oneL = (vecLong) (1);
349  vecLong TwoL = (vecLong) (2);
350 
351  for (size_t i = 0; i < numBlocks; i++) {
352 
353  vec a = c7x::strm_eng<0, vec>::get_adv();
354 
355  Sign = (vecLong) (0);
356  F = a;
357 
358  N = (vecLong) (0);
359 
360  __vpred cmp_cond1 = __cmp_lt_pred(F, zero);
361  F = __select(cmp_cond1, (F * n_one), F);
362  Sign = __select(cmp_cond1, oneL, Sign);
363 
364  vec temp1 = divspMod_atan2_i<vec>(p_one, F);
365  vecLong temp2 = N + oneL;
366  vec temp3_0 = (F * sqrt3) - p_one;
367  vec temp3_1 = (F + sqrt3);
368  vec temp3 = divspMod_atan2_i<vec>(temp3_0, temp3_1);
369 
370  __vpred cmp_cond2 = __cmp_lt_pred(p_one, F);
371  F = __select((cmp_cond2), temp1, F);
372  N = __select((cmp_cond2), TwoL, N);
373 
374  __vpred cmp_cond3 = __cmp_lt_pred(iims3, F);
375  N = __select((cmp_cond3), temp2, N);
376  F = __select((cmp_cond3), temp3, F);
377 
378  H = F;
379  H = __abs(H);
380 
381  G = H * H;
382  RN = ((((((p3_vec * G) + p2_vec) * G) + p1_vec) * G) + p0_vec) * G;
383  RD = ((((((G + q3_vec) * G) + q2_vec) * G) + q1_vec) * G) + q0_vec;
384 
385  R = divspMod_atan2_i<vec>(RN, RD);
386 
387  F = F + (F * R);
388 
389  vec temp4 = F * n_one;
390  __vpred cmp_cond4 = __cmp_gt_pred(N, oneL);
391  F = __select(cmp_cond4, temp4, F);
392 
393  c7x::uint_vec index = (c7x::as_uint_vec(N)) + MATHLIB_VTABLE_OFFSET;
394 
395  c7x::uint_vec highbits = MATHLIB_LUTReadUpperBits(index);
396  c7x::uint_vec lowbits = MATHLIB_LUTReadLowerBits(index);
397  vec vTable = c7x::reinterpret<c7x::double_vec>(__permute_even_even_int(
398  MATHLIB_vperm_data_interweave_0_63, c7x::as_uchar_vec(highbits), c7x::as_uchar_vec(lowbits)));
399 
400  H = F + vTable;
401  vec temp5 = H * n_one;
402  __vpred cmp_cond5 = __cmp_eq_pred(Sign, oneL);
403  H = __select(cmp_cond5, temp5, H);
404 
405  __vpred tmp = c7x::strm_agen<0, vec>::get_vpred();
406  vec *addr = c7x::strm_agen<0, vec>::get_adv(pDst);
407  __vstore_pred(tmp, addr, H);
408  }
410 }
411 
412 template <> inline void MATHLIB_atan2_vector<double>(size_t length, double *pSrc0, double *pSrc1, double *pDst)
413 {
414  // variables
415  size_t numBlocks = 0; // compute loop's iteration count
416  size_t remNumBlocks = 0; // when numBlocks is not a multiple of SIMD width
417 
418  // derive c7x vector type from template typename
419  typedef typename c7x::make_full_vector<double>::type vec;
420 
421  __SE_TEMPLATE_v1 se0Params = __gen_SE_TEMPLATE_v1();
422  __SE_TEMPLATE_v1 se1Params = __gen_SE_TEMPLATE_v1();
423  __SA_TEMPLATE_v1 sa0Params = __gen_SA_TEMPLATE_v1();
424 
425  MATHLIB_SE0SA01DSequentialInit(&se0Params, &sa0Params, length, pSrc0, pDst);
426 
427  // calculate compute loop's iteration counter
428  numBlocks = length / c7x::element_count_of<vec>::value;
429  remNumBlocks = length % c7x::element_count_of<vec>::value;
430  if (remNumBlocks) {
431  numBlocks++;
432  }
433 
434  se1Params.DIMFMT = __SE_DIMFMT_3D;
435  se1Params.ELETYPE = c7x::se_eletype<vec>::value;
436  se1Params.VECLEN = c7x::se_veclen<vec>::value;
437  se1Params.DECDIM1 = __SE_DECDIM_DIM2;
438  se1Params.DECDIM1_WIDTH = length;
439 
440  se1Params.ICNT0 = c7x::element_count_of<vec>::value;
441  se1Params.ICNT1 = 2;
442  se1Params.DIM1 = ((double *) pSrc1) - ((double *) pSrc0);
443  se1Params.ICNT2 = numBlocks;
444  se1Params.DIM2 = c7x::element_count_of<vec>::value;
445 
446  // open SE0, SE1, and SA0 for reading and writing operands
447  MATHLIB_SE0SE1SA0Open(&se0Params, &sa0Params, pSrc0, pSrc1);
448 
449  /***********************************************************************/
450  /* Create and assign values for constants employed on atan2 computation */
451  /***********************************************************************/
452  vec HalfPI, MATHLIB_PI, Maxv, X, Y, Z, W, resVec, NegHalfPi, NegMaxv;
453 
454  HalfPI = (vec) (1.57079632679489661923);
455  NegHalfPi = (vec) (-1.57079632679489661923);
456  MATHLIB_PI = (vec) (3.14159265358979323846);
457  Maxv = (vec) (1.7976931348623157e+308);
458  NegMaxv = (vec) (-1.7976931348623157e+308);
459 
460  vec zero = (vec) (0.0);
461 
462  for (size_t i = 0; i < numBlocks; i++) {
463 
464  Y = c7x::strm_eng<0, vec>::get_adv();
465  X = c7x::strm_eng<1, vec>::get_adv();
466 
467  Z = divspMod_atan2_i<vec>(Y, X);
468 
469  __vpred tmp = c7x::strm_agen<0, vec>::get_vpred();
470  vec *addr = c7x::strm_agen<0, vec>::get_adv(pDst);
471  __vstore_pred(tmp, addr, Z);
472  }
474 
475  atandpMod_atan2dpi_dp(&se0Params, &sa0Params, length, pSrc0, pDst);
476 
477  __SE0_OPEN(pSrc0, se1Params);
478  __SE1_OPEN(pDst, se0Params);
479  __SA0_OPEN(sa0Params);
480 
481  for (size_t i = 0; i < numBlocks; i++) {
482 
483  Y = c7x::strm_eng<0, vec>::get_adv();
484  X = c7x::strm_eng<0, vec>::get_adv();
485  W = c7x::strm_eng<1, vec>::get_adv();
486 
487  Z = divspMod_atan2_i<vec>(Y, X);
488 
489  resVec = W;
490 
491  vec res_pi = MATHLIB_PI + W;
492  __vpred cond1 = __cmp_lt_pred(X, zero);
493  __vpred cond2 = __cmp_lt_pred(zero, W);
494  res_pi = __select(cond2, (W - MATHLIB_PI), res_pi);
495  resVec = __select(cond1, res_pi, resVec);
496 
497  __vpred cond3 = __cmp_eq_pred(X, zero);
498  __vpred cond4 = __cmp_lt_pred(zero, Y);
499 
500  vec res1 = __select(cond4, HalfPI, (NegHalfPi));
501  resVec = __select(cond3, res1, resVec);
502 
503  __vpred cond5 = __cmp_eq_pred(Y, zero);
504  __vpred cond6 = __cmp_le_pred(zero, X);
505 
506  vec res2 = __select(cond6, zero, MATHLIB_PI);
507  resVec = __select(cond5, res2, resVec);
508 
509  __vpred cond7 = __cmp_lt_pred(Maxv, Z);
510  resVec = __select((cond7), HalfPI, resVec);
511 
512  __vpred cond8 = __cmp_lt_pred(Z, (NegMaxv));
513  resVec = __select(cond8, (NegHalfPi), resVec);
514 
515  __vpred tmp = c7x::strm_agen<0, vec>::get_vpred();
516  vec *addr = c7x::strm_agen<0, vec>::get_adv(pDst);
517  __vstore_pred(tmp, addr, resVec);
518  }
520  return;
521 }
522 
523 // this method performs exponential computation of input vector
524 template <typename T> MATHLIB_STATUS MATHLIB_atan2(size_t length, T *pSrc0, T *pSrc1, T *pDst);
525 
526 template <> MATHLIB_STATUS MATHLIB_atan2<float>(size_t length, float *pSrc0, float *pSrc1, float *pDst)
527 {
528  MATHLIB_STATUS status = MATHLIB_SUCCESS; // return function status
529 
530  // check for null pointers and non-zero length
531  status = MATHLIB_checkParams(length, pSrc0, pSrc1, pDst);
532 
533  // Calling Scalar operations for C7504 and vector operations for others
534  if (status == MATHLIB_SUCCESS) {
535  if (length < 2) {
536  pDst[0] = MATHLIB_atan2_scalar_ci<float>(pSrc0[0], pSrc1[0]);
537  }
538  else {
539  MATHLIB_atan2_vector<float>(length, pSrc0, pSrc1, pDst);
540  }
541  }
542  return status;
543 }
544 
545 template <> MATHLIB_STATUS MATHLIB_atan2<double>(size_t length, double *pSrc0, double *pSrc1, double *pDst)
546 {
547  MATHLIB_STATUS status = MATHLIB_SUCCESS; // return function status
548 
549  // check for null pointers and non-zero length
550  status = MATHLIB_checkParams(length, pSrc0, pSrc1, pDst);
551 
552  // Calling Scalar operations for C7504 and vector operations for others
553  if (status == MATHLIB_SUCCESS) {
554  if (length < 2) {
555  pDst[0] = MATHLIB_atan2_scalar_ci<double>(pSrc0[0], pSrc1[0]);
556  }
557  else {
558  MATHLIB_atan2_vector<double>(length, pSrc0, pSrc1, pDst);
559  }
560  }
561  return status;
562 }
563 
564 /******************************************************************************/
565 /* */
566 /* C-interface wrapper functions */
567 /* */
568 /******************************************************************************/
569 
570 extern "C" {
571 
572 // single-precision wrapper
573 MATHLIB_STATUS MATHLIB_atan2_sp(size_t length, float *pSrc0, float *pSrc1, float *pDst)
574 {
575  MATHLIB_STATUS status = MATHLIB_atan2<float>(length, pSrc0, pSrc1, pDst);
576  return status;
577 }
578 
579 // double-precision wrapper
580 MATHLIB_STATUS MATHLIB_atan2_dp(size_t length, double *pSrc0, double *pSrc1, double *pDst)
581 {
582  MATHLIB_STATUS status = MATHLIB_atan2<double>(length, pSrc0, pSrc1, pDst);
583  return status;
584 }
585 
586 } // extern "C"
void MATHLIB_atan2_vector< double >(size_t length, double *pSrc0, double *pSrc1, double *pDst)
MATHLIB_STATUS MATHLIB_atan2< double >(size_t length, double *pSrc0, double *pSrc1, double *pDst)
static vecType atan22f_sr1i_atan2_i(vecType g1, vecType pih, vecBool s, vecBool bn, vecBool an)
void MATHLIB_atan2_vector< float >(size_t length, float *pSrc0, float *pSrc1, float *pDst)
static vecType divspMod_atan2_i(vecType a, vecType b)
MATHLIB_STATUS MATHLIB_atan2(size_t length, T *pSrc0, T *pSrc1, T *pDst)
static void MATHLIB_atan2_vector(size_t length, T *pSrc0, T *pSrc1, T *pDst)
MATHLIB_STATUS MATHLIB_atan2< float >(size_t length, float *pSrc0, float *pSrc1, float *pDst)
static void atandpMod_atan2dpi_dp(__SE_TEMPLATE_v1 *restrict se0Params, __SA_TEMPLATE_v1 *restrict sa0Params, size_t length, T *restrict pSrc0, T *restrict pDst)
double MATHLIB_atan2_scalar_ci< double >(double a, double b)
float MATHLIB_atan2_scalar_ci< float >(float a, float b)
MATHLIB_STATUS MATHLIB_atan2_dp(size_t length, double *pSrc0, double *pSrc1, double *pDst)
This function is the C interface for MATHLIB_atan2. Function accepts double pointers.
MATHLIB_STATUS MATHLIB_atan2_sp(size_t length, float *pSrc0, float *pSrc1, float *pDst)
This function is the C interface for MATHLIB_atan2. Function accepts float pointers.
#define MATHLIB_VTABLE_OFFSET
Definition: MATHLIB_lut.h:67
static c7x::uint_vec MATHLIB_LUTReadLowerBits(vecType vecOffset)
This method reads bits 31-0 of LUT value at vecOffset.
Definition: MATHLIB_lut.h:111
static c7x::uint_vec MATHLIB_LUTReadUpperBits(vecType vecOffset)
This method reads bits 63-32 of LUT value at vecOffset.
Definition: MATHLIB_lut.h:86
static void MATHLIB_SE0SE1SA0Open(__SE_TEMPLATE_v1 *se0Params, __SA_TEMPLATE_v1 *sa0Params, T *pSrc0, T *pSrc1)
This method performs SE0, SE1, and SA0 open.
static void MATHLIB_SE0SA0Close()
This method performs SE0 and SA0 close.
static void MATHLIB_SE0SE1SA0Close()
This method performs SE0, SE1, and SA0 close.
static void MATHLIB_SE0SA01DSequentialInit(__SE_TEMPLATE_v1 *se0Params, __SA_TEMPLATE_v1 *sa0Params, size_t length, T *pSrc, T *pDst)
static MATHLIB_STATUS MATHLIB_checkParams(size_t length, T *pSrc, T *pDst)
This method performs parameter checks for MATHLIB function.
static void MATHLIB_SE0SA0Open(__SE_TEMPLATE_v1 *se0Params, __SA_TEMPLATE_v1 *sa0Params, T *pSrc)
This method performs SE0 and SA0 open.
MATHLIB_STATUS_NAME
The enumeration of all status codes.
@ MATHLIB_SUCCESS