[C++] 求反矩陣與行列式

我是直接用 Gauss-Jordan elimination 去算反矩陣。

因為我預設是讀 3*3 的矩陣,所以文字檔的格式如下

0 2 0
2 0 2
1 2 3

即在每個數字之間加上空格即可。

/******************************************************************************
Using Gauss-Jordan elimination to find the inverse matrix and determinant.
******************************************************************************/
#include<iostream>
#include<fstream>
#include<cmath>
#include <string>
#include <sstream>

using namespace std;

int main()
{
const int m=3; //這裡寫死了, 請自行修改成不會寫死的情況

  ifstream inFile("matrix.txt"); //要讀的資料
  string (*arr)[m] = new string[m][m];

  string line;
  int y = 0;
  while(getline(inFile,line)) {
    istringstream ss(line);
    string word;
    int x = 0;
    while(ss >> word) {
      arr[y][x] = word;
      ++x;
    }
    ++y;
  }
  inFile.close();
  ofstream fout;
  fout.open ("INV-MATRIX.txt");
double A[m][m], temp[m][m], I[m][m], A1[m][m];
double determinant=1;

//這時讀取的資料是字串, 下面只是字串轉數字。 

  for (int i=0; i < m; i++)
    for (int j=0; j < m; j++)
      A[i][j] = atof(arr[i][j].c_str()); 

  delete []arr;      

for (int i=0;i < m;i++) for (int j=0; j < m; j++){
    temp[i][j] = A[i][j];
    A1[i][j] = A[i][j];
    if (i==j) I[i][j]=1;
    else I[i][j]=0;}

int d = 0;
do{
   if(A[d][d]==0){
      if(d == m) {determinant=0;}
      else{
           int t = d+1;
           do{
              if (A[d][t] !=0){
                determinant = 1;
                for (int k=d; k < m; k++) {
                    A[k][d] = A[k][t]+A[k][d];
                    I[k][d] = I[k][t]+I[k][d];}} //set d-row  = d-row + t-row 

              else {t++; determinant=0;}
            }while(determinant==0 && t < m); } //往 (i+1)-row 開始找, A[i][t] 是否有非 0 的元素
          }

      if(determinant==1){
       for(int j=0; j < m; j++)
        for(int k=0; k < m; k++)
         if (k != d){ A[j][k] = A[j][k]-A[j][d]*temp[d][k]/A[d][d];
                      I[j][k] = I[j][k]-I[j][d]*temp[d][k]/A[d][d]; }

       for(int i=0; i < m; i++)
        for(int j=0; j < m; j++)
         {temp[i][j] = A[i][j];}  

       d++;
       }fout<<endl;
}while(d < m && determinant==1); 

if(determinant==1){
  for(int i=0; i < m; i++) determinant = A[i][i]*determinant;

  fout << "determinant=" << determinant << endl;

   for(int i=0; i < m; i++)
     if (A[i][i] !=1)
      for(int j=0; j < m; j++)
       I[j][i] = I[j][i]/A[i][i];

   cout << "反矩陣已輸出" << endl;

   for (int i=0; i < m; i++){
    for (int j=0; j < m; j++) {fout << I[i][j] << "\t";} fout << endl;}

   fout<<endl;
   fout<<endl;
   fout<<endl;

   //下面是檢查算出來的反矩陣是否正確。
   /*
   double Ch[m][m];
   for(int i=0; i < m; i++){
    for(int j=0; j < m; j++)
    {
      Ch[i][j]=0;
      for(int k=0; k < m; k++) Ch[i][j] = Ch[i][j] + A1[k][j]*I[i][k];
      fout<<Ch[i][j]<<"\t"; }
      fout<<endl;
    }*/

fout.close();

}
else cout << "determinant=0, 沒有反矩陣" << endl;

   system("pause");

   return(0);
}

4 回應

  1. 您好,上網找算反距陣的程式找到您的程式,我也是用高斯喬丹去算反矩陣,不過想請問您幾個問題。
    1.您的記事本格式是要輸入怎樣?
    2.如果計算的矩陣對角線上有0這個值,要如何繼續運算下去?
    ex:

    2034
    1044
    1123
    2220

    謝謝您的解答。

  2. 第一個問題: 加空格, 下面是矩陣 ->文字檔
    [1,2] ->1 2
    [2,1] ->2 1

    第二個問題: 假設 [d][d] 為零, 往下找 [d][d+1], [d][d+2], ….. 一個不為零, 然後兩列相加使得 [d][d] 不為零, 基本上這去翻線性代數課本或其相關書籍都能找得到。

  3. 請問一下妳的txt檔要如何撰寫
    可以舉個例子嗎? 我都不會成功 謝謝!

留言