通过高斯消元C ++确定矩阵的行列式

时间:2014-09-03 16:07:41

标签: c++ matrix gaussian determinants

我试图找到找到方阵的行列式的代码,我遇到了这段代码。

    int det(vector<vector<int> > mat) {
        int n = mat.size();


        for(int col = 0; col < n; ++col) {
            bool found = false;
            for(int row = col; row < n; ++row) {
                if(mat[row][col]) {
                    mat[row].swap(mat[col]);
                    found = true;
                    break;
                }
            }
            if(!found) {
                return 0;
            }
            for(int row = col + 1; row < n; ++row) {
                while(true) {
                    int del = mat[row][col] / mat[col][col];
                    for (int j = col; j < n; ++j) {
                        mat[row][j] -= del * mat[col][j];
                    }
                    if (mat[row][col] == 0)
                        break;
                    else
                        mat[row].swap(mat[col]);
                }
            }
        }

        li res = 1;

        for(int i = 0; i < n; ++i) {
            res *= mat[i][i];
        }
        return abs(res);
    }

但是我在理解第20-29行时遇到了麻烦,即从另一行的多个行中减去行。我的意思是为什么这里需要while循环?如我一般 减去商*除数,它应该总是0,对吗?所以我认为它应该只是一次迭代。那么,为什么我们需要执行这个mat[row].swap(mat[col]);操作呢? 提前谢谢。

1 个答案:

答案 0 :(得分:1)

您的代码中有一些奇怪的逻辑可以解释您使用整数运算执行计算的事实。

假设您有一个3x3矩阵,前两行是:

4 6 5
1 2 3

delcol=0计算row=1时,您将获得:

del = 1/4 = 0

这样,当你计算:

mat[row][j] -= del * mat[col][j];

mat[row][j]根本不会改变。

要考虑到这一点,您可以交换行。现在前两行是:

1 2 3
4 6 5

如果像这样交换行,del的值为4/1 = 4。现在这一行:

mat[row][j] -= del * mat[col][j];

确实有所作为。 mat[1][0]的值最终为零,这正是您所需要的。所以你打破了while循环。

这是一个功能的检测版本,它产生大量的调试输出,带有帮助函数来打印矩阵,主函数来测试代码。

#include <iostream>
#include <vector>
#include <stdlib.h>

using namespace std;

void printMatrix(vector<vector<int> > const& mat)
{
   int n = mat.size();
   for(int row = 0; row < n; ++row) {
      for(int col = 0; col < n; ++col) {
         cout << mat[row][col] << " ";
      }
      cout << "\n";
   }
   cout << "\n";
}

int det(vector<vector<int> > mat) {
   int n = mat.size();

   for(int col = 0; col < n; ++col) {
      cout << "Column: " << col << "\n";
      printMatrix(mat);
      bool found = false;
      for(int row = col; row < n; ++row) {
         if(mat[row][col]) {
            cout << "Got non-zero value for row " << row << " and col " << col << "\n";
            if ( row != col )
            {
               cout << "(1) Swapping rows " << col << " and " << row << "\n";
               mat[row].swap(mat[col]);
               printMatrix(mat);
            }
            else
            {
               cout << "Not swapping rows\n";
            }
            found = true;
            break;
         }
      }

      if(!found) {
         cout << "Did not find a non-zero row. Column: " << col << "\n";
         return 0;
      }

      for(int row = col + 1; row < n; ++row) {
         while(true) {
            int del = mat[row][col] / mat[col][col];
            cout << "del: " << del << "\n";
            for (int j = col; j < n; ++j) {
               mat[row][j] -= del * mat[col][j];
            }
            if (mat[row][col] == 0)
            {
               break;
            }
            else
            {
               cout << "(2) Swapping rows " << col << " and " << row << "\n";
               mat[row].swap(mat[col]);
               printMatrix(mat);
            }
         }
      }
   }

   printMatrix(mat);
   long res = 1;

   for(int i = 0; i < n; ++i) {
      res *= mat[i][i];
   }
   return abs(res);
}

int main()
{
   vector<vector<int> > mat = { {4, 6, 5}, {1, 2, 3}, {8, 10, 9} };
   int r = det(mat);
   cout << "Determinant: " << r << endl;
   return 0;
}