1 /* ----------------------------------------------------------------------
2 * Copyright (C) 2010-2013 ARM Limited. All rights reserved.
4 * $Date: 17. January 2013
7 * Project: CMSIS DSP Library
10 * Description: Fast sine calculation for floating-point values.
12 * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
17 * - Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
19 * - Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in
21 * the documentation and/or other materials provided with the
23 * - Neither the name of ARM LIMITED nor the names of its contributors
24 * may be used to endorse or promote products derived from this
25 * software without specific prior written permission.
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
30 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
31 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
32 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
33 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
34 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
35 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
39 * -------------------------------------------------------------------- */
44 * @ingroup groupFastMath
50 * Computes the trigonometric sine function using a combination of table lookup
51 * and cubic interpolation. There are separate functions for
52 * Q15, Q31, and floating-point data types.
53 * The input to the floating-point version is in radians while the
54 * fixed-point Q15 and Q31 have a scaled input with the range
55 * [0 +0.9999] mapping to [0 2*pi). The fixed-point range is chosen so that a
56 * value of 2*pi wraps around to 0.
58 * The implementation is based on table lookup using 256 values together with cubic interpolation.
60 * -# Calculation of the nearest integer table index
61 * -# Fetch the four table values a, b, c, and d
62 * -# Compute the fractional portion (fract) of the table index.
63 * -# Calculation of wa, wb, wc, wd
64 * -# The final result equals <code>a*wa + b*wb + c*wc + d*wd</code>
75 * wa=-(1/6)*fract.^3 + (1/2)*fract.^2 - (1/3)*fract;
76 * wb=(1/2)*fract.^3 - fract.^2 - (1/2)*fract + 1;
77 * wc=-(1/2)*fract.^3+(1/2)*fract.^2+fract;
78 * wd=(1/6)*fract.^3 - (1/6)*fract;
90 * Example code for the generation of the floating-point sine table:
93 * for(n = -1; n < (tableSize + 1); n++)
95 * sinTable[n+1]=sin(2*pi*n/tableSize);
98 * where pi value is 3.14159265358979
101 static const float32_t sinTable
[259] = {
102 -0.024541229009628296f
, 0.000000000000000000f
, 0.024541229009628296f
,
103 0.049067676067352295f
, 0.073564566671848297f
, 0.098017141222953796f
,
104 0.122410677373409270f
, 0.146730467677116390f
,
105 0.170961886644363400f
, 0.195090323686599730f
, 0.219101235270500180f
,
106 0.242980182170867920f
, 0.266712754964828490f
, 0.290284663438797000f
,
107 0.313681751489639280f
, 0.336889863014221190f
,
108 0.359895050525665280f
, 0.382683426141738890f
, 0.405241310596466060f
,
109 0.427555084228515630f
, 0.449611335992813110f
, 0.471396744251251220f
,
110 0.492898195981979370f
, 0.514102756977081300f
,
111 0.534997642040252690f
, 0.555570244789123540f
, 0.575808167457580570f
,
112 0.595699310302734380f
, 0.615231573581695560f
, 0.634393274784088130f
,
113 0.653172850608825680f
, 0.671558976173400880f
,
114 0.689540565013885500f
, 0.707106769084930420f
, 0.724247097969055180f
,
115 0.740951120853424070f
, 0.757208824157714840f
, 0.773010432720184330f
,
116 0.788346409797668460f
, 0.803207516670227050f
,
117 0.817584812641143800f
, 0.831469595432281490f
, 0.844853579998016360f
,
118 0.857728600502014160f
, 0.870086967945098880f
, 0.881921291351318360f
,
119 0.893224298954010010f
, 0.903989315032958980f
,
120 0.914209783077239990f
, 0.923879504203796390f
, 0.932992815971374510f
,
121 0.941544055938720700f
, 0.949528157711029050f
, 0.956940352916717530f
,
122 0.963776051998138430f
, 0.970031261444091800f
,
123 0.975702106952667240f
, 0.980785250663757320f
, 0.985277652740478520f
,
124 0.989176511764526370f
, 0.992479562759399410f
, 0.995184719562530520f
,
125 0.997290432453155520f
, 0.998795449733734130f
,
126 0.999698817729949950f
, 1.000000000000000000f
, 0.999698817729949950f
,
127 0.998795449733734130f
, 0.997290432453155520f
, 0.995184719562530520f
,
128 0.992479562759399410f
, 0.989176511764526370f
,
129 0.985277652740478520f
, 0.980785250663757320f
, 0.975702106952667240f
,
130 0.970031261444091800f
, 0.963776051998138430f
, 0.956940352916717530f
,
131 0.949528157711029050f
, 0.941544055938720700f
,
132 0.932992815971374510f
, 0.923879504203796390f
, 0.914209783077239990f
,
133 0.903989315032958980f
, 0.893224298954010010f
, 0.881921291351318360f
,
134 0.870086967945098880f
, 0.857728600502014160f
,
135 0.844853579998016360f
, 0.831469595432281490f
, 0.817584812641143800f
,
136 0.803207516670227050f
, 0.788346409797668460f
, 0.773010432720184330f
,
137 0.757208824157714840f
, 0.740951120853424070f
,
138 0.724247097969055180f
, 0.707106769084930420f
, 0.689540565013885500f
,
139 0.671558976173400880f
, 0.653172850608825680f
, 0.634393274784088130f
,
140 0.615231573581695560f
, 0.595699310302734380f
,
141 0.575808167457580570f
, 0.555570244789123540f
, 0.534997642040252690f
,
142 0.514102756977081300f
, 0.492898195981979370f
, 0.471396744251251220f
,
143 0.449611335992813110f
, 0.427555084228515630f
,
144 0.405241310596466060f
, 0.382683426141738890f
, 0.359895050525665280f
,
145 0.336889863014221190f
, 0.313681751489639280f
, 0.290284663438797000f
,
146 0.266712754964828490f
, 0.242980182170867920f
,
147 0.219101235270500180f
, 0.195090323686599730f
, 0.170961886644363400f
,
148 0.146730467677116390f
, 0.122410677373409270f
, 0.098017141222953796f
,
149 0.073564566671848297f
, 0.049067676067352295f
,
150 0.024541229009628296f
, 0.000000000000000122f
, -0.024541229009628296f
,
151 -0.049067676067352295f
, -0.073564566671848297f
, -0.098017141222953796f
,
152 -0.122410677373409270f
, -0.146730467677116390f
,
153 -0.170961886644363400f
, -0.195090323686599730f
, -0.219101235270500180f
,
154 -0.242980182170867920f
, -0.266712754964828490f
, -0.290284663438797000f
,
155 -0.313681751489639280f
, -0.336889863014221190f
,
156 -0.359895050525665280f
, -0.382683426141738890f
, -0.405241310596466060f
,
157 -0.427555084228515630f
, -0.449611335992813110f
, -0.471396744251251220f
,
158 -0.492898195981979370f
, -0.514102756977081300f
,
159 -0.534997642040252690f
, -0.555570244789123540f
, -0.575808167457580570f
,
160 -0.595699310302734380f
, -0.615231573581695560f
, -0.634393274784088130f
,
161 -0.653172850608825680f
, -0.671558976173400880f
,
162 -0.689540565013885500f
, -0.707106769084930420f
, -0.724247097969055180f
,
163 -0.740951120853424070f
, -0.757208824157714840f
, -0.773010432720184330f
,
164 -0.788346409797668460f
, -0.803207516670227050f
,
165 -0.817584812641143800f
, -0.831469595432281490f
, -0.844853579998016360f
,
166 -0.857728600502014160f
, -0.870086967945098880f
, -0.881921291351318360f
,
167 -0.893224298954010010f
, -0.903989315032958980f
,
168 -0.914209783077239990f
, -0.923879504203796390f
, -0.932992815971374510f
,
169 -0.941544055938720700f
, -0.949528157711029050f
, -0.956940352916717530f
,
170 -0.963776051998138430f
, -0.970031261444091800f
,
171 -0.975702106952667240f
, -0.980785250663757320f
, -0.985277652740478520f
,
172 -0.989176511764526370f
, -0.992479562759399410f
, -0.995184719562530520f
,
173 -0.997290432453155520f
, -0.998795449733734130f
,
174 -0.999698817729949950f
, -1.000000000000000000f
, -0.999698817729949950f
,
175 -0.998795449733734130f
, -0.997290432453155520f
, -0.995184719562530520f
,
176 -0.992479562759399410f
, -0.989176511764526370f
,
177 -0.985277652740478520f
, -0.980785250663757320f
, -0.975702106952667240f
,
178 -0.970031261444091800f
, -0.963776051998138430f
, -0.956940352916717530f
,
179 -0.949528157711029050f
, -0.941544055938720700f
,
180 -0.932992815971374510f
, -0.923879504203796390f
, -0.914209783077239990f
,
181 -0.903989315032958980f
, -0.893224298954010010f
, -0.881921291351318360f
,
182 -0.870086967945098880f
, -0.857728600502014160f
,
183 -0.844853579998016360f
, -0.831469595432281490f
, -0.817584812641143800f
,
184 -0.803207516670227050f
, -0.788346409797668460f
, -0.773010432720184330f
,
185 -0.757208824157714840f
, -0.740951120853424070f
,
186 -0.724247097969055180f
, -0.707106769084930420f
, -0.689540565013885500f
,
187 -0.671558976173400880f
, -0.653172850608825680f
, -0.634393274784088130f
,
188 -0.615231573581695560f
, -0.595699310302734380f
,
189 -0.575808167457580570f
, -0.555570244789123540f
, -0.534997642040252690f
,
190 -0.514102756977081300f
, -0.492898195981979370f
, -0.471396744251251220f
,
191 -0.449611335992813110f
, -0.427555084228515630f
,
192 -0.405241310596466060f
, -0.382683426141738890f
, -0.359895050525665280f
,
193 -0.336889863014221190f
, -0.313681751489639280f
, -0.290284663438797000f
,
194 -0.266712754964828490f
, -0.242980182170867920f
,
195 -0.219101235270500180f
, -0.195090323686599730f
, -0.170961886644363400f
,
196 -0.146730467677116390f
, -0.122410677373409270f
, -0.098017141222953796f
,
197 -0.073564566671848297f
, -0.049067676067352295f
,
198 -0.024541229009628296f
, -0.000000000000000245f
, 0.024541229009628296f
203 * @brief Fast approximation to the trigonometric sine function for floating-point data.
204 * @param[in] x input value in radians.
208 float32_t
arm_sin_f32(
211 float32_t sinVal
, fract
, in
; /* Temporary variables for input, output */
212 int32_t index
; /* Index variable */
213 uint32_t tableSize
= (uint32_t) TABLE_SIZE
; /* Initialise tablesize */
214 float32_t wa
, wb
, wc
, wd
; /* Cubic interpolation coefficients */
215 float32_t a
, b
, c
, d
; /* Four nearest output values */
216 float32_t
*tablePtr
; /* Pointer to table */
218 float32_t fractsq
, fractby2
, fractby6
, fractby3
, fractsqby2
;
219 float32_t oneminusfractby2
;
220 float32_t frby2xfrsq
, frby6xfrsq
;
222 /* input x is in radians */
223 /* Scale the input to [0 1] range from [0 2*PI] , divide input by 2*pi */
224 in
= x
* 0.159154943092f
;
226 /* Calculation of floor value of input */
229 /* Make negative values towards -infinity */
235 /* Map input value to [0 1] */
236 in
= in
- (float32_t
) n
;
238 /* Calculation of index of the table */
239 index
= (uint32_t) (tableSize
* in
);
241 /* fractional value calculation */
242 fract
= ((float32_t
) tableSize
* in
) - (float32_t
) index
;
244 /* Checking min and max index of table */
254 /* Initialise table pointer */
255 tablePtr
= (float32_t
*) & sinTable
[index
];
257 /* Read four nearest values of input value from the sin table */
263 /* Cubic interpolation process */
264 fractsq
= fract
* fract
;
265 fractby2
= fract
* 0.5f
;
266 fractby6
= fract
* 0.166666667f
;
267 fractby3
= fract
* 0.3333333333333f
;
268 fractsqby2
= fractsq
* 0.5f
;
269 frby2xfrsq
= (fractby2
) * fractsq
;
270 frby6xfrsq
= (fractby6
) * fractsq
;
271 oneminusfractby2
= 1.0f
- fractby2
;
272 wb
= fractsqby2
- fractby3
;
273 wc
= (fractsqby2
+ fract
);
274 wa
= wb
- frby6xfrsq
;
275 wb
= frby2xfrsq
- fractsq
;
277 wc
= wc
- frby2xfrsq
;
278 wd
= (frby6xfrsq
) - fractby6
;
279 wb
= wb
+ oneminusfractby2
;
281 /* Calculate sin value */
282 sinVal
= (sinVal
+ (b
* wb
)) + ((c
* wc
) + (d
* wd
));
284 /* Return the output value */
290 * @} end of sin group