【python3】【计算方法】高斯消元法求解线性方程组 [a]{x} = b

高斯消元法求解线性方程组 [a]{x} = b

求解过程

使用高斯消元法求解线性方程组 [a]{x} = b,其中 [a] 是一个 Vandermonde 矩阵,{x} 是未知向量,b 是常向量。

高斯消元法的求解过程可以表示为以下矩阵变换:

[ a 1 , 1 a 1 , 2 ⋯ a 1 , n b 1 a 2 , 1 a 2 , 2 ⋯ a 2 , n b 2 ⋮ ⋮ ⋱ ⋮ ⋮ a n , 1 a n , 2 ⋯ a n , n b n ] ⟶ [ 1 a 1 , 2 ′ ⋯ a 1 , n ′ b 1 ′ 0 1 ⋯ a 2 , n ′ b 2 ′ ⋮ ⋮ ⋱ ⋮ ⋮ 0 0 ⋯ 1 b n ′ ] \left[\begin{array}{cccc|c} a_{1,1} & a_{1,2} & \cdots & a_{1,n} & b_1 \\ a_{2,1} & a_{2,2} & \cdots & a_{2,n} & b_2 \\ \vdots & \vdots & \ddots & \vdots & \vdots \\ a_{n,1} & a_{n,2} & \cdots & a_{n,n} & b_n \\ \end{array}\right] \longrightarrow \left[\begin{array}{cccc|c} 1 & a_{1,2}' & \cdots & a_{1,n}' & b_1' \\ 0 & 1 & \cdots & a_{2,n}' & b_2' \\ \vdots & \vdots & \ddots & \vdots & \vdots \\ 0 & 0 & \cdots & 1 & b_n' \\ \end{array}\right] a1,1a2,1an,1a1,2a2,2an,2a1,na2,nan,nb1b2bn 100a1,210a1,na2,n1b1b2bn

其中, a i , j ′ a_{i,j}' ai,j 表示经过消元得到的新系数, b i ′ b_i' bi 表示经过消元得到的新常数项。
无序列表形式:

  • 先将第一行除以 a 1 , 1 a_{1,1} a1,1
  • 将第一行的倍数加到后面的行上,使得第一列下面的元素都为零。
  • 用同样的方法消去第二行、第三行,直到最后一行。
  • 经过消元得到上三角矩阵后,可以通过回带求解出未知向量 {x} 的值。
  • 从最后一行开始,依次求解每个未知量,直到求解出第一个未知量 {x}_1

回带的过程可以表示为以下公式:

x n = b n ′ a n , n ′ {x}_n = \frac{b_n'}{a_{n,n}'} xn=an,nbn

x i = 1 a i , i ′ ( b i ′ − ∑ j = i + 1 n a i , j ′ x j ) for  i = n − 1 , n − 2 , … , 1 {x}_i = \frac{1}{a_{i,i}'} \left(b_i' - \sum\limits_{j=i+1}^n a_{i,j}' {x}_j\right) \quad \text{for } i=n-1, n-2, \ldots, 1 xi=ai,i1(bij=i+1nai,jxj)for i=n1,n2,,1

其中, n n n 是未知向量的长度。

案例

代码

from numpy import zeros, float64, array, product, \
                  diagonal, matmul
from gaussElimin import *

def vandermode(v):
    n = len(v)
    a = zeros((n,n), dtype=float64)
    for j in range(n):
        a[:,j] = v**(n-j-1)
    return a

v = array([1.0, 1.2, 1.4, 1.6, 1.8, 2.0])
b = array([0.0, 1.0, 0.0, 1.0, 0.0, 1.0])
a = vandermode(v)
aOrig = a.copy()    # Save original matrix
bOrig = b.copy()    # and the constant vector
x = gaussElimin(a,b)
det = product(diagonal(a))
print('x =\n',x)
print('\ndet =',det)
print('\nCheck result: [a]{x} - b =\n', \
      matmul(aOrig,x) - bOrig)
input("\nPress return to exit")

解析

  • 代码定义了一个名为 vandermode 的函数。
  • 该函数接受一个一维 Numpy 数组 v 并返回一个 Vandermonde 矩阵 a,其元素是 v 中元素的幂。
  • 代码使用此函数生成一个 Vandermonde 矩阵 a 和一个常向量 b
  • 它使用高斯消元法解出线性方程组 [a]{x} = b,其中 {x} 是解向量。
  • 矩阵 a 的行列式也被计算了。
  • 然后代码打印出解向量 x 和行列式 det
  • 最后,代码通过从原始矩阵 aOrig 和向量 bOrig 的乘积中减去 b 来检查结果,其中 aOrigbOrig 是原始矩阵 a 和向量 b 的副本。
  • 代码末尾的 input 语句等待用户按回车键退出程序。

算法

## 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
  • 这是一个名为 gaussElimin 的模块,其中包含一个函数 gaussElimin(a,b),用于使用高斯消元法求解线性方程组 [a]{b} = {x}

  • 此函数接受两个参数 ab,其中 a 是一个 Numpy 数组,表示系数矩阵,b 是一个 Numpy 数组,表示常数向量。

  • 该函数的求解过程分为两个阶段:消元阶段和回带阶段。

  • 在消元阶段,函数使用高斯消元法将系数矩阵 a 转化为上三角矩阵。

  • 在回带阶段,函数使用回带法求解未知向量 {x}

  • 具体来说,消元阶段的过程是:对于每一行,找到第一个非零元素,将该元素所在的列消成上三角形式。

  • 对于第 k k k 行和第 i i i 行( i > k i>k i>k),如果 a i , k ≠ 0 a_{i,k} \neq 0 ai,k=0,则计算消元因子 λ = a i , k / a k , k \lambda = a_{i,k}/a_{k,k} λ=ai,k/ak,k,然后对第 i i i 行做如下操作:

    a i , k + 1 : n = a i , k + 1 : n − λ a k , k + 1 : n a_{i,k+1:n} = a_{i,k+1:n} - \lambda a_{k,k+1:n} ai,k+1:n=ai,k+1:nλak,k+1:n

    同时,将常数向量 b b b 的第 i i i 个元素也更新:

    b i = b i − λ b k b_i = b_i - \lambda b_k bi=biλbk

  • 回带阶段的过程是:从最后一行开始,依次求解每个未知量,直到求解出第一个未知量 x 1 x_1 x1

  • 对于第 k k k 行,设 x k + 1 : n x_{k+1:n} xk+1:n 表示未知向量的后 n − k n-k nk 个元素,使用如下公式求解 x k x_k xk

    x k = 1 a k , k ( b k − ∑ j = k + 1 n a k , j x j ) x_k = \frac{1}{a_{k,k}} \left(b_k - \sum\limits_{j=k+1}^n a_{k,j} x_j\right) xk=ak,k1 bkj=k+1nak,jxj

  • 最终,函数返回解向量 {x}

案例计算结果

x =
 [   416.66666667  -3125.00000004   9250.00000012 -13500.00000017
   9709.33333345  -2751.00000003]

det = -1.1324620799859046e-06

Check result: [a]{x} - b =
 [ 0.00000000e+00  0.00000000e+00  1.81898940e-12  1.09139364e-11
 -1.81898940e-11  4.36557457e-11]

Press return to exit


Process finished with exit code 0

附:思维导图

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hmywillstronger

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值