MATHLIB User Guide
MATHLIB_asin_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_asin_scalar.h - Single precision floating point arcsine */
39 /* optimized inlined C implementation (w/ intrinsics) */
40 /* =========================================================================== */
41 
42 #ifndef MATHLIB_ASIN_SCALAR_H_
43 #define MATHLIB_ASIN_SCALAR_H_ 1
44 
45 #include <c6x_migration.h>
46 
47 static inline float sqrtsp_asinsp_i(float x);
48 static inline float pol_est_asinsp_i(float x);
49 static inline float MATHLIB_asin_scalar(float x);
50 
51 #ifndef __cplusplus /* FOR PROTECTION PURPOSE - C++ NOT SUPPORTED. */
52 #pragma CODE_SECTION(MATHLIB_asin_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_asinsp_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_asinsp_i */
79 
80 #ifndef __cplusplus /* FOR PROTECTION PURPOSE - C++ NOT SUPPORTED. */
81 #pragma CODE_SECTION(pol_est_asinsp_i, ".text:optci");
82 #endif
83 
84 /* ======================================================================== */
85 /* Polynomial calculation to estimate the arc_sine 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_asinsp_i(float x)
95 {
96  /* coefficients for the polynomial for asin(x) */
97  const float c16 = 0.053002771381990f;
98  const float c14 = -0.010980624698693f;
99  const float c12 = 0.020659425186833f;
100  const float c10 = 0.022862784546374f;
101  const float c8 = 0.030636056280974f;
102  const float c6 = 0.044450959710588f;
103  const float c4 = 0.075034659380970f;
104  const float c2 = 0.166664771293503f;
105 
106  float x2, x4, x6, x8, x10, x12;
107  float pol, tmp1, tmp2;
108 
109  /* calculate the powers of x */
110  x2 = x * x;
111  x4 = x2 * x2;
112  x6 = x2 * x4;
113  x8 = x4 * x4;
114  x10 = x6 * x4;
115  x12 = x8 * x4;
116 
117  /* ====================================================================== */
118  /* The polynomial calculation is done in two seperate parts. */
119  /* tmp1 = c2 x^2 + c4 x^4 + c6 x^6 + c8 x^8 */
120  /* tmp2 = c10 x^10 + c12 x^12 + c14 x^14 + c16 x^16 */
121  /* In order to reduce the number of multiplications x is factored out of */
122  /* the polynomial and multiplied by later. */
123  /* ====================================================================== */
124 
125  tmp1 = ((c8 * x8) + (c6 * x6)) + ((c4 * x4) + (c2 * x2));
126  tmp2 = ((((c16 * x4) + (c14 * x2)) + c12) * x12) + (c10 * x10);
127 
128  pol = tmp1 + tmp2;
129  pol = (pol * x) + x;
130 
131  return pol;
132 } /* pol_est_asinsp_i */
133 
134 #ifndef __cplusplus /* FOR PROTECTION PURPOSE - C++ NOT SUPPORTED. */
135 #pragma CODE_SECTION(asinsp_i, ".text:optci");
136 #endif
137 
138 /* ====================================================================== */
139 /* The type of calculation for asin(x) depends on the value of x: */
140 /* */
141 /* for x_abs <= 1/sqrt(2), res = pol_est_asinsp_i (input x) */
142 /* for x_abs > 1/sqrt(2), res = pi/2 - pol_est_asinsp_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 asin(x). */
147 /* ====================================================================== */
148 
149 static inline float MATHLIB_asin_scalar(float x)
150 {
151  const float pi2 = 1.570796327f; /* pi/2 */
152  const float rsqr2 = 0.7071067811f;
153  float s = 1.0f;
154  float res, x_abs, a, temp;
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_asinsp_i(temp); /* a= sqrt(1 - x^2) */
161  temp = pol_est_asinsp_i(a);
162  res = pi2 - temp;
163  }
164  else { /* |x| <= 1/sqrt(2) */
165  res = pol_est_asinsp_i(x_abs);
166  }
167 
168  if (x < 0.0f) {
169  s = -s; /* sign var */
170  }
171 
172  if (x_abs > 1.0f) {
173  res = _itof(0x7FFFFFFFu); /* NaN */
174  }
175 
176  return (res * s); /* restore sign for quadrant 3 & 4*/
177 } /* asinsp_i */
178 
179 #endif /* MATHLIB_ASIN_SCALAR_H_ */
180 
181 /* ======================================================================== */
182 /* End of file: MATHLIB_asin_scalar.h */
183 /* ======================================================================== */
static float pol_est_asinsp_i(float x)
static float sqrtsp_asinsp_i(float x)
static float MATHLIB_asin_scalar(float x)