矩阵求逆的算法

本文深入探讨了矩阵求逆的算法,包括理论基础和实际应用。通过实例解析,阐述了如何利用高斯消元法、LU分解等方法计算矩阵的逆,并讨论了浮点数误差对结果的影响。同时,提到了在编程实现中需要注意的缓冲区管理和空指针问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//***************************
//求任何一个矩阵的逆矩阵
//***************************
#include <stdio.h>
#include <malloc.h>

void main( void )
{
    float *buffer,*p;  //定义数组首地址指针变量
    short int row,num; //定义矩阵行数row及矩阵元素个数
    short int i,j;
    float determ;     //定义矩阵的行列式

    float comput_D(float *p,short int n);     //求矩阵的行列式
    float Creat_M(float *p, short int m,short int n,short int k); //求代数余子式
    void Print( float *p,short int n);    //打印n×n的矩阵

    printf("/nPlease input the number of rows: ");
    scanf("%d",&row);
    
    num=2 * row * row;
    buffer = (float *)calloc(num, sizeof(float));    //分配内存单元

    p=buffer;
    if(p != NULL)
    {
        for(i=0;i<row;i++)                  //输入各单元值
        {
            printf("Input the number of %d row ",i+1);
            for(j=0;j<row;j++)
            {
                scanf("%f",p++);
            }
        }  
    }
    else
        printf( "Can't allocate memory/n" );

    printf("/nThe original matrix is:/n");
    Print(buffer,row);    //打印该矩阵

    determ=comput_D(buffer,row);    //求整个矩阵的行列式
    p=buffer + row * row;
    if (determ != 0)
    {
        for (i=0;i<row; i++)      //求逆矩阵
            for (j=0; j<row; j++)
                   *(p+j*row+i)=  Creat_M(buffer,i,j,row)/determ;    
            
        printf("The determinant is %G/n",determ);

        p=buffer + row * row;
        printf("/nThe inverse matrix is:/n"); 
        Print(p,row);    //打印该矩阵
    }
    else
        printf("The determnant is 0, and there is no inverse matrix !/n");
    free( buffer );
}
//--------------------------------------------------------
//功能:求矩阵 n X n 的行列式
//入口参数:矩阵首地址 p;矩阵行数 n
//返回值:矩阵的行列式值
//--------------------------------------------------------
float comput_D(float *p,short int n)  
{
    short int i,j,m;        //i--row; j--column
    short int lop=0;
    float result=0;
    float mid=1;
    
    if (n!=1)
    {
        lop=(n==2)?1:n;    //控制求和循环次数,若为2阶,则循环1次,否则为n次

        for(m=0;m<lop;m++)
        {
            mid=1;         //顺序求和
            for(i=0,j=m;i<n;i++,j++)
                mid = mid * ( *(p+i*n+j%n) );
            result+=mid;
        }

        for(m=0;m<lop;m++)
        {                       
            mid=1;         //逆序相减
            for(i=0,j=n-1-m+n; i<n; i++,j--)
                mid=mid * ( *(p+i*n+j%n));
            result-=mid;
        }
       }
    else result=*p;
    return(result);
}
//----------------------------------------------------
//功能:求k×k矩阵中元素A(mn)的代数余子式
//入口参数:k×k矩阵首地址;元素A的下标m,n; 矩阵行数 k
//返回值: k×k矩阵中元素A(mn)的代数余子式
//----------------------------------------------------
float Creat_M(float *p, short int m,short int n,short int k)
{
    short int len;
    short int i,j;
    float mid_result=0;
    short int quo=1;
    float *p_creat,*p_mid;

    len=(k-1)*(k-1);
    p_creat = (float *)calloc(len, sizeof(float));    //分配内存单元
    p_mid=p_creat;
    for(i=0;i<k;i++)
        for(j=0;j<k;j++)
        {
            if (i!=m && j!=n)
                *p_mid++ =* (p+i*k+j);            
        } 
    //    Print(p_creat,k-1);
    quo = (m + n) %2==0 ? 1:-1; 
    mid_result = (float ) quo * comput_D(p_creat,k-1);
    free(p_creat);
    return(mid_result);
}
//-------------------------------------------
//功能:打印n×n的矩阵
//入口参数:n×n矩阵的首地址;该矩阵的行数 n
//返回值: 无
//-------------------------------------------
void Print( float *p,short int n)    
{
    int i,j;
    for (i=0;i<n;i++)
    {
        for (j=0; j<n;j++)
            printf("%10G ",*p++);
        printf("/n");
    }
    printf("--------------/n");
}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值