Vector Optimized Library of Kernels 3.1.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
58static 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
181static 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
290static 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
342static 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 */