C语言求逆矩阵案例详解
更新时间:2021年8月16日 12:00 点击:1677
一般求逆矩阵的方法有两种,伴随阵法和初等变换法。但是这两种方法都不太适合编程。伴随阵法的计算量大,初等变换法又难以编程实现。
适合编程的求逆矩阵的方法如下:
- 对可逆矩阵A进行QR分解:A=QR
- 求上三角矩阵R的逆矩阵
- 求出A的逆矩阵:A^(-1)=R^(-1)Q^(H)
以上三步都有具体的公式与之对应,适合编程实现。
C语言实现代码:
#include <stdio.h> #include <math.h> #define SIZE 8 double b[SIZE][SIZE]={0};//应该读作“贝尔塔”,注释中用B表示 double t[SIZE][SIZE]={0};//求和的那项 double Q[SIZE][SIZE]={0};//正交矩阵 double QH[SIZE][SIZE]={0};//正交矩阵的转置共轭 double R[SIZE][SIZE]={0};// double invR[SIZE][SIZE]={0};//R的逆矩阵 double invA[SIZE][SIZE]={0};//A的逆矩阵,最终的结果 //={0};// double matrixR1[SIZE][SIZE]={0}; double matrixR2[SIZE][SIZE]={0}; //double init[3][3]={3,14,9,6,43,3,6,22,15}; double init[8][8]={ 0.0938 , 0.5201 , 0.4424 , 0.0196 , 0.3912 , 0.9493 , 0.9899 , 0.8256, 0.5254 , 0.3477 , 0.6878 , 0.3309 , 0.7691 , 0.3276 , 0.5144 , 0.7900, 0.5303 , 0.1500 , 0.3592 , 0.4243 , 0.3968 , 0.6713 , 0.8843 , 0.3185, 0.8611 , 0.5861 , 0.7363 , 0.2703 , 0.8085 , 0.4386 , 0.5880 , 0.5341, 0.4849 , 0.2621 , 0.3947 , 0.1971 , 0.7551 , 0.8335 , 0.1548 , 0.0900, 0.3935 , 0.0445 , 0.6834 , 0.8217 , 0.3774 , 0.7689 , 0.1999 , 0.1117, 0.6714 , 0.7549 , 0.7040 , 0.4299 , 0.2160 , 0.1673 , 0.4070 , 0.1363, 0.7413 , 0.2428 , 0.4423 , 0.8878 , 0.7904 , 0.8620 , 0.7487 , 0.6787 }; /*/ 函数名:int main() 输入: 输出: 功能:求矩阵的逆 pure C language 首先对矩阵进行QR分解之后求上三角矩阵R的逆阵最后A-1=QH*R-1,得到A的逆阵。 作者:HLdongdong *////////////////////////////////////////////////////////////////////// int main() { int i;//数组 行 int j;//数组 列 int k;//代表B的角标 int l;//数组 列 double dev; double numb;//计算的中间变量 double numerator,denominator; double ratio; /////////////////求B///////////////// for(i=0;i<SIZE;++i) { for(j=0;j<SIZE;++j) { b[j][i]=init[j][i]; } for(k=0;k<i;++k) { if(i) { numerator=0.0; denominator=0.0; for(l=0;l<SIZE;++l) { numerator+=init[l][i]*b[l][k]; denominator+=b[l][k]*b[l][k]; } dev=numerator/denominator; t[k][i]=dev; for(j=0;j<SIZE;++j) { b[j][i]-=t[k][i]*b[j][k];//t init =0 !!! } } } } ///////////////////对B单位化,得到正交矩阵Q矩阵//////////////////// for(i=0;i<SIZE;++i) { numb=0.0; for(j=0;j<SIZE;++j) { numb+=(b[j][i]*b[j][i]); } dev=sqrt(numb); for(j=0;j<SIZE;++j) { Q[j][i]=b[j][i]/dev; } matrixR1[i][i]=dev; } /////////////////////求上三角R阵/////////////////////// for(i=0;i<SIZE;++i) { for(j=0;j<SIZE;++j) { if(j<i) { matrixR2[j][i]=t[j][i]; } else if(j==i) { matrixR2[j][i]=1; } else { matrixR2[j][i]=0; } } } mulMatrix(matrixR1,matrixR2,SIZE,SIZE,SIZE,R); ///////////////////////QR分解完毕////////////////////////// printf("QR分解:\n"); printf("Q=\n"); for(i=0;i<SIZE;++i) { for(j=0;j<SIZE;++j) { printf("%2.4f ",Q[i][j]); // } printf("\n"); } printf("R=\n"); for(i=0;i<SIZE;++i) { for(j=0;j<SIZE;++j) { printf("%2.4f ",R[i][j]); // } printf("\n"); } /////////////////////求R的逆阵////////////////////////// for(i=SIZE-1;i>=0;--i) { invR[i][i]=1/R[i][i]; //R[i][i]=invR[i][i]; if(i!=(SIZE-1))//向右 { for(j=i+1;j<SIZE;++j) { invR[i][j]=invR[i][j]*invR[i][i]; R[i][j]=R[i][j]*invR[i][i]; } } if(i)//向上 { for(j=i-1;j>=0;--j) { ratio=R[j][i]; for(k=i;k<SIZE;++k) { invR[j][k]-=ratio*invR[i][k]; R[j][k]-=ratio*R[i][k]; } } } } /////////////////////////////////////////////////////// printf("inv(R)=\n"); for(i=0;i<SIZE;++i) { for(j=0;j<SIZE;++j) { printf(" %2.4f ",invR[i][j]); // } printf("\n"); } ////////////////////结果和MATLAB差一个负号,神马鬼????????///////////////////// /////////////////////求QH////////////////////////// for(i=0;i<SIZE;++i)//实矩阵就是转置 { for(j=0;j<SIZE;++j) { QH[i][j]=Q[j][i]; } } ///////////////////////求A的逆阵invA///////////////////////////// mulMatrix(invR,QH,SIZE,SIZE,SIZE,invA); printf("inv(A)=\n"); for(i=0;i<SIZE;++i) { for(j=0;j<SIZE;++j) { printf(" %2.4f ",invA[i][j]); // } printf("\n"); } ///////////////////////结果与MATLAB的结果在千分位后有出入,但是负号都是对的^v^/////////////////////////// return 0; }
另附上矩阵乘法的子函数
/*/ 函数名:void mulMatrix(double matrix1[SIZE][SIZE],double matrix2[SIZE][SIZE],int high1,int weight,int weight2,double mulMatrixOut[SIZE][SIZE]) 输入:依次是 左矩阵,右矩阵,左矩阵高度,左矩阵宽度,右矩阵宽度,输出矩阵 输出: 功能:矩阵乘法 作者:HLdongdong *// void mulMatrix(double matrix1[SIZE][SIZE],double matrix2[SIZE][SIZE],int high1,int weight,int weight2,double mulMatrixOut[SIZE][SIZE]) { int i,j,k; for(i=0;i<high1;++i) { for(j=0;j<weight2;j++) { for(k=0;k<weight;++k) { mulMatrixOut[i][j]+=matrix1[i][k]*matrix2[k][j]; } } } }
到此这篇关于C语言求逆矩阵案例详解的文章就介绍到这了,更多相关C语言求逆矩阵内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!
上一篇: 带你了解C语言的数据的存储
相关文章
- 这篇文章主要为大家详细介绍了C语言实现放烟花的程序,有音乐播放,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-02-23
- 本篇文章主要介绍C语言中char的知识,并附有代码实例,以便大家在学习的时候更好的理解,有需要的可以看一下...2020-04-25
- 这篇文章主要介绍了详解如何将c语言文件打包成exe可执行程序,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-25
- free函数是释放之前某一次malloc函数申请的空间,而且只是释放空间,并不改变指针的值。下面我们就来详细探讨下...2020-04-25
详解C语言中的rename()函数和remove()函数的使用方法
这篇文章主要介绍了详解C语言中的rename()函数和remove()函数的使用方法,是C语言入门学习中的基础知识,需要的朋友可以参考下...2020-04-25- 这篇文章主要介绍了C语言中计算正弦的相关函数总结,包括正弦和双曲线正弦以及反正弦的函数,需要的朋友可以参考下...2020-04-25
- 这篇文章主要介绍了C语言中求和、计算平均值、方差和标准差的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-12-10
- 本篇文章主要讲解C语言 基本语法,这里提供简单的示例和代码来详细讲解C语言的基本语法,开始学习C语言的朋友可以看一下,希望能够给你带来帮助...2021-09-18
- 这篇文章主要介绍了C语言中send()函数和sendto()函数的使用方法,是C语言入门学习中的基础知识,需要的朋友可以参考下...2020-04-25
- 这篇文章主要介绍了C语言中memcpy 函数的用法详解的相关资料,需要的朋友可以参考下...2020-04-25
- 这篇文章主要介绍了使用C语言操作文件的基本函数整理,包括创建和打开以及关闭文件的操作方法,需要的朋友可以参考下...2020-04-25
- 这篇文章主要介绍了C语言中查找字符在字符串中出现的位置的方法,分别是strchr()函数和strrchr()函数的使用,需要的朋友可以参考下...2020-04-25
- 很多同学在学习c语言的时候是不是会碰到a++和++a都有甚么作用啊。今天我们就来探讨下...2020-04-25
- 今天小编就为大家分享一篇C语言实现从文件读入一个3*3数组,并计算每行的平均值,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-04-25
- 下面小编就为大家带来一篇C语言实现时间戳转日期的算法(推荐)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-04-25
- 本文给大家简单介绍下c实现linux下的数据库备份的方法和具体的源码,十分的实用,有需要的小伙伴可以参考下。...2020-04-25
- 这篇文章主要介绍了C语言之整数划分问题(递归法)实例代码的相关资料,需要的朋友可以参考下...2020-04-25
- 这篇文章主要对C语言中const关键字的用法进行了详细的分析介绍,需要的朋友可以参考下...2020-04-25
- 这篇文章主要介绍了c语言实现找最大值最小值位置查找,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-04
C语言正则表达式详解 regcomp() regexec() regfree()用法详解
C语言处理正则表达式常用的函数有regcomp()、regexec()、regfree()和regerror(),这里就为大家介绍一下,需要的朋友可以参考一下啊...2020-04-25