Обратная матрица Вычисление + код

Обратная матрица

Обратной матрицей для квадратной матрицы A называется такая матрица {\displaystyle A^{-1}}, для которой справедливо:

{\displaystyle A \cdot A^{-1}=A^{-1} \cdot A=E},

где E — единичная матрица.

Вычисление обратной матрицы осуществляется в следующем порядке:

{\displaystyle A^{-1} = {\frac {A^{*T}}{|A|}}}

Матрица алгебраических дополнений {\displaystyle A^*} находится следующим образом:
  • из исходной матрицы находим матрицу миноров;
  • меняем в матрице миноров знак тех элементов, у которых сумма индексов строки и столбца представляет собой нечетное значение (нумерация индексов строки и столбца начинается с 0)
Знак миноров в матрице алгебраических дополнений
Размерность матрицы миноров такая же как у исходной матрицы {\displaystyle A}. Чтобы найти матрицу миноров нужно для каждого элемента исходной матрицы вычеркнуть все элементы строки и столбца, в которых данный элемент расположен, а затем найти определитель получившейся матрицы. Например, для того чтобы найти минор элемента a1 2, нужно

{\displaystyle { {\begin{vmatrix} a_{00} & a_{01} & \textcolor{red}{a_{02}} & a_{03} \\ \textcolor{red}{a_{10}} & \textcolor{red}{a_{11}} & \textcolor{red}{a_{12}} & \textcolor{red}{a_{13}}\\ a_{20} & a_{21} & \textcolor{red}{a_{22}} & a_{23} \\ a_{30} & a_{31} & \textcolor{red}{a_{32}} & a_{33} \\ \end{vmatrix} } = {\begin{vmatrix} a_{00} & a_{01} & a_{03} \\ a_{20} & a_{21} & a_{23} \\ a_{30} & a_{31} & a_{33} \\ \end{vmatrix} } } }

Реализация на Си

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
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
// Функция ввода элементов матрицы
double** Input(int rows, int cols) 
{
  double** p;
  p = (double**)malloc(rows * sizeof(double*));
  for (int i = 0; i < rows; i++) 
  {
    p[i] = (double*)malloc(cols * sizeof(double));
    for (int j = 0; j < cols; j++)
    {
      printf("mas[%d][%d]= ", i, j);
      scanf("%lf", &p[i][j]);
    }
  }
  return p;
}
// Функция вывода элементов матрицы
void Output(double** mas, int rows, int cols) 
{
  for (int i = 0; i < rows; i++) {
    for (int j = 0; j < cols; j++)
      printf("%8.4lf ", mas[i][j]);
    printf("\n");
  }
}

// Транспонирование матрицы
double** Transpone(double** mas, int rows, int cols)
{
  double** rez;
  rez = (double**)malloc(cols * sizeof(double*));
  for (int i = 0; i < cols; i++)
  {
    rez[i] = (double*)malloc(rows * sizeof(double));
    for (int j = 0; j < rows; j++)
      rez[i][j] = mas[j][i];
  }
  return rez;
}

// Функция освобождения памяти, выделенной под матрицу
void Free(double** mas, int rows)
{
  if (mas == 0) return;    // если память не была выделена, выходим
  for (int i = 0; i < rows; i++)
    free(mas[i]);
  free(mas);
}

// Получение матрицы без i-й строки и j-го столбца
// (функция нужна для вычисления определителя и миноров)
double** GetMatr(double** mas, int rows, int cols, int row, int col) {
  int di, dj;
  double** p = (double**)malloc((rows - 1) * sizeof(double*));
  di = 0;
  for (int i = 0; i < rows - 1; i++) { // проверка индекса строки
    if (i == row)  // строка совпала с вычеркиваемой
      di = 1;    // - дальше индексы на 1 больше
    dj = 0;
    p[i] = (double*)malloc((cols - 1) * sizeof(double));
    for (int j = 0; j < cols - 1; j++) { // проверка индекса столбца
      if (j == col)  // столбец совпал с вычеркиваемым
        dj = 1;    // - дальше индексы на 1 больше
      p[i][j] = mas[i + di][j + dj];
    }
  }
  return p;
}

// Рекурсивное вычисление определителя
double Determinant(double** mas, int m) {
  int k;
  double** p = 0;
  double d = 0;
  k = 1; //(-1) в степени i
  if (m < 1) { printf("Определитель вычислить невозможно!"); return 0; }
  if (m == 1) { d = mas[0][0]; return(d); }
  if (m == 2) { d = mas[0][0] * mas[1][1] - (mas[1][0] * mas[0][1]); return(d); }
  if (m > 2) {
    for (int i = 0; i < m; i++) {
      p = GetMatr(mas, m, m, i, 0);
      d = d + k * mas[i][0] * Determinant(p, m - 1);
      k = -k;
    }
  }
  Free(p, m-1);
  return(d);
}

// Обратная матрица
double** Mreverse(double** mas, int m)
{
  double** rez = (double**)malloc(m * sizeof(double*));
  double det = Determinant(mas, m); // находим определитель исходной матрицы
  for (int i = 0; i < m; i++)
  {
    rez[i] = (double*)malloc(m * sizeof(double));
    for (int j = 0; j < m; j++)
    {
      rez[i][j] = Determinant(GetMatr(mas, m, m, i, j), m - 1);
      if ((i + j) % 2 == 1)       // если сумма индексов строки и столбца нечетная
        rez[i][j] = -rez[i][j];    // меняем знак минора
      rez[i][j] = rez[i][j] / det;
    }
  }
  return Transpone(rez, m, m);
}

int main() 
{
  int n;
  double** mas;
  int* b;
  system("chcp 1251");
  system("cls");
  printf("Введите размерность матрицы: ");
  scanf("%d", &n);
  mas = Input(n, n);
  printf("Исходная матрица: \n");
  Output(mas, n, n);
  // Находим обратную матрицу
  double** mas_reverse = Mreverse(mas, n);
  printf("\nОбратная матрица: \n");
  Output(mas_reverse, n, n);
  // Освобождаем память
  Free(mas_reverse, n);
  Free(mas, n);
  getchar(); getchar();
  return 0;
}

Результат выполнения

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Прокрутить вверх