2014 dxdy logo

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

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




Начать новую тему Эта тема закрыта, вы не можете редактировать и оставлять сообщения в ней.
 
 не пойму, где ошибка в коде
Сообщение21.07.2011, 22:25 


21/07/11
105
Есть матрица порядка 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 
Заслуженный участник


04/05/09
4587
У вас настолько неэффективный алгоритм, что даже если вы исправите ошибки (я их не искал), то всё равно не дождётесь результатов для матрицы размера 3638.

 Профиль  
                  
 
 Re: не пойму, где ошибка в коде
Сообщение22.07.2011, 00:47 


28/09/09
29
http://alglib.sources.ru/matrixops/inv.php

 Профиль  
                  
 
 Re: не пойму, где ошибка в коде
Сообщение22.07.2011, 01:20 
Заслуженный участник


26/07/09
1559
Алматы
Я честно запустил код топикстартера, но программка рухнула ещё при предварительном вычислении определителя -- может быть не хватило памяти на такую рекурсию... :) Другие ошибки особо не искал...

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

 Профиль  
                  
 
 Re: не пойму, где ошибка в коде
Сообщение22.07.2011, 09:41 


21/07/11
105
Не могли бы Вы дать рабочие коды для вычисления обратной матрицы такого порядка

 Профиль  
                  
 
 Re: не пойму, где ошибка в коде
Сообщение22.07.2011, 13:03 
Заслуженный участник


26/07/09
1559
Алматы
Да вам же уже приводили ссылку... См. выше. Ещё можете посмотреть теорию+ссылки в wiki/Invertible_matrix#Methods_of_matrix_inversion и ещё здесь.

 Профиль  
                  
 
 Re: не пойму, где ошибка в коде
Сообщение22.09.2011, 21:59 


17/05/11
158
Как не профессионально! Время фортранов прошло, пришло на смену - ООП. К тому же, много проще воспользоваться готовыми библиотеками и попробывать там посчитать.

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

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

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Эта тема закрыта, вы не можете редактировать и оставлять сообщения в ней.  [ Сообщений: 7 ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group