GNU Radio 3.6.5 C++ API

volk_32fc_magnitude_squared_32f_a.h

Go to the documentation of this file.
00001 #ifndef INCLUDED_volk_32fc_magnitude_squared_32f_a_H
00002 #define INCLUDED_volk_32fc_magnitude_squared_32f_a_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 squared 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_squared_32f_a_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_load_ps(complexVectorPtr);
00026       complexVectorPtr += 4;
00027 
00028       cplxValue2 = _mm_load_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       _mm_store_ps(magnitudeVectorPtr, result);
00037       magnitudeVectorPtr += 4;
00038     }
00039 
00040     number = quarterPoints * 4;
00041     for(; number < num_points; number++){
00042       float val1Real = *complexVectorPtr++;
00043       float val1Imag = *complexVectorPtr++;
00044       *magnitudeVectorPtr++ = (val1Real * val1Real) + (val1Imag * val1Imag);
00045     }
00046 }
00047 #endif /* LV_HAVE_SSE3 */
00048 
00049 #ifdef LV_HAVE_SSE
00050 #include <xmmintrin.h>
00051   /*!
00052     \brief Calculates the magnitude squared of the complexVector and stores the results in the magnitudeVector
00053     \param complexVector The vector containing the complex input values
00054     \param magnitudeVector The vector containing the real output values
00055     \param num_points The number of complex values in complexVector to be calculated and stored into cVector
00056   */
00057 static inline void volk_32fc_magnitude_squared_32f_a_sse(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){
00058     unsigned int number = 0;
00059     const unsigned int quarterPoints = num_points / 4;
00060 
00061     const float* complexVectorPtr = (float*)complexVector;
00062     float* magnitudeVectorPtr = magnitudeVector;
00063 
00064     __m128 cplxValue1, cplxValue2, iValue, qValue, result;
00065     for(;number < quarterPoints; number++){
00066       cplxValue1 = _mm_load_ps(complexVectorPtr);
00067       complexVectorPtr += 4;
00068 
00069       cplxValue2 = _mm_load_ps(complexVectorPtr);
00070       complexVectorPtr += 4;
00071 
00072       // Arrange in i1i2i3i4 format
00073       iValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(2,0,2,0));
00074       // Arrange in q1q2q3q4 format
00075       qValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(3,1,3,1));
00076 
00077       iValue = _mm_mul_ps(iValue, iValue); // Square the I values
00078       qValue = _mm_mul_ps(qValue, qValue); // Square the Q Values
00079 
00080       result = _mm_add_ps(iValue, qValue); // Add the I2 and Q2 values
00081 
00082       _mm_store_ps(magnitudeVectorPtr, result);
00083       magnitudeVectorPtr += 4;
00084     }
00085 
00086     number = quarterPoints * 4;
00087     for(; number < num_points; number++){
00088        float val1Real = *complexVectorPtr++;
00089        float val1Imag = *complexVectorPtr++;
00090       *magnitudeVectorPtr++ = (val1Real * val1Real) + (val1Imag * val1Imag);
00091     }
00092 }
00093 #endif /* LV_HAVE_SSE */
00094 
00095 #ifdef LV_HAVE_GENERIC
00096   /*!
00097     \brief Calculates the magnitude squared of the complexVector and stores the results in the magnitudeVector
00098     \param complexVector The vector containing the complex input values
00099     \param magnitudeVector The vector containing the real output values
00100     \param num_points The number of complex values in complexVector to be calculated and stored into cVector
00101   */
00102 static inline void volk_32fc_magnitude_squared_32f_a_generic(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){
00103   const float* complexVectorPtr = (float*)complexVector;
00104   float* magnitudeVectorPtr = magnitudeVector;
00105   unsigned int number = 0;
00106   for(number = 0; number < num_points; number++){
00107     const float real = *complexVectorPtr++;
00108     const float imag = *complexVectorPtr++;
00109     *magnitudeVectorPtr++ = (real*real) + (imag*imag);
00110   }
00111 }
00112 #endif /* LV_HAVE_GENERIC */
00113 
00114 #endif /* INCLUDED_volk_32fc_magnitude_32f_a_H */