Python数值线性方程组

介绍

代数方程组的形式为

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 , ( 1 ) \begin{array}{c}A_{11} x_{1}+A_{12} x_{2}+\cdots+A_{1 n} x_{n}=b_{1} \\A_{21} x_{1}+A_{22} x_{2}+\cdots+A_{2 n} x_{n}=b_{2} \\\vdots \\A_{n 1} x_{1}+A_{n 2} x_{2}+\cdots+A_{n n} x_{n}=b_{n}\end{array},\qquad(1) A11x1+A12x2++A1nxn=b1A21x1+A22x2++A2nxn=b2An1x1+An2x2++Annxn=bn,(1)

其中系数 A i j A_{i j} Aij和常数 b j b_{j} bj是已知的, x i x_{i} xi表示未知数。 用矩阵表示法将等式写为

[ 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 ] , ( 2 ) \left[\begin{array}{cccc}A_{11} & A_{12} & \cdots & A_{1 n} \\A_{21} & A_{22} & \cdots & A_{2 n} \\\vdots & \vdots & \ddots & \vdots \\A_{n 1} & A_{n 2} & \cdots & A_{n n}\end{array}\right]\left[\begin{array}{c}x_{1} \\x_{2} \\\vdots \\x_{n}\end{array}\right]=\left[\begin{array}{c}b_{1} \\b_{2} \\\vdots \\b_{n}\end{array}\right],\qquad(2) A11A21An1A12A22An2A1nA2nAnnx1x2xn=b1b2bn,(2)

或简单化为,

A x = b , ( 3 ) \mathbf{A} \mathbf{x}=\mathbf{b},\qquad(3) Ax=b,(3)

出于计算目的,这些方程式的一个特别有用的表示形式是通过将常数矢量b附加到系数矩阵A上而获得的增强系数矩阵,其格式如下:

[ 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 3 b n ] , ( 4 ) \left[\begin{array}{ll}\mathbf{A} & \mathbf{b}\end{array}\right]=\left[\begin{array}{cccc|c}A_{11} & A_{12} & \cdots & A_{1 n} & b_{1} \\A_{21} & A_{22} & \cdots & A_{2 n} & b_{2} \\\vdots & \vdots & \ddots & \vdots & \vdots \\A_{n 1} & A_{n 2} & \cdots & A_{n 3} & b_{n}\end{array}\right],\qquad(4) [Ab]=A11A21An1A12A22An2A1nA2nAn3b1b2bn,(4)

解的唯一性

假设系数矩阵的行列式不是奇异的,则由n个未知数组成的n个线性方程组具有唯一的解。 即 ∣ A ∣ ≠ 0 |\mathbf{A}| \neq 0 A=0。非奇异矩阵的行和列在线性上是独立的,因为没有行(或列)是其他行(或列)的线性组合。

如果系数矩阵是奇异的,则取决于常数矢量,方程式可能具有无限数量的解或根本没有解。 作为说明,请考虑以下等式

2 x + y = 3 4 x + 2 y = 6 2 x+y=3 \quad 4 x+2 y=6 2x+y=34x+2y=6

由于可以通过将第一方程式乘以二来获得第二方程式,因此满足第一方程式的x和y的任何组合也是第二方程式的解。 这种组合的数量是无限的。 相反,等式

2 x + y = 3 4 x + 2 y = 0 2 x+y=3 \quad 4 x+2 y=0 2x+y=34x+2y=0

之所以没有解,是因为等式 2 x + y = 0 2 x+y=0 2x+y=0的第二个方程与第一个方程矛盾。 因此,任何满足一个方程式的解决方案都不能满足另一个方程式。

病态条件

一个明显的问题是,当系数矩阵几乎为奇数时(即 ∣ A ∣ |\mathbf{A}| A非常小)会发生什么。 为了确定系数矩阵的行列式是否为“小”,我们需要一个可以用来确定行列式的参考。 该参考称为矩阵的范数,用 ∥ A ∥ \|\mathbf{A}\| A表示。 然后我们可以说行列式很小,如果

∣ A ∣ < < ∥ A ∥ |\mathbf{A}|<<\|\mathbf{A}\| A<<A

现有文献中已经定义了矩阵的几个范式,例如Euclidan范式

∥ A ∥ e = ∑ i = 1 n ∑ j = 1 n A i j 2 , ( 5 a ) \|\mathbf{A}\|_{e}=\sqrt{\sum_{i=1}^{n} \sum_{j=1}^{n} A_{i j}^{2}}\qquad,\qquad(5a) Ae=i=1nj=1nAij2 ,(5a)

行和范数,也称为无穷范数

∥ A ∥ ∞ = max ⁡ 1 ≤ i ≤ n ∑ j = 1 n ∣ A i j ∣ , ( 5 b ) \|\mathbf{A}\|_{\infty}=\max _{1 \leq i \leq n} \sum_{j=1}^{n}\left|A_{i j}\right|,\qquad(5b) A=1inmaxj=1nAij,(5b)

条件的形式化度量是矩阵条件数,定义为

cond ⁡ ( A ) = ∥ A ∥ ∥ A − 1 ∥ , ( 5 c ) \operatorname{cond}(\mathbf{A})=\|\mathbf{A}\|\left\|\mathbf{A}^{-1}\right\|,\qquad(5c) cond(A)=AA1,(5c)

如果该数字接近于1,则表示矩阵条件良好。 条件数随着病态程度的增加而增加,对于奇异矩阵达到无穷大。 请注意,条件数不是唯一的,但取决于矩阵范数的选择。 不幸的是,对于大型矩阵,条件数的计算成本很高。 在大多数情况下,通过将行列式与矩阵中元素的大小进行比较就可以评估条件。

如果等式条件不好,系数矩阵的小变化将导致解的大变化。 作为说明,请考虑以下等式

2 x + y = 3 2 x + 1.001 y = 0 2 x+y=3 \quad 2 x+1.001 y=0 2x+y=32x+1.001y=0

的解 x = 1501.5 , y = − 3000 x=1501.5, y=-3000 x=1501.5,y=3000。 由于 ∣ A ∣ = 2 ( 1.001 ) − 2 ( 1 ) = 0.002 |\mathbf{A}|=2(1.001)-2(1)=0.002 A=2(1.001)2(1)=0.002比系数小得多,这些方程式的条件不好。 通过将第二个方程更改为 2 x + 1.002 y = 0 2 x+1.002 y=0 2x+1.002y=0并重新求解方程,可以验证病态的影响。 结果是 x = 751.5 , y = − 1500 x=751.5, y=-1500 x=751.5,y=1500。 请注意, y y y系数的0.1%变化导致解的100%变化。

病态方程的数值解是不可信的。 原因是在求解过程中不可避免的舍入误差等同于在系数矩阵中引入小的变化。 反过来,这会在解中引入较大的误差,误差的大小取决于病态的严重程度。 在可疑情况下,应计算系数矩阵的行列式,以便可以估计病态的程度。 只需少量的计算即可在解中或解之后完成此操作。

线性系统

线性代数方程式几乎出现在数值分析的所有分支中。 但是它们在工程中最明显的应用是在线性系统的分析中(任何响应与输入成比例的系统都被认为是线性的)。 线性系统包括结构,弹性固体,热流,流体渗漏,电磁场和电路(即,工程课程中讲授的大多数主题)。

如果系统是离散的,例如桁架或电路,则其分析将直接导致线性代数方程。 例如,在静态确定的桁架中,当写下节点的平衡条件时,方程式就出现了。 未知数 x 1 , x 2 , … , x n x_{1}, x_{2}, \ldots, x_{n} x1,x2,,xn表示构件中的力和支撑反作用力,常数 b 1 , b 2 , … , b n b_{1}, b_{2}, \ldots, b_{n} b1,b2,,bn是规定的外部载荷。

连续系统的行为是通过微分方程而不是代数方程来描述的。 但是,由于数值分析只能处理离散变量,因此首先需要用代数方程组来近似微分方程。 众所周知的有限差分,有限元和边界元分析方法都以这种方式工作。 他们使用不同的近似值来实现“离散化”,但是在每种情况下,最终任务都是相同的:求解线性代数方程组的系统(通常是非常大的系统)。

总之,线性系统的建模总是产生形式为 A x = b \mathbf{A} \mathbf{x}=\mathbf{b} Ax=b的方程,其中b是输入,x表示系统的响应。 反映系统特征的系数矩阵A与输入无关。 换句话说,如果输入改变,则方程必须再次用不同的b来求解,但是要使用相同的A。因此,希望有一种方程求解算法,可以用最少的计算量处理任意数量的常数向量。

解方法

解决线性代数方程组的方法有两种:直接方法和迭代方法。 直接方法的共同特征是,它们可以将原始方程式转换为可以更容易求解的等效方程式(具有相同解的方程式)。 通过应用以下三个操作来执行转换。 这些所谓的基本运算不会改变解,但是如括号中所示,它们可能会影响系数矩阵的行列式。

  1. 交换两个方程式(更改 ∣ A ∣ |\mathbf{A}| A的符号)
  2. 将方程乘以非零常数( ∣ A ∣ |\mathbf{A}| A乘以相同常数)
  3. 将一个方程乘以非零常数,然后从另一个方程中减去(保留 ∣ A ∣ |\mathbf{A}| A不变)

迭代或间接方法从对解x的猜测开始,然后反复细化解,直到达到某个收敛准则为止。 由于需要大量的迭代,因此迭代方法通常比直接方法效率低。 但是,如果系数矩阵很大且稀疏(大多数系数为零),它们确实具有显着的计算优势。

直接方法

表1列出了三种流行的直接方法,每种方法都使用基本运算来产生其自己易于解决的最终形式的方程。

上表1中,U表示上三角矩阵,L是下三角矩阵,并且I表示单位矩阵。 如果方阵在前导对角线的一侧仅包含零个元素,则称其为三角形。 因此,一个3×3的上三角矩阵具有以下形式

U = [ U 11 U 12 U 13 0 U 22 U 23 0 0 U 33 ] \mathbf{U}=\left[\begin{array}{ccc}U_{11} & U_{12} & U_{13} \\0 & U_{22} & U_{23} \\0 & 0 & U_{33}\end{array}\right] U=U1100U12U220U13U23U33

并且3×3下三角矩阵显示为

L = [ L 11 0 0 L 21 L 22 0 L 31 L 32 L 33 ] \mathbf{L}=\left[\begin{array}{ccc}L_{11} & 0 & 0 \\L_{21} & L_{22} & 0 \\L_{31} & L_{32} & L_{33}\end{array}\right] L=L11L21L310L22L3200L33

三角矩阵在线性代数中起着重要作用,因为它们简化了许多计算。 例如,考虑方程 L x = c \mathbf{L x}=\mathbf{c} Lx=c,或

L 11 x 1 = c 1 L 21 x 1 + L 22 x 2 = c 2 L 31 x 1 + L 32 x 2 + L 33 x 3 = c 3 \begin{aligned}L_{11} x_{1} &=c_{1} \\L_{21} x_{1}+L_{22} x_{2} &=c_{2} \\L_{31} x_{1}+L_{32} x_{2}+L_{33} x_{3} &=c_{3}\end{aligned} L11x1L21x1+L22x2L31x1+L32x2+L33x3=c1=c2=c3

如果我们从第一个方程开始向前求解方程,则计算非常简单,因为每个方程一次只包含一个未知数。

因此,解将如下进行:

x 1 = c 1 / L 11 x 2 = ( c 2 − L 21 x 1 ) / L 22 x 3 = ( c 3 − L 31 x 1 − L 32 x 2 ) / L 33 \begin{array}{l}x_{1}=c_{1} / L_{11} \\x_{2}=\left(c_{2}-L_{21} x_{1}\right) / L_{22} \\x_{3}=\left(c_{3}-L_{31} x_{1}-L_{32} x_{2}\right) / L_{33}\end{array} x1=c1/L11x2=(c2L21x1)/L22x3=(c3L31x1L32x2)/L33

此过程称为正向替换。 以类似的方式,在高斯消除中遇到的Ux = c可以很容易地通过反向替换解决,该替换从最后一个方程式开始,一直向后遍历这些方程式。

如果我们用两组等效方程式: L y = b \mathbf{L} \mathbf{y}=\mathbf{b} Ly=b U x = y \mathbf{U x}=\mathbf{y} Ux=y代替它们,则与LU分解相关的方程式 L U x = b \mathbf{L U x}=\mathbf{b} LUx=b也可以快速求解。 现在, L y = b \mathbf{L y}=\mathbf{b} Ly=b可以通过正向替换解决 y y y,然后通过反向替换解决 U x = y \mathbf{U x}=\mathbf{y} Ux=y的问题。

由高斯-若尔当消元法生成的等式 I x = c \mathbf{I x}=\mathbf{c} Ix=c等效于 x = c \mathbf{x}=\mathbf{c} x=c(回想恒等式 I x = x \mathbf{I x}=\mathbf{x} Ix=x),因此 c c c已经是解。

**示例1,**确定以下矩阵是否为奇数:

A = [ 2.1 − 0.6 1.1 3.2 4.7 − 0.8 3.1 − 6.5 4.1 ] \mathbf{A}=\left[\begin{array}{rrr}2.1 & -0.6 & 1.1 \\3.2 & 4.7 & -0.8 \\3.1 & -6.5 & 4.1\end{array}\right] A=2.13.23.10.64.76.51.10.84.1

**解:**对A的第一行的拉普拉斯行列式的求解,得出

∣ A ∣ = 2.1 ∣ 4.7 − 0.8 − 6.5 4.1 ∣ − ( − 0.6 ) ∣ 3.2 − 0.8 3.1 4.1 ∣ + 1.1 ∣ 3.2 4.7 3.1 − 6.5 ∣ = 2.1 ( 14.07 ) + 0.6 ( 15.60 ) + 1.1 ( 35.37 ) = 0 \begin{aligned}|\mathbf{A}| &=2.1\left|\begin{array}{rr}4.7 & -0.8 \\-6.5 & 4.1\end{array}\right|-(-0.6)\left|\begin{array}{rr}3.2 & -0.8 \\3.1 & 4.1\end{array}\right|+1.1\left|\begin{array}{rr}3.2 & 4.7 \\3.1 & -6.5\end{array}\right| \\&=2.1(14.07)+0.6(15.60)+1.1(35.37)=0\end{aligned} A=2.14.76.50.84.1(0.6)3.23.10.84.1+1.13.23.14.76.5=2.1(14.07)+0.6(15.60)+1.1(35.37)=0

由于行列式为零,因此矩阵是奇异的。 可以验证奇异性归因于以下行依赖性: ( row ⁡ 3 ) = ( 3 × row ⁡ 1 ) − ( row ⁡ 2 ) (\operatorname{row} 3)=(3 \times \operatorname{row} 1)-(\operatorname{row} 2) (row3)=(3×row1)(row2)

**示例2,**求解等式Ax=b,其中

A = [ 8 − 6 2 − 4 11 − 7 4 − 7 6 ] b = [ 28 − 40 33 ] \mathbf{A}=\left[\begin{array}{rrr}8 & -6 & 2 \\-4 & 11 & -7 \\4 & -7 & 6\end{array}\right] \quad \mathbf{b}=\left[\begin{array}{r}28 \\-40 \\33\end{array}\right] A=8446117276b=284033

知道系数矩阵的LU分解为(您应对此进行验证)

A = L U = [ 2 0 0 − 1 2 0 1 − 1 1 ] [ 4 − 3 1 0 4 − 3 0 0 2 ] \mathbf{A}=\mathbf{L} \mathbf{U}=\left[\begin{array}{rrr}2 & 0 & 0 \\-1 & 2 & 0 \\1 & -1 & 1\end{array}\right]\left[\begin{array}{rrr}4 & -3 & 1 \\0 & 4 & -3 \\0 & 0 & 2\end{array}\right] A=LU=211021001400340132

**解:**我们首先通过正向替换来求解方程式 L y = b \mathbf{L} \mathbf{y}=\mathbf{b} Ly=b

2 y 1 = 28 y 1 = 28 / 2 = 14 − y 1 + 2 y 2 = − 40 y 2 = ( − 40 + y 1 ) / 2 = ( − 40 + 14 ) / 2 = − 13 y 1 − y 2 + y 3 = 33 y 3 = 33 − y 1 + y 2 = 33 − 14 − 13 = 6 \begin{array}{rl}2 y_{1}=28 & y_{1}=28 / 2=14 \\-y_{1}+2 y_{2}=-40 & y_{2}=\left(-40+y_{1}\right) / 2=(-40+14) / 2=-13 \\y_{1}-y_{2}+y_{3}=33 & y_{3}=33-y_{1}+y_{2}=33-14-13=6\end{array} 2y1=28y1+2y2=40y1y2+y3=33y1=28/2=14y2=(40+y1)/2=(40+14)/2=13y3=33y1+y2=331413=6

然后通过反向替换从 U x = y \mathbf{U x}=\mathbf{y} Ux=y中获得解 x x x

2 x 3 = y 3 x 3 = y 3 / 2 = 6 / 2 = 3 4 x 2 − 3 x 3 = y 2 x 2 = ( y 2 + 3 x 3 ) / 4 = [ − 13 + 3 ( 3 ) ] / 4 = − 1 4 x 1 − 3 x 2 + x 3 = y 1 x 1 = ( y 1 + 3 x 2 − x 3 ) / 4 = [ 14 + 3 ( − 1 ) − 3 ] / 4 = 2 \begin{array}{rl}2 x_{3}=y_{3} & x_{3}=y_{3} / 2=6 / 2=3 \\4 x_{2}-3 x_{3}=y_{2} & x_{2}=\left(y_{2}+3 x_{3}\right) / 4=[-13+3(3)] / 4=-1 \\4 x_{1}-3 x_{2}+x_{3}=y_{1} & x_{1}=\left(y_{1}+3 x_{2}-x_{3}\right) / 4=[14+3(-1)-3] / 4=2\end{array} 2x3=y34x23x3=y24x13x2+x3=y1x3=y3/2=6/2=3x2=(y2+3x3)/4=[13+3(3)]/4=1x1=(y1+3x2x3)/4=[14+3(1)3]/4=2

因此解为 x = [ 2 − 1 3 ] T \mathbf{x}=\left[\begin{array}{lll}2 & -1 & 3\end{array}\right]^{T} x=[213]T

高斯消元法

高斯消元是求解联立方程式最熟悉的方法。 它由两部分组成:消元阶段和反向替换阶段。 如表1所示,消元阶段的功能是将方程式转换为Ux = c的形式。 然后通过反替换求解方程。 为了说明该过程,让我们求解以下方程式:

4 x 1 − 2 x 2 + x 3 = 11 , ( a ) − 2 x 1 + 4 x 2 − 2 x 3 = − 16 , ( b ) x 1 − 2 x 2 + 4 x 3 = 17 , ( c ) \begin{aligned}4 x_{1}-2 x_{2}+x_{3} &=11,\qquad(a) \\-2 x_{1}+4 x_{2}-2 x_{3} &=-16,\qquad(b) \\x_{1}-2 x_{2}+4 x_{3} &=17,\qquad(c)\end{aligned} 4x12x2+x32x1+4x22x3x12x2+4x3=11,(a)=16,(b)=17,(c)

消元阶段。 消元阶段仅使用表1中列出的基本运算之一-将一个方程式(例如,方程式j)乘以常数λ,然后从另一个方程式(方程式i)中减去它。 此操作的符号表示为

 Eq.  ( i ) ←  Eq.  ( i ) − λ ×  Eq.  ( j ) , ( 6 ) \text { Eq. }(i) \leftarrow \text { Eq. }(i)-\lambda \times \text { Eq. }(j),\qquad(6)  Eq. (i) Eq. (i)λ× Eq. (j),(6)

减去方程,即  Eq.  ( j ) \text { Eq. }(j)  Eq. (j),称为枢轴方程。

我们通过取  Eq. (a)  \text { Eq. (a) }  Eq. (a) (等式 a a a)作为枢轴方程开始消元,并选择乘数λ,以便从  Eq. (b)  \text { Eq. (b) }  Eq. (b) (等式 b b b)和  Eq. (c)  \text { Eq. (c) }  Eq. (c) (等式 c c c)中消除 x 1 x_{1} x1

 Eq. (b)  ←  Eq. (b)  − ( − 0.5 ) ×  Eq. (a)   Eq. (c)  ←  Eq. (c)  − 0.25 ×  Eq. (a)  \begin{array}{l}\text { Eq. (b) } \leftarrow \text { Eq. (b) }-(-0.5) \times \text { Eq. (a) } \\\text { Eq. (c) } \leftarrow \text { Eq. (c) }-0.25 \times \text { Eq. (a) }\end{array}  Eq. (b)  Eq. (b) (0.5)× Eq. (a)  Eq. (c)  Eq. (c) 0.25× Eq. (a) 

经过这种转换,方程式变为

4 x 1 − 2 x 2 + x 3 = 11 , ( a ) 3 x 2 − 1.5 x 3 = − 10.5 , ( b ) − 1.5 x 2 + 3.75 x 3 = 14.25 , ( c ) \begin{aligned}4 x_{1}-2 x_{2}+x_{3} &=11,\qquad(a) \\3 x_{2}-1.5 x_{3} &=-10.5,\qquad(b) \\-1.5 x_{2}+3.75 x_{3} &=14.25,\qquad(c)\end{aligned} 4x12x2+x33x21.5x31.5x2+3.75x3=11,(a)=10.5,(b)=14.25,(c)

这样就完成了第一遍。 现在我们选择(b)作为枢轴方程,并从(c)中消除 x 2 x_2 x2

 Eq.  ( c ) ←  Eq.  ( c ) − ( − 0.5 ) × E q \text { Eq. }(\mathrm{c}) \leftarrow \text { Eq. }(\mathrm{c})-(-0.5) \times \mathrm{Eq}  Eq. (c) Eq. (c)(0.5)×Eq

得出方程式

4 x 1 − 2 x 2 + x 3 = 11 , ( a ) 3 x 2 − 1.5 x 3 = − 10.5 , ( b ) 3 x 3 = 9 , ( c ) \begin{aligned}4 x_{1}-2 x_{2}+x_{3} &=11,\qquad(a) \\3 x_{2}-1.5 x_{3} &=-10.5,\qquad(b) \\3 x_{3} &=9,\qquad(c)\end{aligned} 4x12x2+x33x21.5x33x3=11,(a)=10.5,(b)=9,(c)

消元阶段现已完成。 原始方程式已替换为等效方程式,可以通过反替换轻松地对其进行求解。

如前所述,增系数矩阵是执行计算的一种更方便的工具。 因此,原始方程式将写为

[ 4 − 2 1 11 − 2 4 − 2 − 16 1 − 2 4 17 ] \left[\begin{array}{rrr|r}4 & -2 & 1 & 11 \\-2 & 4 & -2 & -16 \\1 & -2 & 4 & 17\end{array}\right] 421242124111617

高斯消元的第一遍和第二遍产生的等效方程将显示为

[ 4 − 2 1 11.00 0 3 − 1.5 − 10.50 0 − 1.5 3.75 14.25 ] \left[\begin{array}{rrr|r}4 & -2 & 1 & 11.00 \\0 & 3 & -1.5 & -10.50 \\0 & -1.5 & 3.75 & 14.25\end{array}\right] 400231.511.53.7511.0010.5014.25

[ 4 − 2 1 11.0 0 3 − 1.5 − 10.5 0 0 3 9.0 ] \left[\begin{array}{ccc|r}4 & -2 & 1 & 11.0 \\0 & 3 & -1.5 & -10.5 \\0 & 0 & 3 & 9.0\end{array}\right] 40023011.5311.010.59.0

重要的是要注意,等式(6)中的基本行操作使系数矩阵的行列式保持不变。 这很幸运,因为三角矩阵的行列式非常容易计算-它是对角元素的乘积(您可以很容易地验证这一点)。 换一种说法,

∣ A ∣ = ∣ U ∣ = U 11 × U 22 × ⋯ × U n n , ( 7 ) |\mathbf{A}|=|\mathbf{U}|=U_{11} \times U_{22} \times \cdots \times U_{n n},\qquad(7) A=U=U11×U22××Unn,(7)

反向替换阶段。 现在可以通过以先前描述的方式进行反向替换来计算未知数。 以方程 (c),(b)和(a)的顺序求解方程,我们得到

x 3 = 9 / 3 = 3 x 2 = ( − 10.5 + 1.5 x 3 ) / 3 = [ − 10.5 + 1.5 ( 3 ) ] / 3 = − 2 x 1 = ( 11 + 2 x 2 − x 3 ) / 4 = [ 11 + 2 ( − 2 ) − 3 ] / 4 = 1 \begin{array}{l}x_{3}=9 / 3=3 \\x_{2}=\left(-10.5+1.5 x_{3}\right) / 3=[-10.5+1.5(3)] / 3=-2 \\x_{1}=\left(11+2 x_{2}-x_{3}\right) / 4=[11+2(-2)-3] / 4=1\end{array} x3=9/3=3x2=(10.5+1.5x3)/3=[10.5+1.5(3)]/3=2x1=(11+2x2x3)/4=[11+2(2)3]/4=1

算法

**消元阶段。**让我们在消元阶段的某个时刻看一下这些方程。 假设A的前k行已经转换为上三角形式。 因此,当前的枢轴方程为第k个方程,其下面的所有方程仍需转换。 以下扩展系数矩阵描述了这种情况。 请注意,A的分量不是原始方程式的系数(第一行除外),因为它们已通过消元程序进行了更改。 常数向量b的分量也相同。

假设第i行是要转换的枢轴方程下面的典型行,这意味着元素 A i k A_{i k} Aik将被消除。 我们可以通过将枢轴行乘以 λ = A i k / A k k \lambda=A_{i k} / A_{k k} λ=Aik/Akk来实现,从第i行减去它。 第i行中的相应更改是

A i j ← A i j − λ A k j , j = k , k + 1 , … , n , ( 8 a ) b i ← b i − λ b k , ( 8 b ) \begin{aligned}A_{i j} & \leftarrow A_{i j}-\lambda A_{k j}, \quad j=k, k+1, \ldots, n,\qquad(8a) \\b_{i} & \leftarrow b_{i}-\lambda b_{k},\qquad(8b)\end{aligned} AijbiAijλAkj,j=k,k+1,,n,(8a)biλbk,(8b)

要将整个系数矩阵转换为上式三角形,则等式(8)中的k和i必须具有范围 k = 1 , 2 , … , n − 1 k=1,2, \ldots, n-1 k=1,2,,n1(选择枢轴行), i = k + 1 , k + 2 , … , n i=k+1,k+2, \ldots, n i=k+1,k+2,,n(选择要转换的行)。 消元阶段的算法现在几乎可以自己编写:

for k in range(0,n-1):
	  for i in range(k+1,n):
		if a[i,k] != 0.0:
				lam = a[i,k]/a[k,k]
				a[i,k+1:n] = a[i,k+1:n] - lam*a[k,k+1:n]
				b[i] = b[i] - lam*b[k]

为避免不必要的操作,前面的算法与等式(8)略有不同。以下列方式:

  • 如果 A i k A_{i k} Aik恰好为零,则跳过i行的变换。
  • 等式(8a)中的索引j从k+1而不是k开始。 因此, A i k A_{i k} Aik不会被零替换,而是会保留其原始值。 由于求解阶段无论如何都不会访问系数矩阵的下三角部分,因此其内容无关紧要。

**反向替换阶段。**高斯消去后,增系数矩阵的形式为

[ A b ] = [ A 11 A 12 A 13 ⋯ A 1 n b 1 0 A 22 A 23 ⋯ A 2 n b 2 0 0 A 33 ⋯ A 3 n b 3 ⋮ ⋮ ⋮ ⋱ ⋮ ⋮ 0 0 0 ⋯ A n n b n ] \left[\begin{array}{c|c}\mathbf{A} & \mathbf{b}\end{array}\right]=\left[\begin{array}{ccccc|c}A_{11} & A_{12} & A_{13} & \cdots & A_{1 n} & b_{1} \\0 & A_{22} & A_{23} & \cdots & A_{2 n} & b_{2} \\0 & 0 & A_{33} & \cdots & A_{3 n} & b_{3} \\\vdots & \vdots & \vdots & \ddots & \vdots & \vdots \\0 & 0 & 0 & \cdots & A_{n n} & b_{n}\end{array}\right] [Ab]=A11000A12A2200A13A23A330A1nA2nA3nAnnb1b2b3bn

首先求解最后一个方程 A n n x n = b n A_{n n} x_{n}=b_{n} Annxn=bn,得到

x n = b n / A n n , ( 9 ) x_{n}=b_{n} / A_{n n},\qquad(9) xn=bn/Ann,(9)

现在考虑反向替换的阶段,其中已经计算了 x n , x n − 1 , … , x k + 1 x_{n}, x_{n-1}, \ldots, x_{k+1} xn,xn1,,xk+1(按此顺序),并且我们将根据第 k k k个方程确定 x k x_k xk

A k k x k + A k , k + 1 x k + 1 + ⋯ + A k n x n = b k A_{k k} x_{k}+A_{k, k+1} x_{k+1}+\cdots+A_{k n} x_{n}=b_{k} Akkxk+Ak,k+1xk+1++Aknxn=bk

解为:

x k = ( b k − ∑ j = k + 1 n A k j x j ) 1 A k k , k = n − 1 , n − 2 , … , 1 , ( 10 ) x_{k}=\left(b_{k}-\sum_{j=k+1}^{n} A_{k j} x_{j}\right) \frac{1}{A_{k k}}, \quad k=n-1, n-2, \ldots, 1,\qquad(10) xk=bkj=k+1nAkjxjAkk1,k=n1,n2,,1,(10)

反向替换的对应算法是

for k in range(n-1,-1,-1):
 x[k]=(b[k] - dot(a[k,k+1:n],x[k+1:n]))/a[k,k]

运算计数。 算法的执行时间主要取决于执行的长运算(乘法和除法)的数量。 可以证明高斯消元包含大约 n 3 / 3 n^{3} / 3 n3/3这样运算(n是等式数),进行 n 2 / 2 n^{2} / 2 n2/2反向替换操作。这些数字表明大部分运算时间进入消元阶段。 而且,时间随着方程数的增加而迅速增加

高斯消元函数

函数gaussElimin组合了消元阶段和反向替换阶段。 在反向替换期间,b被解矢量x覆盖,因此b包含退出时的解。

## module gaussElimin
’’’ x = gaussElimin(a,b).
		Solves [a]{b} = {x} by Gauss elimination.
’’’
import numpy as np
def gaussElimin(a,b):
		n = len(b)
		# Elimination Phase
		for k in range(0,n-1):
				for i in range(k+1,n):
						if a[i,k] != 0.0:
							lam = a [i,k]/a[k,k]
							a[i,k+1:n] = a[i,k+1:n] - lam*a[k,k+1:n]
							b[i] = b[i] - lam*b[k]
		# Back substitution
		for k in range(n-1,-1,-1):
				b[k] = (b[k] - np.dot(a[k,k+1:n],b[k+1:n]))/a[k,k]
		return b

详情参阅 - 亚图跨际

你可能感兴趣的:(Python,Python,线性代数,数值)