c语言矩阵库

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

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

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LAPACK(Linear Algebra PACKage)是一个用于高性能线性代数计算的软件。它提供了一系列用于求解线性方程组、特征值问题、奇异值分解和最小二乘问题等的算法和子程序。 LAPACK 是一个开源的,最初是由美国国家标准与技术研究院(NIST)和美国劳伦斯伯克利国家实验室(LBL)开发的,现在由社区维护和更新。它是 Fortran 语言编写的,但也有一些针对不同编程语言的接口和封装器。在 C 语言中使用 LAPACK,你可以使用相应的 C 接口或封装器来调用 LAPACK 提供的函数。 要在 C 语言中使用 LAPACK,你需要下载并安装 LAPACK ,并将其链接到你的 C 项目中。在链接时,你需要指定 LAPACK 的路径和名称,以便编译器能够找到并链接所需的函数。 以下是一个使用 LAPACK 进行线性方程组求解的示例: ```c #include <stdio.h> #include <lapacke.h> int main() { lapack_int n = 3; // 方程组的大小 lapack_int nrhs = 1; // 右侧向量的数量 double A[] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 10.0 }; // 系数矩阵 double b[] = { 1.0, 2.0, 3.0 }; // 右侧向量 lapack_int info; // 调用 LAPACK 的线性方程组求解函数 info = LAPACKE_dgesv(LAPACK_ROW_MAJOR, n, nrhs, A, n, NULL, b, nrhs); if (info == 0) { printf("线性方程组求解成功!\n"); printf("解向量 x: %lf, %lf, %lf\n", b[0], b[1], b[2]); } else { printf("线性方程组求解失败,错误码:%d\n", info); } return 0; } ``` 在上述示例中,我们使用了 LAPACKE_dgesv 函数来求解一个大小为3的线性方程组。函数的参数包括矩阵的存储方式(LAPACK_ROW_MAJOR 表示按行存储)、方程组的大小、右侧向量的数量、系数矩阵、右侧向量等。函数返回一个整数值,用于表示求解的状态。 请注意,在使用 LAPACK 前,你需要确保已正确配置并链接 LAPACK ,并将 lapacke.h 头文件包含在你的源代码中。 这只是一个简单的示例,LAPACK 还提供了许多其他功能和函数,可用于解决更复杂的线性代数问题。你可以参考 LAPACK 的文档和示例代码来了解更多详细信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值