当前位置: 首页 > news >正文

C语言计算矩阵的逆

在线性代数中,求一个矩阵的逆矩阵通常运算量很大。运用本程序可以快速实现这一过程。

数学原理

要求一个矩阵的逆,该矩阵需要满足一定的条件:为一个方阵,且其行列式的值不为0。因此,本程序需要先验证矩阵的行列式不为0,再进一步求其逆矩阵。
逆矩阵的计算公式如下:
A−1=1det(A)A∗A^{-1}=\frac{1}{det(A)}A^* A1=det(A)1A
其中A*为A的伴随矩阵:
A∗=(A11A21⋯An1A12A22⋯An2⋮⋮⋮A1nA2n⋯Ann)A^*=\begin{pmatrix} A_{11}&A_{21}&\cdots&A_{n1} \\ A_{12}&A_{22}&\cdots&A_{n2} \\ \vdots&\vdots&&\vdots \\ A_{1n}&A_{2n}&\cdots&A_{nn} \\ \end{pmatrix} A=A11A12A1nA21A22A2nAn1An2Ann
其中,Aij是aij关于行列式det(A)的代数余子式。

完整代码

#include <stdio.h>
#include "solve_det.h"int algebraic_cofactor(int det[], int n, int i, int j) {int cofactor[(n-1)*(n-1)];for (int r = 0; r < i; r++) {for (int c = 0; c < j; c++) {cofactor[r*(n-1)+c] = det[r*n+c];}for (int c = j + 1; c < n; c++) {cofactor[r*(n-1)+c-1] = det[r*n+c];}}for (int r = i + 1; r < n; r++) {for (int c = 0; c < j; c++) {cofactor[(r-1)*(n-1)+c] = det[r*n+c];}for (int c = j + 1; c < n; c++) {cofactor[(r-1)*(n-1)+c-1] = det[r*n+c];}}int result = solve_det(cofactor, n - 1);if ((i + j) % 2 == 1) {result = -result;}return result;
}int main() {int n;printf("n = ");scanf("%d", &n);int det[n*n];for (int r = 0; r < n; r++) {printf("row %d: ", r + 1);for (int c = 0; c < n; c++) {scanf("%d", &det[r*n+c]);}}int DET = solve_det(det, n);if (DET == 0) {printf("The matrix is not invertible!");return 0;}else {double adjoint_matrix[n][n];for (int r = 0; r < n; r++) {for (int c = 0; c < n; c++) {adjoint_matrix[r][c] = 1.0 * algebraic_cofactor(det, n, c, r) / DET;}}printf("\nresult:");for (int r = 0; r < n; r++) {printf("\nrow %d: ", r + 1);for (int c = 0; c < n; c++) {printf("%.2f ", adjoint_matrix[r][c]);}}return 0;}
} 

其中,头文件solve_det.h的代码如下:

void swap(int *a, int *b) {int temp = *a;*a = *b;*b = temp;
}int odd_even(int list[], int size) {int o_e = 1;for (int i = 0; i < size; i++) {for (int j = i + 1; j < size; j++) {if (list[i] > list[j]) {o_e = -o_e;}}}return o_e;
}int last(int list[], int size) {for (int i = 0; i < size; i++) {if (list[i] != size - i - 1) {return 0;}}return 1;
}void sort(int list[], int size, int first) {int smallest, smallestx;for (int i = first; i < size - 1; i++) {smallest = size;for (int j = i; j < size; j++) {if (list[j] < smallest) {smallest = list[j];smallestx = j;}}swap(&list[i], &list[smallestx]);}
}void next(int list[], int size) {int bigger, biggerx, first;for (int i = size - 2; i >= 0; i--) {first = list[i];bigger = size + 1;for (int j = i + 1; j < size; j++) {if (list[j] > first && list[j] < bigger) {bigger = list[j];biggerx = j;}}if (bigger < size + 1) {swap(&list[i], &list[biggerx]);sort(list, size, i + 1);return;}}
}int solve_det(int det[], int n) {int nums[n];for (int i = 0; i < n; i++) {nums[i] = i;}int result = 0, r;while (1) {r = odd_even(nums, n);for (int k = 0; k < n; k++) {r *= det[k*n+nums[k]];}result += r;if (last(nums, n)) {return result;}else {next(nums, n);}}
}

代码解释

关于solve_det.h的解释可以在博文《C语言计算行列式的值》中找到,区别仅仅是把主函数中的内容转移至了solve_det函数中。为了传参方便,原本以二维数组形式表示的行列式det被改成了等效的一维数组,即将n×n个元素按行和列的原顺序放入n*n的一维数组中。
下面对本程序的代码进行逐段解释。

求代数余子式函数algebraic_cofactor

这段代码的作用是求一个矩阵中指定位置(第i行第j列)元素的代数余子式。首先,去除该元素所在的行和列上的所有元素,得到一个n-1阶的矩阵cofactor,即为余子式:

int cofactor[(n-1)*(n-1)];
for (int r = 0; r < i; r++) {for (int c = 0; c < j; c++) {cofactor[r*(n-1)+c] = det[r*n+c];}for (int c = j + 1; c < n; c++) {cofactor[r*(n-1)+c-1] = det[r*n+c];}
}
for (int r = i + 1; r < n; r++) {for (int c = 0; c < j; c++) {cofactor[(r-1)*(n-1)+c] = det[r*n+c];}for (int c = j + 1; c < n; c++) {cofactor[(r-1)*(n-1)+c-1] = det[r*n+c];}
}

同样,cofactor也是以一维数组的形式对二维数组进行等效表示。然后,调用solve_det函数求余子式的值:

int result = solve_det(cofactor, n - 1);

最后,需要乘上系数(−1)i+j(-1)^{i+j}(1)i+j,即只需在i+j为奇数时,将result取为自身的相反数,并返回:

if ((i + j) % 2 == 1) {result = -result;
}
return result;

主函数Part1:输入矩阵阶数及所有元素

本部分的代码与《C语言计算行列式的值》中的相同,不再赘述。

int n;
printf("n = ");
scanf("%d", &n);int det[n*n];for (int r = 0; r < n; r++) {printf("row %d: ", r + 1);for (int c = 0; c < n; c++) {scanf("%d", &det[r*n+c]);}}

主函数Part2:检验矩阵满足求逆的条件

int DET = solve_det(det, n);if (DET == 0) {printf("The matrix is not invertible!");return 0;
}

当矩阵行列式的值DET为0时中止程序,否则进行后续步骤:

主函数Part3:求矩阵的逆

else {double adjoint_matrix[n][n];for (int r = 0; r < n; r++) {for (int c = 0; c < n; c++) {adjoint_matrix[r][c] = 1.0 * algebraic_cofactor(det, n, c, r) / DET;}}printf("\nresult:");for (int r = 0; r < n; r++) {printf("\nrow %d: ", r + 1);for (int c = 0; c < n; c++) {printf("%.2f ", adjoint_matrix[r][c]);}}return 0;}

按照矩阵的逆的公式求值。由于需要将伴随矩阵的每一项除以DET,因此可能会出现浮点数,将adjoint_matrix的元素类型设定为double。打印结果时设定保留小数点后两位。

运行结果示例

当行列式的值为0时中止程序:
运行结果示例1
一个正确计算的矩阵的逆:
运行结果示例2

http://www.dtcms.com/a/438688.html

相关文章:

  • 如何传递上层变数到编译过的模组当中
  • 广东十大网站建设外贸公司招聘条件
  • C语言类型转换与错误处理
  • 线上宣传方式昆明网络推广优化
  • 日语学习-日语知识点小记-进阶-JLPT-N1阶段应用练习(3):语法 +考え方16+2022年7月N1
  • 51单片机AD/DA
  • 九.寄生参数对变换器参数设计的影响
  • MapSet练习OJ题讲解(2易2中1难)
  • 1.2.1 RAG:构建你的专属知识库
  • 做网站找个人还是公司电商网站建设的意义
  • 网站开发人员定罪成都系统网站建设
  • 小迪web自用笔记49
  • win7 不能安装 scales 1.4.0,ggplot2,无法找到动态链接库的注入点
  • 厦门模板网站极简风格 网站
  • 第四届人工智能与智能信息处理国际学术会议(AIIIP 2025)
  • 网站建设与维护的试卷易点网络科技有限公司
  • wordpress标签调用代码优化师证书
  • 基于ECA-ResNet50的OAM光束相位重建:深度学习在光学涡旋场分析中的突破性应用
  • 搭建nginx的高性能web集群
  • 四川省城乡和建设厅网站微信公众上传wordpress
  • 从单词到语素的形态学
  • c++之基础A(自定义函数)(第二课)
  • 单图像去雨研究综述
  • REST架构的6大约束与API
  • 深圳婚纱摄影网站建设网络维护工程师工资多少
  • 北京企业网站搭建wordpress 国际化
  • uniappx几个生命周期说明
  • 网站推广策划思路的内容企业网组建
  • R语言绘制股票K线图及布林线
  • 【C++】26. 智能指针