GNU Radio Manual and C++ API Reference  3.7.5.1
The Free & Open Software Radio Ecosystem
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
volk_32fc_magnitude_squared_32f.h
Go to the documentation of this file.
1 #ifndef INCLUDED_volk_32fc_magnitude_squared_32f_u_H
2 #define INCLUDED_volk_32fc_magnitude_squared_32f_u_H
3 
4 #include <inttypes.h>
5 #include <stdio.h>
6 #include <math.h>
7 
8 #ifdef LV_HAVE_SSE3
9 #include <pmmintrin.h>
10  /*!
11  \brief Calculates the magnitude squared of the complexVector and stores the results in the magnitudeVector
12  \param complexVector The vector containing the complex input values
13  \param magnitudeVector The vector containing the real output values
14  \param num_points The number of complex values in complexVector to be calculated and stored into cVector
15  */
16 static inline void volk_32fc_magnitude_squared_32f_u_sse3(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){
17  unsigned int number = 0;
18  const unsigned int quarterPoints = num_points / 4;
19 
20  const float* complexVectorPtr = (float*)complexVector;
21  float* magnitudeVectorPtr = magnitudeVector;
22 
23  __m128 cplxValue1, cplxValue2, result;
24  for(;number < quarterPoints; number++){
25  cplxValue1 = _mm_loadu_ps(complexVectorPtr);
26  complexVectorPtr += 4;
27 
28  cplxValue2 = _mm_loadu_ps(complexVectorPtr);
29  complexVectorPtr += 4;
30 
31  cplxValue1 = _mm_mul_ps(cplxValue1, cplxValue1); // Square the values
32  cplxValue2 = _mm_mul_ps(cplxValue2, cplxValue2); // Square the Values
33 
34  result = _mm_hadd_ps(cplxValue1, cplxValue2); // Add the I2 and Q2 values
35 
36  _mm_storeu_ps(magnitudeVectorPtr, result);
37  magnitudeVectorPtr += 4;
38  }
39 
40  number = quarterPoints * 4;
41  for(; number < num_points; number++){
42  float val1Real = *complexVectorPtr++;
43  float val1Imag = *complexVectorPtr++;
44  *magnitudeVectorPtr++ = (val1Real * val1Real) + (val1Imag * val1Imag);
45  }
46 }
47 #endif /* LV_HAVE_SSE3 */
48 
49 #ifdef LV_HAVE_SSE
50 #include <xmmintrin.h>
51  /*!
52  \brief Calculates the magnitude squared of the complexVector and stores the results in the magnitudeVector
53  \param complexVector The vector containing the complex input values
54  \param magnitudeVector The vector containing the real output values
55  \param num_points The number of complex values in complexVector to be calculated and stored into cVector
56  */
57 static inline void volk_32fc_magnitude_squared_32f_u_sse(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){
58  unsigned int number = 0;
59  const unsigned int quarterPoints = num_points / 4;
60 
61  const float* complexVectorPtr = (float*)complexVector;
62  float* magnitudeVectorPtr = magnitudeVector;
63 
64  __m128 cplxValue1, cplxValue2, iValue, qValue, result;
65  for(;number < quarterPoints; number++){
66  cplxValue1 = _mm_loadu_ps(complexVectorPtr);
67  complexVectorPtr += 4;
68 
69  cplxValue2 = _mm_loadu_ps(complexVectorPtr);
70  complexVectorPtr += 4;
71 
72  // Arrange in i1i2i3i4 format
73  iValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(2,0,2,0));
74  // Arrange in q1q2q3q4 format
75  qValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(3,1,3,1));
76 
77  iValue = _mm_mul_ps(iValue, iValue); // Square the I values
78  qValue = _mm_mul_ps(qValue, qValue); // Square the Q Values
79 
80  result = _mm_add_ps(iValue, qValue); // Add the I2 and Q2 values
81 
82  _mm_storeu_ps(magnitudeVectorPtr, result);
83  magnitudeVectorPtr += 4;
84  }
85 
86  number = quarterPoints * 4;
87  for(; number < num_points; number++){
88  float val1Real = *complexVectorPtr++;
89  float val1Imag = *complexVectorPtr++;
90  *magnitudeVectorPtr++ = (val1Real * val1Real) + (val1Imag * val1Imag);
91  }
92 }
93 #endif /* LV_HAVE_SSE */
94 
95 #ifdef LV_HAVE_GENERIC
96  /*!
97  \brief Calculates the magnitude squared of the complexVector and stores the results in the magnitudeVector
98  \param complexVector The vector containing the complex input values
99  \param magnitudeVector The vector containing the real output values
100  \param num_points The number of complex values in complexVector to be calculated and stored into cVector
101  */
102 static inline void volk_32fc_magnitude_squared_32f_generic(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){
103  const float* complexVectorPtr = (float*)complexVector;
104  float* magnitudeVectorPtr = magnitudeVector;
105  unsigned int number = 0;
106  for(number = 0; number < num_points; number++){
107  const float real = *complexVectorPtr++;
108  const float imag = *complexVectorPtr++;
109  *magnitudeVectorPtr++ = (real*real) + (imag*imag);
110  }
111 }
112 #endif /* LV_HAVE_GENERIC */
113 
114 #endif /* INCLUDED_volk_32fc_magnitude_32f_u_H */
115 #ifndef INCLUDED_volk_32fc_magnitude_squared_32f_a_H
116 #define INCLUDED_volk_32fc_magnitude_squared_32f_a_H
117 
118 #include <inttypes.h>
119 #include <stdio.h>
120 #include <math.h>
121 
122 #ifdef LV_HAVE_SSE3
123 #include <pmmintrin.h>
124  /*!
125  \brief Calculates the magnitude squared of the complexVector and stores the results in the magnitudeVector
126  \param complexVector The vector containing the complex input values
127  \param magnitudeVector The vector containing the real output values
128  \param num_points The number of complex values in complexVector to be calculated and stored into cVector
129  */
130 static inline void volk_32fc_magnitude_squared_32f_a_sse3(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){
131  unsigned int number = 0;
132  const unsigned int quarterPoints = num_points / 4;
133 
134  const float* complexVectorPtr = (float*)complexVector;
135  float* magnitudeVectorPtr = magnitudeVector;
136 
137  __m128 cplxValue1, cplxValue2, result;
138  for(;number < quarterPoints; number++){
139  cplxValue1 = _mm_load_ps(complexVectorPtr);
140  complexVectorPtr += 4;
141 
142  cplxValue2 = _mm_load_ps(complexVectorPtr);
143  complexVectorPtr += 4;
144 
145  cplxValue1 = _mm_mul_ps(cplxValue1, cplxValue1); // Square the values
146  cplxValue2 = _mm_mul_ps(cplxValue2, cplxValue2); // Square the Values
147 
148  result = _mm_hadd_ps(cplxValue1, cplxValue2); // Add the I2 and Q2 values
149 
150  _mm_store_ps(magnitudeVectorPtr, result);
151  magnitudeVectorPtr += 4;
152  }
153 
154  number = quarterPoints * 4;
155  for(; number < num_points; number++){
156  float val1Real = *complexVectorPtr++;
157  float val1Imag = *complexVectorPtr++;
158  *magnitudeVectorPtr++ = (val1Real * val1Real) + (val1Imag * val1Imag);
159  }
160 }
161 #endif /* LV_HAVE_SSE3 */
162 
163 #ifdef LV_HAVE_SSE
164 #include <xmmintrin.h>
165  /*!
166  \brief Calculates the magnitude squared of the complexVector and stores the results in the magnitudeVector
167  \param complexVector The vector containing the complex input values
168  \param magnitudeVector The vector containing the real output values
169  \param num_points The number of complex values in complexVector to be calculated and stored into cVector
170  */
171 static inline void volk_32fc_magnitude_squared_32f_a_sse(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){
172  unsigned int number = 0;
173  const unsigned int quarterPoints = num_points / 4;
174 
175  const float* complexVectorPtr = (float*)complexVector;
176  float* magnitudeVectorPtr = magnitudeVector;
177 
178  __m128 cplxValue1, cplxValue2, iValue, qValue, result;
179  for(;number < quarterPoints; number++){
180  cplxValue1 = _mm_load_ps(complexVectorPtr);
181  complexVectorPtr += 4;
182 
183  cplxValue2 = _mm_load_ps(complexVectorPtr);
184  complexVectorPtr += 4;
185 
186  // Arrange in i1i2i3i4 format
187  iValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(2,0,2,0));
188  // Arrange in q1q2q3q4 format
189  qValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(3,1,3,1));
190 
191  iValue = _mm_mul_ps(iValue, iValue); // Square the I values
192  qValue = _mm_mul_ps(qValue, qValue); // Square the Q Values
193 
194  result = _mm_add_ps(iValue, qValue); // Add the I2 and Q2 values
195 
196  _mm_store_ps(magnitudeVectorPtr, result);
197  magnitudeVectorPtr += 4;
198  }
199 
200  number = quarterPoints * 4;
201  for(; number < num_points; number++){
202  float val1Real = *complexVectorPtr++;
203  float val1Imag = *complexVectorPtr++;
204  *magnitudeVectorPtr++ = (val1Real * val1Real) + (val1Imag * val1Imag);
205  }
206 }
207 #endif /* LV_HAVE_SSE */
208 
209 #ifdef LV_HAVE_NEON
210 #include <arm_neon.h>
211 //
212 
213  /*!
214  \brief Calculates the magnitude squared of the complexVector and stores the results in the magnitudeVector
215  \param complexVector The vector containing the complex input values
216  \param magnitudeVector The vector containing the real output values
217  \param num_points The number of complex values in complexVector to be calculated and stored into cVector
218  */
219 static inline void volk_32fc_magnitude_squared_32f_neon(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){
220  unsigned int number = 0;
221  const unsigned int quarterPoints = num_points / 4;
222 
223  const float* complexVectorPtr = (float*)complexVector;
224  float* magnitudeVectorPtr = magnitudeVector;
225 
226  float32x4x2_t cmplx_val;
227  float32x4_t result;
228  for(;number < quarterPoints; number++){
229  cmplx_val = vld2q_f32(complexVectorPtr);
230  complexVectorPtr += 8;
231 
232  cmplx_val.val[0] = vmulq_f32(cmplx_val.val[0], cmplx_val.val[0]); // Square the values
233  cmplx_val.val[1] = vmulq_f32(cmplx_val.val[1], cmplx_val.val[1]); // Square the values
234 
235  result = vaddq_f32(cmplx_val.val[0], cmplx_val.val[1]); // Add the I2 and Q2 values
236 
237  vst1q_f32(magnitudeVectorPtr, result);
238  magnitudeVectorPtr += 4;
239  }
240 
241  number = quarterPoints * 4;
242  for(; number < num_points; number++){
243  float val1Real = *complexVectorPtr++;
244  float val1Imag = *complexVectorPtr++;
245  *magnitudeVectorPtr++ = (val1Real * val1Real) + (val1Imag * val1Imag);
246  }
247 }
248 #endif /* LV_HAVE_NEON */
249 
250 
251 #ifdef LV_HAVE_GENERIC
252  /*!
253  \brief Calculates the magnitude squared of the complexVector and stores the results in the magnitudeVector
254  \param complexVector The vector containing the complex input values
255  \param magnitudeVector The vector containing the real output values
256  \param num_points The number of complex values in complexVector to be calculated and stored into cVector
257  */
258 static inline void volk_32fc_magnitude_squared_32f_a_generic(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){
259  const float* complexVectorPtr = (float*)complexVector;
260  float* magnitudeVectorPtr = magnitudeVector;
261  unsigned int number = 0;
262  for(number = 0; number < num_points; number++){
263  const float real = *complexVectorPtr++;
264  const float imag = *complexVectorPtr++;
265  *magnitudeVectorPtr++ = (real*real) + (imag*imag);
266  }
267 }
268 #endif /* LV_HAVE_GENERIC */
269 
270 #endif /* INCLUDED_volk_32fc_magnitude_32f_a_H */
float complex lv_32fc_t
Definition: volk_complex.h:56