【NA】高斯消元法

前言.

  • 科学计算与工程应用中,很多问题话归到最终都是线性方程组的形式,例如前面《函数最佳逼近》《最小二乘拟合》中推导出的正规方程,此外还有差分法求解常微分方程、偏微分方程等。
  • 在天文学中,Kepler第一定律指出行星的轨道是椭圆,如果想确定一颗小行星绕太阳运行的轨道,可在轨道平面内建立以太阳为原点的直角坐标系,轨道方程可以设为 a 1 x 2 + 2 ⋅ a 2 x y + a 3 y 2 + 2 ⋅ a 4 x + 2 ⋅ a 5 y + 1 = 0 a_1x^2+2·a_2xy+a_3y^2+2·a_4x+2·a_5y+1=0 a1x2+2a2xy+a3y2+2a4x+2a5y+1=0
  • 如果要确定轨道方程中的参数,可以在5个不同的时间点对小行星进行观测,获取其不同时刻的坐标 ( x i , y i ) ∣ i = 1 , 2 , . . . , 5 (x_i,y_i)|i=1,2,...,5 (xi,yi)i=1,2,...,5,于是轨道参数的求解转化为求解一个线性方程组 A x = b . Ax=b. Ax=b.
  • 后面讨论的线性方程组大致可以按照系数矩阵分为两类,一类是低阶稠密矩阵,阶数通常不超过150,非零元素很多;另一类是高阶稀疏矩阵,阶数较高但零元素较多。两类线性方程组也分别对应两种求解策略,对于低阶稠密阵,通常直接进行求解,例如高斯消元法及其诸多改进算法;对于高阶稀疏阵,通常使用迭代过程逐步逼近线性方程组的解。

下面的讨论中线性方程组 A x = b Ax=b Ax=b 的系数矩阵 A A A 都是可逆矩阵,因此方程组具有唯一解。( b = 0 ⃗ b=\vec 0 b=0 时零解是唯一解)

高斯消元法.

  • 基本思想就是手工解方程组时的消元策略,不过计算机执行时,首先将系数矩阵通过初等变换转化为上三角矩阵,而后对待求变量从后向前 x n → x n − 1 → . . . → x 1 x_n\rightarrow x_{n-1}\rightarrow...\rightarrow x_1 xnxn1...x1 回代计算。
  • 在计算机中使用高斯消元法求解线性方程组 A x = b Ax=b Ax=b 时只需要存储增广矩阵 [ A     b ] [A~~~b] [A   b],而后消元过程中只需要对其中的元素直接更新即可。得到上三角矩阵后,可以将解直接存储在增广矩阵最右列。
  • 对于下面的增广矩阵 [ A     b ] = [ a 11 a 12 ⋯ a 1 n b 1 a 21 a 22 ⋯ a 2 n b 2 ⋮ ⋮ ⋱ ⋮ ⋮ a n 1 a n 2 ⋯ a n n b n ] [A~~~b]=\left[ \begin{matrix} a_{11} & a_{12} & \cdots & a_{1n} & b_{1}\\ a_{21}& a_{22} & \cdots & a_{2n} & b_{2}\\ \vdots& \vdots& \ddots & \vdots& \vdots \\a_{n1} & a_{n2} & \cdots&a_{nn} & b_{n} \end{matrix} \right] [A   b]=a11a21an1a12a22an2a1na2nannb1b2bn
  • 欲将其转化成上三角矩阵,就是要将系数矩阵主对角线下方的元素通过初等变换化为 0 0 0,以第一列为例,对于主对角线下方的元素 a k 1 , k = 2 , 3 , . . . , n a_{k1},k=2,3,...,n ak1,k=2,3,...,n ,只需要做变换 a k 1 = a k 1 − a k 1 a 11 ⋅ a 11 a_{k1}=a_{k1}-\frac{a_{k1}}{a_{11}}·a_{11} ak1=ak1a11ak1a11即第 k k k 行减去 a k 1 a 11 \frac{a_{k1}}{a_{11}} a11ak1 倍的第 1 1 1 行。
  • 将其一般化得到,对于第 t t t 次高斯消元更新,我们更新的目标是第 t t t 列主对角线以下的元素,即 a k t , k = t + 1 , t + 2 , . . . , n a_{kt},k=t+1,t+2,...,n akt,k=t+1,t+2,...,n,令 l k t = − a k t a t t ,   t ∈ { 1 , 2 , . . . , n } , k = t + 1 , t + 2 , . . . , n l_{kt}=-\frac{a_{kt}}{a_{tt}},~t\in\{1,2,...,n\},k=t+1,t+2,...,n lkt=attakt, t{1,2,...,n},k=t+1,t+2,...,n
  • 因此对下面第 t + 1 , t + 2 , . . . , n t+1,t+2,...,n t+1,t+2,...,n 行所作变换为 a k = a k + l k t ⋅ a t ,   t ∈ { 1 , 2 , . . . , n } , k = t + 1 , t + 2 , . . . , n a_{k}=a_k+l_{kt}·a_t,~t\in\{1,2,...,n\},k=t+1,t+2,...,n ak=ak+lktat, t{1,2,...,n},k=t+1,t+2,...,n
  • 最终得到的增广矩阵如下 [ A     b ] = [ a 11 a 12 ⋯ a 1 n b 1 0 a 22 ⋯ a 2 n b 2 ⋮ ⋮ ⋮ ⋮ 0 0 ⋯ a n n b n ] [A~~~b]=\left[ \begin{matrix} a_{11} & a_{12} & \cdots & a_{1n} & b_{1}\\ 0& a_{22} & \cdots & a_{2n} & b_{2}\\ \vdots& \vdots& & \vdots& \vdots \\0 & 0 & \cdots&a_{nn} & b_{n} \end{matrix} \right] [A   b]=a1100a12a220a1na2nannb1b2bn注意此处增广矩阵内元素的值已经发生了变化,据此可得 x n = b n a n n x_n=\frac{b_n}{a_{nn}} xn=annbn x k = b k − ∑ j = k + 1 n a k j x j a k k ,   k = n − 1 , n − 2 , . . . , 1 x_k=\frac{b_k-\sum^n_{j=k+1}a_{kj}x_j}{a_{kk}},~k=n-1,n-2,...,1 xk=akkbkj=k+1nakjxj, k=n1,n2,...,1 x k x_k xk 的求解过程即为回代求解。
  • 高斯消元法大致分为两步:消元与回代。在消元过程, l k t l_{kt} lkt 的计算需要进行 n − 1 n-1 n1 次乘法运算,而系数矩阵元素的乘法次数可以这样考虑,第一次消元时,可以直接将第一列主对角线以下的元素赋为0,而需要计算 ( n − 1 ) 2 (n-1)^2 (n1)2 个元素的更新值,依次类推,整个系数矩阵的乘法次数为 ∑ i = 1 n − 1 i 2 = ( n − 1 ) ⋅ n ⋅ ( 2 n − 1 ) 6 ≈ n 3 3 \sum^{n-1}_{i=1}i^2=\frac{(n-1)·n·(2n-1)}6\approx\frac {n^3}3 i=1n1i2=6(n1)n(2n1)3n3后面 b b b 更新所需的乘法次数以及回代过程的乘法次数可以类似计算,最终可以判断出高斯消元法大概的时间复杂度为 O ( n 3 ) O(n^3) O(n3),相较于仅有理论意义的克莱默法则 O ( n ! ) O(n!) O(n!) 无疑是一个极大的提升。
  • 高斯消元法的特点是,按顺序对第 1 , 2 , . . . , n 1,2,...,n 1,2,...,n 列在对角线以下的元素进行校园,我们将每次消元时作为 l k t l_{kt} lkt 分母的主对角线元素称为主元素。一般高斯消元法可能会遇到如下两个问题,①如果某个主元素为零,则消元过程无法进行;②如果某个主元素绝对值过小,可能会导致消元过程数值不精确。于是我们尝试对一般高斯消元法做出改进。
  • 下图来自Anany P162
    在这里插入图片描述

列主元消去法.

  • 为了避免上部分最后提到的两个问题,列主元消去法在每一步进行消元时,先遍历当前第 t t t 列对角线下方的元素,从中选出绝对值最大的数,假设它处于第 q q q 行,于是将 t , q t,q t,q 两行交换,就能在一定程度上提升高斯消元法的数值稳定性。
  • 时间复杂度和高斯消元法相同为 O ( n 3 ) . O(n^3). O(n3).
  • 下图来自Anany P163
    在这里插入图片描述

Gauss-Jordan消元法.

  • 高斯消元法将系数矩阵 A A A 转化为上三角矩阵,而高斯若当消元法则将其直接转化为单位矩阵 E E E,并且其中也引入了选取列主元素的策略。
  • 在第 t t t 步消元时,选择第 t t t对角线下方绝对值最大的元素,将其所在行与第 t t t 行交换。令 l k t = − a k t a t t ,   k = 1 , 2 , . . . , t − 1 , t + 1 , . . . , n l_{kt}=-\frac{a_{kt}}{a_{tt}},~k=1,2,...,t-1,t+1,...,n lkt=attakt, k=1,2,...,t1,t+1,...,n l t t = 1 a t t l_{tt}=\frac1{a_{tt}} ltt=att1对每一行都做初等变换 a k = a k + l k t ⋅ a t ,   k = 1 , 2 , . . . , n a_k=a_k+l_{kt}·a_t,~k=1,2,...,n ak=ak+lktat, k=1,2,...,n最后进行对角元素的单位化,即 a k = l t t ⋅ a k a_k=l_{tt}·a_k ak=lttak
  • 可以发现高斯若当消元法求解线性方程组的乘法次数大约是 n 3 2 \frac{n^3}2 2n3,比一般高斯消元法以及列主元消去法略大,但高斯若当消元法可以很方便用于求出可逆矩阵 A A A 的逆矩阵 A − 1 . A^{-1}. A1.
  • 根据线性代数的知识,对分块矩阵 M = [ A     E ] M=[A~~~E] M=[A   E] 做初等变换,当分块矩阵中左块 A A A 被转化为单位矩阵时,右块 E E E 即被转化为 A A A 的逆矩阵 A − 1 . A^{-1}. A1.

无关紧要.

  • 看过Anany这本书的话,在第一段伪代码的后文中,Anany指出此段代码最内层循环效率低下,并且在第二段伪代码中做出了优化。
  • 第一段伪代码中效率低下的原因在于,在最内层以 k k k 为循环变量的循环体中, A [ j , i ] ∗ A [ i , i ] A[j,i]*A[i,i] A[j,i]A[i,i] 是循环不变量,也就是说对于不同的 k k k 是不会变化的,很自然我们能想到对于它的计算发生了无用的重复计算,因此将其外提到 k k k 循环外,以临时变量 t e m p temp temp 来标识。
  • 编译原理中循环优化会完成这一工作,即循环不变量的外提,现代的高性能编译器在编译优化时,即使我们写出了上面这种无用计算的代码,它也会自动将其转换为第二种使用临时变量的高性能代码。但知道Compiler为我们默默付出了努力,还是有些必要的。
  • 循环优化
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值