首页 > 编程语言 >【c++】高斯-约旦法求逆矩阵

【c++】高斯-约旦法求逆矩阵

时间:2023-01-20 22:33:25浏览次数:50  
标签:temp point int 矩阵 c++ ++ 约旦 col 法求

给出n阶方阵A,求解其逆矩阵A-1的方法:

  1.构造n×2n的矩阵(A,I)

  2.用高斯-约旦消元法将其化简为(I,A-1),即可得到A的逆矩阵A-1

第一版的代码:

void inverse(double A[N][N], double k, double inv_A[N][N]) {
    double t[N][N]{};
    int max{ 0 };
    double temp{ 0.0 };
    for (int i = 0;i != k;++i) {
        for (int j = 0;j != k;++j) {
            t[i][j] = A[i][j];
        }
    }
    //show(t,N,N);
    for (int i = 0;i != k;++i) {
        for (int j = 0;j != k;++j) {
            inv_A[i][j] = (i == j) ? (double)1 : 0;
        }
    }
    //show(inv_A, k, k);
    for (int col = 0;col != k;++col) {
        //寻找一列中最大的数
        max = col;
        for (int i = col+1;i != k;++i) {
            if (fabs(t[i][col]) > fabs(t[col][col])) {
                max = i;
            }
        }
       // std::cout << "max: " << max << '\n';
        //换行
        temp = 0.0;
        if(max!=col){
            for (int row = 0;row != k;++row) {
                temp = t[max][row];
                t[max][row] = t[col][row];
                t[col][row] = temp;
                temp = inv_A[max][row];
                inv_A[max][row] = inv_A[col][row];
                inv_A[col][row] = temp;
            }
        }
        std::cout << "inv: \n";
        show(inv_A, k, k);
        //将对角线元素先化为1
        temp = t[col][col];
        for (int i = 0;i != k;++i) {
            t[col][i] /= temp;
            inv_A[col][i] /= temp;
        }

        //消元,和高斯法解方程不同,这里的消元还要使对角线上方的元素为0
        for (int row = 0;row != k;++row) {
            if (row != col) {
                temp = t[row][col];
                for (int j = 0;j != k;++j) {
                    t[row][j] -= temp*t[col][j];
                    inv_A[row][j] -= temp*inv_A[col][j];
                }
            }
            else {
                continue;
            }
        }
       /*std::cout << "col: \n";
        show(inv_A, k, k);*/ 
    }
}

 

point 1:验证的方法->采用之前的矩阵乘法,将初始矩阵和计算所得的矩阵进行相乘的操作,看是否为单位矩阵。

point 2:可以采用std::vector

point 3:assert,判断原始矩阵是不是满秩

vec inverse(vec A) {
    int row{ static_cast<int> (A.size()) };
    int col{ static_cast<int>(A[0].size()) };
    vec B(row, vecRow(col));
    int point;
    double temp,m;
    //构建单位化矩阵
    for (int i = 0;i != row;++i) {
        for (int j = 0;j != col;++j) {
            if (i == j) {
                B[i][j] = 1.0;
            }
            else {
                B[i][j] = 0.0;
            }
        }
    }
    //一列一列来
    for (int k = 0;k != col;++k) {
        //选主元
        point = k;
        //寻找k列中绝对值最大的数的行point
        for (int r = k+1;r != row;++r) {
            if (fabs(A[point][k]) < fabs(A[r][k])) {
                point = r;
            }
        }
        //判断A是否为奇异矩阵
        //assert(fabs(A[point][k]) > 1e-6 && "A为奇异矩阵");
        //换行
        if(k!=point){
            for (int i = 0;i != col;++i) {
                temp = A[point][i];
                A[point][i] = A[k][i];
                A[k][i] = temp;
                temp = B[point][i];
                B[point][i] = B[k][i];
                B[k][i] = temp;
            }
        }
        assert(fabs(A[k][k]) > 1e-6 && "奇异矩阵");
        //将主对角线上的元素单位化
        temp = A[k][k];
        for (int i = 0;i != row;i++) {
            A[k][i] /= temp;
            B[k][i] /= temp;
        }
        //消去
        m = 0.0;
        for (int i = 0;i != row;++i) {
            if (i != k) {
                m = A[i][k];
                for (int j = 0;j != col;++j) {
                    A[i][j] -= m * A[k][j];
                    B[i][j] -= m * B[k][j];
                }
            }
        }
    }return B;
}

主函数:

int main()
{
    vec A{ {0.012,0.010,0.167},
           {1.000,0.833,5.910},
           {3200 ,1200 ,4.200} };
    vecRow B{ 0.6781,12.1,981 };
    vecRow x;
    /*x = equationSolver(A, B);
    for (double i : x) {
        std::cout << i << "  ";
    }
    std::cout << "A:\n";
    show(A);*/
    vec invA;
    invA = inverse(A);
    std::cout << "A的逆矩阵:\n";
    show(invA);
    vec mul;
    mul = Multi2(A, invA);
    std::cout << "mul:\n";
    show(mul);

}

 

标签:temp,point,int,矩阵,c++,++,约旦,col,法求
From: https://www.cnblogs.com/zhimingyiji/p/17063347.html

相关文章

  • CUDA C++编程
    核函数作用调用核函数的时候,代码会被N个CUDA线程执行N次。 修饰符__global__返回值函数名(){  ...执行代码} 调用函数名<<<BlockNumber,ThreadNumber>>>()......
  • 史上最简单 OpenCV for C++ 在 Windows 和 Ubuntu 上编译安装使用教程
    准备工作原材料Ubuntu系统(非必须,Windows也可以,主要是Ubuntu适合编译)OpenCV3.4.1压缩包OpenCVcontrib3.4.1压缩包MinGW(Windows上运行GCC)版本信息......
  • 把KMP算法嚼碎了才利于消化!(C++)
    相信不少人在学数据结构的时候都被KMP算法搞的迷迷糊糊的,原理看的似懂非懂,代码写不出来,或者写出来了也不知道为什么就可以这么写。本文力求尽可能通俗详细的讲解KMP算法,让......
  • C++概述
    计算两个整数相加之和#include<iostream>usingnamespacestd;/*函数功能:计算两个整数相加之和*/intAdd(inta,intb){return(a+b);}//主函数intmai......
  • c++ namespace
    名字空间:名字空间有两个特征:1.顺序2.嵌套顺序:编译器和解释器相当于一个翻译官,拿着本子一行一行读代码,只有见过的名字才会记到本子上,每见过的名字他就不认识(所以C++需......
  • C#调用C++动态链接库dll之P/Invoke方式 — 1.无参无返回值函数调用
    1.新建一个C++空项目CPPTest2.新建一个PInvokeTest.cpp文件,并写下如下代码需要注意:下文中的两个函数名HelloWorld需要完全一致,只有这样才能确保被完全声明为一个其......
  • C++ Templates 中文版 电子书 pdf
    本书是C++模板编程的完全指南,旨在通过基本概念、常用技巧和应用实例3方面的有用资料,为读者打下C++模板知识的坚实基础。关注公众号:后厂村搬砖工。发送:电子书即可。......
  • C++ 基础语法2
    #include<iostream>usingnamespacestd;#include<string>#include<time.h>//结构体定义//structStudent//{//stringname;//intage;//intcount;//};//在结构体尾......
  • C++基础语法 3(面向对象、C++在执行过程当中4个区域、引用)
    #include<iostream>usingnamespacestd;//标注空间#include<string>#include<time.h>#include<cstdlib>//面向对象/*C++在执行过程当中4个区域:代码区:存放二进制代码,由操作......
  • C++基础语法4()
    #include<iostream>usingnamespacestd;//标注空间#include<string>#include<time.h>#include<cstdlib>//函数的提高1;函数的默认参数函数的形参可以有默认值!返回类型......