使用迭代方法计算逆矩阵

时间:2014-12-10 05:35:17

标签: c matrix matrix-inverse

我的教授给我们分配了一个实验室,我已经被困住了,在网上找不到任何帮助。它特别适用于特征值<1的矩阵。 1.

鉴于3x3矩阵A = {(。5,-1,0),(0,.6666,0),(。5,-1,.6666)},你应该使用A ^ -1 = I + B + B ^ 2 + B ^ 3 ..... B ^ 20,其中I是单位矩阵,B = I - A.有两个输出,一个是A ^ -1,另一个是A * A ^ -1来检查结果。

到目前为止,我已经尝试了两种不同的乘法函数。抱歉,我的命名很糟糕。 i,j和k分别是行,列和循环计数器。

void mPower(double x[][3], double y[][3], double z[][3])
{
  int i, j, k;

  for (i = 0; i < 3; i++) 
    for (j = 0; j < 3; j++)   {
      for (k = 0; k < 3; k++)
        z[i][j] = z[i][j] + (x[i][k] * y[k][j]);
}
}

mPower是我可能错误的乘法函数。作为替代方案,我试过

void multiplyMatrix(double x[][3], double y[][3], double z[][3])
{
  int i, j, k;
   int sum = 0;

for (i = 0; i <= 2; i++) {
  for (j = 0; j <= 2; j++) {
     sum = 0;
     for (k = 0; k <= 2; k++) {
        sum = sum + x[i][k] * y[k][j];
     }
     z[i][j] = sum;
  }
  }

}

但是,我只得零。

void printIt(double a[][3], double b[][3])
{
 int i, j;

 for (i = 0; i < 3; i++)
 {
     printf ("\n\t\t\t");
     for (j = 0; j < 3; j++)
         printf ("%7.4f", a[i][j]);
     printf ("\t");
     for (j = 0; j < 3; j++)
         printf ("%7.4f", b[i][j]);
         printf ("\n\n\t");
 }
}

int main()
{
  int i, j, k;
  double b1[][3] = {.5, 1., 0., 0., .6666, 0., -.5, -1., .6666};
  double b3[3][3] = {0};
  double addOn[3][3];
  double aInverse[3][3];
  double identity[][3] = {1., 0., 0., 0., 1., 0., 0., 0., 1.};
  mPower (b1, b1, b3);
  for (k = 0; k < 20; k++)     {
      addOn[i][j] = addOn[i][j] + b3[i][j];
      mPower (b1, addOn, b3);
}

for (i = 0; i < 3; i++)  {
    for (j = 0; j < 3; j++)
        aInverse[i][j] = identity[i][j] + addOn[i][j];
}

printIt(b3, aInverse);
system("pause");

return 0;
}

PrintIt至少使显示格式化得很好,但我担心主要问题中的for循环。我无法绕过该怎么做。我正在获得各地的价值观,而我真的很难搞清楚这样一个利基问题所涉及的数学问题。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

我试图修复你的逻辑(结果代码效率非常低,可以写得更好)。我认为我发现的一些问题是:

  1. 未初始化变量addOn
  2. 根据前言中B = I-A的定义,你的b不正确(差减法)。
  3. 你的addOn = addOn + b3的累积不是双循环使用 未初始化的i和j。
  4. 您似乎没有反向检查(a * a ^ -1)= I
  5. (注意,我得到的是-0.000,因为我们使用的是IEEE双精度数字,所以数学并不精确,特别是在三分之一时。)

    #include <stdio.h>
    
    void mPower(double x[3][3], double y[3][3], double z[3][3])
    {
      int i, j, k;
    
      for (i = 0; i < 3; i++) 
        for (j = 0; j < 3; j++)   {
          z[i][j] = 0;
          for (k = 0; k < 3; k++)
            z[i][j] += (x[i][k] * y[k][j]);
    }
    }
    
    void mAdd(double x[3][3], double y[3][3]) 
    {
      int i, j;
      for (i = 0; i < 3; i++)  
        for (j = 0; j < 3; j++)
           x[i][j] += y[i][j];
    }
    
    void mCopy(double x[3][3], double y[3][3]) 
    {
      int i, j;
      for (i = 0; i < 3; i++)  
        for (j = 0; j < 3; j++)
           x[i][j] = y[i][j];
    }
    
    void printIt(double a[3][3], double b[3][3])
    {
     int i, j;
    
     for (i = 0; i < 3; i++)
     {
         printf ("\n\t\t\t");
         for (j = 0; j < 3; j++)
             printf ("%7.4f", a[i][j]);
         printf ("\t");
         for (j = 0; j < 3; j++)
             printf ("%7.4f", b[i][j]);
             printf ("\n\n\t");
     }
    }
    
    int main()
    {
      int i, j, k;
      double a[3][3] = {.5, -1., 0., 0., .6666, 0., .5, -1., .6666};
      double b1[3][3] = {.5, 1., 0., 0., 1-.6666, 0., -.5, 1., 1-.6666};
      double b3[3][3] = {0};
      double addOn[3][3] = {0};
      double aInverse[3][3] = {0};
      double identity[][3] = {1., 0., 0., 0., 1., 0., 0., 0., 1.};
    printIt(aInverse, b1);
      mAdd( aInverse, identity );
    printIt(aInverse, b1);
      mCopy( b3, b1 );
      mCopy( addOn, b1 );
      for (k = 0; k < 20; k++)     {
        mAdd( aInverse, addOn );
        mPower(b3, b1, addOn);
        mCopy( b3, addOn );
    printf( "loop iteration %d\n", k );
    printIt(aInverse, addOn );
    }
    printf( "aInverse\n" );
    printIt(b1, aInverse);
    printf( "verify\n");
    mPower(a,aInverse,b3);
    printIt(a,b3);
    
    return 0;
    }
    

    我得到的结果:

    aInverse
    
             0.5000 1.0000 0.0000    2.0000 3.0003 0.0000
    
    
             0.0000 0.3334 0.0000    0.0000 1.5002 0.0000
    
    
            -0.5000 1.0000 0.3334   -1.5001 0.0000 1.5002
    
    verify
    
             0.5000-1.0000 0.0000    1.0000-0.0000 0.0000
    
    
             0.0000 0.6666 0.0000    0.0000 1.0000 0.0000
    
    
             0.5000-1.0000 0.6666    0.0000 0.0000 1.0000