GNU Radio 3.4.0 C++ API
volk_32fc_s32f_power_32fc_a16.h
Go to the documentation of this file.
00001 #ifndef INCLUDED_volk_32fc_s32f_power_32fc_a16_H
00002 #define INCLUDED_volk_32fc_s32f_power_32fc_a16_H
00003 
00004 #include <inttypes.h>
00005 #include <stdio.h>
00006 
00007 #if LV_HAVE_SSE
00008 #include <xmmintrin.h>
00009 
00010 #if LV_HAVE_LIB_SIMDMATH
00011 #include <simdmath.h>
00012 #endif /* LV_HAVE_LIB_SIMDMATH */
00013 
00014 /*!
00015   \brief Takes each the input complex vector value to the specified power and stores the results in the return vector
00016   \param cVector The vector where the results will be stored
00017   \param aVector The complex vector of values to be taken to a power
00018   \param power The power value to be applied to each data point
00019   \param num_points The number of values in aVector to be taken to the specified power level and stored into cVector
00020 */
00021 static inline void volk_32fc_s32f_power_32fc_a16_sse(lv_32fc_t* cVector, const lv_32fc_t* aVector, const float power, unsigned int num_points){
00022   unsigned int number = 0;
00023   const unsigned int quarterPoints = num_points / 4;
00024   
00025   lv_32fc_t* cPtr = cVector;
00026   const lv_32fc_t* aPtr = aVector;
00027 
00028 #if LV_HAVE_LIB_SIMDMATH
00029   __m128 vPower = _mm_set_ps1(power);
00030   
00031   __m128 cplxValue1, cplxValue2, magnitude, phase, iValue, qValue;
00032   for(;number < quarterPoints; number++){
00033     
00034     cplxValue1 = _mm_load_ps((float*)aPtr); 
00035     aPtr += 2;
00036     
00037     cplxValue2 = _mm_load_ps((float*)aPtr); 
00038     aPtr += 2;
00039     
00040     // Convert to polar coordinates
00041     
00042     // Arrange in i1i2i3i4 format
00043     iValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(2,0,2,0));
00044     // Arrange in q1q2q3q4 format
00045     qValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(3,1,3,1));
00046     
00047     phase = atan2f4(qValue, iValue); // Calculate the Phase
00048     
00049     magnitude = _mm_sqrt_ps(_mm_add_ps(_mm_mul_ps(iValue, iValue), _mm_mul_ps(qValue, qValue))); // Calculate the magnitude by square rooting the added I2 and Q2 values
00050     
00051     // Now calculate the power of the polar coordinate data
00052     magnitude = powf4(magnitude, vPower); // Take the magnitude to the specified power
00053     
00054     phase = _mm_mul_ps(phase, vPower); // Multiply the phase by the specified power
00055     
00056     // Convert back to cartesian coordinates
00057     iValue = _mm_mul_ps( cosf4(phase), magnitude); // Multiply the cos of the phase by the magnitude
00058     qValue = _mm_mul_ps( sinf4(phase), magnitude); // Multiply the sin of the phase by the magnitude
00059     
00060     cplxValue1 = _mm_unpacklo_ps(iValue, qValue); // Interleave the lower two i & q values
00061     cplxValue2 = _mm_unpackhi_ps(iValue, qValue); // Interleave the upper two i & q values
00062     
00063     _mm_store_ps((float*)cPtr,cplxValue1); // Store the results back into the C container
00064     
00065     cPtr += 2;
00066     
00067     _mm_store_ps((float*)cPtr,cplxValue2); // Store the results back into the C container
00068     
00069     cPtr += 2;
00070   }
00071   
00072   number = quarterPoints * 4;
00073 #endif /* LV_HAVE_LIB_SIMDMATH */
00074 
00075   lv_32fc_t complexPower;
00076   ((float*)&complexPower)[0] = power;
00077   ((float*)&complexPower)[1] = 0;
00078   for(;number < num_points; number++){
00079     *cPtr++ = lv_cpow((*aPtr++), complexPower);
00080   }
00081 }
00082 #endif /* LV_HAVE_SSE */
00083 
00084 #if LV_HAVE_GENERIC
00085   /*!
00086     \brief Takes each the input complex vector value to the specified power and stores the results in the return vector
00087     \param cVector The vector where the results will be stored
00088     \param aVector The complex vector of values to be taken to a power
00089     \param power The power value to be applied to each data point
00090     \param num_points The number of values in aVector to be taken to the specified power level and stored into cVector
00091   */
00092 static inline void volk_32fc_s32f_power_32fc_a16_generic(lv_32fc_t* cVector, const lv_32fc_t* aVector, const float power, unsigned int num_points){
00093   lv_32fc_t* cPtr = cVector;
00094   const lv_32fc_t* aPtr = aVector;
00095   unsigned int number = 0;
00096   lv_32fc_t complexPower;
00097   ((float*)&complexPower)[0] = power;
00098   ((float*)&complexPower)[1] = 0.0;
00099 
00100   for(number = 0; number < num_points; number++){
00101     *cPtr++ = lv_cpow((*aPtr++), complexPower);
00102   }
00103 }
00104 #endif /* LV_HAVE_GENERIC */
00105 
00106 
00107 
00108 
00109 #endif /* INCLUDED_volk_32fc_s32f_power_32fc_a16_H */