[学习笔记]ARM_DSP库——基础函数(绝对值、求和、乘法、点乘)

ARM_DSP库——基础函数

绝对值、求和、乘法、点乘

一、绝对值(Vector Absolute Value)

这部分函数主要用于求绝对值,公式描述如下:

pDst[n] = abs(pSrc[n]),   0 <= n < blockSize;

特别注意,这部分函数支持目标指针和源指针指向相同的缓冲区。

函数arm_abs_f32

用于求32位浮点数的绝对值。

函数arm_abs_q31

用于求32位定点数的绝对值。

函数arm_abs_q15

用于求16位定点数的绝对值。

函数arm_abs_q7

用于求8位定点数的绝对值。

  • 函数参数:
    • 第 1 个参数是原数据地址。
    • 第 2 个参数是求绝对值后目的数据地址。
    • 第 3 个参数转换的数据个数,这里是指的定点数个数。
    • 函数形参的源地址和目的地址可以使用同一个缓冲。

使用举例

#define log_i printf
void DSP_ABS(void)
{
	float32_t pSrc;
	float32_t pDst;

	q31_t pSrc1;
	q31_t pDst1;

	q15_t pSrc2;
	q15_t pDst2;

	q7_t pSrc3;
	q7_t pDst3;

	/* 求绝对值 */
	pSrc -= 1.23f;
	arm_abs_f32(&pSrc, &pDst, 1);
	log_i("arm_abs_f32 = %f\r\n", pDst);

	pSrc1 -= 1;
	arm_abs_q31(&pSrc1, &pDst1, 1);
	log_i("arm_abs_q31 = %d\r\n", pDst1);

	pSrc2 = -32768;
	arm_abs_q15(&pSrc2, &pDst2, 1);
	log_i("arm_abs_q15 = %d\r\n", pDst2);

	pSrc3 = 127;
	arm_abs_q7(&pSrc3, &pDst3, 1);
	log_i("arm_abs_q7 = %d\r\n", pDst3);
	log_i("**********************\r\n");
}

二、求和(Vector Addition)

这部分函数主要用于求和,公式描述如下:

pDst[n] = pSrcA[n] + pSrcB[n],   0 <= n < blockSize;

函数arm_add_f32

用于求两个 32 位浮点数的和。

函数 arm_add_q31

用于求两个32位定点数的和。

函数 arm_add_q15

用于求两个 16 位定点数的和。

函数 arm_add_q7

用于求两个 8 位定点数的和。

  • 函数参数:
    • 第 1 个参数是加数地址。
    • 第 2 个参数是被加数地址。
    • 第 3 个参数是和地址。
    • 第 4 个参数是定点数个数,其实就是执行加法的次数。

使用举例

#define log_i printf
void DSP_Add(void)
{
	float32_t pSrcA;
	float32_t pSrcB;
	float32_t pDst;

	q31_t pSrcA1;
	q31_t pSrcB1;
	q31_t pDst1;

	q15_t pSrcA2;
	q15_t pSrcB2;
	q15_t pDst2;

	q7_t pSrcA3;
	q7_t pSrcB3;
	q7_t pDst3;

	/* 求和 */
	pSrcA = 0.1f;
	pSrcB = 0.2f;
	arm_add_f32(&pSrcA, &pSrcB, &pDst, 1);
	log_i("arm_add_f32 = %f\r\n", pDst);

	pSrcA1 = 1;
	pSrcB1 = 1;
	arm_add_q31(&pSrcA1, &pSrcB1, &pDst1, 1);
	log_i("arm_add_q31 = %d\r\n", pDst1);

	pSrcA2 = 2;
	pSrcB2 = 2;
	arm_add_q15(&pSrcA2, &pSrcB2, &pDst2, 1);
	log_i("arm_add_q15 = %d\r\n", pDst2);

	pSrcA3 = 30;
	pSrcB3 = 120;
	arm_add_q7(&pSrcA3, &pSrcB3, &pDst3, 1);
	log_i("arm_add_q7 = %d\r\n", pDst3);
	log_i("**********************\r\n");
}

三、乘法(Vector Multiplication)

这部分函数主要用于乘法,公式描述如下:

pDst[n] = pSrcA[n] * pSrcB[n],   0 <= n < blockSize;

函数 arm_mult_f32

用于求32位浮点数的乘法。

函数 arm_mult_q31

用于求32位定点数的乘法。

函数 arm_mult_q15

用于求16位定点数的乘法。

函数 arm_mult_q7

用于求8位定点数的乘法。

  • 函数参数:
    • 第 1 个参数是乘数地址。
    • 第 2 个参数是被乘数地址。
    • 第 3 个参数是结果地址。
    • 第 4 个参数是数据块大小,其实就是执行乘法的次数。

使用举例

 void DSP_Multiplication(void)
{
 float32_t pSrcA[5] = {1.0f,1.0f,1.0f,1.0f,1.0f};
 float32_t pSrcB[5] = {1.0f,1.0f,1.0f,1.0f,1.0f};
 float32_t pDst[5];

 q31_t pSrcA1[5] = {1,1,1,1,1};
 q31_t pSrcB1[5] = {1,1,1,1,1};
 q31_t pDst1[5];

 q15_t pSrcA2[5] = {1,1,1,1,1};
 q15_t pSrcB2[5] = {1,1,1,1,1};
 q15_t pDst2[5];

 q7_t  pSrcA3[5] = {0x70,1,1,1,1};
 q7_t  pSrcB3[5] = {0x7f,1,1,1,1};
 q7_t  pDst3[5];


 /*求乘积*********************************/
 pSrcA[0] += 1.1f;
 arm_mult_f32(pSrcA, pSrcB, pDst, 5);
 printf("arm_mult_f32 = %f\r\n", pDst[0]);

 pSrcA1[0] += 1;
 arm_mult_q31(pSrcA1, pSrcB1, pDst1, 5);
 printf("arm_mult_q31 = %d\r\n", pDst1[0]);

 pSrcA2[0] += 1;
 arm_mult_q15(pSrcA2, pSrcB2, pDst2, 5);
 printf("arm_mult_q15 = %d\r\n", pDst2[0]);

 pSrcA3[0] += 1;
 arm_mult_q7(pSrcA3, pSrcB3, pDst3, 5);
 printf("arm_mult_q7 = %d\r\n", pDst3[0]);
 printf("*********************\r\n");
}

四、点乘(Vector Dot Product)

这部分函数主要用于点乘,公式描述如下:

sum = pSrcA[0]*pSrcB[0] + pSrcA[1]*pSrcB[1] + ... + pSrcA[blockSize-1]*pSrcB[blockSize-1];

函数 arm_dot_prod_f32

用于求32位浮点数的点乘。

函数 arm_dot_prod_q31

用于求32位定点数的点乘。

函数 arm_dot_prod_q15

用于求32位定点数的点乘。

函数 arm_dot_prod_q7

用于求8位定点数的点乘。

  • 函数参数:
    • 第 1 个参数是乘数地址。
    • 第 2 个参数是被乘数地址。
    • 第 3 个参数是定点数个数,其实就是执行点乘的次数。
    • 第 4 个参数是结果地址。

使用举例

void DSP_DotProduct(void)
{
	float32_t pSrcA[5] = {1.0f,1.0f,1.0f,1.0f,1.0f};
	float32_t pSrcB[5] = {1.0f,1.0f,1.0f,1.0f,1.0f};
	float32_t result;

	q31_t pSrcA1[5] = {0x7ffffff0,1,1,1,1};
	q31_t pSrcB1[5] = {1,1,1,1,1};
	q63_t result1;

	q15_t pSrcA2[5] = {1,1,1,1,1};
	q15_t pSrcB2[5] = {1,1,1,1,1};
	q63_t result2;

	q7_t  pSrcA3[5] = {1,1,1,1,1};
	q7_t  pSrcB3[5] = {1,1,1,1,1};
	q31_t result3;


	/* 求点乘 */
	arm_dot_prod_f32(pSrcA, pSrcB, 5, &result);
	log_i("arm_dot_prod_f32 = %f\r\n", result);

	arm_dot_prod_q31(pSrcA1, pSrcB1, 5, &result1);
	log_i("arm_dot_prod_q31 = %lld\r\n", result1);

	arm_dot_prod_q15(pSrcA2, pSrcB2, 5, &result2);
	log_i("arm_dot_prod_q15 = %lld\r\n", result2);

	arm_dot_prod_q7(pSrcA3, pSrcB3, 5, &result3);
	log_i("arm_dot_prod_q7 = %d\r\n", result3);
	log_i("*************************\r\n");
}
  • 2
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值