高斯消去法

高斯消去法(Gaussian elimination)是指,通过前进消去和后退带入这样的两段计算求解的方法。 

加减法(中学所学)是我们平常用的解法之一。 例如,现有如下所示的二元一次方程组。

将等式两边同乘以一个实数,上下系数合并,消去其中一元未知数的方法便是熟知的加减法。

之后,把带入式1,解得

把上式用行列式表示如下,

之后,第2行乘以,上下相减,得到

的形式。随后,从最下面的式子中解出未知数,代入,得到:

前面的操作是指,把系数行列的左下部分(不包括对角元素)全部变成0,求解如下所示的三角行列(upper triangle matrix)。

这样的处理称作前进消去(forward elimination)。 根据前进消去,未知数可通过解出, 把带入行可以解出,之后把 代入行可以解出 。然后反复执行类似的操作直到解出,这时我们便得到了所有解。这样的后半部分的处理称作后退代入(back substitution)。通过前进消去和后退代入求解n元1次方程组的方法便是高斯消去法。

高斯消去法的代码实现

首先,把常数向量添加到的最后一列组成的行列。

其中第i行j列的元素表示为 

由于要在C,C++上实现,这里的元素序号从0开始计数。

前进消去可以表示成下式

这里的

根据上式,把更新得到上三角行列。这一步的C++代码如下。

 // 前进消去(forward elimination)//  - 将左下角元素变为0
for(int k = 0; k < n-1; ++k){double akk = A[k][k];for(int i = k+1; i < n; ++i){double aik = A[i][k];for(int j = k+1; j < n+1; ++j){ A[i][j] = A[i][j]-aik*(A[k][j]/akk);}}
}

这里的二维数组A[n][n+1]中存储着系数行列和常数向量。

后退代入的公式如下。

C++代码:

// 后代入(back substitution)
//  - x_n的解为b_n/a_nn,x_n,代入n-1行求出x_(n-1)A[n-1][n] = A[n-1][n]/A[n-1][n-1];
for(int i = n-2; i >= 0; --i){double ax = 0.0;for(int j = i+1; j < n; ++j){ax += A[i][j]*A[j][n];}A[i][n] = (A[i][n]-ax)/A[i][i];
}

计算结果存储于A[i][n]中。

高斯消去法的完整代码如下。

/*!* 高斯消去法(无主元交换)* @param[inout] A 为n×n的系数项与n×1的常数项(b)合并后n×(n+1)的行列* @param[in] n n元一次方程组* @return 1:成功*/
int GaussElimination(vector< vector<double> > &A, int n)
{// 前进消去(forward elimination)//  - 左下角元素为0for(int k = 0; k < n-1; ++k){double akk = A[k][k];for(int i = k+1; i < n; ++i){double aik = A[i][k];for(int j = k+1; j < n+1; ++j){ A[i][j] = A[i][j]-aik*(A[k][j]/akk);}}}// 后退代入(back substitution)A[n-1][n] = A[n-1][n]/A[n-1][n-1];for(int i = n-2; i >= 0; --i){double ax = 0.0;for(int j = i+1; j < n; ++j){ax += A[i][j]*A[j][n];}A[i][n] = (A[i][n]-ax)/A[i][i];}return 1;
}

上面使用STL的vector代替2维数组。

主元选择

我们先重新看一遍高斯消去法中的前进消去公式。

会发现右侧的第二项中包含除以的计算。当前进消去过程中对角元素中有0时,则会停止计算。即使不为0,当有绝对值很小的数出现时也会有误差出现。

针对上述问题,这里我们对主元消元法(pivotal elimination method)进行说明。首先,我们知道联立方程的公式的顺序是可以交换的。也就是说,处理第行时,把其对角元素与同列还未处理的元素 的值进行比较,把绝对值最大的那一行与行互换后,应用到前进消去公式中。上述操作便是主元消元。 像这样的只交换行的操作称为部分主元消元(partial pivoting), 列方向也交换的操作称为完全主元消元(complete pivoting)。值得注意的是,部分主元消元中未知数的顺序不发生变化,完全主元消元中,未知数的顺序会发生变化。

包含主元消元的高斯消去法代码如下

/*!* 主元选择(Pivoting)*  - 只交换行的部分主元消去法* @param[inout] A * @param[in] n n元一次方程组* @param[in] k 对象行* @return 1:成功*/
inline void Pivoting(vector< vector<double> > &A, int n, int k)
{// 检索k行后k列的绝对值最大元素所在行int p = k; // 绝对值最大的行double am = fabs(A[k][k]);// 最大値for(int i = k+1; i < n; ++i){if(fabs(A[i][k]) > am){p = i;am = fabs(A[i][k]);}}// 若k != p,行交换(主元选择)if(k != p) swap(A[k], A[p]);
}/*!* 高斯消去法(pivoting)* @param[inout] A * @param[in] n n元一次方程组* @return 1:成功*/
int GaussEliminationWithPivoting(vector< vector<double> > &A, int n)
{// 前进消去(forward elimination)for(int k = 0; k < n-1; ++k){// 主元消去Pivoting(A, n, k);double akk = A[k][k];for(int i = k+1; i < n; ++i){double aik = A[i][k];for(int j = k; j < n+1; ++j){A[i][j] = A[i][j]-aik*(A[k][j]/akk);}}}// 后退代入(back substitution)A[n-1][n] = A[n-1][n]/A[n-1][n-1];for(int i = n-2; i >= 0; --i){double ax = 0.0;for(int j = i+1; j < n; ++j){ax += A[i][j]*A[j][n];}A[i][n] = (A[i][n]-ax)/A[i][i];}return 1;
}

高斯・约当法

将高斯消去法的前进消去扩增,可以求出正方行列的逆行列,这种方法称作高斯约当法(Gauss-Jordan method)。

首先我们假设 是一个 的正方行列。 若 ,则是一个正则行列(regular matrix)(反之为奇异行列(singular matrix))。如果把 的单位行列表示成 ,且 非奇异,则只存在一个 行列 满足 。  这个可以用逆矩阵表示。

对于n元1次方程组,用替换,用替换。增广行列可以表示为

由于,两边同乘,得到

也就是说,增广行列的左侧一半变成了单位行列,右侧一半可以得到逆行列。

此时,逆行列为,

像这样的,扩增前进消去,执行上述处理求得逆行列的方法,便是高斯・约旦法。

高斯・约当法的实现

高斯・约当法公式如下。

求得逆行列代码如下

/*!* 高斯・约当法(无Pivoting)* @param[inout] A n×2n的增广行列* @param[in] n n元一次方程* @return 1:成功*/
int GaussJordan(vector< vector<double> > &A, int n)
{// 将增广行列的右半部分变为单位行列for(int i = 0; i < n; ++i){for(int j = 0; j < n; ++j){A[i][j+n] = (i == j ? 1.0 : 0.0);}}// 根据Gauss-Jordan method计算逆行列for(int k = 0; k < n; ++k){double akk = A[k][k];// 为使得对角元素为1,k行所有元素除以a_kkfor(int j = 0; j < 2*n; ++j){A[k][j] /= akk;}// k列的非对角元素变为0for(int i = 0; i < n; ++i){if(i == k) continue;double aik = A[i][k];for(int j = 0; j < 2*n; ++j){A[i][j] -= A[k][j]*aik;}}}return 1;
}

参考文献

  • 佐藤次男, 中村理一郎, “よくわかる数値計算 アルゴリズムと誤差解析の実際”, 日刊工業新聞社, 2001.
  • 川上一郎, “数値計算の基礎”, http://www7.ocn.ne.jp/~kawa1/

【数值计算】数值解析--n元一次联立方程组:直接解法相关推荐

  1. c语言如何就是联立方程组,准备出国读研的兄弟们:我们真的不如美国人勤奋---转自网络(转载)...

    最痛苦的是第一次计量经济学作业.计量经济学是我们这里面最难的课,基本就是统计学在经济学中的应用,而且这门课是最近几十年才兴起的,国内教得很 浅.虽然我本科学了经济应用统计学,数理统计学,计量经济学,三 ...

  2. 双曲线和直线联立公式_高中圆锥曲线解题技巧之齐次化联立(四)

    在开始介绍齐次化联立,我说过使用齐次化联立的题型特征,就是涉及两条直线的斜率和或者斜率积,并且这两条直线过同一个定点,其实还有一种题型也可以尝试使用齐次化联立,就是两直线夹角为定值问题,这个题型在全国 ...

  3. 双曲线和直线联立公式_谈直线和双曲线的位置关系之(1)联立方程法

    [专题九]登峰造极,唯我独尊 --谈直线和双曲线的位置关系之(1)联立 方程法 直线与双曲线的位置关系题型包括①判断交点个数②判断相切.相交.相离三种位置关系③求弦长及三角形面积等问题:用到的思想是数 ...

  4. 【BZOJ3503】【Cqoi2014】和谐矩阵 高斯消元,解异或方程组

    #include <stdio.h> int main() {puts("转载请注明出处");puts("地址:blog.csdn.net/vmurder/a ...

  5. Spark实施项目第七天-创建dw层订单明细表且与sku、spu、商标、类别进行联立

    HBase中对四个维表进行建表 create table gmall_base_category3 ( id varchar primary key ,info.name varchar, info. ...

  6. 计算机多媒体技术视差估计,面向立体视频的视差_运动同步联立预测算法

    <面向立体视频的视差_运动同步联立预测算法>由会员分享,可在线阅读,更多相关<面向立体视频的视差_运动同步联立预测算法(6页珍藏版)>请在技术文库上搜索. 1.第 22 卷第 ...

  7. Web项目实战 | 购物系统v2.0 | 开发记录(九)Controller层返回数据的封装 | 商品批量操作 | 五表联立实现商品搜索

    --若发现文章内容有误,敬请指正,望不吝赐教,感谢! 文章目录 以往记录 运行环境 一.设计Bean用于Controller层返回数据 二.商品批量操作 2.1 批量操作的前端设计 2.2 批量操作的 ...

  8. Latex+WinDet联立公式编号及一行多图片写法

    1.公式联立编号 实现代码 \begin{equation}%%编号\operatorname{ReLu}(\mathrm{x})=\left\{\begin{array}{ll}x & if ...

  9. fatfs文件系统与u盘驱动联立起来(usb_host)

    1.FatFS是一个为小型嵌入式系统设计文件系统模块 正常移植系统后我们需要修改文件系统的两个.C文件ffconf.h和 diskio.c .             ffconf.h 配置文件  修 ...

最新文章

  1. python与办公自动化-用 Python 自动化办公,我与大神之间的差距一下就拉小了
  2. asp.net 的page 基类页面 做一些判断 可以定义一个基类页面 继承Page类 然后重写OnPreLoad事件...
  3. 优化您的ApplicationContext
  4. smtplib 抄送邮件_用Python收发电子邮件
  5. java分治法求数列的最大子段和_同事为进大厂天天刷Java面试题,面试却履败!究其原因竟是它在捣鬼。...
  6. 头部导航菜单选中状态切换
  7. mysql 修改表属主_mysql主从配置实现一主一从读写分离
  8. 使用AdventNet快速开发网管软件Agent端
  9. 宋宝华:公元1024年Linux内核的尘封往事
  10. NC65新增按钮、新增按钮拦截器,某个字段制作超链接
  11. 秋招面经合集:阿里、华为、美团、携程、去哪儿、小米、京东都有
  12. Maya---基础知识总结
  13. PHP没有工作经验简历怎么写,没有工作经验应届生如何写简历呢?
  14. Springboot-banner图-定制化
  15. ES8218E低功耗24位ADC芯片 可直接接麦克风
  16. Android系统之ContentObserver和SettingsProvider结合使用(三)
  17. Java集合(一)Java集合及其关系
  18. 15款最佳的MySQL管理工具和应用程序
  19. 反应式架构:基本概念
  20. N位加减法运算器实现(Verilog HDL)|计算机组成

热门文章

  1. Git之新建分支命令
  2. 与神对话:每个行为都是爱的表达
  3. 安装office的ISO版本,虚拟光驱
  4. C语言宏定义函数中的“_##”的意思
  5. 用ch340烧录stm32
  6. codewars练习(javascript)-2021/2/1
  7. 关于高斯光学的一些知识
  8. 存储过程和函数-数据库
  9. 微信小程序自定义组件开发即组件间通信详解
  10. html中a标签如何进行锚点,a标签中的锚点使用方法