当前位置:网站首页>数值计算方法 Chapter5. 解线性方程组的直接法
数值计算方法 Chapter5. 解线性方程组的直接法
2022-06-12 07:33:00 【Espresso Macchiato】
0. 问题描述
这一章节考察的就是如何求解线性方程组:
{ a 11 x 1 + a 12 x 2 + . . . + a 1 n x n = b 1 a 21 x 1 + a 22 x 2 + . . . + a 2 n x n = b 2 . . . a n 1 x 1 + a n 2 x 2 + . . . + a n n x n = b n \left\{ \begin{aligned} a_{11}x_1 + a_{12}x_2 + ... + a_{1n}x_n &= b_1 \\ a_{21}x_1 + a_{22}x_2 + ... + a_{2n}x_n &= b_2 \\ ... \\ a_{n1}x_1 + a_{n2}x_2 + ... + a_{nn}x_n &= b_n \end{aligned} \right. ⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧a11x1+a12x2+...+a1nxna21x1+a22x2+...+a2nxn...an1x1+an2x2+...+annxn=b1=b2=bn
或者可以用矩阵来表达:
( a 11 a 12 . . . a 1 n a 21 a 22 . . . a 2 n . . . a n 1 a n 2 . . . a n n ) ( x 1 x 2 . . . x n ) = ( b 1 b 2 . . . b n ) \begin{pmatrix} a_{11} & a_{12} & ... & a_{1n} \\ a_{21} & a_{22} & ... & a_{2n} \\ ... \\ a_{n1} & a_{n2} & ... & a_{nn} \end{pmatrix} \begin{pmatrix} x_1 \\ x_2 \\ ... \\ x_n \end{pmatrix} =\begin{pmatrix} b_1 \\ b_2 \\ ... \\ b_n \end{pmatrix} ⎝⎜⎜⎛a11a21...an1a12a22an2.........a1na2nann⎠⎟⎟⎞⎝⎜⎜⎛x1x2...xn⎠⎟⎟⎞=⎝⎜⎜⎛b1b2...bn⎠⎟⎟⎞
1. 消元法
1. 三角方程组
首先,我们来考察一些特殊形式的方程:
1. 对角方程组
对角方程组的函数形式如下:
( a 11 a 22 . . . a n n ) ( x 1 x 2 . . . x n ) = ( b 1 b 2 . . . b n ) \begin{pmatrix} a_{11} & & & \\ & a_{22} & & \\ & & ... & \\ & & & a_{nn} \end{pmatrix} \begin{pmatrix} x_1 \\ x_2 \\ ... \\ x_n \end{pmatrix} =\begin{pmatrix} b_1 \\ b_2 \\ ... \\ b_n \end{pmatrix} ⎝⎜⎜⎛a11a22...ann⎠⎟⎟⎞⎝⎜⎜⎛x1x2...xn⎠⎟⎟⎞=⎝⎜⎜⎛b1b2...bn⎠⎟⎟⎞
显然,可以直接写出 x i = b i / a i i x_i = b_i / a_{ii} xi=bi/aii,其中, i ∈ [ 1 , n ] i \in [1, n] i∈[1,n]。
2. 下三角方程组
下面,我们考察一下一个稍微复杂一点的情况,即下三角矩阵的情况:
( a 11 a 21 a 22 . . . a n 1 a n 2 . . . a n n ) ( x 1 x 2 . . . x n ) = ( b 1 b 2 . . . b n ) \begin{pmatrix} a_{11} & & & \\ a_{21} & a_{22} & & \\ & & ... & \\ a_{n1} & a_{n2} & ... & a_{nn} \end{pmatrix} \begin{pmatrix} x_1 \\ x_2 \\ ... \\ x_n \end{pmatrix} = \begin{pmatrix} b_1 \\ b_2 \\ ... \\ b_n \end{pmatrix} ⎝⎜⎜⎛a11a21an1a22an2......ann⎠⎟⎟⎞⎝⎜⎜⎛x1x2...xn⎠⎟⎟⎞=⎝⎜⎜⎛b1b2...bn⎠⎟⎟⎞
此时,问题的难度会多少复杂一点,但是也同样可以直接给出解答如下:
x i = b i − ∑ j < i a i j x j a i i x_i = \frac{b_i - \sum_{j < i}a_{ij}x_j}{a_ii} xi=aiibi−∑j<iaijxj
我们可以给出python伪代码如下:
def down_triangle(A, b):
n = len(A)
x = [0 for _ in range(n)]
for i in range(n):
y = b[i]
for j in range(i):
y -= A[i][j] * x[j]
x[i] = y / A[i][i]
return x
3. 上三角方程组
同样的,对于上三角函数的情况,我们同样有:
( a 11 a 12 . . . a 1 n a 22 . . . a 2 n . . . a n n ) ( x 1 x 2 . . . x n ) = ( b 1 b 2 . . . b n ) \begin{pmatrix} a_{11} & a_{12} & ... & a_{1n} \\ & a_{22} & ... & a_{2n} \\ & & ... & \\ & & & a_{nn} \end{pmatrix} \begin{pmatrix} x_1 \\ x_2 \\ ... \\ x_n \end{pmatrix} =\begin{pmatrix} b_1 \\ b_2 \\ ... \\ b_n \end{pmatrix} ⎝⎜⎜⎛a11a12a22.........a1na2nann⎠⎟⎟⎞⎝⎜⎜⎛x1x2...xn⎠⎟⎟⎞=⎝⎜⎜⎛b1b2...bn⎠⎟⎟⎞
可以解得:
x i = b i − ∑ j > i a i j x j a i i x_i = \frac{b_i - \sum_{j > i}a_{ij}x_j}{a_ii} xi=aiibi−∑j>iaijxj
同样的,我们可以给出python伪代码如下:
def up_triangle(A, b):
n = len(A)
x = [0 for _ in range(n)]
for i in range(n-1, -1, -1):
y = b[i]
for j in range(i+1, n):
y -= A[i][j] * x[j]
x[i] = y / A[i][i]
return x
2. Gauss消元法
现在,我们来考察一下一般形式的多元线性方程的解法。
其核心的思路其实还是将其转换成三角矩阵然后进行求解。
我们同样给出python伪代码如下:
def gauss_elimination(A, b):
n = len(A)
for i in range(n-1):
for k in range(i+1, n):
c = A[k][i] / A[i][i]
for j in range(i, n):
A[k][j] -= c * A[i][j]
b[k] -= c * b[i]
return up_triangle(A, b)
3. Gauss-Jordan消元法
Gauss-Jordan消元法和上述Gauss消元法本质上是一样的,不过Gauss消元法是将一般矩阵转换成三角矩阵,而Gauss-Jordan消元法是将一般矩阵转换成对角矩阵。
同样的,我们给出python伪代码如下:
def gauss_jordan_elimination(A, b):
n = len(A)
for i in range(n-1):
for k in range(i+1, n):
c = A[k][i] / A[i][i]
for j in range(i, n):
A[k][j] -= c * A[i][j]
b[k] -= c * b[i]
for j in range(n-1, 0, -1):
for i in range(j):
c = A[i][j] / A[j][j]
A[i][j] = 0
b[i] -= c * b[j]
res = [b[i] / A[i][i] for i in range(n)]
return res
2. 直接分解法
直接分解法和上述消元法其实并没有本质上的不同,不过区别在于,直接分解法的核心思路在于基于三角阵的特异性从而不断地尝试将一般矩阵转换为三角阵的形式然后进行求解。
1. Dolittle分解
Dolittle分解的思路是说将一般 n n n阶矩阵 A A A转换成 A = L U A = LU A=LU,其中, L L L是一个对角元素为1的下三角矩阵,而 U U U是一个上三角矩阵。
即:
( a 11 a 12 . . . a 1 n a 21 a 22 . . . a 2 n . . . a n 1 a n 2 . . . a n n ) = ( 1 l 21 1 . . . l n 1 l n 2 . . . 1 ) ( u 11 u 12 . . . u 1 n u 22 . . . u 2 n . . . u n n ) \begin{pmatrix} a_{11} & a_{12} & ... & a_{1n} \\ a_{21} & a_{22} & ... & a_{2n} \\ & & ... & \\ a_{n1} & a_{n2} & ... & a_{nn} \end{pmatrix} = \begin{pmatrix} 1 & & & \\ l_{21} & 1 & & \\ & ... & & \\ l_{n1} & l_{n2} & ... & 1 \end{pmatrix} \begin{pmatrix} u_{11} & u_{12} & ... & u_{1n} \\ & u_{22} & ... & u_{2n} \\ & & ... & \\ & & & u_{nn} \end{pmatrix} ⎝⎜⎜⎛a11a21an1a12a22an2............a1na2nann⎠⎟⎟⎞=⎝⎜⎜⎛1l21ln11...ln2...1⎠⎟⎟⎞⎝⎜⎜⎛u11u12u22.........u1nu2nunn⎠⎟⎟⎞
而两个三角矩阵 L L L和 U U U都是相对比较容易求解的。
我们易有:
{ u i j = a i j − ∑ k = 1 i − 1 l i k u k j l i j = ( a i j − ∑ k = 1 j − 1 l i k u k j ) / u j j \left\{ \begin{aligned} u_{ij} &= a_{ij} - \sum_{k=1}^{i-1}l_{ik}u_{kj} \\ l_{ij} &= (a_{ij} - \sum_{k=1}^{j-1}l_{ik}u_{kj}) / u_{jj} \end{aligned} \right. ⎩⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎧uijlij=aij−k=1∑i−1likukj=(aij−k=1∑j−1likukj)/ujj
此时,对于待求解方程 A x = b Ax = b Ax=b即可变为:
L U x = b LUx = b LUx=b
更进一步的,我们可以将其拆分为两个方程:
{ L y = b U x = y \left\{ \begin{aligned} Ly &= b \\ Ux &= y \end{aligned} \right. { LyUx=b=y
分别解上述两个方程,即可得到最终的解 x x x:
{ y i = b i − ∑ j = 1 i − 1 l i j y j x i = ( y i − ∑ j = i + 1 n u i j x j ) / u i i \left\{ \begin{aligned} y_i &= b_i - \sum_{j=1}^{i-1} l_{ij}y_{j} \\ x_i &= (y_{i} - \sum_{j=i+1}^{n} u_{ij}x_j) / u_{ii} \end{aligned} \right. ⎩⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎧yixi=bi−j=1∑i−1lijyj=(yi−j=i+1∑nuijxj)/uii
同样的,我们可以给出python伪代码如下:
def dolittle_solve(A, b):
n = len(A)
L = [[0 for _ in range(n)] for _ in range(n)]
U = [[0 for _ in range(n)] for _ in range(n)]
for k in range(n):
L[k][k] = 1
for j in range(k, n):
U[k][j] = A[k][j]
for r in range(k):
U[k][j] -= L[k][r] * U[r][j]
for i in range(k+1, n):
L[i][k] = A[i][k]
for r in range(k):
L[i][k] -= L[i][r] * U[r][k]
L[i][k] /= U[k][k]
y = [0 for _ in range(n)]
for i in range(n):
y[i] = b[i]
for j in range(i):
y[i] -= L[i][j] * y[j]
x = [0 for _ in range(n)]
for i in range(n-1, -1, -1):
x[i] = y[i]
for j in range(i+1, n):
x[i] -= U[i][j] * x[j]
x[i] /= U[i][i]
return x
2. Courant分解
Courant分解和Dolittle分解本质上并无区别,依然是将一般的参数矩阵 A A A拆分成两个三个矩阵,不过对于Courant分解而言, L L L是一个一般的下三角矩阵,而 U U U是对角元素全为1的上三角矩阵。
即:
( a 11 a 12 . . . a 1 n a 21 a 22 . . . a 2 n . . . a n 1 a n 2 . . . a n n ) = ( l 11 l 21 l 22 . . . l n 1 l n 2 . . . l n n ) ( 1 u 12 . . . u 1 n 1 . . . u 2 n . . . 1 ) \begin{pmatrix} a_{11} & a_{12} & ... & a_{1n} \\ a_{21} & a_{22} & ... & a_{2n} \\ & & ... & \\ a_{n1} & a_{n2} & ... & a_{nn} \end{pmatrix} = \begin{pmatrix} l_{11} & & & \\ l_{21} & l_{22} & & \\ & ... & & \\ l_{n1} & l_{n2} & ... & l_{nn} \end{pmatrix} \begin{pmatrix} 1 & u_{12} & ... & u_{1n} \\ & 1 & ... & u_{2n} \\ & & ... & \\ & & & 1 \end{pmatrix} ⎝⎜⎜⎛a11a21an1a12a22an2............a1na2nann⎠⎟⎟⎞=⎝⎜⎜⎛l11l21ln1l22...ln2...lnn⎠⎟⎟⎞⎝⎜⎜⎛1u121.........u1nu2n1⎠⎟⎟⎞
此时,仿上我们很快就能得到 L L L和 U U U的表达式如下:
{ l i j = a i k − ∑ r = 1 k − 1 l i r u r k u i j = ( a k j − ∑ r = 1 k − 1 l k r u r j ) / l k k \left\{ \begin{aligned} l_{ij} &= a_{ik} - \sum_{r=1}^{k-1} l_{ir}u_{rk} \\ u_{ij} &= (a_{kj} - \sum_{r=1}^{k-1}l_{kr}u_{rj}) / l_{kk} \end{aligned} \right. ⎩⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎧lijuij=aik−r=1∑k−1lirurk=(akj−r=1∑k−1lkrurj)/lkk
同样的,我们可以通过下述函数对最终的解 x x x进行求解:
{ L y = b U x = y \left\{ \begin{aligned} Ly &= b \\ Ux &= y \end{aligned} \right. { LyUx=b=y
最终结果表达式如下:
{ y i = ( b i − ∑ j = 1 i − 1 l i j y j ) / l i i x i = y i − ∑ j = i + 1 n u i j x j \left\{ \begin{aligned} y_i &= (b_i - \sum_{j=1}^{i-1} l_{ij}y_{j}) / l_{ii} \\ x_i &= y_{i} - \sum_{j=i+1}^{n} u_{ij}x_j \end{aligned} \right. ⎩⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎧yixi=(bi−j=1∑i−1lijyj)/lii=yi−j=i+1∑nuijxj
同样给出python伪代码实现如下:
def courant_solve(A, b):
n = len(A)
L = [[0 for _ in range(n)] for _ in range(n)]
U = [[0 for _ in range(n)] for _ in range(n)]
for k in range(n):
for i in range(k, n):
L[i][k] = A[i][k]
for r in range(k):
L[i][k] -= L[i][r] * U[r][k]
U[k][k] = 1
for j in range(k+1, n):
U[k][j] = A[k][j]
for r in range(k):
U[k][j] -= L[k][r] * U[r][j]
U[k][j] /= L[k][k]
y = [0 for _ in range(n)]
for i in range(n):
y[i] = b[i]
for j in range(i):
y[i] -= L[i][j] * y[j]
y[i] /= L[i][i]
x = [0 for _ in range(n)]
for i in range(n-1, -1, -1):
x[i] = y[i]
for j in range(i+1, n):
x[i] -= U[i][j] * x[j]
return x
3. 追赶法
追赶法本质上只是Courant分解的一种特殊情况而已。
它的解法和Courant分解完全一致,唯一不同的是,这里的 A A A矩阵是比较特殊的三元矩阵,即:
A = ( a 1 b 1 c 2 a 2 b 2 . . . c n − 1 a n − 1 b n − 1 c n a n ) A = \begin{pmatrix} a_1 & b_1 \\ c_2 & a_2 & b_2 \\ & & ... & \\ & & c_{n-1} & a_{n-1} & b_{n-1} \\ & & & c_{n} & a_{n} \end{pmatrix} A=⎝⎜⎜⎜⎜⎛a1c2b1a2b2...cn−1an−1cnbn−1an⎠⎟⎟⎟⎟⎞
由此,展开矩阵 L L L和 U U U也可以同步修改为:
L = ( u 1 w 2 u 2 . . . . . . w n u n ) , U = ( 1 v 1 1 v 2 . . . 1 ) L = \begin{pmatrix} u_1 \\ w_2 & u_2 \\ & ... & ... \\ & & w_n & u_n \end{pmatrix} , U = \begin{pmatrix} 1 & v_1\\ & 1 & v_2\\ & & ... \\ & & & 1 \end{pmatrix} L=⎝⎜⎜⎛u1w2u2......wnun⎠⎟⎟⎞,U=⎝⎜⎜⎛1v11v2...1⎠⎟⎟⎞
此时,由于矩阵 L L L和 U U U的特殊性,我们可以直接写出最终的解如下:
{ u i = a i − c i v i − 1 v i = b i / u i y i = ( f i − c i y i − 1 ) / u i x i = ( y i − v i x i + 1 ) \left\{ \begin{aligned} u_i &= a_i - c_iv_{i-1} \\ v_i &= b_i / u_i \\ y_i &= (f_i - c_i y_{i-1}) / u_i \\ x_i &= (y_i - v_i x_{i+1}) \end{aligned} \right. ⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧uiviyixi=ai−civi−1=bi/ui=(fi−ciyi−1)/ui=(yi−vixi+1)
4. 对称正定矩阵的 L D L T LDL^T LDLT分解
同样的, L D L T LDL^T LDLT分解和上述Dolittle分解和Courant分解其实本质上也差不多,但是不同的是,这里针对的问题是对称正定矩阵。
因此,对于对称正定矩阵,我们总可以有:
A = L D L T = ( 1 l 21 1 . . . l n 1 l n 2 . . . 1 ) ( d 1 d 2 . . . d n ) ( 1 l 12 . . . l 1 n 1 . . . l 2 n . . . 1 ) \begin{aligned} A &= LDL^T \\ &= \begin{pmatrix} 1 \\ l_{21} & 1 \\ & ... \\ l_{n1} & l_{n2} & ... & 1 \end{pmatrix} \begin{pmatrix} d_1 \\ & d_2 \\ & & ... \\ & & & d_n \end{pmatrix} \begin{pmatrix} 1 & l_{12} & ... & l_{1n}\\ & 1 & ... & l_{2n}\\ & & ... \\ & & & 1 \end{pmatrix} \end{aligned} A=LDLT=⎝⎜⎜⎛1l21ln11...ln2...1⎠⎟⎟⎞⎝⎜⎜⎛d1d2...dn⎠⎟⎟⎞⎝⎜⎜⎛1l121.........l1nl2n1⎠⎟⎟⎞
此时,我们可以解得:
{ d k = a k k − ∑ r = 1 k − 1 d r l k r 2 l i k = ( a i k − ∑ r = 1 k − 1 d r l i r l k r ) / d k \left\{ \begin{aligned} d_k &= a_{kk} - \sum_{r=1}^{k-1}d_rl_{kr}^2\\ l_{ik} &= (a_{ik} - \sum_{r=1}^{k-1}d_rl_{ir}l_{kr}) / d_k \end{aligned} \right. ⎩⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎧dklik=akk−r=1∑k−1drlkr2=(aik−r=1∑k−1drlirlkr)/dk
进而,我们可以将方程 A x = L D L T x = b Ax = LDL^Tx = b Ax=LDLTx=b拆成三步进行完成:
{ L z = b D y = z L T x = y \left\{ \begin{aligned} Lz &= b \\ Dy &= z \\ L^T x &= y \end{aligned} \right. ⎩⎪⎨⎪⎧LzDyLTx=b=z=y
解得:
{ z i = b i − ∑ j = 1 i − 1 l i j z j y i = z i / d i x i = y i − ∑ j = i + 1 n l j i x j \left\{ \begin{aligned} z_i &= b_i - \sum_{j=1}^{i-1}l_{ij}z_{j} \\ y_i &= z_i / d_i \\ x_i &= y_i - \sum_{j=i+1}^{n}l_{ji}x_j \end{aligned} \right. ⎩⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎧ziyixi=bi−j=1∑i−1lijzj=zi/di=yi−j=i+1∑nljixj
同样,我们给出python伪代码如下:
def ldl_solve(A, b):
n = len(A)
l = [[0 for _ in range(n)] for _ in range(n)]
d = [0 for _ in range(n)]
for k in range(n):
d[k] = A[k][k]
for r in range(k):
d[k] -= d[r] * l[k][r] * l[k][r]
l[k][k] = 1
for i in range(k+1, n):
l[i][k] = A[i][k]
for r in range(k):
l[i][k] -= d[r] * l[i][r] * l[k][r]
l[i][k] /= d[k]
z = [0 for _ in range(n)]
for i in range(n):
z[i] = b[i]
for j in range(i):
z[i] -= l[i][j] * z[j]
y = [z[i]/d[i] for i in range(n)]
x = [0 for _ in range(n)]
for i in range(n-1, -1, -1):
x[i] = y[i]
for j in range(i+1, n):
x[i] -= l[j][i] * x[j]
return x
边栏推荐
- 5 lines of code identify various verification codes
- Personalized federated learning with Moreau envelopes
- 初步认知Next.js中ISR/RSC/Edge Runtime/Streaming等新概念
- Summary of semantic segmentation learning (II) -- UNET network
- Arrangement of statistical learning knowledge points gradient descent, least square method, Newton method
- VS 2019 MFC 通过ACE引擎连接并访问Access数据库类库封装
- Modelarts培训任务1
- 2022电工(初级)考试题库及模拟考试
- Voice assistant - potential skills and uncalled call technique mining
- knife4j 初次使用
猜你喜欢

Voice assistant - Qu - single entity recall

Federated meta learning with fast convergence and effective communication

GD32F4(5):GD32F450时钟配置为200M过程分析

Voice assistant - Multi round conversation (process implementation)

Dynamic coordinate transformation in ROS (dynamic parameter adjustment + dynamic coordinate transformation)

Voice assistant - Multi round conversation (theory and concept)

Gradient epic memory for continuous learning

Principle and application of PWM

2022r2 mobile pressure vessel filling test question simulation test platform operation

Improved schemes for episodic memory based lifelong learning
随机推荐
Voice assistant - Qu - single entity recall
FCPX插件:简约线条呼出文字标题介绍动画Call Outs With Photo Placeholders for FCPX
Nine project management issues that PM should understand
Interview computer network - transport layer
Golang 快速生成数据库表的 model 和 queryset
How to stop MySQL service under Linux
VS 2019 MFC 通过ACE引擎连接并访问Access数据库类库封装
Vs2019 MFC IP address Control Control inherit cipaddressctrl class redessine
Modelarts培训任务1
Voice assistant -- Architecture and design of Instruction Assistant
linux下怎么停止mysql服务
[college entrance examination] prospective college students look at it, choose the direction and future, and grasp it by themselves
Thyristor, it is a very important AC control device
右击文件转圈卡住、刷新、白屏、闪退、桌面崩溃的通用解决方法
鸿蒙os-第一次培训
@Datetimeformat @jsonformat differences
Source code learning - [FreeRTOS] privileged_ Understanding of function meaning
R语言使用RStudio将可视化结果保存为pdf文件(export--Save as PDF)
Machine learning from entry to re entry: re understanding of SVM
Leetcode34. find the first and last positions of elements in a sorted array