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