代码实现功能:矩阵加减、数乘、矩阵乘法、转置、求逆

缺点同样明显:求逆矩阵过程中使用递归算法,占用大量内存,移植单片机时应考虑单片机运行内存的大小 

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

更多推荐