Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 204, средняя оценка - 4.91
Карина!
0 / 0 / 0
Регистрация: 08.11.2010
Сообщений: 9
#1

Найти обратную матрицу и умножить ее на вектор - C++

08.11.2010, 20:49. Просмотров 26647. Ответов 25
Метки нет (Все метки)

Очень нужна помощь для нахождения обратной матрицы на С++.
Дело в том что мне нужно реализовать такую задачу:
найти обратную матрицу и умножить ее на вектор.
каким методом лучше находить обратную матрицу и какой алгоритм нахождения...помогите пожалуйста.
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.11.2010, 20:49     Найти обратную матрицу и умножить ее на вектор
Посмотрите здесь:
в матрице А(n x m) найти первый столбец, не содержащий отрицательных элементов, и умножить его как вектор на матрицу А C++
Умножить матрицу квадратную на вектор C++
Умножить квадратную матрицу на вектор C++
C++ Умножить вектор-строку на матрицу
Умножить матрицу 10х10 на вектор из 10 элементов C++
C++ Найти обратную матрицу
Найти обратную матрицу C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
silent_1991
Эксперт С++
4960 / 3036 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
16.11.2012, 16:15     Найти обратную матрицу и умножить ее на вектор #16
Цитата Сообщение от AlexP11223 Посмотреть сообщение
Если детерминант всегда не 0, то он не нужен?
Если уверены, что матрица не вырожденная - проверка не нужна. Но лучше её всё же оставить (я бы оставил), универсальность никогда не повредит.
Ternsip
660 / 188 / 6
Регистрация: 10.05.2012
Сообщений: 595
07.05.2013, 21:03     Найти обратную матрицу и умножить ее на вектор #17
Написал вот. Работает правильно, но не проверял на контесторах, так что, если найдёте баги пишите.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include <iostream>
#include <cmath>
#include <algorithm>
#include <vector>
#include <map>
#include <stack>
#include <deque>
#include <set>
#include <string>
#include <limits>
#include <fstream>
 
using namespace std;
 
vector < vector <double> > inverse(vector < vector <double> > a) {
    int n = a.size();
    vector < vector <double> > ans(n, vector <double> (n, 0));  
    for (int i = 0; i < n; i++){
        ans[i][i] = 1.0;
    }  
    for (int i = 0; i < n; i++){
        int row = i;
        double mx = a[i][i];
        for(int k = i + 1; k < n; k++){
            if (abs(a[k][i]) > mx){
                row = k;
                mx = abs(a[k][i]);
            }
        }
        if (row != i) {
            swap(a[row], a[i]);
            swap(ans[row], ans[i]);
        }
        for (int j = i+1; j < n; j++){
            double e = a[j][i]/a[i][i];
            for (int k = 0; k < n; k++){
                a[j][k] -= e*a[i][k];
                ans[j][k] -= e*ans[i][k];
            }
        }
    }
    for (int i = n - 1; i >= 0; i--) {
        for (int j = i - 1; j >= 0; j--){
            double e = a[j][i]/a[i][i];
            for (int k = 0; k < n; k++){
                a[j][k] -= e*a[i][k];
                ans[j][k] -= e*ans[i][k];
            }
        }
        for (int j = 0; j < n; j++) {
            ans[i][j] /= a[i][i];
        }
    }
    return ans;
}
 
int main(){
    int n;
    cin >> n;
    vector < vector <double> > a(n, vector <double> (n, 0)), ans;
 
    for (int i = 0; i < n; i++){
        for (int j = 0; j < n; j++){
            scanf("%lf", &a[i][j]);
        }
    } 
 
    ans = inverse(a);
 
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            printf("%.15lf ", ans[i][j]);
        }
        puts("");
    }
    return 0;
}
Добавлено через 5 минут
Обновил код

Добавлено через 34 минуты
Лично протестировал несколько матриц, всё сходилось. Особенно удобно проверять так : сделали матрицу, нашли обратную, затем нашли обратную к обратной и сверились.
Sabijan
0 / 0 / 0
Регистрация: 21.02.2013
Сообщений: 7
23.02.2014, 14:17     Найти обратную матрицу и умножить ее на вектор #18
извините, если придирчиво проверять(как делает это мой препод по кодингу), ваш код не работает в случае с нулевыми элементами, например для такой матрицы:
0 0 2
0 5 4
6 4 6

Добавлено через 15 минут
Цитата Сообщение от Ternsip Посмотреть сообщение
Лично протестировал несколько матриц, всё сходилось. Особенно удобно проверять так : сделали матрицу, нашли обратную, затем нашли обратную к обратной и сверились.
я пробовал проверять через excel
матрица
0 0 2
0 5 4
6 4 6
первая строка матрицы, найденной юзая ваш код не совпадает
в прочем другие две строки выводятся правильно
silent_1991
Эксперт С++
4960 / 3036 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
23.02.2014, 14:51     Найти обратную матрицу и умножить ее на вектор #19
Цитата Сообщение от Sabijan Посмотреть сообщение
если придирчиво проверять
Это не придирчивость, а вполне обычная проверка стандартной ситуации. У произвольной матрицы на главной диагонали запросто могут быть нулевые элементы. Поэтому правильный метод и включает шаг с перестановкой строк в случае, если очередная строка на главной диагонали содержит нулевой элемент.
Sabijan
0 / 0 / 0
Регистрация: 21.02.2013
Сообщений: 7
23.02.2014, 15:11     Найти обратную матрицу и умножить ее на вектор #20
извините, пытался реализовать ваш код на dev cpp вышла проблема с std::swap. какую библиотеку подключить?

Добавлено через 55 секунд
или можно заменить swap чем-нибудь?
CEBEP
105 / 105 / 9
Регистрация: 21.03.2010
Сообщений: 437
23.02.2014, 16:11     Найти обратную матрицу и умножить ее на вектор #21
C++ (Qt)
1
template <typename T> void swap(T& a, T& b) { T c(a); a = b; b = c; }
Sabijan
0 / 0 / 0
Регистрация: 21.02.2013
Сообщений: 7
23.02.2014, 16:59     Найти обратную матрицу и умножить ее на вектор #22
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// ìåòîäîì ГЈГ*ГіГ±Г±Г* - æîðäГ*Г*Г* 
#include <windows.h>
#include <fstream.h>
#include <iostream.h>
#include <math.h>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <vector>
#include <map>
#include <stack>
#include <deque>
#include <set>
#include <string>
#include <limits>
#include <fstream>
 
 
 
float inversion(float **mass, int n) // ñîçäГ*ГҐГ¬ ГґГіГ*êöèþ
{
 
 
 
//float a[n];
// ðåçåðâèðóåì ГЇГ*ìÿòü äëÿ äèГ*Г*ìè÷åñêèé Г¬Г*Г±Г±ГЁГў ГґГіГ*êöèè
    float **mass2 = new float *[n]; 
    for (int i=0; i<n; i++)
    mass2[i]=new float [n];
 
 
 
 
    for (int i = 0; i < n; i++)
    {
        mass2[i][i] = 1;
    }  
    for (int i = 0; i < n; i++){
        int row = i;
        float mx = mass[i][i];
        for(int k = i + 1; k < n; k++){
            if (fabs(mass[k][i]) > mx){
                row = k;
                mx = fabs(mass[k][i]);
            }
        }
        for(int i=0; i<n; i++)
        {
        for (int j=0; j<n; j++)
        {
        if (row != i) {
           mass[row][j]= mass[i][j];
            mass2[row][j]= mass2[i][j];
            }
        }
        }
        for (int j = i+1; j < n; j++){
            float e = mass[j][i]/mass[i][i];
            for (int k = 0; k < n; k++){
                mass[j][k] -= e*mass[i][k];
                mass2[j][k] -= e*mass2[i][k];
            }
        }
    }
    for (int i = n - 1; i >= 0; i--) {
        for (int j = i - 1; j >= 0; j--){
            float e = mass[j][i]/mass[i][i];
            for (int k = 0; k < n; k++){
                mass[j][k] -= e*mass[i][k];
                mass2[j][k] -= e*mass2[i][k];
            }
        }
        for (int j = 0; j < n; j++) {
            mass2[i][j] /= mass[i][i];
        }
        
 
    }
               for (int i=0; i<n; i++)
           for (int j=0; j<n; j++)
// ??????????????? ???????, mass2 -???????? ??????? ?????????? ?? ? ???????? ???????
           mass[i][j] = mass2[i][j];   
//    Г®Г·ГЁГ№Г*ГҐГ¬ ГЇГ*ìÿòü Г¬Г*Г±Г±ГЁГўГ* ГґГіГ*êöèè mass2
           for (int i=0; i<n; i++)
           delete [] mass2[i];
           delete [] mass2;
           
    
}
 
 
 
int main()
{
// Г±ГІГ*Г*Г¤Г*ðòГ*ûé ââîä
    int n;
    //cout<<"\n enter n"<<endl;
    //cin>>n;
  
    float **matrix=new float *[n];
    for (int i=0; i<n; i++)
    matrix[i] = new float [n];
    char *str = new char [1024];
    int i=0;
    ifstream base("matrix.txt");
    while (!base.eof())
    {
        base.getline(str, 1024, '\n');
        i++;
    }
    base.close();
    delete str;
    n=pow(i,0.5);
    ifstream fin("matrix.txt");
    for (int i=0; i<n; i++)
    for (int j=0; j<n; j++)
    {
        fin>>matrix[i][j];
    }
    fin.close();
    for (int i=0; i<n; i++)
    {
    for(int j=0; j<n; j++)
    {
            cout<<matrix[i][j];
            }
            cout<<endl;
            }
// âûçûâГ*ГҐГ¬ ГґГіГ*êöèþ
    inversion(matrix, n);
// âûâîäèì îáðГ*ГІГ*ГіГѕ Г¬Г*òðèöó
    for (int i=0; i<n; i++)
    {
    for (int j=0; j<n; j++)
    cout<<matrix[i][j]<<" ";
    cout<<endl;
    }
    ofstream fout("out.txt");
    for (int i=0; i<n; i++)
    {
    for (int j=0; j<n; j++)
        fout<<matrix[i][j]<<"   ";
        fout<<endl;
    }
    fout.close();
    for (int i=0; i<n; i++)
    delete [] matrix[i];
    delete [] matrix;
    system("pause");
    return 0;
}
прошу помочь с кодом(выдернул из этой же темы). сроки сдачи на завтра. ломается на нулях, если я введу матрицу. можно ли исправить код, не особенно мудря?
0 0 2
0 5 4
6 5 6
silent_1991
Эксперт С++
4960 / 3036 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
24.02.2014, 07:12     Найти обратную матрицу и умножить ее на вектор #23
Sabijan, чем не подходит мой код? В нём обратная матрица для указанной вами считается правильно (и обратная к обратной, в том числе, даёт исходную). Кроме того, реализация достаточно простая.
Sabijan
0 / 0 / 0
Регистрация: 21.02.2013
Сообщений: 7
24.02.2014, 08:20     Найти обратную матрицу и умножить ее на вектор #24
silent_1991, спасибо большое. я из вашего первого кода взял алгоритм, из последнего сдеал функцию swaper для обмена строк и от себя добавил динамические массивы и ввод и вывод в файл. сдача программы прошла на ура.
YURITIGER
0 / 0 / 0
Регистрация: 24.12.2014
Сообщений: 5
07.04.2017, 14:28     Найти обратную матрицу и умножить ее на вектор #25
silent_1991, спасибо за код. подскажите, а что в нем необходимо изменить, чтобы задавать исходную матрицу не с клавиатуры, а прямо в теле программы?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
07.04.2017, 15:01     Найти обратную матрицу и умножить ее на вектор
Еще ссылки по теме:
C++ Найти матрицу, обратную заданной
Для матрицы а(n, n) найти обратную матрицу C++
C++ С помощью метода отражения найти обратную матрицу
Почему матрица на вектор умножается быстрее чем вектор на матрицу? C++
матрица на вектор, вроде правильно, а вектор на матрицу? посмотрите пожалуйста? C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Fulcrum_013
663 / 731 / 72
Регистрация: 14.12.2014
Сообщений: 5,699
Завершенные тесты: 3
07.04.2017, 15:01     Найти обратную матрицу и умножить ее на вектор #26
Цитата Сообщение от silent_1991 Посмотреть сообщение
Если уверены, что матрица не вырожденная - проверка не нужна. Но лучше её всё же оставить (я бы оставил), универсальность никогда не повредит.
Проверка и перестановка для того чтобы делить всегда на максимальный по модулю элемент для того чтобы запятая не утонула. если к примеру встретится элемент 1e+4 и раза 3 поделится на 1e-4 то будет очень не хилый улет в небеса и мусор в младших разрядах. А если делить на 1e-4 на 1e+4 то результат будет быстро идти в ноль куда ему и дорога.
Yandex
Объявления
07.04.2017, 15:01     Найти обратную матрицу и умножить ее на вектор
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru