介绍
在这个实验中,你将学习如何使用 C 编程计算方阵的逆矩阵。逆矩阵是线性代数中的一个重要概念,它在求解线性方程组、计算机图形学、数据分析以及许多科学计算领域都有应用。
我们将通过几个步骤来探索矩阵求逆的过程:从用户输入读取一个方阵,计算矩阵的行列式和伴随矩阵,最后使用这些值计算逆矩阵。这个实验将提供用 C 代码实现这些数学运算的实践经验,加强你对编程概念和线性代数原理的理解。
通过这个实验,你将能够实现一个完整的矩阵求逆程序,并理解该过程中涉及的底层数学技术。
在这个实验中,你将学习如何使用 C 编程计算方阵的逆矩阵。逆矩阵是线性代数中的一个重要概念,它在求解线性方程组、计算机图形学、数据分析以及许多科学计算领域都有应用。
我们将通过几个步骤来探索矩阵求逆的过程:从用户输入读取一个方阵,计算矩阵的行列式和伴随矩阵,最后使用这些值计算逆矩阵。这个实验将提供用 C 代码实现这些数学运算的实践经验,加强你对编程概念和线性代数原理的理解。
通过这个实验,你将能够实现一个完整的矩阵求逆程序,并理解该过程中涉及的底层数学技术。
在这一步,你将创建一个程序,从用户输入读取一个方阵。方阵的行数和列数相等,这是计算矩阵逆矩阵的要求。
首先,让我们了解一下我们需要做什么:
让我们从在项目目录中创建一个新的 C 文件开始:
~/project 目录下创建一个名为 matrix_input.c 的新文件将以下代码复制到文件中:
#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 display the matrix
void displayMatrix(int matrix[MAX_SIZE][MAX_SIZE], int size) {
printf("\nMatrix Contents:\n");
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
printf("%d\t", matrix[i][j]);
}
printf("\n");
}
}
int main() {
int matrix[MAX_SIZE][MAX_SIZE];
int size;
// Get matrix size from user
printf("Matrix Input Program\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 matrix
displayMatrix(matrix, size);
return 0;
}
让我们了解一下这段代码的关键组成部分:
#define MAX_SIZE 10 - 这定义了最大矩阵大小的常量readMatrix() - 一个使用嵌套循环读取矩阵每个元素的函数displayMatrix() - 一个以表格形式打印矩阵的函数main() 函数中,我们从用户那里获取大小并在读取矩阵之前验证它现在,让我们编译并运行我们的程序:
在 WebIDE 中打开一个终端
使用以下命令编译程序:
cd ~/project
gcc matrix_input.c -o matrix_input
运行程序:
./matrix_input
你应该看到类似于这样的输出:
Matrix Input Program
====================
Enter the size of the square matrix (1-10): 3
Enter the elements of the 3x3 matrix:
Enter element [0][0]: 1
Enter element [0][1]: 2
Enter element [0][2]: 3
Enter element [1][0]: 4
Enter element [1][1]: 5
Enter element [1][2]: 6
Enter element [2][0]: 7
Enter element [2][1]: 8
Enter element [2][2]: 9
Matrix Contents:
1 2 3
4 5 6
7 8 9
你现在已经成功创建了一个从用户输入读取方阵并显示它的程序。这是我们矩阵求逆计算过程的第一步。
在计算矩阵的逆矩阵之前,我们需要理解并实现两个关键的数学运算:求矩阵的行列式和余子式。行列式是从方阵导出的标量值,它在确定矩阵是否可逆方面起着至关重要的作用。
在这一步,你将:
让我们为这一步创建一个新文件:
~/project 目录下创建一个名为 matrix_determinant.c 的新文件将以下代码复制到文件中:
#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;
// Looping for each element of the matrix
for (int row = 0; row < n; row++) {
for (int col = 0; col < n; col++) {
// Copying into temporary matrix only those elements
// which are not in given row and column
if (row != p && col != q) {
temp[i][j++] = matrix[row][col];
// Row is filled, so increase row index and
// reset column index
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; // Initialize result
// Base case: if matrix contains single element
if (n == 1)
return matrix[0][0];
int temp[MAX_SIZE][MAX_SIZE]; // To store cofactors
int sign = 1; // To store sign multiplier
// Iterate for each element of first row
for (int f = 0; f < n; f++) {
// Getting cofactor of matrix[0][f]
getCofactor(matrix, temp, 0, f, n);
// Adding to determinant with appropriate sign
det += sign * matrix[0][f] * determinant(temp, n - 1);
// Alternating sign factor
sign = -sign;
}
return det;
}
// Function to display the matrix
void displayMatrix(int matrix[MAX_SIZE][MAX_SIZE], int size) {
printf("\nMatrix Contents:\n");
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
printf("%d\t", matrix[i][j]);
}
printf("\n");
}
}
int main() {
int matrix[MAX_SIZE][MAX_SIZE];
int size;
// Get matrix size from user
printf("Matrix Determinant 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 matrix
displayMatrix(matrix, size);
// Calculate and display the determinant
int det = determinant(matrix, size);
printf("\nDeterminant of the matrix is: %d\n", det);
// Check if matrix is invertible
if (det == 0) {
printf("The matrix is not invertible (determinant is zero).\n");
} else {
printf("The matrix is invertible (determinant is non-zero).\n");
}
return 0;
}
让我们了解一下这段代码的关键组成部分:
getCofactor() - 此函数通过删除特定的行和列来提取一个子矩阵。这对于计算行列式和伴随矩阵至关重要。determinant() - 一个递归函数,它使用余子式展开法计算矩阵的行列式。理解数学概念:
余子式:对于矩阵中的每个元素,余子式是删除该元素的行和列后形成的子矩阵的行列式,乘以 (-1)^(i+j),其中 i, j 是行和列的索引。
行列式:行列式是从方阵计算出的一个特殊数字。对于 2×2 矩阵 [[a,b],[c,d]],行列式是 (a×d - b×c)。对于更大的矩阵,我们使用余子式展开。
可逆性:只有当矩阵的行列式不为零时,矩阵才是可逆的。
现在,让我们编译并运行我们的程序:
使用以下命令编译程序:
cd ~/project
gcc matrix_determinant.c -o matrix_determinant
运行程序:
./matrix_determinant
你应该看到类似于这样的输出:
Matrix Determinant Calculator
=============================
Enter the size of the square matrix (1-10): 3
Enter the elements of the 3x3 matrix:
Enter element [0][0]: 1
Enter element [0][1]: 2
Enter element [0][2]: 3
Enter element [1][0]: 0
Enter element [1][1]: 1
Enter element [1][2]: 4
Enter element [2][0]: 5
Enter element [2][1]: 6
Enter element [2][2]: 0
Matrix Contents:
1 2 3
0 1 4
5 6 0
Determinant of the matrix is: 49
The matrix is invertible (determinant is non-zero).
尝试输入不同的矩阵,包括一些行列式为零的矩阵,看看程序的行为。例如,如果你输入一个矩阵,其中一行是另一行的倍数,那么行列式应该为零。
你现在已经成功实现了行列式计算,这是求矩阵逆矩阵的关键组成部分。
计算矩阵逆矩阵的下一步是计算矩阵的伴随矩阵(也称为伴随矩阵)。矩阵的伴随矩阵是余子式矩阵的转置。一旦我们有了矩阵的伴随矩阵和行列式,我们就可以使用以下公式计算逆矩阵:
逆矩阵 (A) = 伴随矩阵 (A) / 行列式 (A)
在这一步,你将:
让我们为这一步创建一个新文件:
~/project 目录下创建一个名为 matrix_adjoint.c 的新文件将以下代码复制到文件中:
#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 display the 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");
}
}
int main() {
int matrix[MAX_SIZE][MAX_SIZE];
int adj[MAX_SIZE][MAX_SIZE];
int size;
// Get matrix size from user
printf("Matrix Adjoint 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 the adjoint
adjoint(matrix, adj, size);
// Display the adjoint matrix
printf("\nAdjoint Matrix:\n");
displayMatrix(adj, size);
// Calculate and display the determinant
int det = determinant(matrix, size);
printf("\nDeterminant of the matrix is: %d\n", det);
return 0;
}
让我们了解一下这段代码的关键新组件:
adjoint() - 此函数计算矩阵的伴随矩阵,它是余子式矩阵的转置。对于矩阵中的每个元素 (i, j),我们:
理解伴随矩阵的计算:
矩阵 A 的伴随矩阵(或伴随矩阵)表示为 adj(A)。对于 2×2 矩阵:
A = [a b]
[c d]
伴随矩阵是:
adj(A) = [ d -b]
[-c a]
对于更大的矩阵,我们计算每个元素的余子式,然后转置结果矩阵。
现在,让我们编译并运行我们的程序:
使用以下命令编译程序:
cd ~/project
gcc matrix_adjoint.c -o matrix_adjoint
运行程序:
./matrix_adjoint
你应该看到类似于这样的输出:
Matrix Adjoint Calculator
=========================
Enter the size of the square matrix (1-10): 3
Enter the elements of the 3x3 matrix:
Enter element [0][0]: 1
Enter element [0][1]: 0
Enter element [0][2]: 2
Enter element [1][0]: 3
Enter element [1][1]: 0
Enter element [1][2]: 4
Enter element [2][0]: 5
Enter element [2][1]: 0
Enter element [2][2]: 6
Original Matrix:
1 0 2
3 0 4
5 0 6
Adjoint Matrix:
0 0 0
-8 -4 4
0 0 0
Determinant of the matrix is: 0
请注意,在这个例子中,行列式为 0,这意味着矩阵不可逆。让我们尝试另一个可逆矩阵的例子:
Matrix Adjoint Calculator
=========================
Enter the size of the square matrix (1-10): 3
Enter the elements of the 3x3 matrix:
Enter element [0][0]: 5
Enter element [0][1]: -2
Enter element [0][2]: 2
Enter element [1][0]: 1
Enter element [1][1]: 0
Enter element [1][2]: 3
Enter element [2][0]: 3
Enter element [2][1]: 1
Enter element [2][2]: 4
Original Matrix:
5 -2 2
1 0 3
3 1 4
Adjoint Matrix:
-3 11 -5
13 14 -11
-1 -7 2
Determinant of the matrix is: 15
在这种情况下,行列式为 15(非零),这意味着我们可以计算该矩阵的逆矩阵。你现在已经成功实现了伴随矩阵的计算,这是矩阵求逆的倒数第二步。
现在你已经实现了计算矩阵的行列式和伴随矩阵的函数,你终于可以计算矩阵的逆矩阵了。如前所述,求逆矩阵的公式是:
逆矩阵 (A) = 伴随矩阵 (A) / 行列式 (A)
在最后一步,你将:
让我们为最后一步创建一个新文件:
~/project 目录下创建一个名为 matrix_inverse.c 的新文件将以下代码复制到文件中:
#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 语言实现了一个完整的矩阵逆矩阵计算器。
在这个实验中,你已经用 C 语言编程实现了一个完整的矩阵逆矩阵计算器。在整个实验过程中,你探索了几个关键概念,并逐步实现了它们:
你首先创建了一个程序,从用户输入中读取一个方阵并显示它,学习了如何在 C 语言中处理二维数组。
然后,你使用余子式展开法实现了行列式的计算,这是一种递归方法,构成了矩阵求逆的基础。
接下来,你基于你的代码构建了计算矩阵的伴随矩阵,它是余子式矩阵的转置。
最后,你将所有这些组件结合起来,使用公式:逆矩阵 = 伴随矩阵 / 行列式,计算了矩阵的逆矩阵。
这些数学运算是线性代数的基础,并在各个领域都有广泛的应用,包括计算机图形学、机器学习、求解线性方程组等等。
该实现展示了几个编程概念,例如:
通过完成这个实验,你获得了矩阵运算(特别是矩阵求逆)的数学理论和编程实现的实践经验。