矩阵求逆矩阵[通俗易懂]

矩阵求逆矩阵[通俗易懂]因为坐标系转换实现需要求系数矩阵,所以这里只介绍n*n维矩阵求逆矩阵的方法单位矩阵E定义:100…0010…0001…0000…1对角线上都

大家好,又见面了,我是你们的朋友全栈君。

因为坐标系转换实现需要求系数矩阵,所以这里只介绍n*n维矩阵求逆矩阵的方法

 

单位矩阵E定义:

1 0 0 … 0

0 1 0 … 0

0 0 1 … 0

0 0 0 … 1

对角线上都是1,其他位置全是0

 

矩阵相乘:

n*n维矩阵A和B相乘(我们用Aij表示A矩阵第i行第j列的值)

(A*B)ij = Ai1*B1j+Ai2*B2j+Ai3*B3j+…+Ain*Bnj

 

逆矩阵定义:

假设一个n*n维矩阵A,如果存在一个n*n维矩阵B,使得A*B=E,那么就说B是A的逆矩阵A-1,同样A也是B的逆矩阵B-1

一个矩阵的逆矩阵不是一定存在的(可以通过判断行列式的值(也就是矩阵的模)等不等于0来判断逆矩阵存不存在,等于0就不存在逆矩阵)

 

矩阵行列式求值方法:

矩阵求逆矩阵[通俗易懂]

 

我们需要了解等一下矩阵的初等变换

线性代数中,矩阵的初等行变换是指以下三种变换类型 :
(1) 交换矩阵的两行(对调i,j,两行记为ri,rj);
(2) 以一个非零数k乘矩阵的某一行所有元素(第i行乘以k记为ri×k);
(3) 把矩阵的某一行所有元素乘以一个数k后加到另一行对应的元素(第j行乘以k加到第i行记为ri+krj)。
类似地,把以上的“行”改为“列”便得到矩阵初等列变换的定义,把对应的记号“r”换为“c”。
矩阵的初等行变换与初等列变换合称为矩阵的初等变换。

 

我们需要知道使用初等变换对矩阵的模的值的改变

第一类初等变换(换行换列)使行列式变号。

第二类初等变换(某行或某列乘k倍)使行列式变k倍。

第三类初等变换(某行(列)乘k倍加到另一行(列))使行列式不变。

 

上三角矩阵定义:

主对角线以下都是零的方阵称为上三角矩阵。上三角矩阵具有行列式对角线元素相乘、上三角矩阵乘以系数后也是上三角矩阵、上三角矩阵间的加减法和乘法运算的结果仍是上三角矩阵等性质。

示例:

1 5 6 2
0 4 8 5
0 0 3 1
0 0 0 5
为一个上三角矩阵。

 

计算行列式或者矩阵的时候,可以行变换和列变换混着用吗?

1、计算行列式时,可以同时施加第一、第三类初等行/列变换,施加第二类变换时需要将行列式乘上相应的系数

2、求矩阵的秩时,也即求相抵标准形时,可以施加三种初等行变换,或施加三种初等列变换(不可混用)

3、和单位矩阵拼在一起求逆矩阵时,竖着拼就只能用列变换,横着拼就只能用行变换

4、解方程只能行变换

 

A矩阵的伴随矩阵A*的求法:

假设A为n阶矩阵,定义矩阵矩阵求逆矩阵[通俗易懂]为A的伴随矩阵,记作{A^*}

 

 矩阵求逆矩阵[通俗易懂],Mij是矩阵A去掉i行j列后,所得矩阵的行列式。

 

求矩阵逆矩阵的两种方法:

一、根据定义

A-1 = (1/|A|)*A*

矩阵求逆矩阵[通俗易懂]

求出来A矩阵的模和伴随矩阵就可以

 

二、构造分块矩阵(A|E)

把分块矩阵(A|E)的A使用初等变换化成E,那么右边的E在跟着A一起初等变换之后的矩阵就是A-1

原理(下图来源于:https://wenku.baidu.com/view/62c266db094e767f5acfa1c7aa00b52acec79c0c.html):

矩阵求逆矩阵[通俗易懂]

矩阵求逆矩阵[通俗易懂]

 

 

C++代码实现:

代码来源于:https://blog.csdn.net/XX_123_1_RJ/article/details/39268041?locationNum=5&fps=1

代码思想:

采用第二种方法计算逆矩阵

获取行列式的值:把矩阵化为上三角矩阵之后按照定义求矩阵的模(注意,因为代码中fun函数,把矩阵变成上三角矩阵使用了初等行变换的1,3规则,又因为第一条规则会影响到行列式值的正负,所以需要记录一下行交换了几次)

#include<iostream> #include<iomanip> using namespace std; int const n=3; //确定矩阵的节数  /* 作者 星星笔记 */ int main() { void temp(double aa[],double bb[],int n); double fun(double array[n][n]); double a[n][n],b[n][2*n],c[n][n],det1,yinzhi; double bb; int i,j,kk=0,k,u; for(i=0;i<n;i++) //初始化一个辅助矩阵  for(j=0;j<2*n;j++) b[i][j]=0; //---------输入原始矩阵---------------  cout<<"请输入一个"<<n<<"节方阵"<<endl; for(i=0;i<n;i++) for(j=0;j<n;j++) cin>>a[i][j]; //把矩阵a复制给矩阵b  for(i=0;i<n;i++) for(j=0;j<n;j++) b[i][j]=a[i][j]; for(j=0;j<n;j++) b[j][n+j]=1; //------------------------------------ //------------测试查看----------  /* cout<<"a所对应的at矩阵b为:"<<endl; for(i=0;i<n;i++) for(j=0;j<2*n;j++) { cout<<setw(6)<<b[i][j]; kk=kk+1; if(kk%(2*n)==0) cout<<endl; } */ //---------------------------------- // det1=fun(a);//获取行列式的值  for(i=0;i<n;i++) { // b[i][i] 等于 0 的情况 if(b[i][i]==0) for(j=i;j<n;j++) { if(b[j][i]!=0) temp(b[i],b[j],2*n); //交换两行   } // b[i][i] 不等于 0 的情况 for(k=i+1;k<n;k++) { yinzhi = -1 * b[k][i] / b[i][i]; for(u=0; u < 2*n; u++) { b[k][u] = b[k][u] + b[i][u] * yinzhi; } } } det1 = fun(a);// 获取行列式的值,把矩阵化为上三角矩阵之后按照定义求矩阵的模(注意,因为代码中把矩阵变成上三角矩阵使用了初等行变换的1,3规则,又因为第一条规则会影响到行列式值的正负,所以需要记录一下行交换了几次)  if(det1 == 0) // 如果行列式的值为0 则是不可逆的。  { cout<<"此矩阵不可逆:"<<endl; return 0; } if(det1 != 0) { for(i=0; i<n; i++) //左矩阵 的对角线 全部 转化为 1  { bb = b[i][i]; // bb 不会等于0 因为对角线有有一个为0 说明行列式的值为零, for(j=0; j<2*n; j++) b[i][j] = b[i][j] / bb; } for(i=n-1; i>0; i--) for(k=0; k<i; k++) { bb = b[k][i]; for(u=0; u<2*n; u++) b[k][u] = b[k][u] - bb*b[i][u]; } } //------------测试查看----------  /* cout<<"变化后的at矩阵"<<endl; for(i=0;i<n;i++) for(j=0;j<2*n;j++) { cout<<setw(6)<<b[i][j]; kk=kk+1; if(kk%(2*n)==0) cout<<endl; } cout<<endl; */ //------------------------------  for(i=0; i<n; i++) for(j=0; j<n; j++) c[i][j] = b[i][j+n]; kk = 0; if(det1!=0) //输出逆矩阵   { cout<<"其可逆且其行列式的值det为:"<<det1<<endl<<endl; cout<<"可逆a矩阵的逆矩阵为c矩阵:"<<endl; for(i=0; i<n; i++) for(j=0; j<n; j++) { cout<<setw(15)<<c[i][j]; kk = kk+1; if(kk%n == 0) cout<<endl; } } return 0; } void temp(double aa[],double bb[],int n) { //交换数组指定的两行,即进行行变换(具体为行交换)  int i; double temp1; for(i=0; i<n; i++) { temp1 = aa[i]; aa[i] = bb[i]; bb[i] = temp1; } } double fun(double array[n][n]) { int ii,jj,k,u; int iter = 0; double det1=1,yin; for(ii=0; ii<n; ii++) { if(array[ii][ii] == 0) for(jj=ii;jj<n;jj++) { if(array[jj][ii] != 0) { temp(array[ii],array[jj],n);//交换两行  iter++; } } for(k=ii+1; k<n; k++) { yin = -1 * array[k][ii] / array[ii][ii]; for(u=0; u<n; u++) { array[k][u] = array[k][u] + array[ii][u] * yin; } } } for(ii=0;ii<n;ii++) det1 = det1 * array[ii][ii]; if(iter % 2 == 1) det1 = -det1; return (det1); //返回行列式的值  } 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/154677.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • ie9的兼容视图设置_ie9兼容性视图设置找不到

    ie9的兼容视图设置_ie9兼容性视图设置找不到ie9比ie8又向W3C标准靠近了一步,可能会导致原有的网页显示变乱;如果出现这种情况,选择ie9兼容性视图,网页显示就会正常。ie9分别有,为当前网页设置兼容性和为所有网站设置兼容性视图两种,下面分别说明:一、为当前网页设置兼容性视图1、快捷步骤:按alt键——工具——兼容性视图(V);或者按alt键——工具——按F12——浏览器模式(B):IE9——Internet…

  • Java设计模式之创建型:建造者模式

    Java设计模式之创建型:建造者模式

  • stm32开发教程_单片机STM32

    stm32开发教程_单片机STM32本博客的编写目的:一、自我总结,记录。二、分享,输出,加深思考。三、不作细致如书本般编排,尽管那样的排版很好看,但是过于耗费时间,还有很多东西没有必要说明,完全可以自己去解决,但还是尽量做好排版,便于阅读。四、尽可能举一反三,做到真正能够处理实际问题。STM32开发实战(1)目录一、概述,目的二、搭建步骤三、时钟部分案例分析四、理论总结一、

  • linux中ll排序命令,ll命令

    linux中ll排序命令,ll命令-a列出目录下所有的文件,包括.开头的隐藏文件-A列出目录下所有的文件,不包括.开头的隐藏文件-c配合-lt:根据ctime排序及显示ctime(文件状态最后更改的时间)配合-l:显示ctime但根据名称排序否则:根据ctime排序-C每栏由上至下列出项目–color[=WHEN]控制是否使用色彩分辨文件。WHEN可以是‘never‘、‘always‘或‘auto‘…

  • Protel99se基本教程 Protel 99SE从零开始学习教程视频教程「建议收藏」

    Protel99se基本教程 Protel 99SE从零开始学习教程视频教程「建议收藏」Protel如何从零开始学习?找个有实例的书,或有原理图,有PCB的书,把他画好,先从单面板画起,(找个简单的)自己再热转印法制作PCB,钻孔、焊接元件、调试等等,看似后面与学PROTEL无关,但这些可以让你对PCB布线有更深认识,比如、元件封装尺寸一定要精确、焊盘大小、走线粗细、元件布局放置等等,更能总结好的画图经验!更接近实际应用,这样才能掌握画图的乐趣,当我自己布的PCB的发射机,可以用收音…

  • JAVA乐观锁_spring的线程池配置

    JAVA乐观锁_spring的线程池配置首先介绍一些乐观锁与悲观锁:悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。传统的关系型数据库里边就用到了很

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号