GNU Radio 3.6.5 C++ API

volk_32fc_magnitude_32f_u.h

Go to the documentation of this file.
00001 #ifndef INCLUDED_volk_32fc_magnitude_32f_u_H
00002 #define INCLUDED_volk_32fc_magnitude_32f_u_H
00003 
00004 #include <inttypes.h>
00005 #include <stdio.h>
00006 #include <math.h>
00007 
00008 #ifdef LV_HAVE_SSE3
00009 #include <pmmintrin.h>
00010   /*!
00011     \brief Calculates the magnitude of the complexVector and stores the results in the magnitudeVector
00012     \param complexVector The vector containing the complex input values
00013     \param magnitudeVector The vector containing the real output values
00014     \param num_points The number of complex values in complexVector to be calculated and stored into cVector
00015   */
00016 static inline void volk_32fc_magnitude_32f_u_sse3(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){
00017     unsigned int number = 0;
00018     const unsigned int quarterPoints = num_points / 4;
00019 
00020     const float* complexVectorPtr = (float*)complexVector;
00021     float* magnitudeVectorPtr = magnitudeVector;
00022 
00023     __m128 cplxValue1, cplxValue2, result;
00024     for(;number < quarterPoints; number++){
00025       cplxValue1 = _mm_loadu_ps(complexVectorPtr);
00026       complexVectorPtr += 4;
00027 
00028       cplxValue2 = _mm_loadu_ps(complexVectorPtr);
00029       complexVectorPtr += 4;
00030 
00031       cplxValue1 = _mm_mul_ps(cplxValue1, cplxValue1); // Square the values
00032       cplxValue2 = _mm_mul_ps(cplxValue2, cplxValue2); // Square the Values
00033 
00034       result = _mm_hadd_ps(cplxValue1, cplxValue2); // Add the I2 and Q2 values
00035 
00036       result = _mm_sqrt_ps(result);
00037 
00038       _mm_storeu_ps(magnitudeVectorPtr, result);
00039       magnitudeVectorPtr += 4;
00040     }
00041 
00042     number = quarterPoints * 4;
00043     for(; number < num_points; number++){
00044       float val1Real = *complexVectorPtr++;
00045       float val1Imag = *complexVectorPtr++;
00046       *magnitudeVectorPtr++ = sqrtf((val1Real * val1Real) + (val1Imag * val1Imag));
00047     }
00048 }
00049 #endif /* LV_HAVE_SSE3 */
00050 
00051 #ifdef LV_HAVE_SSE
00052 #include <xmmintrin.h>
00053   /*!
00054     \brief Calculates the magnitude of the complexVector and stores the results in the magnitudeVector
00055     \param complexVector The vector containing the complex input values
00056     \param magnitudeVector The vector containing the real output values
00057     \param num_points The number of complex values in complexVector to be calculated and stored into cVector
00058   */
00059 static inline void volk_32fc_magnitude_32f_u_sse(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){
00060     unsigned int number = 0;
00061     const unsigned int quarterPoints = num_points / 4;
00062 
00063     const float* complexVectorPtr = (float*)complexVector;
00064     float* magnitudeVectorPtr = magnitudeVector;
00065 
00066     __m128 cplxValue1, cplxValue2, iValue, qValue, result;
00067     for(;number < quarterPoints; number++){
00068       cplxValue1 = _mm_loadu_ps(complexVectorPtr);
00069       complexVectorPtr += 4;
00070 
00071       cplxValue2 = _mm_loadu_ps(complexVectorPtr);
00072       complexVectorPtr += 4;
00073 
00074       // Arrange in i1i2i3i4 format
00075       iValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(2,0,2,0));
00076       // Arrange in q1q2q3q4 format
00077       qValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(3,1,3,1));
00078 
00079       iValue = _mm_mul_ps(iValue, iValue); // Square the I values
00080       qValue = _mm_mul_ps(qValue, qValue); // Square the Q Values
00081 
00082       result = _mm_add_ps(iValue, qValue); // Add the I2 and Q2 values
00083 
00084       result = _mm_sqrt_ps(result);
00085 
00086       _mm_storeu_ps(magnitudeVectorPtr, result);
00087       magnitudeVectorPtr += 4;
00088     }
00089 
00090     number = quarterPoints * 4;
00091     for(; number < num_points; number++){
00092        float val1Real = *complexVectorPtr++;
00093        float val1Imag = *complexVectorPtr++;
00094       *magnitudeVectorPtr++ = sqrtf((val1Real * val1Real) + (val1Imag * val1Imag));
00095     }
00096 }
00097 #endif /* LV_HAVE_SSE */
00098 
00099 #ifdef LV_HAVE_GENERIC
00100   /*!
00101     \brief Calculates the magnitude of the complexVector and stores the results in the magnitudeVector
00102     \param complexVector The vector containing the complex input values
00103     \param magnitudeVector The vector containing the real output values
00104     \param num_points The number of complex values in complexVector to be calculated and stored into cVector
00105   */
00106 static inline void volk_32fc_magnitude_32f_u_generic(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){
00107   const float* complexVectorPtr = (float*)complexVector;
00108   float* magnitudeVectorPtr = magnitudeVector;
00109   unsigned int number = 0;
00110   for(number = 0; number < num_points; number++){
00111     const float real = *complexVectorPtr++;
00112     const float imag = *complexVectorPtr++;
00113     *magnitudeVectorPtr++ = sqrtf((real*real) + (imag*imag));
00114   }
00115 }
00116 #endif /* LV_HAVE_GENERIC */
00117 
00118 #endif /* INCLUDED_volk_32fc_magnitude_32f_u_H */