Вычисление обратной матрицы
Теперь, когда мы реализовали функции для вычисления определителя и присоединенной матрицы (adjoint) матрицы, мы, наконец, можем вычислить обратную матрицу. Как упоминалось ранее, формула для нахождения обратной:
Обратная(A) = Присоединенная(A) / Определитель(A)
На этом заключительном этапе мы:
- Реализуем функцию обращения матрицы
- Создадим полную программу, которая считывает матрицу и вычисляет ее обратную
- Добавим улучшенное форматирование вывода для лучшей читаемости
Давайте создадим новый файл для этого заключительного этапа:
- Создайте новый файл с именем
matrix_inverse.c
в каталоге ~/project
Скопируйте следующий код в файл:
#include <stdio.h>
#define MAX_SIZE 10
// Function to read matrix elements from user
void readMatrix(int matrix[MAX_SIZE][MAX_SIZE], int size) {
printf("Enter the elements of the %dx%d matrix:\n", size, size);
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
printf("Enter element [%d][%d]: ", i, j);
scanf("%d", &matrix[i][j]);
}
}
}
// Function to get cofactor of matrix[p][q] in temp[][]
void getCofactor(int matrix[MAX_SIZE][MAX_SIZE], int temp[MAX_SIZE][MAX_SIZE],
int p, int q, int n) {
int i = 0, j = 0;
for (int row = 0; row < n; row++) {
for (int col = 0; col < n; col++) {
if (row != p && col != q) {
temp[i][j++] = matrix[row][col];
if (j == n - 1) {
j = 0;
i++;
}
}
}
}
}
// Recursive function to find determinant of matrix
int determinant(int matrix[MAX_SIZE][MAX_SIZE], int n) {
int det = 0;
if (n == 1)
return matrix[0][0];
int temp[MAX_SIZE][MAX_SIZE];
int sign = 1;
for (int f = 0; f < n; f++) {
getCofactor(matrix, temp, 0, f, n);
det += sign * matrix[0][f] * determinant(temp, n - 1);
sign = -sign;
}
return det;
}
// Function to calculate the adjoint of a matrix
void adjoint(int matrix[MAX_SIZE][MAX_SIZE], int adj[MAX_SIZE][MAX_SIZE], int n) {
if (n == 1) {
adj[0][0] = 1;
return;
}
int sign = 1;
int temp[MAX_SIZE][MAX_SIZE];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
// Get cofactor of matrix[i][j]
getCofactor(matrix, temp, i, j, n);
// Sign of adj[j][i] positive if sum of row and column indices is even
sign = ((i + j) % 2 == 0) ? 1 : -1;
// Interchanging rows and columns to get the transpose of the cofactor matrix
adj[j][i] = sign * determinant(temp, n - 1);
}
}
}
// Function to calculate the inverse of a matrix
int inverse(int matrix[MAX_SIZE][MAX_SIZE], float inverse[MAX_SIZE][MAX_SIZE], int n) {
// Find determinant of matrix
int det = determinant(matrix, n);
// If determinant is zero, matrix is not invertible
if (det == 0) {
printf("Matrix is not invertible as determinant is zero.\n");
return 0;
}
// Find adjoint of matrix
int adj[MAX_SIZE][MAX_SIZE];
adjoint(matrix, adj, n);
// Find inverse by dividing adjoint by determinant
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
inverse[i][j] = adj[i][j] / (float)det;
}
}
return 1;
}
// Function to display an integer matrix
void displayMatrix(int matrix[MAX_SIZE][MAX_SIZE], int size) {
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
printf("%d\t", matrix[i][j]);
}
printf("\n");
}
}
// Function to display a float matrix (for inverse)
void displayFloatMatrix(float matrix[MAX_SIZE][MAX_SIZE], int size) {
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
printf("%.4f\t", matrix[i][j]);
}
printf("\n");
}
}
int main() {
int matrix[MAX_SIZE][MAX_SIZE];
float inv[MAX_SIZE][MAX_SIZE];
int size;
// Get matrix size from user
printf("Matrix Inverse Calculator\n");
printf("=========================\n");
printf("Enter the size of the square matrix (1-%d): ", MAX_SIZE);
scanf("%d", &size);
// Validate matrix size
if (size <= 0 || size > MAX_SIZE) {
printf("Invalid matrix size. Please enter a size between 1 and %d.\n", MAX_SIZE);
return 1;
}
// Read matrix elements
readMatrix(matrix, size);
// Display the original matrix
printf("\nOriginal Matrix:\n");
displayMatrix(matrix, size);
// Calculate and display the determinant
int det = determinant(matrix, size);
printf("\nDeterminant of the matrix is: %d\n", det);
// Calculate and display the inverse
if (inverse(matrix, inv, size)) {
printf("\nInverse Matrix:\n");
displayFloatMatrix(inv, size);
}
return 0;
}
Давайте разберем ключевые новые компоненты этого кода:
-
inverse()
- Эта функция вычисляет обратную матрицу путем:
- Нахождения определителя
- Проверки, является ли определитель ненулевым (обратимым)
- Вычисления присоединенной матрицы
- Деления каждого элемента присоединенной матрицы на определитель
-
displayFloatMatrix()
- Новая функция для отображения обратной матрицы с точностью до плавающей точки, поскольку элементы обратной матрицы не обязательно являются целыми числами.
Понимание обращения матрицы:
Для матрицы A обратная A^(-1) удовлетворяет уравнению: A × A^(-1) = A^(-1) × A = I, где I – единичная матрица.
Формула, которую мы используем: A^(-1) = adj(A) / det(A)
Теперь давайте скомпилируем и запустим нашу программу:
-
Скомпилируйте программу следующей командой:
cd ~/project
gcc matrix_inverse.c -o matrix_inverse
-
Запустите программу:
./matrix_inverse
Вы должны увидеть вывод, похожий на этот:
Matrix Inverse Calculator
=========================
Enter the size of the square matrix (1-10): 3
Enter the elements of the 3x3 matrix:
Enter element [0][0]: 4
Enter element [0][1]: 3
Enter element [0][2]: 1
Enter element [1][0]: 0
Enter element [1][1]: -1
Enter element [1][2]: 2
Enter element [2][0]: -3
Enter element [2][1]: 3
Enter element [2][2]: 1
Original Matrix:
4 3 1
0 -1 2
-3 3 1
Determinant of the matrix is: 37
Inverse Matrix:
0.0270 0.1351 -0.1351
0.2432 -0.0541 -0.2432
-0.1081 0.4865 0.1081
Давайте проверим результат: произведение исходной матрицы и ее обратной должно быть очень близко к единичной матрице. Вы можете проверить это вручную для небольших матриц.
Для примера 2×2, давайте попробуем:
Matrix Inverse Calculator
=========================
Enter the size of the square matrix (1-10): 2
Enter the elements of the 2x2 matrix:
Enter element [0][0]: 4
Enter element [0][1]: 7
Enter element [1][0]: 2
Enter element [1][1]: 6
Original Matrix:
4 7
2 6
Determinant of the matrix is: 10
Inverse Matrix:
0.6000 -0.7000
-0.2000 0.4000
Для матрицы 2×2 вы можете легко проверить обратную, используя формулу:
Для матрицы A = [[a, b], [c, d]], обратная:
A^(-1) = (1/det(A)) × [[d, -b], [-c, a]]
где det(A) = a×d - b×c
В нашем примере:
det(A) = 4×6 - 7×2 = 24 - 14 = 10
A^(-1) = (1/10) × [[6, -7], [-2, 4]] = [[0.6, -0.7], [-0.2, 0.4]]
Поздравляем! Теперь вы успешно реализовали полный калькулятор обратной матрицы на C.