Проблемы с классами при поиске обратной матрицы

Seemann92

Доброго времени суток! Задача такова. Необходимо создать класс, который создавал бы матрицу заданного размера (квадратную), рассчитывал её определитель и находил обратную матрицу. Нашёл необходимые функции здесь и вот здесь. После того, как вставил код в описание класса, обратная матрица стала рассчитываться некорректно. Тестировал на матрице размером 3х3. Последний столбец рассчитывается правильно, остальные нет. Если прописать данный код вне класса (причём и создание матрицы тоже), всё работает как надо. Подскажите, пожалуйста, в чём здесь проблема. Класс СMatrix:
#define R 9
 
class CMatrix{
****** mas[R][R], E[R][R];
****** kst, temp;
int n, p, t;
public:
        CMatrix(int);
        int Opr();
        void Inversion();
};
 
CMatrix::CMatrix(int N){
        n=N;
        randomize();
        cout<<"Ishodnaya matriza: "<<endl;
        for (int i=0; i<n; i++){
                for (int j=0; j<n; j++){
                        mas[i][j]=random(100);
                        cout<<mas[i][j]<<"\t";
                }
                cout<<endl;
        }
        cout<<endl;
}
 
int CMatrix::Opr(){
        p=0;
    for (int i=0; i<n-1; i++){
        t=1;
        while(mas[i][i]==0){
            for(int j=0; j<n; j++){
                mas[i][j]=kst;
                mas[i][j]=mas[i+t][j];
                mas[i+t][j]=kst;
            }
            p++;
            t++;
        }
        for (int k=i+1; k<n; k++){
            kst=mas[k][i]/mas[i][i];
            for(int j=0; j<n; j++)
                mas[k][j]-=mas[i][j]*kst;
        }
    }
    kst=pow(-1.0, p);
    for(int i=0; i<n; i++)
        kst*=mas[i][i];
    cout<<"Opredelitel': "<<kst;
        if (kst) return 1;
        else return 0;
}
 
void CMatrix::Inversion(){
        for (int i=0; i<n; i++)
                for (int j=0; j<n; j++){
                        if (i==j) E[i][j]=1.0;
                        else E[i][j]=0.0;
                }
        for (int k=0; k<n; k++){
                temp=mas[k][k];
                for (int j=0; j<n; j++){
                        mas[k][j]/=temp;
                        E[k][j]/=temp;
                }
                for (int i=k+1; i<n; i++){
                        temp=mas[i][k];
                        for (int j=0; j<n; j++){
                                mas[i][j]-=mas[k][j]*temp;
                                E[i][j]-=E[k][j]*temp;
                        }
                }
        }
        for (int k=n-1; k>0; k--){
                for (int i=k-1; i>=0; i--){
                        temp=mas[i][k];
                        for (int j=0; j<n; j++){
                                mas[i][j]-=mas[k][j]*temp;
                                E[i][j]-=E[k][j]*temp;
                        }
                }
        }
        cout<<endl<<"Obratnaya matriza:\n";
        for (int i=0; i<n; i++){
                for (int j=0; j<n; j++)
                        cout<<E[i][j]<<"\t";
                cout<<endl;
        }
}
8 ответов

Seemann92

Seemann92, попробуйте ввести новую переменную для обратной матрицы, а то она обновляет сама себя.


Seemann92

sl_k, как я понял, в этом-то и суть метода. Одни и те же операции должны проводиться над исходной матрицей и единичной матрицей того же размера.


Seemann92

Seemann92, c диагональной матрицей 3х3 метод работает. можете дать свой пример, на котором тестировали. ваш результат, и что должно получиться.


Seemann92

sl_k, я генерировал матрицы с помощью рандома, запускал расчёт обратной матрицы. Результаты сверял с решениями на онлайн ресурсах. У такой же программы, реализованной без классов, решение совпадало с решением на сайте. У данного примера - нет.


Seemann92

#include<iostream>
#include<cmath>
using namespace std;
 
#define R 3
 
class CMatrix{
****** mas[R][R], E[R][R];
****** kst, temp;
int n, p, t;
public:
        CMatrix(int);
        int Opr();
        void Inversion();
};
 
CMatrix::CMatrix(int N){
        n=N;
 
        cout<<"Ishodnaya matriza: "<<endl;
        mas[0][0] = 2; mas[0][1] = 1; mas[0][2] = -1;
         mas[1][0] = 5; mas[1][1] = 2; mas[1][2] = 4;
          mas[2][0] = 7; mas[2][1] = 3; mas[2][2] = 2;
        
        
        for (int i=0; i<n; i++){
           for (int j=0; j<n; j++){
 
                cout<<mas[i][j]<< " ";
           }
 
       
        cout<<endl;
        }
}
 
int CMatrix::Opr(){
        p=0;
    for (int i=0; i<n-1; i++){
        t=1;
        while(mas[i][i]==0){
            for(int j=0; j<n; j++){
                mas[i][j]=kst;
                mas[i][j]=mas[i+t][j];
                mas[i+t][j]=kst;
            }
            p++;
            t++;
        }
        for (int k=i+1; k<n; k++){
            kst=mas[k][i]/mas[i][i];
            for(int j=0; j<n; j++)
                mas[k][j]-=mas[i][j]*kst;
        }
    }
    kst=pow(-1.0, p);
    for(int i=0; i<n; i++)
        kst*=mas[i][i];
    cout<<"Opredelitel': "<<kst;
        if (kst) return 1;
        else return 0;
}
 
void CMatrix::Inversion(){
        for (int i=0; i<n; i++)
                for (int j=0; j<n; j++){
                        if (i==j) E[i][j]=1.0;
                        else E[i][j]=0.0;
                }
        for (int k=0; k<n; k++){
                temp=mas[k][k];
                for (int j=0; j<n; j++){
                        mas[k][j]/=temp;
                        E[k][j]/=temp;
                }
                for (int i=k+1; i<n; i++){
                        temp=mas[i][k];
                        for (int j=0; j<n; j++){
                                mas[i][j]-=mas[k][j]*temp;
                                E[i][j]-=E[k][j]*temp;
                        }
                }
        }
        for (int k=n-1; k>0; k--){
                for (int i=k-1; i>=0; i--){
                        temp=mas[i][k];
                        for (int j=0; j<n; j++){
                                mas[i][j]-=mas[k][j]*temp;
                                E[i][j]-=E[k][j]*temp;
                        }
                }
        }
        cout<<endl<<"Obratnaya matriza:\n";
        for (int i=0; i<n; i++){
                for (int j=0; j<n; j++)
                        cout<<E[i][j]<<"\t";
                cout<<endl;
        }
}
 
 
int main(){
   CMatrix matrix(3);
   matrix.Inversion();
   return 0;
}
и этот код работает. Проверил тут в примере 2.11 http://www.mathelp.spb.ru/book1/omatrix.htm


Seemann92

sl_k, а вот и оно! Тестируя свою версию программы, сначала вызывал метод Opr() для расчёта определителя. Как видно из кода, метод вносил некоторое коррективы в исходную матрицу. Ваш самый первый совет о новой переменной был верен, но в отношении другого метода. Спасибо. Буду исправлять.


Seemann92

возьми здесь вроде работает http://algorithmlib.org/gauss_inverse - обратная матрица, http://algorithmlib.org/gauss_det - определитель матрицы


Seemann92

vanomux, да и этот уже отладил. Спасибо.