Исключение Гаусса-Джордана

Я должен разработать алгоритм как расширение прямого исключения, которое выполняет исключения Гаусса Джордана на матрице. Моя программа выполняет и создает диагональ чисел, но они не все 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

person xtheking    schedule 01.04.2013    source источник
comment
Каков ожидаемый результат?   -  person askewchan    schedule 02.04.2013
comment
@askewchan только что отредактировал это в первом сообщении   -  person xtheking    schedule 02.04.2013


Ответы (2)


На основе алгоритма A[j][i] > A[pivotrow][i] должно быть |A[j][i]| > |A[pivotrow][i]|, оба они являются абсолютными значениями. А где у вас функция подкачки? Я не думаю, что C++ имеет свой собственный swap(int[][] a, int[][]b).

person user2861318    schedule 09.10.2013
comment
Нет ничего плохого в том, что он использует std::swap — аргументы представляют собой элементы массива, а не целые массивы. - person Ben Voigt; 17.04.2015

Я только что создал класс QMatrix. Он использует встроенный вектор > контейнер.

Вы можете использовать его следующим образом:

#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;
}

Он отлично работает... но должны быть способы повысить его скорость без ущерба для гибкости.

person moldovean    schedule 16.04.2015