GNU Radio Manual and C++ API Reference  3.7.6.1
The Free & Open Software Radio Ecosystem
volk_32fc_magnitude_squared_32f.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2014 Free Software Foundation, Inc.
4  *
5  * This file is part of GNU Radio
6  *
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  *
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Radio; see the file COPYING. If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 #ifndef INCLUDED_volk_32fc_magnitude_squared_32f_u_H
24 #define INCLUDED_volk_32fc_magnitude_squared_32f_u_H
25 
26 #include <inttypes.h>
27 #include <stdio.h>
28 #include <math.h>
29 
30 #ifdef LV_HAVE_AVX
31 #include <immintrin.h>
32  /*!
33  \brief Calculates the magnitude squared of the complexVector and stores the results in the magnitudeVector
34  \param complexVector The vector containing the complex input values
35  \param magnitudeVector The vector containing the real output values
36  \param num_points The number of complex values in complexVector to be calculated and stored into cVector
37  */
38 static inline void volk_32fc_magnitude_squared_32f_u_avx(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){
39  unsigned int number = 0;
40  const unsigned int eighthPoints = num_points / 8;
41 
42  const float* complexVectorPtr = (float*)complexVector;
43  float* magnitudeVectorPtr = magnitudeVector;
44 
45  __m256 cplxValue1, cplxValue2, complex1, complex2, result;
46  for(;number < eighthPoints; number++){
47  cplxValue1 = _mm256_loadu_ps(complexVectorPtr);
48  complexVectorPtr += 8;
49 
50  cplxValue2 = _mm256_loadu_ps(complexVectorPtr);
51  complexVectorPtr += 8;
52 
53  cplxValue1 = _mm256_mul_ps(cplxValue1, cplxValue1); // Square the values
54  cplxValue2 = _mm256_mul_ps(cplxValue2, cplxValue2); // Square the Values
55 
56  complex1 = _mm256_permute2f128_ps(cplxValue1, cplxValue2, 0x20);
57  complex2 = _mm256_permute2f128_ps(cplxValue1, cplxValue2, 0x31);
58 
59  result = _mm256_hadd_ps(complex1, complex2); // Add the I2 and Q2 values
60 
61  _mm256_storeu_ps(magnitudeVectorPtr, result);
62  magnitudeVectorPtr += 8;
63  }
64 
65  number = eighthPoints * 8;
66  for(; number < num_points; number++){
67  float val1Real = *complexVectorPtr++;
68  float val1Imag = *complexVectorPtr++;
69  *magnitudeVectorPtr++ = (val1Real * val1Real) + (val1Imag * val1Imag);
70  }
71 }
72 #endif /* LV_HAVE_AVX */
73 
74 #ifdef LV_HAVE_SSE3
75 #include <pmmintrin.h>
76  /*!
77  \brief Calculates the magnitude squared of the complexVector and stores the results in the magnitudeVector
78  \param complexVector The vector containing the complex input values
79  \param magnitudeVector The vector containing the real output values
80  \param num_points The number of complex values in complexVector to be calculated and stored into cVector
81  */
82 static inline void volk_32fc_magnitude_squared_32f_u_sse3(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){
83  unsigned int number = 0;
84  const unsigned int quarterPoints = num_points / 4;
85 
86  const float* complexVectorPtr = (float*)complexVector;
87  float* magnitudeVectorPtr = magnitudeVector;
88 
89  __m128 cplxValue1, cplxValue2, result;
90  for(;number < quarterPoints; number++){
91  cplxValue1 = _mm_loadu_ps(complexVectorPtr);
92  complexVectorPtr += 4;
93 
94  cplxValue2 = _mm_loadu_ps(complexVectorPtr);
95  complexVectorPtr += 4;
96 
97  cplxValue1 = _mm_mul_ps(cplxValue1, cplxValue1); // Square the values
98  cplxValue2 = _mm_mul_ps(cplxValue2, cplxValue2); // Square the Values
99 
100  result = _mm_hadd_ps(cplxValue1, cplxValue2); // Add the I2 and Q2 values
101 
102  _mm_storeu_ps(magnitudeVectorPtr, result);
103  magnitudeVectorPtr += 4;
104  }
105 
106  number = quarterPoints * 4;
107  for(; number < num_points; number++){
108  float val1Real = *complexVectorPtr++;
109  float val1Imag = *complexVectorPtr++;
110  *magnitudeVectorPtr++ = (val1Real * val1Real) + (val1Imag * val1Imag);
111  }
112 }
113 #endif /* LV_HAVE_SSE3 */
114 
115 #ifdef LV_HAVE_SSE
116 #include <xmmintrin.h>
117  /*!
118  \brief Calculates the magnitude squared of the complexVector and stores the results in the magnitudeVector
119  \param complexVector The vector containing the complex input values
120  \param magnitudeVector The vector containing the real output values
121  \param num_points The number of complex values in complexVector to be calculated and stored into cVector
122  */
123 static inline void volk_32fc_magnitude_squared_32f_u_sse(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){
124  unsigned int number = 0;
125  const unsigned int quarterPoints = num_points / 4;
126 
127  const float* complexVectorPtr = (float*)complexVector;
128  float* magnitudeVectorPtr = magnitudeVector;
129 
130  __m128 cplxValue1, cplxValue2, iValue, qValue, result;
131  for(;number < quarterPoints; number++){
132  cplxValue1 = _mm_loadu_ps(complexVectorPtr);
133  complexVectorPtr += 4;
134 
135  cplxValue2 = _mm_loadu_ps(complexVectorPtr);
136  complexVectorPtr += 4;
137 
138  // Arrange in i1i2i3i4 format
139  iValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(2,0,2,0));
140  // Arrange in q1q2q3q4 format
141  qValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(3,1,3,1));
142 
143  iValue = _mm_mul_ps(iValue, iValue); // Square the I values
144  qValue = _mm_mul_ps(qValue, qValue); // Square the Q Values
145 
146  result = _mm_add_ps(iValue, qValue); // Add the I2 and Q2 values
147 
148  _mm_storeu_ps(magnitudeVectorPtr, result);
149  magnitudeVectorPtr += 4;
150  }
151 
152  number = quarterPoints * 4;
153  for(; number < num_points; number++){
154  float val1Real = *complexVectorPtr++;
155  float val1Imag = *complexVectorPtr++;
156  *magnitudeVectorPtr++ = (val1Real * val1Real) + (val1Imag * val1Imag);
157  }
158 }
159 #endif /* LV_HAVE_SSE */
160 
161 #ifdef LV_HAVE_GENERIC
162  /*!
163  \brief Calculates the magnitude squared of the complexVector and stores the results in the magnitudeVector
164  \param complexVector The vector containing the complex input values
165  \param magnitudeVector The vector containing the real output values
166  \param num_points The number of complex values in complexVector to be calculated and stored into cVector
167  */
168 static inline void volk_32fc_magnitude_squared_32f_generic(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){
169  const float* complexVectorPtr = (float*)complexVector;
170  float* magnitudeVectorPtr = magnitudeVector;
171  unsigned int number = 0;
172  for(number = 0; number < num_points; number++){
173  const float real = *complexVectorPtr++;
174  const float imag = *complexVectorPtr++;
175  *magnitudeVectorPtr++ = (real*real) + (imag*imag);
176  }
177 }
178 #endif /* LV_HAVE_GENERIC */
179 
180 #endif /* INCLUDED_volk_32fc_magnitude_32f_u_H */
181 #ifndef INCLUDED_volk_32fc_magnitude_squared_32f_a_H
182 #define INCLUDED_volk_32fc_magnitude_squared_32f_a_H
183 
184 #include <inttypes.h>
185 #include <stdio.h>
186 #include <math.h>
187 
188 #ifdef LV_HAVE_AVX
189 #include <immintrin.h>
190  /*!
191  \brief Calculates the magnitude squared of the complexVector and stores the results in the magnitudeVector
192  \param complexVector The vector containing the complex input values
193  \param magnitudeVector The vector containing the real output values
194  \param num_points The number of complex values in complexVector to be calculated and stored into cVector
195  */
196 static inline void volk_32fc_magnitude_squared_32f_a_avx(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){
197  unsigned int number = 0;
198  const unsigned int eighthPoints = num_points / 8;
199 
200  const float* complexVectorPtr = (float*)complexVector;
201  float* magnitudeVectorPtr = magnitudeVector;
202 
203  __m256 cplxValue1, cplxValue2, complex1, complex2, result;
204  for(;number < eighthPoints; number++){
205  cplxValue1 = _mm256_load_ps(complexVectorPtr);
206  complexVectorPtr += 8;
207 
208  cplxValue2 = _mm256_load_ps(complexVectorPtr);
209  complexVectorPtr += 8;
210 
211  cplxValue1 = _mm256_mul_ps(cplxValue1, cplxValue1); // Square the values
212  cplxValue2 = _mm256_mul_ps(cplxValue2, cplxValue2); // Square the Values
213 
214  complex1 = _mm256_permute2f128_ps(cplxValue1, cplxValue2, 0x20);
215  complex2 = _mm256_permute2f128_ps(cplxValue1, cplxValue2, 0x31);
216 
217  result = _mm256_hadd_ps(complex1, complex2); // Add the I2 and Q2 values
218 
219  _mm256_store_ps(magnitudeVectorPtr, result);
220  magnitudeVectorPtr += 8;
221  }
222 
223  number = eighthPoints * 8;
224  for(; number < num_points; number++){
225  float val1Real = *complexVectorPtr++;
226  float val1Imag = *complexVectorPtr++;
227  *magnitudeVectorPtr++ = (val1Real * val1Real) + (val1Imag * val1Imag);
228  }
229 }
230 #endif /* LV_HAVE_AVX */
231 
232 #ifdef LV_HAVE_SSE3
233 #include <pmmintrin.h>
234  /*!
235  \brief Calculates the magnitude squared of the complexVector and stores the results in the magnitudeVector
236  \param complexVector The vector containing the complex input values
237  \param magnitudeVector The vector containing the real output values
238  \param num_points The number of complex values in complexVector to be calculated and stored into cVector
239  */
240 static inline void volk_32fc_magnitude_squared_32f_a_sse3(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){
241  unsigned int number = 0;
242  const unsigned int quarterPoints = num_points / 4;
243 
244  const float* complexVectorPtr = (float*)complexVector;
245  float* magnitudeVectorPtr = magnitudeVector;
246 
247  __m128 cplxValue1, cplxValue2, result;
248  for(;number < quarterPoints; number++){
249  cplxValue1 = _mm_load_ps(complexVectorPtr);
250  complexVectorPtr += 4;
251 
252  cplxValue2 = _mm_load_ps(complexVectorPtr);
253  complexVectorPtr += 4;
254 
255  cplxValue1 = _mm_mul_ps(cplxValue1, cplxValue1); // Square the values
256  cplxValue2 = _mm_mul_ps(cplxValue2, cplxValue2); // Square the Values
257 
258  result = _mm_hadd_ps(cplxValue1, cplxValue2); // Add the I2 and Q2 values
259 
260  _mm_store_ps(magnitudeVectorPtr, result);
261  magnitudeVectorPtr += 4;
262  }
263 
264  number = quarterPoints * 4;
265  for(; number < num_points; number++){
266  float val1Real = *complexVectorPtr++;
267  float val1Imag = *complexVectorPtr++;
268  *magnitudeVectorPtr++ = (val1Real * val1Real) + (val1Imag * val1Imag);
269  }
270 }
271 #endif /* LV_HAVE_SSE3 */
272 
273 #ifdef LV_HAVE_SSE
274 #include <xmmintrin.h>
275  /*!
276  \brief Calculates the magnitude squared of the complexVector and stores the results in the magnitudeVector
277  \param complexVector The vector containing the complex input values
278  \param magnitudeVector The vector containing the real output values
279  \param num_points The number of complex values in complexVector to be calculated and stored into cVector
280  */
281 static inline void volk_32fc_magnitude_squared_32f_a_sse(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){
282  unsigned int number = 0;
283  const unsigned int quarterPoints = num_points / 4;
284 
285  const float* complexVectorPtr = (float*)complexVector;
286  float* magnitudeVectorPtr = magnitudeVector;
287 
288  __m128 cplxValue1, cplxValue2, iValue, qValue, result;
289  for(;number < quarterPoints; number++){
290  cplxValue1 = _mm_load_ps(complexVectorPtr);
291  complexVectorPtr += 4;
292 
293  cplxValue2 = _mm_load_ps(complexVectorPtr);
294  complexVectorPtr += 4;
295 
296  // Arrange in i1i2i3i4 format
297  iValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(2,0,2,0));
298  // Arrange in q1q2q3q4 format
299  qValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(3,1,3,1));
300 
301  iValue = _mm_mul_ps(iValue, iValue); // Square the I values
302  qValue = _mm_mul_ps(qValue, qValue); // Square the Q Values
303 
304  result = _mm_add_ps(iValue, qValue); // Add the I2 and Q2 values
305 
306  _mm_store_ps(magnitudeVectorPtr, result);
307  magnitudeVectorPtr += 4;
308  }
309 
310  number = quarterPoints * 4;
311  for(; number < num_points; number++){
312  float val1Real = *complexVectorPtr++;
313  float val1Imag = *complexVectorPtr++;
314  *magnitudeVectorPtr++ = (val1Real * val1Real) + (val1Imag * val1Imag);
315  }
316 }
317 #endif /* LV_HAVE_SSE */
318 
319 #ifdef LV_HAVE_NEON
320 #include <arm_neon.h>
321 //
322 
323  /*!
324  \brief Calculates the magnitude squared of the complexVector and stores the results in the magnitudeVector
325  \param complexVector The vector containing the complex input values
326  \param magnitudeVector The vector containing the real output values
327  \param num_points The number of complex values in complexVector to be calculated and stored into cVector
328  */
329 static inline void volk_32fc_magnitude_squared_32f_neon(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){
330  unsigned int number = 0;
331  const unsigned int quarterPoints = num_points / 4;
332 
333  const float* complexVectorPtr = (float*)complexVector;
334  float* magnitudeVectorPtr = magnitudeVector;
335 
336  float32x4x2_t cmplx_val;
337  float32x4_t result;
338  for(;number < quarterPoints; number++){
339  cmplx_val = vld2q_f32(complexVectorPtr);
340  complexVectorPtr += 8;
341 
342  cmplx_val.val[0] = vmulq_f32(cmplx_val.val[0], cmplx_val.val[0]); // Square the values
343  cmplx_val.val[1] = vmulq_f32(cmplx_val.val[1], cmplx_val.val[1]); // Square the values
344 
345  result = vaddq_f32(cmplx_val.val[0], cmplx_val.val[1]); // Add the I2 and Q2 values
346 
347  vst1q_f32(magnitudeVectorPtr, result);
348  magnitudeVectorPtr += 4;
349  }
350 
351  number = quarterPoints * 4;
352  for(; number < num_points; number++){
353  float val1Real = *complexVectorPtr++;
354  float val1Imag = *complexVectorPtr++;
355  *magnitudeVectorPtr++ = (val1Real * val1Real) + (val1Imag * val1Imag);
356  }
357 }
358 #endif /* LV_HAVE_NEON */
359 
360 
361 #ifdef LV_HAVE_GENERIC
362  /*!
363  \brief Calculates the magnitude squared of the complexVector and stores the results in the magnitudeVector
364  \param complexVector The vector containing the complex input values
365  \param magnitudeVector The vector containing the real output values
366  \param num_points The number of complex values in complexVector to be calculated and stored into cVector
367  */
368 static inline void volk_32fc_magnitude_squared_32f_a_generic(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){
369  const float* complexVectorPtr = (float*)complexVector;
370  float* magnitudeVectorPtr = magnitudeVector;
371  unsigned int number = 0;
372  for(number = 0; number < num_points; number++){
373  const float real = *complexVectorPtr++;
374  const float imag = *complexVectorPtr++;
375  *magnitudeVectorPtr++ = (real*real) + (imag*imag);
376  }
377 }
378 #endif /* LV_HAVE_GENERIC */
379 
380 #endif /* INCLUDED_volk_32fc_magnitude_32f_a_H */
float complex lv_32fc_t
Definition: volk_complex.h:56