1 /******************************************************************************
2  * @file     fast_math_functions.h
3  * @brief    Public header file for CMSIS DSP Library
4  * @version  V1.10.0
5  * @date     08 July 2021
6  * Target Processor: Cortex-M and Cortex-A cores
7  ******************************************************************************/
8 /*
9  * Copyright (c) 2010-2020 Arm Limited or its affiliates. All rights reserved.
10  *
11  * SPDX-License-Identifier: Apache-2.0
12  *
13  * Licensed under the Apache License, Version 2.0 (the License); you may
14  * not use this file except in compliance with the License.
15  * You may obtain a copy of the License at
16  *
17  * www.apache.org/licenses/LICENSE-2.0
18  *
19  * Unless required by applicable law or agreed to in writing, software
20  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
21  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22  * See the License for the specific language governing permissions and
23  * limitations under the License.
24  */
25 
26 
27 #ifndef _FAST_MATH_FUNCTIONS_H_
28 #define _FAST_MATH_FUNCTIONS_H_
29 
30 #include "arm_math_types.h"
31 #include "arm_math_memory.h"
32 
33 #include "dsp/none.h"
34 #include "dsp/utils.h"
35 
36 #include "dsp/basic_math_functions.h"
37 
38 #include <math.h>
39 
40 #ifdef   __cplusplus
41 extern "C"
42 {
43 #endif
44 
45   /**
46    * @brief Macros required for SINE and COSINE Fast math approximations
47    */
48 
49 #define FAST_MATH_TABLE_SIZE  512
50 #define FAST_MATH_Q31_SHIFT   (32 - 10)
51 #define FAST_MATH_Q15_SHIFT   (16 - 10)
52 
53 #ifndef PI
54   #define PI               3.14159265358979f
55 #endif
56 
57 #ifndef PI_F64
58   #define PI_F64 3.14159265358979323846
59 #endif
60 
61 
62 
63 /**
64  * @defgroup groupFastMath Fast Math Functions
65  * This set of functions provides a fast approximation to sine, cosine, and square root.
66  * As compared to most of the other functions in the CMSIS math library, the fast math functions
67  * operate on individual values and not arrays.
68  * There are separate functions for Q15, Q31, and floating-point data.
69  *
70  */
71 
72 
73    /**
74    * @brief  Fast approximation to the trigonometric sine function for floating-point data.
75    * @param[in] x  input value in radians.
76    * @return  sin(x).
77    */
78   float32_t arm_sin_f32(
79   float32_t x);
80 
81 
82   /**
83    * @brief  Fast approximation to the trigonometric sine function for Q31 data.
84    * @param[in] x  Scaled input value in radians.
85    * @return  sin(x).
86    */
87   q31_t arm_sin_q31(
88   q31_t x);
89 
90   /**
91    * @brief  Fast approximation to the trigonometric sine function for Q15 data.
92    * @param[in] x  Scaled input value in radians.
93    * @return  sin(x).
94    */
95   q15_t arm_sin_q15(
96   q15_t x);
97 
98 
99   /**
100    * @brief  Fast approximation to the trigonometric cosine function for floating-point data.
101    * @param[in] x  input value in radians.
102    * @return  cos(x).
103    */
104   float32_t arm_cos_f32(
105   float32_t x);
106 
107 
108   /**
109    * @brief Fast approximation to the trigonometric cosine function for Q31 data.
110    * @param[in] x  Scaled input value in radians.
111    * @return  cos(x).
112    */
113   q31_t arm_cos_q31(
114   q31_t x);
115 
116 
117   /**
118    * @brief  Fast approximation to the trigonometric cosine function for Q15 data.
119    * @param[in] x  Scaled input value in radians.
120    * @return  cos(x).
121    */
122   q15_t arm_cos_q15(
123   q15_t x);
124 
125 
126 /**
127   @brief         Floating-point vector of log values.
128   @param[in]     pSrc       points to the input vector
129   @param[out]    pDst       points to the output vector
130   @param[in]     blockSize  number of samples in each vector
131  */
132   void arm_vlog_f32(
133   const float32_t * pSrc,
134         float32_t * pDst,
135         uint32_t blockSize);
136 
137 
138 
139 /**
140   @brief         Floating-point vector of log values.
141   @param[in]     pSrc       points to the input vector
142   @param[out]    pDst       points to the output vector
143   @param[in]     blockSize  number of samples in each vector
144  */
145   void arm_vlog_f64(
146   const float64_t * pSrc,
147         float64_t * pDst,
148         uint32_t blockSize);
149 
150 
151 
152   /**
153    * @brief  q31 vector of log values.
154    * @param[in]     pSrc       points to the input vector in q31
155    * @param[out]    pDst       points to the output vector in q5.26
156    * @param[in]     blockSize  number of samples in each vector
157    */
158   void arm_vlog_q31(const q31_t * pSrc,
159         q31_t * pDst,
160         uint32_t blockSize);
161 
162   /**
163    * @brief  q15 vector of log values.
164    * @param[in]     pSrc       points to the input vector in q15
165    * @param[out]    pDst       points to the output vector in q4.11
166    * @param[in]     blockSize  number of samples in each vector
167    */
168   void arm_vlog_q15(const q15_t * pSrc,
169         q15_t * pDst,
170         uint32_t blockSize);
171 
172 
173 
174 /**
175   @brief         Floating-point vector of exp values.
176   @param[in]     pSrc       points to the input vector
177   @param[out]    pDst       points to the output vector
178   @param[in]     blockSize  number of samples in each vector
179  */
180   void arm_vexp_f32(
181   const float32_t * pSrc,
182         float32_t * pDst,
183         uint32_t blockSize);
184 
185 
186 
187 /**
188   @brief         Floating-point vector of exp values.
189   @param[in]     pSrc       points to the input vector
190   @param[out]    pDst       points to the output vector
191   @param[in]     blockSize  number of samples in each vector
192  */
193   void arm_vexp_f64(
194   const float64_t * pSrc,
195 		float64_t * pDst,
196 		uint32_t blockSize);
197 
198 
199 
200  /**
201    * @defgroup SQRT Square Root
202    *
203    * Computes the square root of a number.
204    * There are separate functions for Q15, Q31, and floating-point data types.
205    * The square root function is computed using the Newton-Raphson algorithm.
206    * This is an iterative algorithm of the form:
207    * <pre>
208    *      x1 = x0 - f(x0)/f'(x0)
209    * </pre>
210    * where <code>x1</code> is the current estimate,
211    * <code>x0</code> is the previous estimate, and
212    * <code>f'(x0)</code> is the derivative of <code>f()</code> evaluated at <code>x0</code>.
213    * For the square root function, the algorithm reduces to:
214    * <pre>
215    *     x0 = in/2                         [initial guess]
216    *     x1 = 1/2 * ( x0 + in / x0)        [each iteration]
217    * </pre>
218    */
219 
220 
221   /**
222    * @addtogroup SQRT
223    * @{
224    */
225 
226 /**
227   @brief         Floating-point square root function.
228   @param[in]     in    input value
229   @param[out]    pOut  square root of input value
230   @return        execution status
231                    - \ref ARM_MATH_SUCCESS        : input value is positive
232                    - \ref ARM_MATH_ARGUMENT_ERROR : input value is negative; *pOut is set to 0
233  */
arm_sqrt_f32(const float32_t in,float32_t * pOut)234 __STATIC_FORCEINLINE arm_status arm_sqrt_f32(
235   const float32_t in,
236   float32_t * pOut)
237   {
238     if (in >= 0.0f)
239     {
240 #if defined ( __CC_ARM )
241   #if defined __TARGET_FPU_VFP
242       *pOut = __sqrtf(in);
243   #else
244       *pOut = sqrtf(in);
245   #endif
246 
247 #elif defined ( __ICCARM__ )
248   #if defined __ARMVFP__
249       __ASM("VSQRT.F32 %0,%1" : "=t"(*pOut) : "t"(in));
250   #else
251       *pOut = sqrtf(in);
252   #endif
253 
254 #elif defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 )
255       *pOut = _sqrtf(in);
256 #elif defined(__GNUC_PYTHON__)
257       *pOut = sqrtf(in);
258 #elif defined ( __GNUC__ )
259   #if defined (__VFP_FP__) && !defined(__SOFTFP__)
260       __ASM("VSQRT.F32 %0,%1" : "=t"(*pOut) : "t"(in));
261   #else
262       *pOut = sqrtf(in);
263   #endif
264 #else
265       *pOut = sqrtf(in);
266 #endif
267 
268       return (ARM_MATH_SUCCESS);
269     }
270     else
271     {
272       *pOut = 0.0f;
273       return (ARM_MATH_ARGUMENT_ERROR);
274     }
275   }
276 
277 
278 /**
279   @brief         Q31 square root function.
280   @param[in]     in    input value.  The range of the input value is [0 +1) or 0x00000000 to 0x7FFFFFFF
281   @param[out]    pOut  points to square root of input value
282   @return        execution status
283                    - \ref ARM_MATH_SUCCESS        : input value is positive
284                    - \ref ARM_MATH_ARGUMENT_ERROR : input value is negative; *pOut is set to 0
285  */
286 arm_status arm_sqrt_q31(
287   q31_t in,
288   q31_t * pOut);
289 
290 
291 /**
292   @brief         Q15 square root function.
293   @param[in]     in    input value.  The range of the input value is [0 +1) or 0x0000 to 0x7FFF
294   @param[out]    pOut  points to square root of input value
295   @return        execution status
296                    - \ref ARM_MATH_SUCCESS        : input value is positive
297                    - \ref ARM_MATH_ARGUMENT_ERROR : input value is negative; *pOut is set to 0
298  */
299 arm_status arm_sqrt_q15(
300   q15_t in,
301   q15_t * pOut);
302 
303 
304 
305   /**
306    * @} end of SQRT group
307    */
308 
309   /**
310   @brief         Fixed point division
311   @param[in]     numerator    Numerator
312   @param[in]     denominator  Denominator
313   @param[out]    quotient     Quotient value normalized between -1.0 and 1.0
314   @param[out]    shift        Shift left value to get the unnormalized quotient
315   @return        error status
316 
317   When dividing by 0, an error ARM_MATH_NANINF is returned. And the quotient is forced
318   to the saturated negative or positive value.
319  */
320 
321 arm_status arm_divide_q15(q15_t numerator,
322   q15_t denominator,
323   q15_t *quotient,
324   int16_t *shift);
325 
326   /**
327   @brief         Fixed point division
328   @param[in]     numerator    Numerator
329   @param[in]     denominator  Denominator
330   @param[out]    quotient     Quotient value normalized between -1.0 and 1.0
331   @param[out]    shift        Shift left value to get the unnormalized quotient
332   @return        error status
333 
334   When dividing by 0, an error ARM_MATH_NANINF is returned. And the quotient is forced
335   to the saturated negative or positive value.
336  */
337 
338 arm_status arm_divide_q31(q31_t numerator,
339   q31_t denominator,
340   q31_t *quotient,
341   int16_t *shift);
342 
343 
344 
345   /**
346      @brief  Arc tangent in radian of y/x using sign of x and y to determine right quadrant.
347      @param[in]   y  y coordinate
348      @param[in]   x  x coordinate
349      @param[out]  result  Result
350      @return  error status.
351    */
352   arm_status arm_atan2_f32(float32_t y,float32_t x,float32_t *result);
353 
354 
355   /**
356      @brief  Arc tangent in radian of y/x using sign of x and y to determine right quadrant.
357      @param[in]   y  y coordinate
358      @param[in]   x  x coordinate
359      @param[out]  result  Result in Q2.29
360      @return  error status.
361    */
362   arm_status arm_atan2_q31(q31_t y,q31_t x,q31_t *result);
363 
364   /**
365      @brief  Arc tangent in radian of y/x using sign of x and y to determine right quadrant.
366      @param[in]   y  y coordinate
367      @param[in]   x  x coordinate
368      @param[out]  result  Result in Q2.13
369      @return  error status.
370    */
371   arm_status arm_atan2_q15(q15_t y,q15_t x,q15_t *result);
372 
373 #ifdef   __cplusplus
374 }
375 #endif
376 
377 #endif /* ifndef _FAST_MATH_FUNCTIONS_H_ */
378