2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




 
 не пойму, где ошибка в коде
Сообщение21.07.2011, 22:25 
Есть матрица порядка 3638. Мне нужно найти обратную к ней. ( В последствии порядок матрицы будет около 100 000)
Есть код, вот только он не совсем рабочий. На маленьких матрицах порядка 3-4 он работает отлично, а вот на матрице порядка 3638 - не работает. В качестве результата выдает исходную матрицу.
Помогите найти косяк. И по возможности сделать код "по-шустрее"
Вот код на С++
Код:
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <sstream>
#include <vector>
#include <string>
#include <ctime>
#include <cmath>
#include <math.h>
#include <conio.h>

using namespace std;

template <typename T> void FreeMem(T **matr, int n);
template <typename T> void PrintMtx(T **matr, int n);
template <typename T> void SetMtx(T **matr, int n);
template <typename T> void TransponMtx(T **matr, T **tMatr, int n);
void Get_matr(double **matr, int n, double **temp_matr, int indRow, int indCol);
double Det(double **matr, int n);

void main()
{
    srand((unsigned)time(NULL));
    setlocale(0, "");
    int n;
        double det;
    cout << "Введите размер матрицы: ";
    cin >> n;
    double **matr = new double * [n];
    double **obr_matr = new double * [n];
    double **tobr_matr = new double * [n];
    for(int i = 0; i < n; i++)
                {
            matr[i] = new double[n];
            obr_matr[i] = new double[n];
            tobr_matr[i] = new double[n];
        }
       
        SetMtx(matr, n);
        PrintMtx(matr, n);
        det = Det(matr, n);
        cout << "Определитель матрицы = " << det << endl;
        if(det){
                for(int i = 0; i < n; i++){
                        for(int j = 0; j < n; j++){
                                int m = n - 1;
                                double **temp_matr = new double * [m];
                                for(int k = 0; k < m; k++)
                                        temp_matr[k] = new double[m];
                                Get_matr(matr, n, temp_matr, i, j);
                                obr_matr[i][j] = pow(-1.0, i + j + 2) * Det(temp_matr, m) / det;
                                FreeMem(temp_matr, m);
                        }
                }       
        }
        else
  cout << "Т.к. определитель матрицы = 0,\nто матрица вырожденная и обратной не имеет!!!" << endl;
        //Транспонирование матрицы
        TransponMtx(obr_matr, tobr_matr, n);
        //Печать обратной матрицы после транспонирования
        PrintMtx(tobr_matr, n);
                // Освобождение памяти
        FreeMem(tobr_matr, n);
        FreeMem(matr, n);
        FreeMem(obr_matr, n);
}
//Функция транспонирования матрицы
template <typename T> void TransponMtx(T **matr, T **tMatr, int n){
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
                        tMatr[j][i] = matr[i][j];
}
//Функция освобождения памяти
template <typename T> void FreeMem(T **matr, int n)
{
        for(int i = 0; i < n; i++)
                delete [] matr[i];
        delete [] matr;
}

//функция заполнения матрицы
template <typename T> void SetMtx(T **matr, int n)
{
        ifstream ifs1("3.txt");
        for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++)
                                {
                                        ifs1 >> matr[i][j];
                                }
}

//функция печати матрицы
template <typename T> void PrintMtx(T **matr, int n)
{
        ofstream ofs4("2.txt");
        for (int i = 0; i < n; i++){
                for (int j = 0; j < n; j++)
                                        ofs4 << matr[i][j] << " ";
                                ofs4 << endl;
                }               
}

//функция вычеркивания строки и столбца
void Get_matr(double **matr, int n, double **temp_matr, int indRow, int indCol)       
{
        int ki = 0;
        for (int i = 0; i < n; i++){
                if(i != indRow){
                        for (int j = 0, kj = 0; j < n; j++){
                                if (j != indCol){
                                        temp_matr[ki][kj] = matr[i][j];
                                        kj++;
                                }
                        }
                        ki++;           
                }
        }
}

//функция вычисления определителя матрицы
double Det(double **matr, int n)     
{
        double temp = 0;   //временная переменная для хранения определителя
        int k = 1;              //степень
        if(n < 1){
                cout<<"Неверный размер матрицы!!!" << endl;
        return 0;
    }
        else if (n == 1)
                temp = matr[0][0];
        else if (n == 2)
                temp = matr[0][0] * matr[1][1] - matr[1][0] * matr[0][1];
        else{
                for(int i = 0; i < n; i++){
                        int m = n - 1;
                        double **temp_matr = new double * [m];
                        for(int j = 0; j < m; j++)
                                temp_matr[j] = new double [m];
                        Get_matr(matr, n, temp_matr, 0, i);
                        temp = temp + k * matr[0][i] * Det(temp_matr, m);
                        k = -k;
                        FreeMem(temp_matr, m);
                }
        }
        return temp;


Сами матрицы находятся в текстовых файлах. Прикрепил и их:
1.txt - матрица порядка 4 (пробная)
2.txt - сюда записывается результат работы программы
3.txt - матрица порядка 3638
http://narod.ru/disk/19714080001/%D1%84 ... B.rar.html

 
 
 
 Re: не пойму, где ошибка в коде
Сообщение22.07.2011, 00:29 
У вас настолько неэффективный алгоритм, что даже если вы исправите ошибки (я их не искал), то всё равно не дождётесь результатов для матрицы размера 3638.

 
 
 
 Re: не пойму, где ошибка в коде
Сообщение22.07.2011, 00:47 
http://alglib.sources.ru/matrixops/inv.php

 
 
 
 Re: не пойму, где ошибка в коде
Сообщение22.07.2011, 01:20 
Я честно запустил код топикстартера, но программка рухнула ещё при предварительном вычислении определителя -- может быть не хватило памяти на такую рекурсию... :) Другие ошибки особо не искал...

P.S.: Уж лучше Гауссом.

 
 
 
 Re: не пойму, где ошибка в коде
Сообщение22.07.2011, 09:41 
Не могли бы Вы дать рабочие коды для вычисления обратной матрицы такого порядка

 
 
 
 Re: не пойму, где ошибка в коде
Сообщение22.07.2011, 13:03 
Да вам же уже приводили ссылку... См. выше. Ещё можете посмотреть теорию+ссылки в wiki/Invertible_matrix#Methods_of_matrix_inversion и ещё здесь.

 
 
 
 Re: не пойму, где ошибка в коде
Сообщение22.09.2011, 21:59 
Как не профессионально! Время фортранов прошло, пришло на смену - ООП. К тому же, много проще воспользоваться готовыми библиотеками и попробывать там посчитать.

-- Чт сен 22, 2011 23:01:08 --

Использовать [][] в c++ точно так же не профессионально. Проще написать класс матрицы с [i+j*m] и перегрузить оператор [][].

 
 
 [ Сообщений: 7 ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group