QuakeGod
2024-02-25 95322c84888cbe2e92024d4d65698f59b016cb52
提交 | 用户 | age
483170 1 /* ----------------------------------------------------------------------    
Q 2 * Copyright (C) 2010-2014 ARM Limited. All rights reserved.    
3 *    
4 * $Date:        19. March 2015
5 * $Revision:     V.1.4.5
6 *    
7 * Project:         CMSIS DSP Library    
8 * Title:        arm_cmplx_mag_squared_f32.c    
9 *    
10 * Description:    Floating-point complex magnitude squared.    
11 *    
12 * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
13 *  
14 * Redistribution and use in source and binary forms, with or without 
15 * modification, are permitted provided that the following conditions
16 * are met:
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 
22 *     distribution.
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.
26 *
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 * ---------------------------------------------------------------------------- */
40 #include "arm_math.h"
41
42 /**        
43  * @ingroup groupCmplxMath        
44  */
45
46 /**        
47  * @defgroup cmplx_mag_squared Complex Magnitude Squared        
48  *        
49  * Computes the magnitude squared of the elements of a complex data vector.        
50  *       
51  * The <code>pSrc</code> points to the source data and        
52  * <code>pDst</code> points to the where the result should be written.        
53  * <code>numSamples</code> specifies the number of complex samples        
54  * in the input array and the data is stored in an interleaved fashion        
55  * (real, imag, real, imag, ...).        
56  * The input array has a total of <code>2*numSamples</code> values;        
57  * the output array has a total of <code>numSamples</code> values.        
58  *        
59  * The underlying algorithm is used:        
60  *        
61  * <pre>        
62  * for(n=0; n<numSamples; n++) {        
63  *     pDst[n] = pSrc[(2*n)+0]^2 + pSrc[(2*n)+1]^2;        
64  * }        
65  * </pre>        
66  *        
67  * There are separate functions for floating-point, Q15, and Q31 data types.        
68  */
69
70 /**        
71  * @addtogroup cmplx_mag_squared        
72  * @{        
73  */
74
75
76 /**        
77  * @brief  Floating-point complex magnitude squared        
78  * @param[in]  *pSrc points to the complex input vector        
79  * @param[out]  *pDst points to the real output vector        
80  * @param[in]  numSamples number of complex samples in the input vector        
81  * @return none.        
82  */
83
84 void arm_cmplx_mag_squared_f32(
85   float32_t * pSrc,
86   float32_t * pDst,
87   uint32_t numSamples)
88 {
89   float32_t real, imag;                          /* Temporary variables to store real and imaginary values */
90   uint32_t blkCnt;                               /* loop counter */
91
92 #ifndef ARM_MATH_CM0_FAMILY
93   float32_t real1, real2, real3, real4;          /* Temporary variables to hold real values */
94   float32_t imag1, imag2, imag3, imag4;          /* Temporary variables to hold imaginary values */
95   float32_t mul1, mul2, mul3, mul4;              /* Temporary variables */
96   float32_t mul5, mul6, mul7, mul8;              /* Temporary variables */
97   float32_t out1, out2, out3, out4;              /* Temporary variables to hold output values */
98
99   /*loop Unrolling */
100   blkCnt = numSamples >> 2u;
101
102   /* First part of the processing with loop unrolling.  Compute 4 outputs at a time.        
103    ** a second loop below computes the remaining 1 to 3 samples. */
104   while(blkCnt > 0u)
105   {
106     /* C[0] = (A[0] * A[0] + A[1] * A[1]) */
107     /* read real input sample from source buffer */
108     real1 = pSrc[0];
109     /* read imaginary input sample from source buffer */
110     imag1 = pSrc[1];
111
112     /* calculate power of real value */
113     mul1 = real1 * real1;
114
115     /* read real input sample from source buffer */
116     real2 = pSrc[2];
117
118     /* calculate power of imaginary value */
119     mul2 = imag1 * imag1;
120
121     /* read imaginary input sample from source buffer */
122     imag2 = pSrc[3];
123
124     /* calculate power of real value */
125     mul3 = real2 * real2;
126
127     /* read real input sample from source buffer */
128     real3 = pSrc[4];
129
130     /* calculate power of imaginary value */
131     mul4 = imag2 * imag2;
132
133     /* read imaginary input sample from source buffer */
134     imag3 = pSrc[5];
135
136     /* calculate power of real value */
137     mul5 = real3 * real3;
138     /* calculate power of imaginary value */
139     mul6 = imag3 * imag3;
140
141     /* read real input sample from source buffer */
142     real4 = pSrc[6];
143
144     /* accumulate real and imaginary powers */
145     out1 = mul1 + mul2;
146
147     /* read imaginary input sample from source buffer */
148     imag4 = pSrc[7];
149
150     /* accumulate real and imaginary powers */
151     out2 = mul3 + mul4;
152
153     /* calculate power of real value */
154     mul7 = real4 * real4;
155     /* calculate power of imaginary value */
156     mul8 = imag4 * imag4;
157
158     /* store output to destination */
159     pDst[0] = out1;
160
161     /* accumulate real and imaginary powers */
162     out3 = mul5 + mul6;
163
164     /* store output to destination */
165     pDst[1] = out2;
166
167     /* accumulate real and imaginary powers */
168     out4 = mul7 + mul8;
169
170     /* store output to destination */
171     pDst[2] = out3;
172
173     /* increment destination pointer by 8 to process next samples */
174     pSrc += 8u;
175
176     /* store output to destination */
177     pDst[3] = out4;
178
179     /* increment destination pointer by 4 to process next samples */
180     pDst += 4u;
181
182     /* Decrement the loop counter */
183     blkCnt--;
184   }
185
186   /* If the numSamples is not a multiple of 4, compute any remaining output samples here.        
187    ** No loop unrolling is used. */
188   blkCnt = numSamples % 0x4u;
189
190 #else
191
192   /* Run the below code for Cortex-M0 */
193
194   blkCnt = numSamples;
195
196 #endif /* #ifndef ARM_MATH_CM0_FAMILY */
197
198   while(blkCnt > 0u)
199   {
200     /* C[0] = (A[0] * A[0] + A[1] * A[1]) */
201     real = *pSrc++;
202     imag = *pSrc++;
203
204     /* out = (real * real) + (imag * imag) */
205     /* store the result in the destination buffer. */
206     *pDst++ = (real * real) + (imag * imag);
207
208     /* Decrement the loop counter */
209     blkCnt--;
210   }
211 }
212
213 /**        
214  * @} end of cmplx_mag_squared group        
215  */