【STM32F429的DSP教程】第21章DSP矩阵运算-加法,减法和
逆矩阵
第21章      DSP矩阵运算-加法,减法和逆矩阵
本期教程主要讲解矩阵运算中的初始化,加法,逆矩阵和减法。
21.1 初学者重要提⽰
21.2 DSP基础运算指令
21.3 矩阵初始化(MatInit)
21.4 矩阵加法(MatAdd)
21.5 矩阵减法(MatSub)
21.6 逆矩阵(MatInverse)
21.7 实验例程说明(MDK)
21.8 实验例程说明(IAR)
21.9 总结
21.1 初学者重要提⽰
1. 复数运算⽐较重要,后⾯FFT章节要⽤到,如果印象不深的话,需要温习下⾼数知识了。
2.  ARM提供的DSP库逆矩阵求法有局限性,通过Matlab验证是可以求逆矩阵的,⽽DSP库却不能正确求解。
21.2 DSP基础运算指令
本章⽤到的DSP指令在前⾯章节都已经讲解过。
21.3 矩阵初始化(MatInit)
主要⽤于矩阵结构体成员的初始化,浮点格式矩阵结构体定义如下:
typedef struct
{
uint16_t numRows;    // 矩阵⾏数.
uint16_t numCols;    // 矩阵列数
float32_t *pData;    // 矩阵地址
} arm_matrix_instance_f32
定点数Q31格式矩阵结构体定义如下:
typedef struct
{
uint16_t numRows;    //矩阵⾏数
uint16_t numCols;    //矩阵列数
q31_t *pData;        //矩阵地址
} arm_matrix_instance_q31;
定点数Q15格式矩阵结构体定义如下:
typedef struct
{
uint16_t numRows;    //矩阵⾏数
uint16_t numCols;    //矩阵列数
q15_t *pData;        //矩阵地址
} arm_matrix_instance_q15;
21.3.1 函数arm_mat_init_f32
函数原型:
void arm_mat_init_f32(
arm_matrix_instance_f32 * S,
uint16_t nRows,
uint16_t nColumns,
float32_t * pData)
函数描述:
这个函数⽤于浮点格式的矩阵数据初始化。
函数参数:
第1个参数是arm_matrix_instance_f32类型矩阵结构体指针变量。
第2个参数是矩阵⾏数。
第3个参数是矩阵列数。
第4个参数是矩阵数据地址。
21.3.2 函数arm_mat_init_q31
函数原型:
void arm_mat_init_f32(
arm_matrix_instance_f32 * S,
uint16_t nRows,
uint16_t nColumns,
float32_t * pData)
函数描述:
这个函数⽤于定点数Q31格式的矩阵数据初始化。
函数参数:
第1个参数是arm_matrix_instance_q31类型矩阵结构体指针变量。
第2个参数是矩阵⾏数。
第3个参数是矩阵列数。
第4个参数是矩阵数据地址。
21.3.3 函数arm_mat_init_q15
函数原型:
void arm_mat_init_f32(
arm_matrix_instance_f32 * S,
uint16_t nRows,
uint16_t nColumns,
float32_t * pData)
函数描述:
这个函数⽤于定点数Q15格式的矩阵数据初始化。
函数参数:
第1个参数是arm_matrix_instance_q15类型矩阵结构体指针变量。
第2个参数是矩阵⾏数。
第3个参数是矩阵列数。
第4个参数是矩阵数据地址。
21.3.4 使⽤举例
程序设计:
/*
********************************************************************************************************* *    函数名: DSP_MatInit
*    功能说明: 矩阵数据初始化
*    形参:⽆
*    返回值: ⽆
********************************************************************************************************* */
static void DSP_MatInit(void)
{
uint8_t i;
/****浮点数数组******************************************************************/
float32_t pDataA[9] = {1.1f, 1.1f, 2.1f, 2.1f, 3.1f, 3.1f, 4.1f, 4.1f, 5.1f};
arm_matrix_instance_f32 pSrcA; //3⾏3列数据
/****定点数Q31数组******************************************************************/
q31_t pDataA1[9] = {1, 1, 2, 2, 3, 3, 4, 4, 5};
arm_matrix_instance_q31 pSrcA1; //3⾏3列数据
/
****定点数Q15数组******************************************************************/
q15_t pDataA2[9] = {1, 1, 2, 2, 3, 3, 4, 4, 5};
arm_matrix_instance_q15 pSrcA2; //3⾏3列数据
/****浮点数***********************************************************************/
printf("****浮点数******************************************\r\n");
arm_mat_init_f32(&pSrcA, 3,3, pDataA);
for(i = 0; i < 9; i++)
{
printf("pDataA[%d] = %f\r\n", i, pDataA[i]);
}
/****定点数Q31***********************************************************************/
printf("****浮点数******************************************\r\n");
arm_mat_init_q31(&pSrcA1, 3,3, pDataA1);
for(i = 0; i < 9; i++)
{
printf("pDataA1[%d] = %d\r\n", i, pDataA1[i]);
}
/****定点数Q15***********************************************************************/
printf("****浮点数******************************************\r\n");
arm_mat_init_q15(&pSrcA2, 3,3, pDataA2);
for(i = 0; i < 9; i++)
{
printf("pDataA2[%d] = %d\r\n", i, pDataA2[i]);
}
}
实验现象(按下K1按键后串⼝打印模平⽅):
21.4 矩阵加法(MatAdd)
以3*3矩阵为例,矩阵加法的实现公式如下:
21.4.1 函数arm_mat_add_f32
函数原型:
arm_status arm_mat_add_f32(
const arm_matrix_instance_f32 * pSrcA,
const arm_matrix_instance_f32 * pSrcB,
arm_matrix_instance_f32 * pDst)
函数描述:
这个函数⽤于浮点数的矩阵加法。
函数参数:
第1个参数是矩阵A的源地址。
第2个参数是矩阵B的源地址。
第3个参数是矩阵A + 矩阵B计算结果存储的地址。
返回值,ARM_MATH_SUCCESS表⽰成功,ARM_MATH_SIZE_MISMATCH表⽰矩阵⼤⼩不⼀致。注意事项:
1. pSrcA,pSrcB,pDst的⾏数和列数必须是相同的,否则没有办法使⽤加法运算。
2. 矩阵在数组中的存储是从左到右,再从上到下。
21.4.2 函数arm_mat_add_q31
函数原型:
arm_status arm_mat_add_f32(
const arm_matrix_instance_f32 * pSrcA,
const arm_matrix_instance_f32 * pSrcB,
arm_matrix_instance_f32 * pDst)
函数描述:
这个函数⽤于定点数Q31的矩阵加法。
函数参数:
第1个参数是矩阵A的源地址。
第2个参数是矩阵B的源地址。
第3个参数是矩阵A + 矩阵B计算结果存储的地址。
返回值,ARM_MATH_SUCCESS表⽰成功,ARM_MATH_SIZE_MISMATCH表⽰矩阵⼤⼩不⼀致。注意事项:
1. 使⽤了饱和运算,输出结果范围[0x80000000 0x7FFFFFFF]。
2. pSrcA,pSrcB,pDst的⾏数和列数必须是相同的,否则没有办法使⽤加法运算。
matlab中printf输出格式3. 矩阵在数组中的存储是从左到右,再从上到下。
21.4.3 函数arm_mat_add_q15
函数原型:
arm_status arm_mat_add_f32(
const arm_matrix_instance_f32 * pSrcA,
const arm_matrix_instance_f32 * pSrcB,
arm_matrix_instance_f32 * pDst)
函数描述:
这个函数⽤于定点数Q15的矩阵加法。
函数参数:
第1个参数是矩阵A的源地址。
第2个参数是矩阵B的源地址。
第3个参数是矩阵A + 矩阵B计算结果存储的地址。
返回值,ARM_MATH_SUCCESS表⽰成功,ARM_MATH_SIZE_MISMATCH表⽰矩阵⼤⼩不⼀致。注意事项:
1. 使⽤了饱和运算,输出结果范围[0x8000 0x7FFF]。
2. pSrcA,pSrcB,pDst的⾏数和列数必须是相同的,否则没有办法使⽤加法运算。
3. 矩阵在数组中的存储是从左到右,再从上到。
21.4.4 ⽤举例(含Matlab实现)
程序设计:
/*
*********************************************************************************************************
*    函数名: DSP_MatAdd
*    功能说明: 矩阵求和
*    形参:⽆
*    返回值: ⽆
*********************************************************************************************************
*/
static void DSP_MatAdd(void)
{
uint8_t i;
/****浮点数数组******************************************************************/
float32_t pDataA[9] = {1.1f, 1.1f, 2.1f, 2.1f, 3.1f, 3.1f, 4.1f, 4.1f, 5.1f};
float32_t pDataB[9] = {1.1f, 1.1f, 2.1f, 2.1f, 3.1f, 3.1f, 4.1f, 4.1f, 5.1f};
float32_t pDataDst[9];
arm_matrix_instance_f32 pSrcA; //3⾏3列数据
arm_matrix_instance_f32 pSrcB; //3⾏3列数据
arm_matrix_instance_f32 pDst;
/****定点数Q31数组******************************************************************/
q31_t pDataA1[9] = {1, 1, 2, 2, 3, 3, 4, 4, 5};
q31_t pDataB1[9] = {1, 1, 2, 2, 3, 3, 4, 4, 5};
q31_t pDataDst1[9];
arm_matrix_instance_q31 pSrcA1; //3⾏3列数据
arm_matrix_instance_q31 pSrcB1; //3⾏3列数据
arm_matrix_instance_q31 pDst1;