本帖最后由 硬汉Eric2013 于 2015-6-17 15:06 编辑
17.2 复数点乘ComplexDotProduct
17.2.1 arm_cmplx_dot_prod_f32公式描述: realResult=0; imagResult=0; for(n=0;n realResult += pSrcA[(2*n)+0]*pSrcB[(2*n)+0] -pSrcA[(2*n)+1]*pSrcB[(2*n)+1]; imagResult += pSrcA[(2*n)+0]*pSrcB[(2*n)+1] +pSrcA[(2*n)+1]*pSrcB[(2*n)+0]; } 函数定义如下: voidarm_cmplx_dot_prod_f32(float32_t * pSrcA, float32_t * pSrcB, uint32_tnumSamples, float32_t * realResult, float32_t * imagResult) 参数定义: *pSrcA points to the first input vector *pSrcB points to the second input vector numSamples number of complex samples in each vector *realResult real part of the result returned here *imagResult imaginary part of the result returnedhere 注意事项: 1. 数组pSrc和pDst中存储的数据格式是(实部,虚部,实部,虚部……………),一定要按照这个顺序存储数据,比如数据1-j,j,2+3j这个三个数在数组中的存储格式就是:pSrc[6] = {1, -1, 0, 1, 2, 3}。(注意第三个数据是0)。输出结果的实部和虚部是分开的。 17.2.2 arm_cmplx_dot_prod_q31公式描述: realResult=0; imagResult=0; for(n=0;n realResult += pSrcA[(2*n)+0]*pSrcB[(2*n)+0] -pSrcA[(2*n)+1]*pSrcB[(2*n)+1]; imagResult += pSrcA[(2*n)+0]*pSrcB[(2*n)+1] +pSrcA[(2*n)+1]*pSrcB[(2*n)+0]; } 函数定义如下: voidarm_cmplx_dot_prod_q31(q31_t * pSrcA, q31_t * pSrcB, uint32_t numSamples, q63_t * realResult,q63_t * imagResult) 参数定义: *pSrcA points to the first input vector *pSrcB points to the second input vector numSamples number of complex samples in each vector *realResult real part of the result returned here *imagResult imaginary part of the result returnedhere 注意事项: 1. 这个函数的内部使用了64累加器,1.31格式数据乘以1.31格式数据结果就是2.62格式,这里我们将所得结果右移14位,那么数据就是16.48格式。由于加数是不支持饱和运算,所以只要numSamples的个数小于32768就不会有溢出的危险。 2. 数组pSrc和pDst中存储的数据格式是(实部,虚部,实部,虚部……………),一定要按照这个顺序存储数据,比如数据1-j,j,2+3j这个三个数在数组中的存储格式就是:pSrc[6] = {1, -1, 0, 1, 2, 3}。(注意第三个数据是0)。输出结果的实部和虚部是分开的。 17.2.3 arm_cmplx_dot_prod_q15公式描述: realResult=0; imagResult=0; for(n=0; n realResult += pSrcA[(2*n)+0]*pSrcB[(2*n)+0] -pSrcA[(2*n)+1]*pSrcB[(2*n)+1]; imagResult += pSrcA[(2*n)+0]*pSrcB[(2*n)+1] +pSrcA[(2*n)+1]*pSrcB[(2*n)+0]; } 函数定义如下: voidarm_cmplx_dot_prod_q15(q15_t * pSrcA, q15_t * pSrcB, uint32_t numSamples, q31_t *realResult, q31_t * imagResult) 参数定义: *pSrcA points to the first input vector *pSrcB points to the second input vector numSamples number of complex samples in each vector *realResult real part of the result returned here *imagResult imaginary part of the result returnedhere 注意事项: 1. 这个函数的内部使用了64累加器,1.31格式数据乘以1.31格式数据结果就是2.62格式,这里我们将所得结果右移14位,那么数据就是16.48格式。由于加数是不支持饱和运算,所以只要numSamples的个数小于32768就不会有溢出的危险。 2. 数组pSrc和pDst中存储的数据格式是(实部,虚部,实部,虚部……………),一定要按照这个顺序存储数据,比如数据1-j,j,2+3j这个三个数在数组中的存储格式就是:pSrc[6] = {1, -1, 0, 1, 2, 3}。(注意第三个数据是0)。输出结果的实部和虚部是分开的。 17.2.4 实例讲解实验目的: 1. 学习ComplexMathFunctions中复数点乘的实现 实验内容: 1. 按下按键K2, 串口打印函数DSP_CmplxDotProduct的输出结果 实验现象: 通过窗口上位机软件SecureCRT(V5光盘里面有此软件)查看打印信息现象如下:
程序设计:
- /*
- *********************************************************************************************************
- * 函 数 名: DSP_CmplxDotProduct
- * 功能说明: 浮点数cos和sin计算
- * 形 参:无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void DSP_CmplxDotProduct(void)
- {
- uint8_t i;
- float32_t pSrcA[10] = {1.1f, 1.1f, 2.1f, 2.1f, 3.1f, 3.1f, 4.1f, 4.1f, 5.1f, 5.1f};
- float32_t pSrcB[10] = {1.1f, 1.1f, 2.1f, 2.1f, 3.1f, 3.1f, 4.1f, 4.1f, 5.1f, 5.1f};
- float32_t realResult;
- float32_t imagResult;
-
- q31_t pSrcA1[10] = {1*268435456, 1*268435456, 2*268435456, 2*268435456, 3*268435456, 3*268435456,
- 4*268435456, 4*268435456, 5*268435456, 5*268435456};
- q31_t pSrcB1[10] = {1*268435456, 1*268435456, 2*268435456, 2*268435456, 3*268435456, 3*268435456,
- 4*268435456, 4*268435456, 5*268435456, 5*268435456};
- q63_t realResult1;
- q63_t imagResult1;
-
- q15_t pSrcA2[10] = {5000, 10000, 15000, 20000, 25000, 5000, 10000, 15000, 20000, 25000};
- q15_t pSrcB2[10] = {5000, 10000, 15000, 20000, 25000, 5000, 10000, 15000, 20000, 25000};
- q31_t realResult2;
- q31_t imagResult2;
-
- /***浮点数点乘*******************************************************************************/
- arm_cmplx_dot_prod_f32(pSrcA, pSrcB, 5, &realResult, &imagResult); (1)
- printf("arm_cmplx_dot_prod_f32:realResult = %f imagResult = %frn", realResult, imagResult);
-
- /***定点数点乘Q31*******************************************************************************/
- arm_cmplx_dot_prod_q31(pSrcA1, pSrcB1, 5, &realResult1, &imagResult1); (2)
- printf("arm_cmplx_dot_prod_q31:realResult1 = %lld imagResult1 = %lldrn", realResult1, imagResult1);
-
- /***定点数点乘Q15*******************************************************************************/
- arm_cmplx_dot_prod_q15(pSrcA2, pSrcB2, 5, &realResult2, &imagResult2); (3)
- printf("arm_cmplx_dot_prod_q15:realResult2 = %d imagResult2 = %drn", realResult2, imagResult2);
- }
复制代码
1. 讲解复数的点乘以前,要明白简单的复数乘法的实现,也就是前面的那个公式描述: realResult=0; imagResult=0; for(n=0; n realResult +=pSrcA[(2*n)+0]*pSrcB[(2*n)+0] - pSrcA[(2*n)+1]*pSrcB[(2*n)+1]; imagResult +=pSrcA[(2*n)+0]*pSrcB[(2*n)+1] + pSrcA[(2*n)+1]*pSrcB[(2*n)+0]; } 用代数式来表示复数乘法就是: (a+bi)(c+di)=(ac-bd)+(ad+bc)i 这里求解的是浮点数的点乘。 2. Q31格式定点数的点乘。 3. Q15格式定点数的点乘。
|