2

行列でガウス ジョーダン消去法を実行する前方消去法を拡張したアルゴリズムを設計する必要があります。私のプログラムは、数値の対角線を実行して作成していますが、すべてが 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
4

2 に答える 2

1

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;

inverse() 関数:

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

正常に動作します...しかし、柔軟性を損なうことなく速度を向上させる方法があるはずです。

于 2015-04-16T22:08:48.643 に答える
1

アルゴリズムに基づいて、 ]| でA[j][i] > A[pivotrow][i]ある必要があり|A[j][i]| > |A[pivotrow][i、どちらも絶対値です。そして、スワップ機能はどこにありますか? C++ には独自のswap(int[][] a, int[][]b).

于 2013-10-09T05:28:04.887 に答える