求逆矩阵的方法「建议收藏」

求逆矩阵的方法「建议收藏」一般求逆矩阵的方法有两种,伴随阵法和初等变换法。但是这两种方法都不太适合编程。伴随阵法的计算量大,初等变换法又难以编程实现。适合编程的求逆矩阵的方法如下:

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

一般求逆矩阵的方法有两种,伴随阵法和初等变换法。但是这两种方法都不太适合编程。伴随阵法的计算量大,初等变换法又难以编程实现。
适合编程的求逆矩阵的方法如下:
1、对可逆矩阵A进行QR分解:A=QR
2、求上三角矩阵R的逆矩阵
3、求出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];
 }
 }
 }
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/171646.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • blender导入灰度图生成地形模型「建议收藏」

    blender导入灰度图生成地形模型「建议收藏」安装软件在此处下载blender并安装。添加平面1、打开blender,右键删除初始的立方体。2、shift+a选择平面添加进场景:3、按下s键鼠标拖动调节平面大小确定后按下鼠标左键:4、选择顶部菜单的modeling后再右键选择细分:5、在左下角输入细分的数值后按下回车:导入灰度图1、选择顶部菜单的layout后点击右下角的纹理属性然后新建:2、打开自己的灰度图:3、选择修改器属性:4、添加修改器:置换5、选择刚才添加的纹理:6、地形模型生成成功,但会有锯齿

    2022年6月20日
    57
  • phpstrom2021.4.2最新激活码_通用破解码

    phpstrom2021.4.2最新激活码_通用破解码,https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月17日
    40
  • 手机解锁侧面好用还是屏下指纹好用_侧边指纹怎么锁屏

    手机解锁侧面好用还是屏下指纹好用_侧边指纹怎么锁屏说起手机解锁方式,目前智能手机市场上基本上都采用的是屏下指纹、后置指纹和侧面指纹。不少人觉得在一些表现上侧面指纹不如其他两种解锁方式,其实你低估了侧面指纹,它远远比你想象中的还强大!一、外观一体化相比那些搭载后置指纹解锁技术的手机,手机搭载侧面指纹会更加的美观。它既不破坏手机正面屏幕,也不破坏背面机身的完整性,保证了机身的一体化。二、增大用户的解锁姿势相比后置指纹和屏下指纹解锁,侧面指纹简直…

    2022年8月10日
    10
  • 无法初始化 sqlcmd 库,错误编号为 -2147467259

    无法初始化 sqlcmd 库,错误编号为 -2147467259sqlserver2014执行作业报错:进行脚本测试:可见在sp_send_dbmail下面的@query是无法使用临时表的。只有在@query里面写实际的SQL才可以。不能带临时表。正确写法:Selec…

    2022年7月15日
    24
  • Innodb_large_prefix

    Innodb_large_prefix

    2021年10月22日
    86
  • 2016西安教师职称计算机考试,2016教师职称计算机考试模块.doc[通俗易懂]

    2016西安教师职称计算机考试,2016教师职称计算机考试模块.doc[通俗易懂]2016教师职称计算机考试模块2015年教师职称计算机考试模块【职考宝典】为广大考生归纳2015年职称计算机考试模块,让考生提前进入考试氛围,了解考试题型,职考宝典涵盖面积广,模拟题库包含Internet应用,word2003、2007,winXP、wpsoffice、excel2003、2007,ppt2003、2007等。山东广东安徽内蒙古黑龙江湖南山西云南辽宁新疆浙江江西湖北广西甘肃陕西…

    2022年5月8日
    38

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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