如何在C中找出NXN矩阵的逆矩阵

Posted

技术标签:

【中文标题】如何在C中找出NXN矩阵的逆矩阵【英文标题】:How to find out the inverse of an NXN matrix in C 【发布时间】:2020-09-18 23:45:33 【问题描述】:

大家好,我对代码进行了一些更改,以便于理解,看看我目前所拥有的,我将函数的原型保留在代码的开头并且它工作正常,但是当我尝试 2x2 矩阵,因为如果我尝试 3x3、4x4 或 6x6 矩阵,它不能正常工作,行列式计算不正确,我想这是行列式的问题,但我不知道如何解决它。这是代码。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<math.h>


float determinant(int tam,float [][tam]);

void cofactor(int tam,float [][tam]);

void transpose(int tam,float [][tam],float [][tam]);

int validate()

    int val;
    char *buf = (char *) malloc(10);

    memset(buf,0,10);

    while(fgets(buf, 10, stdin) != NULL )
        if(buf[0]!='\n') 
            val = atoi(buf);
            break;
        
    
    free(buf);

    return val;


float determinant(int tam, float matrix[][tam])



    float s = 1, det = 0, b[tam][tam];

    int i, j, m, n, c;

    if (tam == 1)

      

       return (matrix[0][0]);

      

    else

      

       det = 0;

       for (c = 0; c < tam; c++)

         

          m = 0;

          n = 0;

          for (i = 0;i < tam; i++)

            

              for (j = 0 ;j < tam; j++)

                

                  b[i][j] = 0;

                  if (i != 0 && j != c)

                   
                     b[m][n] = matrix[i][j];

                     if (n < (tam - 2))

                      n++;

                     else

                      

                       n = 0;
                       m++;

                       

                     

                 

               

            det = det + s * (matrix[0][c] * determinant( tam - 1,b));
            s = -1 * s;
            
      

      return (det);



 void cofactor( int tam,float num[][tam])

 

   float b[tam][tam], fac[tam][tam];

    int p, q, m, n, i, j;

    float x = 0;


  for (q = 0;q < tam; q++)

  

    for (p = 0;p < tam; p++)

    

     m = 0;

     n = 0;

 for (i = 0;i < tam; i++)

 

   for (j = 0;j < tam; j++)

    

      if (i != q && j != p)

      
        b[m][n] = num[i][j];

        if (n < (tam - 2))

         n++;

        else

         

           n = 0;

           m++;

           

        

    

  

  x = pow(-1, q + p) * determinant( tam - 1,b);

  fac[p][q] = x;




 transpose(tam,num, fac);



  void transpose(int tam,float num[][tam], float fac[][tam])

 

  int i, j;

  float b[tam][tam], inverse[tam][tam], d;



   for (i = 0;i < tam; i++)



  

     for (j = 0;j < tam; j++)

       

         b[i][j] = fac[j][i];

        

    

      d = determinant(tam,num);



     for (i = 0;i < tam; i++)

    

     for (j = 0;j < tam; j++)

       

        inverse[i][j] = b[i][j] / d;

        

    

       printf("\n\n\nThe inverse of matrix is : \n");

       for (i = 0;i < tam; i++)

    

     for (j = 0;j < tam; j++)

       

         printf("\t%f", inverse[i][j]);

        

        printf("\n");

     



    int verify_Size(int line)

        if((line > 0) && (line <= 6))
        
            return 1;
        

    return 0;
    


    int create_Matrix(int LINE)

        int matrix[LINE][LINE];
        float aux[LINE][LINE];

        printf("\n\n\nPle:", (LINE * LINE));
        printf("\n--------------------------------\n");

        for(int i=0;i<LINE;i++)
        
            for(int j=0;j<LINE;j++)
            
                printf("Value[%d][%d]: ",i,j);

                matrix[i][j] = validate();
            
        

        printf("\n\nYour Bidimensional Matrix is:");
        printf("\n--------------------------------\n");


        for(int i=0;i < LINE;i++)
        
            for(int j=0; j< LINE;j++)
            
                printf("\t%2d",matrix[i][j]);
                aux[i][j] = (float) matrix[i][j];

        
        printf("\n");
    

      float d = determinant(LINE,aux);

       printf("\n\nDeterminante Main: %f \n",d);

       if (d == 0)

       printf("\nInverse of Entered Matrix is not possible\n");

       else

        cofactor(LINE,aux);

       return 0;




    int main()

    int flag,line;

    do
        printf("Enter the order of the Matrix:\n");
        printf("-------------------------------\n");

        printf("Lines: ");
        line = validate();


        if(verify_Size(line)== 1)
        
            create_Matrix(line);

        else

            printf("\nMatrix must to be till 6 X 6!\n");

            flag = 0;

        

    while(flag != 1);

    return 0;

【问题讨论】:

I want to remove the function's prototype at the beginning 为什么? 因为我有一个函数可以让用户创建一个 NxN 矩阵,所以在用户创建矩阵之前我不知道矩阵的大小。 您发布的代码看起来被硬编码为 3x3。摆弄原型不会改变这一点。 是的,这就是我想删除原型并将矩阵作为参数传递的想法,直到找到逆矩阵 我将首先通过格式化程序运行您的代码。我试图在初学者的降价代码块中得到它。 【参考方案1】:

您似乎正在通过Cramer's rule 找到逆矩阵。虽然它适用于 2x2 或 3x3 矩阵大小,但实施 Cramer 规则的困难部分通常是评估行列式。如果您按照定义计算 NxN 行列式,则计算是递归的并且具有阶乘 O(N!) 计算复杂度 (Wikipedia)。

我建议切换到另一种算法。 LUP 因式分解快速且相对简单,Wikipedia has an example implementation。

【讨论】:

以上是关于如何在C中找出NXN矩阵的逆矩阵的主要内容,如果未能解决你的问题,请参考以下文章

求高手编写C语言求3*3矩阵的逆矩阵! 具体数值在问题补充里!

雅可比矩阵(偏导数矩阵)的逆矩阵代表啥含义

名词概念

matlab中用左除和逆矩阵法 求方程 为啥答案不一样?

MATLAB编程 逆矩阵怎么表示

为什么常使用梯度下降,很少用最小二乘法