Символы кириллицы выводит некорректно. Как сделать чтобы выводился читабельный текст на русском языке? Тип приложения - не Qt, Qt Creator 4.5.0 основан на Qt 5.10.0. Win7.
|
Статические и динамические матрицы
Задача 6.11. Найти обратную матрицу к квадратной матрице .
Один из методов вычисления обратной матрицы основан на решении систем линейных алгебраических уравнений. Пусть задана некоторая матрица :
( 6.5) |
Необходимо найти матрицу , которая является обратной к матрице :
( 6.6) |
Матрица (6.6) будет обратной к матрице (6.5), если выполняется соотношение , где — это единичная матрица, или более подробно:
( 6.7) |
Результат перемножения матриц из соотношения (6.7) можно представить поэлементно в виде систем линейных уравнений. Умножение матрицы (6.5) на нулевой столбец матрицы (6.6) даст нулевой столбец единичной матрицы:
При умножении матрицы на первый столбец обратной матрицы получается следующая система линейных алгебраических уравнений.
Система, полученная в результате умножения матрицы (6.5) на -й столбец матрицы (6.6), будет выглядеть следующим образом:
Понятно, что -я система будет иметь вид:
Решением каждой из приведённых выше систем будет -й столбец обратной матрицы. Количество систем равно размерности обратной матрицы. Для отыскания решений систем линейных алгебраических уравнений можно воспользоваться методом Гаусса.
Описанный алгоритм представлен в виде блок-схемы на рис. 6.15. Блоки 2–5 отражают формирование вектора правых частей системы линейных алгебраических уравнений. Если условие в блоке 3 выполняется и элемент находится на главной диагонали, то он равен единице, все остальные элементы нулевые. В блоке 6 происходит вызов подпрограммы для решения системы уравнений методом Гаусса. В качестве параметров в эту подпрограмму передаётся исходная матрица , сформированный в блоках 2–5 вектор свободных коэффициентов , размерность системы . Вектор будет решением -й системы уравнений и, следовательно, -м столбцом искомой матрицы .
Как видно из блок-схемы, приведённой на рис. 6.15, при нахождении обратной матрицы понадобится функция SLAU, рассмотренная при решении задачи 6.10. Ниже приведён текст программы с подробными комментариями решения задачи 6.11. В функции main() будет находиться ввод исходной матрицы, обращение к функции INVERSE для вычисления обратной матрицы. Из функции INVERSE будет осуществляться вызов функции SLAU для решения системы линейных алгебраических уравнений.
#include <iostream> #include <math.h> using namespace std; //Функция решения системы линейных алгебраических уравнений методом Гаусса. int SLAU( double ** matrica_a, int n, double *massiv_b, double *x ) { int i, j, k, r; double c,M, max, s; double **a, *b; a=new double * [ n ]; for ( i =0; i<n; i++) a [ i ]=new double [ n ]; b=new double [ n ]; for ( i =0; i<n; i++) for ( j =0; j<n; j++) a [ i ] [ j ]=matrica_a [ i ] [ j ]; for ( i =0; i<n; i++) b [ i ]=massiv_b [ i ]; for ( k=0;k<n; k++) { max=fabs ( a [ k ] [ k ] ); r=k; for ( i=k+1; i<n; i++) if ( fabs ( a [ i ] [ k ] )>max) { max=fabs ( a [ i ] [ k ] ); r= i; } for ( j =0; j<n; j++) { c=a [ k ] [ j ]; a [ k ] [ j ]=a [ r ] [ j ]; a [ r ] [ j ]= c; } c=b [ k ]; b [ k ]=b [ r ]; b [ r ]= c; for ( i=k+1; i<n; i++) { for (M=a [ i ] [ k ] / a [ k ] [ k ], j=k; j<n; j++) a [ i ] [ j ]*=M_a [ k ] [ j ]; b [ i ]_=M_b [ k ]; } } if ( a [ n -1 ] [ n-1]==0) if ( b [ n-1]==0) return -1; else return -2; else { for ( i=n-1; i >=0; i --) { for ( s =0, j= i +1; j<n; j++) s+=a [ i ] [ j ] * x [ j ]; x [ i ]=( b [ i ]- s ) / a [ i ] [ i ]; } return 0; } for ( i =0; i<n; i++) delete [ ] a [ i ]; delete [ ] a; delete [ ] b; } //Функция вычисления обратной матрицы int INVERSE( double **a, int n, double **y ) //Формальные параметры: a — исходная матрица, n — размерность матрицы, y — обратная матрица. //Функция будет возвращать 0, если обратная матрица существует, -1 — в противном случае. { int i, j, res; double *b, *x; //Выделение памяти для промежуточных массивов b и x. b=new double [ n ]; x=new double [ n ]; for ( i =0; i<n; i++) { //Формирование вектора правых частей для нахождения i-го столбца матрицы. for ( j =0; j<n; j++) if ( j==i ) b [ j ]= 1; else b [ j ]= 0; //Нахождение i-го столбца матрицы путём решения СЛАУ Ax = b методом Гаусса. res=SLAU( a, n, b, x ); //Если решение СЛАУ не найдено, то невозможно вычислить обратную матрицу. if ( res !=0) break; else //Формирование i-го столбца обратной матрицы. for ( j =0; j<n; j++) y [ j ] [ i ]=x [ j ]; } //Проверка существования обратной матрицы, если решение одного из уравнений Ax=b не //существует, то невозможно найти обратную матрицу, и функция INVERSE вернёт значение -1. if ( res !=0) return -1; //Если обратная матрица найдена, то функция INVERSE вернёт значение 0, //а обратная матрица будет возвращаться через указатель double **y. else return 0; } int main ( ) { int result, i, j,N; double **a, **b; //Двойные указатели для хранения исходной a и обратной b матрицы. cout<<" N = "; //Ввод размера матрицы. cin>>N; a=new double * [N ]; //Выделение памяти для матриц a и b. for ( i =0; i<N; i++) a [ i ]=new double [N ]; b=new double * [N ]; for ( i =0; i<N; i++) b [ i ]=new double [N ]; cout<<"Ввод матрицы A "<<endl; //Ввод исходной матрицы. for ( i =0; i<N; i++) for ( j =0; j<N; j++) cin>>a [ i ] [ j ]; result=INVERSE( a,N, b ); //Вычисление обратной матрицы. if ( result ==0) //Если обратная матрица существует, то вывести её на экран. { cout<<"Обратная матрица"<<endl; for ( i =0; i<N; cout<<endl, i++) for ( j =0; j<N; j++) cout<<b [ i ] [ j ]<<" \t "; } else //Если обратная матрица не существует, то вывести соответствующее сообщение. cout<<"Нет обратной матрицы"<<endl; }