MATHLIB User Guide
MATHLIB_acos_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 /* MATHLIB_acos_scalar.h - Single precision floating point arc_cosine */
39 /* optimized inlined C implementation (w/ intrinsics) */
40 /* =========================================================================== */
41 
42 #ifndef MATHLIB_ACOS_SCALAR_H_
43 #define MATHLIB_ACOS_SCALAR_H_ 1
44 
45 #include <c6x_migration.h>
46 
47 static inline float sqrtsp_acossp_i(float x);
48 static inline float pol_est_acossp_i(float x);
49 static inline float MATHLIB_acos_scalar(float x);
50 
51 #ifndef __cplusplus /* FOR PROTECTION PURPOSE - C++ NOT SUPPORTED. */
52 #pragma CODE_SECTION(MATHLIB_acos_scalar, ".text:optci");
53 #endif
54 
55 /* =========================================================================== */
56 /* The sqrtsp function returns the square root of a real floating-point value. */
57 /* =========================================================================== */
58 
59 static inline float sqrtsp_acossp_i(float x)
60 {
61  const float half = 0.5f;
62  const float OneP5 = 1.5f;
63  float y, y0, y1, y2, x_half;
64 
65  x_half = x * half;
66  y0 = _rsqrsp(x); /* y0 = 1/sqrt(x) */
67 
68  y1 = OneP5 - (y0 * y0 * x_half);
69  y1 = y0 * y1;
70  y2 = y1 * (OneP5 - (y1 * y1 * x_half));
71  y = x * y2;
72 
73  if (x <= 0.0f) {
74  y = 0.0f;
75  }
76 
77  return (y);
78 } /* sqrtsp_acossp_i */
79 
80 #ifndef __cplusplus /* FOR PROTECTION PURPOSE - C++ NOT SUPPORTED. */
81 #pragma CODE_SECTION(pol_est_acossp_i, ".text:optci");
82 #endif
83 
84 /* ======================================================================== */
85 /* Polynomial calculation to estimate the arc_cosine funtion. */
86 /* The polynomial used is as follows: */
87 /* pol = x + c2 x^3 + c4 x^5 + c6 x^7 + c8 x^9 + c10 x^11 + c12 x^13 + */
88 /* c14 x^15 + c16 x^17, */
89 /* where x is the input, c2 through c16 are the corresponding coefficients */
90 /* to the polynomial, and pol is the result of the polynomial. This */
91 /* polynomial only covers inputs in the range [0, 1/sqrt(2)]. */
92 /* ======================================================================== */
93 
94 static inline float pol_est_acossp_i(float x)
95 {
96  const float c16 = 0.053002771381990f;
97  const float c14 = -0.010980624698693f;
98  const float c12 = 0.020659425186833f;
99  const float c10 = 0.022862784546374f;
100  const float c8 = 0.030636056280974f;
101  const float c6 = 0.044450959710588f;
102  const float c4 = 0.075034659380970f;
103  const float c2 = 0.166664771293503f;
104 
105  float x2, x4, x6, x8, x10, x12;
106  float pol, tmp1, tmp2;
107 
108  /* calculate powers of x */
109  x2 = x * x;
110  x4 = x2 * x2;
111  x6 = x2 * x4;
112  x8 = x4 * x4;
113  x10 = x6 * x4;
114  x12 = x8 * x4;
115 
116  /* ====================================================================== */
117  /* The polynomial calculation is done in two seperate parts. */
118  /* tmp1 = c2 x^2 + c4 x^4 + c6 x^6 + c8 x^8 */
119  /* tmp2 = c10 x^10 + c12 x^12 + c14 x^14 + c16 x^16 */
120  /* In order to reduce the number of multiplications x is factored out of */
121  /* the polynomial and multiplied by later. */
122  /* ====================================================================== */
123 
124  tmp1 = ((c8 * x8) + (c6 * x6)) + ((c4 * x4) + (c2 * x2));
125  tmp2 = ((((c16 * x4) + (c14 * x2)) + c12) * x12) + (c10 * x10);
126 
127  pol = tmp1 + tmp2;
128  pol = (pol * x) + x;
129 
130  return pol;
131 } /* pol_est_acossp_i */
132 
133 #ifndef __cplusplus /* FOR PROTECTION PURPOSE - C++ NOT SUPPORTED. */
134 #pragma CODE_SECTION(acossp_i, ".text:optci");
135 #endif
136 
137 /* ====================================================================== */
138 /* The type of calculation for acos(x) depends on the value of x, and */
139 /* it's based on asin(x), acos(x) = pi/2 - asin(x). */
140 /* */
141 /* for x_abs <= 1/sqrt(2), res = pi/2 - pol_est_acossp_i (input x) */
142 /* for x_abs > 1/sqrt(2), res = pi/2 -(pi/2 - pol_est_acossp_i (input a))*/
143 /* a = sqrt(1 - x^2) */
144 /* where x_abs is the absolute value of the input, a is calculated as */
145 /* shown above and it's used as an input for the polynomial, and res is */
146 /* the value for acos(x). */
147 /* ====================================================================== */
148 
149 static inline float MATHLIB_acos_scalar(float x)
150 {
151  const float pi2 = 1.570796327f; /* pi/2 */
152  const float rsqr2 = 0.7071067811f; /* 1/sqrt(2) */
153  float s = 1.0f;
154  float res, x_abs, temp, a;
155 
156  x_abs = _fabsf(x);
157 
158  if (x_abs > rsqr2) { /* |x| > 1/sqrt(2) */
159  temp = 1.0f - (x_abs * x_abs);
160  a = sqrtsp_acossp_i(temp); /* a = sqrt(1 - x^2) */
161  temp = pol_est_acossp_i(a);
162  res = pi2 - temp;
163  }
164  else { /* |x| <= 1/sqrt(2) */
165  res = pol_est_acossp_i(x_abs);
166  }
167 
168  if (x < 0.0f) {
169  s = -s; /* sign var */
170  }
171 
172  res = pi2 - (res * s); /* restore sign for quadrants 2 & 3*/
173 
174  if (x_abs > 1.0f) {
175  res = _itof(0x7FFFFFFFu); /* NaN */
176  }
177 
178  return (res);
179 } /* MATHLIB_acos_scalar */
180 
181 #endif /* MATHLIB_ACOS_SCALAR_H_ */
182 
183 /* ======================================================================== */
184 /* End of file: MATHLIB_acos_scalar.h */
185 /* ======================================================================== */
static float MATHLIB_acos_scalar(float x)
static float pol_est_acossp_i(float x)
static float sqrtsp_acossp_i(float x)