代码实现功能:矩阵加减、数乘、矩阵乘法、转置、求逆
缺点同样明显:求逆矩阵过程中使用递归算法,占用大量内存,移植单片机时应考虑单片机运行内存的大小
4阶方阵main运行一次时常约30ms
7阶方阵运行一次约100ms
.h 文件
//
// Created by Lenovo on 2022/3/7.
//
#ifndef UNTITLED_JUZHEN_H
#define UNTITLED_JUZHEN_H
#include <stdio.h>
typedef struct matrix_group
{
float matrix[7][7];
int rows;//行
int columns;//列
} matrix;
void show_matrix(matrix *group);
void matrix_initialization(matrix *group,int row,int columns,float a[]);
void do_matrix_multiplication(matrix *group_first,matrix *group_second,matrix *target);//矩阵乘法
void do_matrix_addition(matrix *group_first,matrix *group_second,matrix *target,float sign);//矩阵加减法,sign:1/-1
void do_scalar_multiplication(matrix *group,matrix *target,float num);//矩阵数乘
void do_transposed_matrix(matrix *group,matrix *target);//矩阵转置
void do_inverse_matrix(matrix *group,matrix *target);//求逆矩阵 //递归,所用内存较大
/*
展开时不一定要选定第一列,只要修改 deteminant 函数中的
cofactor = laplace_expansion(matrix,i,0,order);
这一行的 0 修改为其他数值便能改为其他列,或者修改
*/
float determinant(matrix *group,int order);//行列式求值
float laplace_expansion(matrix *group,int r,int c,int order);//拉普拉斯变换
float adjugate_matrix(matrix *group,int order,int r,int c);//伴随矩阵(r,c)元素计算 计算代数余子式
float Pos_Neg_(int judge);//正负判断,奇数为负,偶数为正
float inverse_matrix_math(matrix *group,int order,int r,int c);//计算逆矩阵(r,c)元素值
//order 方阵的阶
#endif //UNTITLED_JUZHEN_H
.c 文件
//
// Created by Lenovo on 2022/3/7.
//
#include <stdio.h>
#include "juzhen.h"
#include "math.h"
void show_matrix(matrix *group)
{
int i,j;
for(i = 0;i < group->rows;i ++)
{
for(j = 0;j < group->columns;j ++)
printf("%f\t", group->matrix[i][j]);
printf("\n");
}
printf("\n");
}
void matrix_initialization(matrix *group,int row,int columns,float a[20]){
int t=0;
for (int i= 0; i <row ; ++i) {
for (int j = 0; j < columns; ++j) {
group->matrix[i][j]=a[t];
++t;
}
}
group->rows=row;
group->columns=columns;
}
void do_matrix_multiplication(matrix *group_first,matrix *group_second,matrix *target)
{
int i,j,k;
if(group_first->columns != group_second->rows)
return;
else
{
for(i = 0;i <group_first->rows;i ++)
{
for(j = 0;j < group_second->columns;j ++)
{
target->matrix[i][j];
for(k = 0;k < group_first->columns;k ++)
target->matrix[i][j] += group_first->matrix[i][k] * group_second->matrix[k][j];
}
}
target->rows = group_first->rows;
target->columns = group_second->columns;
}
}
void do_matrix_addition(matrix *group_first,matrix *group_second,matrix *target,float sign)
{
int i,j;
if((group_first->rows != group_second->rows) != (group_first->columns != group_second->columns))
return;
else
{
for(i = 0;i <group_first->rows;i ++)
{
for(j = 0;j < group_second->columns;j ++)
{
target->matrix[i][j] = group_first->matrix[i][j] + sign * group_second->matrix[i][j];
}
}
target->rows = group_first->rows;
target->columns = group_second->columns;
}
}
void do_scalar_multiplication(matrix *group,matrix *target,float num)
{
int i,j;
for(i = 0;i < group->rows;i ++)
{
for(j = 0;j < group->columns;j ++)
{
target->matrix[i][j] = num * group->matrix[i][j];
}
}
target->rows = group->rows;
target->columns = group->columns;
}
void do_transposed_matrix(matrix *group,matrix *target)//矩阵转置
{
int i,j;
for (i = 0; i < group->rows; ++i) {
for (j = 0; j < group->columns; ++j)
target->matrix[i][j] = group->matrix[j][i];
}
target->rows=group->columns;
target->columns=group->rows;
}
void do_inverse_matrix(matrix *group,matrix *target){
int order=0;
if(group->rows == group->columns) order=group->rows;
int i,j;
for(i = 0;i < order;i ++)
{
for(j = 0;j < order;j ++)
target->matrix[i][j]=inverse_matrix_math(group,order,i,j);
}
target->columns=order;
target->rows=order;
}
float laplace_expansion(matrix *group,int r,int c,int order)//拉普拉斯变换
{
int original_i,original_j,i,j;
float result;
matrix cofactor;
// 缺少行、列赋值
// cofactor.rows=order-1;
// cofactor.columns=order-1;
for(i = 0;i < order;i ++)
for(j = 0;j < order;j ++)
{
original_i = i;
original_j = j;
if(i == r || j == c);
else
{
if(i > r)i --;
if(j > c)j --;
cofactor.matrix[i][j] = group->matrix[original_i][original_j];
i = original_i;
j = original_j;
}
}
if(order >= 2)
result = determinant(&cofactor,order - 1);
return result;
}
float determinant(matrix *group,int order)//行列式求值
{
int i;
float cofactor,result=0,sign = 1;
if(order == 1)
result = group->matrix[0][0];
else
for(i = 0;i < order;i ++)
{
cofactor = laplace_expansion(group,i,0,order);
result += sign * group->matrix[i][0] * cofactor;
sign *= -1;
}
return result;
}
float adjugate_matrix(matrix *group,int order,int r,int c)
{
float result = 0;
if(order == 1 && r == 0 && c == 0)
result = 1;
else
result = Pos_Neg_(r + c) * laplace_expansion(group,c,r,order); //计算代数余子式
if(result <= 0 && result >= -0.0005)
result = fabs(result);
return result;
}
float Pos_Neg_(int judge){
if(judge%2) return -1.0;
else return 1.0;
}
float inverse_matrix_math(matrix *group,int order,int r,int c) //
{
float result = 0;
result = adjugate_matrix(group,order,r,c) / determinant(group,order);
if(result <= 0 && result >= -0.0005)
result = fabs(result);
return result;
}
main.c 的实现
#include <stdio.h>
#include "juzhen.h"
#include "time.h"
clock_t start,stop;
double duration;
int main() {
start = clock();
matrix test_group[10];
float a[20]={1,1,-1,0,1,-0.667,0,0,1,8,9,1.51,3.54,0.65,5.32,4.11};
float a1[49]={1,3.2,4.11,10,6.51,3.54,0.65,
5.32,4.11,10.65,5.32,4.1,0,5.32,
4.11,1.65,5.32,4.1,0,5.32,-0.667,
5.32,4.181,0.32,4.131,1.651,8.8,9.7,
1.501,3.544,0.65,5.32,4.1,14.11,10.65,
9.312,1.65,2.32,1.565,5.332,5.982,4.11,
1.65,5.32,4.01,10.65,5.32,4.41,5.32,
};
matrix_initialization(&test_group[0],7,7,a1);
show_matrix(&test_group[0]);
float test=1.1;
do_scalar_multiplication(&test_group[0],&test_group[1],test);//数乘
show_matrix(&test_group[1]);
do_matrix_addition(&test_group[0],&test_group[1],&test_group[2],1.0);//加法 2=0+1
show_matrix(&test_group[2]);
do_matrix_addition(&test_group[1],&test_group[0],&test_group[3],-1.0);//减法 3= 1-0
show_matrix(&test_group[3]);
do_matrix_multiplication(&test_group[1],&test_group[0],&test_group[4]);//乘法 4=1*0
show_matrix(&test_group[4]);
do_transposed_matrix(&test_group[4],&test_group[5]);//转置
show_matrix(&test_group[5]);
// 1 2 3 -24 18 5
// 0 1 4 逆矩阵: 20 -15 -4
// 0 5 6 -5 4 1
float a2[20]={1,2,-1,-3};
matrix_initialization(&test_group[6],7,7,a1);
show_matrix(&test_group[6]);
do_inverse_matrix(&test_group[6],&test_group[7]);
stop = clock();
duration = ((double)(stop - start))/CLOCKS_PER_SEC;
show_matrix(&test_group[7]);
printf("ticks = %f\n", duration);
return 0;
}
参考内容:C语言实现行列式计算 - 知乎 (zhihu.com)https://zhuanlan.zhihu.com/p/305328519
C语言实现矩阵加法、减法、乘法和数乘运算 - 知乎 (zhihu.com)https://zhuanlan.zhihu.com/p/327070008
C语言求矩阵的伴随矩阵、逆矩阵、转置矩阵 - 知乎 (zhihu.com)https://zhuanlan.zhihu.com/p/307765016