Vector Optimized Library of Kernels  2.4
Architecture-tuned implementations of math kernels
volk_32f_s32f_calc_spectral_noise_floor_32f.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2012, 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 
61 #ifndef INCLUDED_volk_32f_s32f_calc_spectral_noise_floor_32f_a_H
62 #define INCLUDED_volk_32f_s32f_calc_spectral_noise_floor_32f_a_H
63 
64 #include <inttypes.h>
65 #include <stdio.h>
66 #include <volk/volk_common.h>
67 
68 #ifdef LV_HAVE_AVX
69 #include <immintrin.h>
70 
71 static inline void
73  const float* realDataPoints,
74  const float spectralExclusionValue,
75  const unsigned int num_points)
76 {
77  unsigned int number = 0;
78  const unsigned int eighthPoints = num_points / 8;
79 
80  const float* dataPointsPtr = realDataPoints;
81  __VOLK_ATTR_ALIGNED(32) float avgPointsVector[8];
82 
83  __m256 dataPointsVal;
84  __m256 avgPointsVal = _mm256_setzero_ps();
85  // Calculate the sum (for mean) for all points
86  for (; number < eighthPoints; number++) {
87 
88  dataPointsVal = _mm256_load_ps(dataPointsPtr);
89 
90  dataPointsPtr += 8;
91 
92  avgPointsVal = _mm256_add_ps(avgPointsVal, dataPointsVal);
93  }
94 
95  _mm256_store_ps(avgPointsVector, avgPointsVal);
96 
97  float sumMean = 0.0;
98  sumMean += avgPointsVector[0];
99  sumMean += avgPointsVector[1];
100  sumMean += avgPointsVector[2];
101  sumMean += avgPointsVector[3];
102  sumMean += avgPointsVector[4];
103  sumMean += avgPointsVector[5];
104  sumMean += avgPointsVector[6];
105  sumMean += avgPointsVector[7];
106 
107  number = eighthPoints * 8;
108  for (; number < num_points; number++) {
109  sumMean += realDataPoints[number];
110  }
111 
112  // calculate the spectral mean
113  // +20 because for the comparison below we only want to throw out bins
114  // that are significantly higher (and would, thus, affect the mean more
115  const float meanAmplitude = (sumMean / ((float)num_points)) + spectralExclusionValue;
116 
117  dataPointsPtr = realDataPoints; // Reset the dataPointsPtr
118  __m256 vMeanAmplitudeVector = _mm256_set1_ps(meanAmplitude);
119  __m256 vOnesVector = _mm256_set1_ps(1.0);
120  __m256 vValidBinCount = _mm256_setzero_ps();
121  avgPointsVal = _mm256_setzero_ps();
122  __m256 compareMask;
123  number = 0;
124  // Calculate the sum (for mean) for any points which do NOT exceed the mean amplitude
125  for (; number < eighthPoints; number++) {
126 
127  dataPointsVal = _mm256_load_ps(dataPointsPtr);
128 
129  dataPointsPtr += 8;
130 
131  // Identify which items do not exceed the mean amplitude
132  compareMask = _mm256_cmp_ps(dataPointsVal, vMeanAmplitudeVector, _CMP_LE_OQ);
133 
134  // Mask off the items that exceed the mean amplitude and add the avg Points that
135  // do not exceed the mean amplitude
136  avgPointsVal =
137  _mm256_add_ps(avgPointsVal, _mm256_and_ps(compareMask, dataPointsVal));
138 
139  // Count the number of bins which do not exceed the mean amplitude
140  vValidBinCount =
141  _mm256_add_ps(vValidBinCount, _mm256_and_ps(compareMask, vOnesVector));
142  }
143 
144  // Calculate the mean from the remaining data points
145  _mm256_store_ps(avgPointsVector, avgPointsVal);
146 
147  sumMean = 0.0;
148  sumMean += avgPointsVector[0];
149  sumMean += avgPointsVector[1];
150  sumMean += avgPointsVector[2];
151  sumMean += avgPointsVector[3];
152  sumMean += avgPointsVector[4];
153  sumMean += avgPointsVector[5];
154  sumMean += avgPointsVector[6];
155  sumMean += avgPointsVector[7];
156 
157  // Calculate the number of valid bins from the remaining count
158  __VOLK_ATTR_ALIGNED(32) float validBinCountVector[8];
159  _mm256_store_ps(validBinCountVector, vValidBinCount);
160 
161  float validBinCount = 0;
162  validBinCount += validBinCountVector[0];
163  validBinCount += validBinCountVector[1];
164  validBinCount += validBinCountVector[2];
165  validBinCount += validBinCountVector[3];
166  validBinCount += validBinCountVector[4];
167  validBinCount += validBinCountVector[5];
168  validBinCount += validBinCountVector[6];
169  validBinCount += validBinCountVector[7];
170 
171  number = eighthPoints * 8;
172  for (; number < num_points; number++) {
173  if (realDataPoints[number] <= meanAmplitude) {
174  sumMean += realDataPoints[number];
175  validBinCount += 1.0;
176  }
177  }
178 
179  float localNoiseFloorAmplitude = 0;
180  if (validBinCount > 0.0) {
181  localNoiseFloorAmplitude = sumMean / validBinCount;
182  } else {
183  localNoiseFloorAmplitude =
184  meanAmplitude; // For the odd case that all the amplitudes are equal...
185  }
186 
187  *noiseFloorAmplitude = localNoiseFloorAmplitude;
188 }
189 #endif /* LV_HAVE_AVX */
190 
191 #ifdef LV_HAVE_SSE
192 #include <xmmintrin.h>
193 
194 static inline void
196  const float* realDataPoints,
197  const float spectralExclusionValue,
198  const unsigned int num_points)
199 {
200  unsigned int number = 0;
201  const unsigned int quarterPoints = num_points / 4;
202 
203  const float* dataPointsPtr = realDataPoints;
204  __VOLK_ATTR_ALIGNED(16) float avgPointsVector[4];
205 
206  __m128 dataPointsVal;
207  __m128 avgPointsVal = _mm_setzero_ps();
208  // Calculate the sum (for mean) for all points
209  for (; number < quarterPoints; number++) {
210 
211  dataPointsVal = _mm_load_ps(dataPointsPtr);
212 
213  dataPointsPtr += 4;
214 
215  avgPointsVal = _mm_add_ps(avgPointsVal, dataPointsVal);
216  }
217 
218  _mm_store_ps(avgPointsVector, avgPointsVal);
219 
220  float sumMean = 0.0;
221  sumMean += avgPointsVector[0];
222  sumMean += avgPointsVector[1];
223  sumMean += avgPointsVector[2];
224  sumMean += avgPointsVector[3];
225 
226  number = quarterPoints * 4;
227  for (; number < num_points; number++) {
228  sumMean += realDataPoints[number];
229  }
230 
231  // calculate the spectral mean
232  // +20 because for the comparison below we only want to throw out bins
233  // that are significantly higher (and would, thus, affect the mean more
234  const float meanAmplitude = (sumMean / ((float)num_points)) + spectralExclusionValue;
235 
236  dataPointsPtr = realDataPoints; // Reset the dataPointsPtr
237  __m128 vMeanAmplitudeVector = _mm_set_ps1(meanAmplitude);
238  __m128 vOnesVector = _mm_set_ps1(1.0);
239  __m128 vValidBinCount = _mm_setzero_ps();
240  avgPointsVal = _mm_setzero_ps();
241  __m128 compareMask;
242  number = 0;
243  // Calculate the sum (for mean) for any points which do NOT exceed the mean amplitude
244  for (; number < quarterPoints; number++) {
245 
246  dataPointsVal = _mm_load_ps(dataPointsPtr);
247 
248  dataPointsPtr += 4;
249 
250  // Identify which items do not exceed the mean amplitude
251  compareMask = _mm_cmple_ps(dataPointsVal, vMeanAmplitudeVector);
252 
253  // Mask off the items that exceed the mean amplitude and add the avg Points that
254  // do not exceed the mean amplitude
255  avgPointsVal = _mm_add_ps(avgPointsVal, _mm_and_ps(compareMask, dataPointsVal));
256 
257  // Count the number of bins which do not exceed the mean amplitude
258  vValidBinCount = _mm_add_ps(vValidBinCount, _mm_and_ps(compareMask, vOnesVector));
259  }
260 
261  // Calculate the mean from the remaining data points
262  _mm_store_ps(avgPointsVector, avgPointsVal);
263 
264  sumMean = 0.0;
265  sumMean += avgPointsVector[0];
266  sumMean += avgPointsVector[1];
267  sumMean += avgPointsVector[2];
268  sumMean += avgPointsVector[3];
269 
270  // Calculate the number of valid bins from the remaining count
271  __VOLK_ATTR_ALIGNED(16) float validBinCountVector[4];
272  _mm_store_ps(validBinCountVector, vValidBinCount);
273 
274  float validBinCount = 0;
275  validBinCount += validBinCountVector[0];
276  validBinCount += validBinCountVector[1];
277  validBinCount += validBinCountVector[2];
278  validBinCount += validBinCountVector[3];
279 
280  number = quarterPoints * 4;
281  for (; number < num_points; number++) {
282  if (realDataPoints[number] <= meanAmplitude) {
283  sumMean += realDataPoints[number];
284  validBinCount += 1.0;
285  }
286  }
287 
288  float localNoiseFloorAmplitude = 0;
289  if (validBinCount > 0.0) {
290  localNoiseFloorAmplitude = sumMean / validBinCount;
291  } else {
292  localNoiseFloorAmplitude =
293  meanAmplitude; // For the odd case that all the amplitudes are equal...
294  }
295 
296  *noiseFloorAmplitude = localNoiseFloorAmplitude;
297 }
298 #endif /* LV_HAVE_SSE */
299 
300 
301 #ifdef LV_HAVE_GENERIC
302 
303 static inline void
305  const float* realDataPoints,
306  const float spectralExclusionValue,
307  const unsigned int num_points)
308 {
309  float sumMean = 0.0;
310  unsigned int number;
311  // find the sum (for mean), etc
312  for (number = 0; number < num_points; number++) {
313  // sum (for mean)
314  sumMean += realDataPoints[number];
315  }
316 
317  // calculate the spectral mean
318  // +20 because for the comparison below we only want to throw out bins
319  // that are significantly higher (and would, thus, affect the mean more)
320  const float meanAmplitude = (sumMean / num_points) + spectralExclusionValue;
321 
322  // now throw out any bins higher than the mean
323  sumMean = 0.0;
324  unsigned int newNumDataPoints = num_points;
325  for (number = 0; number < num_points; number++) {
326  if (realDataPoints[number] <= meanAmplitude)
327  sumMean += realDataPoints[number];
328  else
329  newNumDataPoints--;
330  }
331 
332  float localNoiseFloorAmplitude = 0.0;
333  if (newNumDataPoints == 0) // in the odd case that all
334  localNoiseFloorAmplitude = meanAmplitude; // amplitudes are equal!
335  else
336  localNoiseFloorAmplitude = sumMean / ((float)newNumDataPoints);
337 
338  *noiseFloorAmplitude = localNoiseFloorAmplitude;
339 }
340 #endif /* LV_HAVE_GENERIC */
341 
342 
343 #endif /* INCLUDED_volk_32f_s32f_calc_spectral_noise_floor_32f_a_H */
344 
345 #ifndef INCLUDED_volk_32f_s32f_calc_spectral_noise_floor_32f_u_H
346 #define INCLUDED_volk_32f_s32f_calc_spectral_noise_floor_32f_u_H
347 
348 #include <inttypes.h>
349 #include <stdio.h>
350 #include <volk/volk_common.h>
351 
352 #ifdef LV_HAVE_AVX
353 #include <immintrin.h>
354 
355 static inline void
357  const float* realDataPoints,
358  const float spectralExclusionValue,
359  const unsigned int num_points)
360 {
361  unsigned int number = 0;
362  const unsigned int eighthPoints = num_points / 8;
363 
364  const float* dataPointsPtr = realDataPoints;
365  __VOLK_ATTR_ALIGNED(16) float avgPointsVector[8];
366 
367  __m256 dataPointsVal;
368  __m256 avgPointsVal = _mm256_setzero_ps();
369  // Calculate the sum (for mean) for all points
370  for (; number < eighthPoints; number++) {
371 
372  dataPointsVal = _mm256_loadu_ps(dataPointsPtr);
373 
374  dataPointsPtr += 8;
375 
376  avgPointsVal = _mm256_add_ps(avgPointsVal, dataPointsVal);
377  }
378 
379  _mm256_storeu_ps(avgPointsVector, avgPointsVal);
380 
381  float sumMean = 0.0;
382  sumMean += avgPointsVector[0];
383  sumMean += avgPointsVector[1];
384  sumMean += avgPointsVector[2];
385  sumMean += avgPointsVector[3];
386  sumMean += avgPointsVector[4];
387  sumMean += avgPointsVector[5];
388  sumMean += avgPointsVector[6];
389  sumMean += avgPointsVector[7];
390 
391  number = eighthPoints * 8;
392  for (; number < num_points; number++) {
393  sumMean += realDataPoints[number];
394  }
395 
396  // calculate the spectral mean
397  // +20 because for the comparison below we only want to throw out bins
398  // that are significantly higher (and would, thus, affect the mean more
399  const float meanAmplitude = (sumMean / ((float)num_points)) + spectralExclusionValue;
400 
401  dataPointsPtr = realDataPoints; // Reset the dataPointsPtr
402  __m256 vMeanAmplitudeVector = _mm256_set1_ps(meanAmplitude);
403  __m256 vOnesVector = _mm256_set1_ps(1.0);
404  __m256 vValidBinCount = _mm256_setzero_ps();
405  avgPointsVal = _mm256_setzero_ps();
406  __m256 compareMask;
407  number = 0;
408  // Calculate the sum (for mean) for any points which do NOT exceed the mean amplitude
409  for (; number < eighthPoints; number++) {
410 
411  dataPointsVal = _mm256_loadu_ps(dataPointsPtr);
412 
413  dataPointsPtr += 8;
414 
415  // Identify which items do not exceed the mean amplitude
416  compareMask = _mm256_cmp_ps(dataPointsVal, vMeanAmplitudeVector, _CMP_LE_OQ);
417 
418  // Mask off the items that exceed the mean amplitude and add the avg Points that
419  // do not exceed the mean amplitude
420  avgPointsVal =
421  _mm256_add_ps(avgPointsVal, _mm256_and_ps(compareMask, dataPointsVal));
422 
423  // Count the number of bins which do not exceed the mean amplitude
424  vValidBinCount =
425  _mm256_add_ps(vValidBinCount, _mm256_and_ps(compareMask, vOnesVector));
426  }
427 
428  // Calculate the mean from the remaining data points
429  _mm256_storeu_ps(avgPointsVector, avgPointsVal);
430 
431  sumMean = 0.0;
432  sumMean += avgPointsVector[0];
433  sumMean += avgPointsVector[1];
434  sumMean += avgPointsVector[2];
435  sumMean += avgPointsVector[3];
436  sumMean += avgPointsVector[4];
437  sumMean += avgPointsVector[5];
438  sumMean += avgPointsVector[6];
439  sumMean += avgPointsVector[7];
440 
441  // Calculate the number of valid bins from the remaining count
442  __VOLK_ATTR_ALIGNED(16) float validBinCountVector[8];
443  _mm256_storeu_ps(validBinCountVector, vValidBinCount);
444 
445  float validBinCount = 0;
446  validBinCount += validBinCountVector[0];
447  validBinCount += validBinCountVector[1];
448  validBinCount += validBinCountVector[2];
449  validBinCount += validBinCountVector[3];
450  validBinCount += validBinCountVector[4];
451  validBinCount += validBinCountVector[5];
452  validBinCount += validBinCountVector[6];
453  validBinCount += validBinCountVector[7];
454 
455  number = eighthPoints * 8;
456  for (; number < num_points; number++) {
457  if (realDataPoints[number] <= meanAmplitude) {
458  sumMean += realDataPoints[number];
459  validBinCount += 1.0;
460  }
461  }
462 
463  float localNoiseFloorAmplitude = 0;
464  if (validBinCount > 0.0) {
465  localNoiseFloorAmplitude = sumMean / validBinCount;
466  } else {
467  localNoiseFloorAmplitude =
468  meanAmplitude; // For the odd case that all the amplitudes are equal...
469  }
470 
471  *noiseFloorAmplitude = localNoiseFloorAmplitude;
472 }
473 #endif /* LV_HAVE_AVX */
474 #endif /* INCLUDED_volk_32f_s32f_calc_spectral_noise_floor_32f_u_H */
volk_32f_s32f_calc_spectral_noise_floor_32f_a_sse
static void volk_32f_s32f_calc_spectral_noise_floor_32f_a_sse(float *noiseFloorAmplitude, const float *realDataPoints, const float spectralExclusionValue, const unsigned int num_points)
Definition: volk_32f_s32f_calc_spectral_noise_floor_32f.h:195
__VOLK_ATTR_ALIGNED
#define __VOLK_ATTR_ALIGNED(x)
Definition: volk_common.h:56
volk_32f_s32f_calc_spectral_noise_floor_32f_generic
static void volk_32f_s32f_calc_spectral_noise_floor_32f_generic(float *noiseFloorAmplitude, const float *realDataPoints, const float spectralExclusionValue, const unsigned int num_points)
Definition: volk_32f_s32f_calc_spectral_noise_floor_32f.h:304
volk_32f_s32f_calc_spectral_noise_floor_32f_a_avx
static void volk_32f_s32f_calc_spectral_noise_floor_32f_a_avx(float *noiseFloorAmplitude, const float *realDataPoints, const float spectralExclusionValue, const unsigned int num_points)
Definition: volk_32f_s32f_calc_spectral_noise_floor_32f.h:72
volk_common.h
volk_32f_s32f_calc_spectral_noise_floor_32f_u_avx
static void volk_32f_s32f_calc_spectral_noise_floor_32f_u_avx(float *noiseFloorAmplitude, const float *realDataPoints, const float spectralExclusionValue, const unsigned int num_points)
Definition: volk_32f_s32f_calc_spectral_noise_floor_32f.h:356