高斯消去法

Gauss-Jordan Elimination

本文关键字:高斯消      更新时间:2023-10-16

我必须设计一个算法作为前向消去的扩展,在矩阵上进行高斯乔丹消去。我的程序正在执行并创建数字对角线,但它们并不都是1。它也不会访问第一行和第一列来将它们更改为0。最后一列,也就是答案应该在的那一列,不会改变。知道怎么做才能更接近解吗?

#include <cmath>
using namespace std;
double BetterForwardElimination(double A[8][9])
{
//Implements Gaussian elimination with partial pivoting
//Input: Matrix A[1..n,1..n] and column-vector b[1..n]
//Output: An equivalent upper-triangular matrix in place ofAand the
//corresponding right-hand side values in place of the (n+1)st column
    //size of array
    int n = 8;
    //int n = sizeof(A)/sizeof(A[0]);
for (int i = 1; i<n; i++)
{
    int pivotrow = i;
    for (int j=i+1; j<n; j++)
    {
        if (A[j][i] > A[pivotrow][i])
        {
            pivotrow = j;
        }
    }
    for (int k=i; k<n-1; k++)
    {
        swap(A[i][k], A[pivotrow][k]);
    }
    for (int j=i+1; j<n; j++)
    {
        //int temp = A[j][i]/A[i][i];
        for (int k = i; k<n; k++)
        {
            A[j][k] = A[j][k] - A[i][k]*(A[j][i]/A[i][i]);
        }
        A[i][j] = 0;
    }
}
return A[n][n];
}

我的输出是这样的:

1   1   1   1   1   1   1   1   0   
1   2   0   0   0   0   0   0   0   
1   0   3   0   0   0   0   0   0   
1   0   0   4   0   0   0   0   0   
11  0   0   0   5   0   0   0   20  
1   0   0   0   0   1   0   0   34  
1   0   0   0   0   0   1   0   -51 
1   0   0   0   0   0   0   -1  -6

期望输出:

1   0   0   0   0   0   0   0   2   
0   1   0   0   0   0   0   0   3   
0   0   1   0   0   0   0   0   5   
0   0   0   1   0   0   0   0   7   
0   0   0   0   1   0   0   0   -7  
0   0   0   0   0   1   0   0   -5  
0   0   0   0   0   0   1   0   -3  
0   0   0   0   0   0   0   1   -2

根据算法,A[j][i] > A[pivotrow][i]应为|A[j][i]| > |A[pivotrow][i]|,两者均为绝对值。交换函数在哪里?我不认为c++有自己的swap(int[][] a, int[][]b)

我刚刚创建了一个QMatrix类。它使用内置的vector>容器。

你可以这样使用:

#include "QMatrix.h"
#include <iostream>
int main(){
QMatrix<double> A(3,3,true);
QMatrix<double> Result = A.inverse()*A; //should give the idendity matrix
std::cout<<A.inverse()<<std::endl;
std::cout<<Result<<std::endl; // for checking
return 0;
}

如果你想看看它是如何工作的,逆函数是这样实现的:

类有以下字段:

template<class T> class QMatrix{
public:
int rows, cols;
std::vector<std::vector<T> > A;

逆函数:

template<class T> 
QMatrix<T> QMatrix<T>:: inverse(){
Identity<T> Id(rows); //the Identity Matrix as a subclass of QMatrix.
QMatrix<T> Result = *this; // making a copy and transforming it to the Identity matrix
T epsilon = 0.000001;
for(int i=0;i<rows;++i){
    //check if Result(i,i)==0, if true, switch the row with another
    for(int j=i;j<rows;++j){
        if(std::abs(Result(j,j))<epsilon) { //uses Overloading()(int int) to extract element from Result Matrix
            Result.replace_rows(i,j+1); //switches rows i with j+1
        }
        else break;
    }
    // main part, making a triangular matrix
    Id(i)=Id(i)*(1.0/Result(i,i));
    Result(i)=Result(i)*(1.0/Result(i,i));  // Using overloading ()(int) to get a row form the matrix
    for(int j=i+1;j<rows;++j){
        T temp = Result(j,i);
        Result(j) = Result(j) - Result(i)*temp;
        Id(j) = Id(j) - Id(i)*temp; //doing the same operations to the identity matrix
        Result(j,i)=0; //not necessary, but looks nicer than 10^-15
    }
}
// solving a triangular matrix 
for(int i=rows-1;i>0;--i){
    for(int j=i-1;j>=0;--j){
        T temp = Result(j,i);
        Id(j) = Id(j) - temp*Id(i);
        Result(j)=Result(j)-temp*Result(i);
    }
}
return Id;
}

它工作得很好…但应该有办法在不损害灵活性的情况下提高其速度。