【计算方法】#01 高斯消去法和列主元高斯消去法的原理简介及C++实现

  • 1. 高斯消去法
    • 1.1 算法的适用条件
    • 1.2 算法步骤和公式
    • 1.3 算法复杂度分析
    • 1.4 算法的C++实现
  • 2 列主元高斯消去法
    • 2.1 经典方法的致命问题
    • 2.2 按列选主元步骤的算法描述
    • 2.3 算法复杂度分析
    • 2.4 算法优势
    • 2.5 算法的C++实现
  • References

求解方程组:Ax=bAx=bAx=b

1. 高斯消去法

1.1 算法的适用条件

满足以下条件中的任一即可

  1. 系数矩阵AAA的各阶顺序主子式均不等于零(充要);

  2. 系数矩阵AAA是对称正定矩阵;

  3. 系数矩阵AAA是严格对角占优矩阵,即对角线元素大于对应行的其余元素之和。

1.2 算法步骤和公式

消元过程(第kkk次消元)
{aij(k)=aij(k−1)−aik(k−1)akk(k−1)akj(k−1)=aij(k−1)−likakj(k−1),i=k+1,k+2,...,n;j=k+1,k+2,...,nbi(k)=bi(k−1)−likbk(k−1),i=k+1,k+2,...,nlik≜aik(k−1)akk(k−1),i=k+1,k+2,...,n\begin{cases} &a_{ij}^{(k)}=a_{ij}^{(k-1)}-\frac{a_{ik}^{(k-1)}}{a_{kk}^{(k-1)}}a_{kj}^{(k-1)}=a_{ij}^{(k-1)}-l_{ik}a_{kj}^{(k-1)}, \\ &i=k+1,k+2,...,n; j=k+1,k+2,...,n \\ \\ &b_i^{(k)} = b_i^{(k-1)}- l_{ik}b_{k}^{(k-1)}, i=k+1,k+2,...,n \\ \\ &l_{ik} \triangleq \frac{a_{ik}^{(k-1)}}{a_{kk}^{(k-1)}}, i=k+1, k+2, ..., n \end{cases} ⎩⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎧​​aij(k)​=aij(k−1)​−akk(k−1)​aik(k−1)​​akj(k−1)​=aij(k−1)​−lik​akj(k−1)​,i=k+1,k+2,...,n;j=k+1,k+2,...,nbi(k)​=bi(k−1)​−lik​bk(k−1)​,i=k+1,k+2,...,nlik​≜akk(k−1)​aik(k−1)​​,i=k+1,k+2,...,n​

回代过程:
{xn=bn(n−1)ann(n−1),xk=bk(k−1)−∑j=k+1nakj(k−1)xjakk(k−1),k=n−1,n−2,...,2,1\left\{ \begin{aligned} x_n &= \frac{b_n^{(n-1)}}{a_{nn}^{(n-1)}},\\ x_k &= \frac{b_k^{(k-1)}-\sum\limits_{j=k+1}^{n}a_{kj}^{(k-1)}x_j}{a_{kk}^{(k-1)}}, k=n-1,n-2,...,2,1 \end{aligned} \right. ⎩⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎧​xn​xk​​=ann(n−1)​bn(n−1)​​,=akk(k−1)​bk(k−1)​−j=k+1∑n​akj(k−1)​xj​​,k=n−1,n−2,...,2,1​

1.3 算法复杂度分析

令运算量为乘除法个数,则

消元过程:N1=∑k=1n−1(n−k)2+2(n−k)=n3/3+n2/2−5n/6N_1=\sum\limits_{k=1}^{n-1}(n-k)^2+2(n-k)=n^3/3+n^2/2-5n/6N1​=k=1∑n−1​(n−k)2+2(n−k)=n3/3+n2/2−5n/6

回代过程:N2=1+(n−1)+∑k=1n−1(n−k)=n2/2+n/2N_2=1 + (n-1) + \sum\limits_{k=1}^{n-1}(n-k)=n^2/2 + n/2N2​=1+(n−1)+k=1∑n−1​(n−k)=n2/2+n/2

高斯消去法总运算量:N=N1+N2=n3/3+n2−n/3N=N_1+N_2=n^3/3+n^2-n/3N=N1​+N2​=n3/3+n2−n/3

时间复杂度:O(n3)O(n^3)O(n3)

空间复杂度:O(n2)O(n^2)O(n2),开销为系数矩阵AAA和一维数组bbb

1.4 算法的C++实现

typedef float elem;
vector<elem> Gauss_Elimination(vector<vector<elem>>& A, vector<elem>& b, elem epsilon){/* 高斯消去法参数简介:A - n维的系数矩阵b - 方程组等号右边的向量,维度1xnepsilon - 矩阵元素的阈值,当主元过小时高斯消去法将数值不稳定使用前的约定:1. 确保A不为空,且Ax=b中各个参数的维度一致注:执行完后,A和b将会改变*/int n = A.size();vector<elem> x(n);// 消元过程for (int k=0; k<n-1; ++k){ // 第k+1步消元// 主元太小,不能继续if(abs(A[k][k]) < epsilon){cout<<"The pivot element is too small. Process aborted."<<endl;return {};}for (int i=k+1; i<n; ++i){ // l[i][k]A[i][k] /= A[k][k];}// b[i]for (int i=k+1; i<n; ++i){b[i] -= A[i][k]*b[k];}// A[i][j]for (int i=k+1; i<n; ++i){for (int j=k+1; j<n; ++j){A[i][j] -= A[i][k] * A[k][j];}}}// 回代过程  for (int k=n-1; k>=0; --k){for (int j=k+1; j<n; ++j){b[k] -= A[k][j] * x[j];}x[k] = b[k] / A[k][k];}return x;
}

2 列主元高斯消去法

2.1 经典方法的致命问题

(∣A∣≠0)⇏(akk(k−1)≠0)(\vert A \vert \neq 0) \nRightarrow (a_{kk}^{(k-1)} \neq 0)(∣A∣​=0)⇏(akk(k−1)​​=0),即使akk(k−1)≠0a_{kk}^{(k-1)} \neq 0akk(k−1)​​=0,但∣akk(k−1)∣\vert a_{kk}^{(k-1)}\vert∣akk(k−1)​∣很小,这就会引起其他元素数量级的剧增和舍入误差的增长,导致计算结果不可靠,甚至计算不能进行下去(上溢)。

2.2 按列选主元步骤的算法描述

相比经典的高斯消去法,在消元过程前额外多了按列选主元步骤交换行步骤,其余流程是一致的。

按列选主元步骤的算法描述: 选取第kkk列的主元,即寻找它所在的行qqq,有:
q=arg max⁡i∈[k,n)∣aik∣q=\argmax\limits_{i\in [k, n)}\vert a_{ik}\vertq=i∈[k,n)argmax​∣aik​∣

交换行步骤的算法描述: 找到主元所在行qqq后,分别交换AAA和bbb的第kkk行和第qqq行元素,即
{swap(akj,aqj),j=k,k+1,...,nswap(bk,bq)\begin{cases} &\rm{swap}(a_{kj}, a_{qj}),j=k,k+1,...,n \\ & \rm{swap}(b_{k}, b_{q}) \end{cases} {​swap(akj​,aqj​),j=k,k+1,...,nswap(bk​,bq​)​

2.3 算法复杂度分析

时间复杂度:O(n3)O(n^3)O(n3),增加的两个步骤的复杂度均为O(n)O(n)O(n)

空间复杂度:O(n2)O(n^2)O(n2)

2.4 算法优势

  1. 由于∣aik(k−1)∣/∣akk(k−1)∣≤1(i=k+1,...,n)\vert a_{ik}^{(k-1)}\vert/\vert a_{kk}^{(k-1)}\vert \le 1 \ (i=k+1, ..., n)∣aik(k−1)​∣/∣akk(k−1)​∣≤1 (i=k+1,...,n),列主元消去法有利于控制误差的传播,故具有较好的数值稳定性;

2.5 算法的C++实现

typedef float elem;
vector<elem> Gauss_Elimination_ColumnPivot(vector<vector<elem>>& A, vector<elem>& b, elem epsilon){/* 列主元的高斯消去法参数简介:A - n维的系数矩阵b - 方程组等号右边的向量,维度1xnepsilon - 矩阵元素的阈值,当主元过小时高斯消去法将数值不稳定使用前的约定:1. 确保A不为空,且Ax=b中各个参数的维度一致注:执行完后,A和b将会改变*/int n = A.size();vector<elem> x(n);// 消元过程for (int k=0; k<n-1; ++k){ // 第k+1步消元elem maxf = 0;int q; // 最大主元所在行// 选主元for (int i=k; i<n; ++i){if(abs(maxf) < abs(A[i][k])){maxf = A[i][k];q = i;}}// 主元太小,不能继续if(abs(maxf) < epsilon){cout<<"The pivot element is too small. Process aborted."<<endl;return {};}// 交换行if(q != k){for (int j=k; j<n; ++j){swap(A[q][j], A[k][j]);}swap(b[q], b[k]);}// 消元过程for (int i=k+1; i<n; ++i){ // l[i][k]A[i][k] /= A[k][k];}// b[i]for (int i=k+1; i<n; ++i){b[i] -= A[i][k]*b[k];}// A[i][j]for (int i=k+1; i<n; ++i){for (int j=k+1; j<n; ++j){A[i][j] -= A[i][k] * A[k][j];}}}// 回代过程  for (int k=n-1; k>=0; --k){for (int j=k+1; j<n; ++j){b[k] -= A[k][j] * x[j];}x[k] = b[k] / A[k][k];}return x;
}

References

[1] 李乃成, 梅立泉. 数值分析[M]. 科学出版社, 2011.

笔者水平有限,如有错误欢迎批评指正~

【计算方法】#01 高斯消去法和列主元高斯消去法的原理简介及C++实现相关推荐

  1. C语言实现高斯消去法和列主元高斯消去法

    本篇主要实现高斯消去法和列主元高斯消去法 高斯消去法和列主元高斯消去法都是为了解线性方程组的有效方法,但列主元高斯消去法是高斯消去法的一个优化版本,强烈建议后面许多地方用到解方程组时,都用列主元高斯消 ...

  2. 【数值分析】顺序高斯消去法和列主元高斯消去法的三个主要不同点

    概要 求解线性方程组 A x = b Ax=b Ax=b 可以使用[顺序高斯消去法]和[列主元高斯消去法],本文试列举二者的三个主要不同点. 不同点 1. 使用条件

  3. 列主元高斯消去法数学原理及超级纯手工Python实现

    一.引言 从高斯消去法,我们看到还是有缺陷,高斯消去法中,当对角元素=0时,消去无法进行,当对角元素很小的时候,导致其他它元素数量级严重增长和舍入误差扩散1,使结果不可靠.因此引出了列主元高斯消去法. ...

  4. 列主元高斯消去法解线性方程组——C语言实现

    原理 高斯消去法 的基本原理就是用初等变换将用行的,逐次消去未知数的方法,把原来的方程组,化为与其等价的上三角方程组. 设有线性方程Ax=B\boldsymbol{A}\boldsymbol{x}=\ ...

  5. 列主元高斯消去法(c语言)(可以实现所有阶的)(超级详细)

    其实列主元高斯消去法无非就是比之前的高斯消去法多了一个判断主元这个步骤,但是里面还是有一些小细节的,比如:你要求一个3*4的增广矩阵,你的主元只需要选两次,第一次是在第一列的0.1.2里面选,第二次就 ...

  6. 列主元高斯消去法Matlab实现

    列主元高斯消去法解线性方程组 在求解线性方程组中,可以使用列主元高斯消去法. 步骤如下: 现有方程组:Ax = b (1)提取出方程组的增广矩阵 A = [A b]: (2)进行n-1次消元,分别对应 ...

  7. 列主元高斯消去法的C++实现

    下述所有内容都是建立在线性方程组有唯一解的情况 高斯消去法主要用来求解线性方程组比如求解下图中的四维线性方程组 该方程组写成行列式形式如下图所示 首先将行列式变为阶梯行列式,以第一行为例: 第一行同时 ...

  8. 关于列主元高斯消去法的matlab实现

    function x  = nagauss1(a,b ,flag) %用途:列主元高斯消去法解线性方程组ax=b % A:系数矩阵,b:右端列变量 % flag:若为0,则显示中间过程,否则不显示,默 ...

  9. Matlab 列主元高斯消去法

    列主元高斯消去法是高斯消去法的优化版本,通过找出列中的最大值,避免了除以很小的数时容易引起的数值偏差. function x=Elim_Gauss(Matrix,n,b) %列主元高斯消去法 %输入- ...

最新文章

  1. Android规范发展
  2. .NET Core 2.1中的分层编译(预览)
  3. Caused by: java.lang.NoClassDefFoundError: org/apache/commons/pool/BasePoolableObjectFactory
  4. 不搞代码来搞我,我又动了谁的奶酪?
  5. M1芯片版mac软件安装出现异常怎么办?解决方法来了
  6. JSP自定义标签_通过属性控制标签体的执行次数
  7. java字段偏移量什么意思_求结构体的字段的偏移量
  8. Routeros2.9.7安装总结
  9. jQuery + html + css 实现王者荣耀官网首页
  10. nanomsg 高性能通信库_NanoMsg框架|NanoMsg的简介
  11. 最新:2021年7月全国程序员平均薪资出炉!你还坐得住吗?
  12. js ajax实现五极联动,前端见微知著AngularJS备忘篇:温故而知新,可以为师矣
  13. 51c语言延时程序怎么编写,C51中延时程序的编写
  14. web和http协议-详解
  15. B站500万粉up主党妹被黑客勒索:交钱赎“人”!顶级安全专家:无解
  16. ajax发送异步请求与ajax发送同步请求
  17. .bat 文件打开软件
  18. 7类AI淘金者:各显神通,但钱到底被谁赚了?
  19. 中冠百年|不同年龄阶段家庭资产配置思路
  20. RoI Transformer 精读

热门文章

  1. 图片合成方法 - paste/seamlessclone/或运算/传统方法
  2. Android视频播放之边缓存边播放
  3. Python urllib3模块详解
  4. html 如何播放3pg文件,3gp是什么格式文件?3gp文件怎么打开/用什么打开?
  5. 【服务器数据恢复】误操作导致RAID0数据不可用的导致数据恢复案例
  6. Tina_Linux量产测试使用指南_new
  7. 1-3 jsp页面跳转时弹出小窗口的方法
  8. PyQt写的简单图像标注工具
  9. git修改提交的commits信息
  10. 计算机冯氏结构的五大部件,冯氏结构五大部件