当前位置:网站首页>数值计算方法 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
边栏推荐
- Detailed explanation of TF2 command line debugging tool in ROS (parsing + code example + execution logic)
- Detailed explanation of addressing mode in 8086
- Exploring shared representations for personalized federated learning paper notes + code interpretation
- Decryption game of private protocol: from secret text to plaintext
- 初步认知Next.js中ISR/RSC/Edge Runtime/Streaming等新概念
- Voice assistant - Qu - single entity recall
- ‘CMRESHandler‘ object has no attribute ‘_ timer‘,socket. gaierror: [Errno 8] nodename nor servname pro
- Missing getting in online continuous learning with neuron calibration thesis analysis + code reading
- ‘CMRESHandler‘ object has no attribute ‘_timer‘,socket.gaierror: [Errno 8] nodename nor servname pro
- The function of C language string Terminator
猜你喜欢

In depth learning - overview of image classification related models

Arrangement of statistical learning knowledge points -- maximum likelihood estimation (MLE) and maximum a posteriori probability (map)

There is no solid line connection between many devices in Proteus circuit simulation design diagram. How are they realized?

Federated reconnaissance: efficient, distributed, class incremental learning paper reading + code analysis
![[yolo-v5 learning notes]](/img/f8/713210cafd7b750df540acbe03fd29.jpg)
[yolo-v5 learning notes]

鸿蒙os-第一次培训

Improved schemes for episodic memory based lifelong learning

Golang 快速生成数据库表的 model 和 queryset

Interview computer network - transport layer

Detailed principle of 4.3-inch TFTLCD based on warship V3
随机推荐
@Datetimeformat @jsonformat differences
vscode 1.68变化与关注点(整理导入语句/实验性新命令中心等)
石油储运生产 2D 可视化,组态应用赋能工业智慧发展
sql——课程实验考查
鸿蒙os-第一次培训
Acwing - 4269 school anniversary
‘CMRESHandler‘ object has no attribute ‘_ timer‘,socket. gaierror: [Errno 8] nodename nor servname pro
右击文件转圈卡住、刷新、白屏、闪退、桌面崩溃的通用解决方法
Chapter V - message authentication and digital signature
2022起重机械指挥考试题模拟考试平台操作
Exposure compensation, white increase and black decrease theory
Exploring shared representations for personalized federated learning paper notes + code interpretation
Vs 2019 MFC connects and accesses access database class library encapsulation through ace engine
R语言e1071包的naiveBayes函数构建朴素贝叶斯模型、predict函数使用朴素贝叶斯模型对测试数据进行预测推理、table函数构建混淆矩阵
Voice assistant -- Qu -- semantic role annotation and its application
2022 simulated test platform operation of hoisting machinery command test questions
VS2019 MFC IP Address Control 控件继承CIPAddressCtrl类重绘
xshell安装
LED lighting experiment with simulation software proteus
Voice assistant - overall architecture and design