迭代法解线性方程组

1.迭代法

设有线性方程组
{ 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 , \begin{cases} a_{11}x_1&+&a_{12}x_2&+&\cdots&+a_{1n}x_n&=&b_1,\\ a_{21}x_1&+&a_{22}x_2&+&\cdots&+a_{2n}x_n&=&b_2,\\ \vdots\\ a_{n1}x_1&+&a_{n2}x_2&+&\cdots&+a_{nn}x_n&=&b_n,& \end{cases} a11x1a21x1an1x1+++a12x2a22x2an2x2++++a1nxn+a2nxn+annxn===b1,b2,bn,现将该线性方程组改写为
{ x 1 = 1 a 11 ( − a 12 x 2 − ⋯ − a 1 n x n + b 1 ) , x 2 = 1 a 22 ( − a 21 x 1 − a 23 x 3 − ⋯ − a 2 n x n + b 2 ) , ⋮ x n = 1 a n n ( − a n 1 x 1 − a n 2 x 2 − ⋯ − a n n − 1 x n − 1 + b n ) ; ( 1 ) \begin{cases} x_1=\dfrac{1}{a_{11}}(-a_{12}x_2&-\cdots&&-a_{1n}x_n&+&b_1),\\ x_2=\dfrac{1}{a_{22}}(-a_{21}x_1&-a_{23}x_3&-\cdots&-a_{2n}x_n&+&b_2),\\ \vdots\\ x_n=\dfrac{1}{a_{nn}}(-a_{n1}x_1&-a_{n2}x_2&-\cdots&-a_{nn-1}x_{n-1}&+&b_n); (1) \end{cases} x1=a111(a12x2x2=a221(a21x1xn=ann1(an1x1a23x3an2x2a1nxna2nxnann1xn1+++b1),b2),bn);(1)或者写为 x = B 0 x + f , x=B_0x+f, x=B0x+f,其中
B 0 = [ 0 − a 12 a 11 − a 13 a 11 … − a 1 n a 11 − a 21 a 22 0 − a 23 a 22 … − a 2 n a 22 − a 31 a 33 − a 32 a 33 0 … − a 3 n a 33 ⋮ ⋮ ⋮ ⋱ ⋮ − a n 1 a n n − a n 2 a n n … − a n n − 1 a n n 0 ] , f = [ b 1 a 11 b 2 a 22 b 3 a 33 ⋮ b n a n n ] B_0=\begin{bmatrix} 0&-\dfrac{a_{12}}{a_{11}}&-\dfrac{a_{13}}{a_{11}}&\ldots&-\dfrac{a_{1n}}{a_{11}}\\ -\dfrac{a_{21}}{a_{22}}&0&-\dfrac{a_{23}}{a_{22}}&\ldots&-\dfrac{a_{2n}}{a_{22}}\\ -\dfrac{a_{31}}{a_{33}}&-\dfrac{a_{32}}{a_{33}}&0&\ldots&-\dfrac{a_{3n}}{a_{33}}\\ \vdots&\vdots&\vdots&\ddots&\vdots\\ -\dfrac{a_{n1}}{a_{nn}}&-\dfrac{a_{n2}}{a_{nn}}&\ldots&-\dfrac{a_{nn-1}}{a_{nn}}&0 \end{bmatrix}, f=\begin{bmatrix} \dfrac{b_1}{a_{11}}\\ \dfrac{b_2}{a_{22}}\\ \dfrac{b_3}{a_{33}}\\ \vdots\\ \dfrac{b_n}{a_{nn}} \end{bmatrix} B0=0a22a21a33a31annan1a11a120a33a32annan2a11a13a22a230annann1a11a1na22a2na33a3n0,f=a11b1a22b2a33b3annbn
任取初始值 x ( 0 ) = ( 0 , 0 , … , 0 ) T x^{(0)}=(0,0,\ldots,0)^T x(0)=(0,0,,0)T,将其带入(1)式右边,得到新的值 x ( 1 ) = ( x 1 ( 1 ) , x 2 ( 1 ) , … , x n ( 1 ) ) T x^{(1)}=(x_1^{(1)},x_2^{(1)},\ldots,x_n^{(1)})^T x(1)=(x1(1),x2(1),,xn(1))T
再将 x ( 1 ) x^{(1)} x(1)带入右边,反复进行从而可以得到一个向量序列
x ( k + 1 ) = B x ( k ) + f , k = 0 , 1 , 2 , … , ( 2 ) x^{(k+1)}=Bx^{(k)}+f,k=0,1,2,\ldots,(2) x(k+1)=Bx(k)+f,k=0,1,2,,(2)其中k表示迭代次数.
迭代法及其收敛性定义
(1)对于给定的线性方程组 x = B x + f , x=Bx+f, x=Bx+f,用公式(2)逐步带入求近似解的方法称为迭代法(或一阶定常迭代法,这里 B 与 k B与k Bk无关).
(2)如果 lim ⁡ k → ∞ x ( k ) 存 在 ( 记 为 x ∗ ) , \lim\limits_{k \to \infty}x^{(k)}存在(记为x^{*}), klimx(k)(x),称次迭代法收敛,显然 x ∗ x^{*} x就是此方程的解,否则称此迭代法发散.

2.雅可比迭代法(Jacobi)

将线性方程组 A x = b Ax=b Ax=b中的系数矩阵 A = ( a i j ) ∈ R n × n A=(a_{ij})\in \mathbb{R}^{n\times n} A=(aij)Rn×n分成三部分
A = [ a 11 a 22 ⋱ a n n ] − [ 0 − a 21 0 ⋮ ⋮ ⋱ − a n − 1 , 1 − a n − 1 , 2 … 0 − a n 1 − a n 2 … − a n , n − 1 0 ] − [ 0 − a 12 … − a 1 , n − 1 − a 1 n 0 … − a 2 , n − 1 − a 2 n ⋱ ⋮ ⋮ 0 − a n − 1 , n 0 ] ≡ D − L − U . A=\begin{bmatrix} a_{11}&&&\\ &a_{22}&&\\ &&\ddots&\\ &&&a_{nn} \end{bmatrix}- \begin{bmatrix} 0&&&&\\ -a_{21}&0&&&\\ \vdots&\vdots&\ddots&&\\ -a_{n-1,1}&-a_{n-1,2}&\ldots&0\\ -a_{n1}&-a_{n2}&\ldots&-a_{n,n-1}&0 \end{bmatrix}- \begin{bmatrix} 0&-a_{12}&\ldots&-a_{1,n-1}&-a_{1n}\\ &0&\ldots&-a_{2,n-1}&-a_{2n}\\ &&\ddots&\vdots&\vdots\\ &&&0&-a_{n-1,n}\\ &&&&0 \end{bmatrix}\equiv D-L-U. A=a11a22ann0a21an1,1an10an1,2an20an,n100a120a1,n1a2,n10a1na2nan1,n0DLU.
a i i ≠ 0 ( i = 1 , 2 , … , n ) , a_{ii}\neq 0(i=1,2,\ldots,n), aii=0(i=1,2,,n),选取 M M M A A A的对角元素部分,即选取 M = D ( 对 角 矩 阵 ) , A = D − N , M=D(对角矩阵),A=D-N, M=D(),A=DN,得到解 A x = b Ax=b Ax=b的雅可比(Jacobi)迭代法
{ x ( 0 ) , 初始向量, x ( k + 1 ) = B x ( k ) + f , k = 0 , 1 , 2 , … , \begin{cases} x^{(0)},\text{初始向量,}\\ x^{(k+1)}=Bx^{(k)}+f,k=0,1,2,\ldots, \end{cases} {x(0),初始向量,x(k+1)=Bx(k)+f,k=0,1,2,,
其中 B = I − D − 1 A = D − 1 ( L + U ) ≡ J , f = D − 1 b . B=I-D^{-1}A=D^{-1}(L+U)\equiv J,f=D^{-1}b. B=ID1A=D1(L+U)J,f=D1b. J 为 A x = b J为Ax=b JAx=b的雅可比迭代法的迭代矩阵.

3.高斯-赛德尔迭代法(Gauss-Seidel)

选取分裂矩阵 M 为 A M为A MA的下三角部分,即选取 M = D − L ( 下 三 角 矩 阵 ) , A = M − N , 于 是 得 到 解 A x = b 的 高 斯 − 赛 德 尔 迭 代 法 . M=D-L(下三角矩阵),A=M-N,于是得到解Ax=b的高斯-赛德尔迭代法. M=DL(),A=MN,Ax=b.
{ x ( 0 ) , 初始向量, x ( k + 1 ) = B x ( k ) + f , k = 0 , 1 , 2 , … , \begin{cases} x^{(0)},\text{初始向量,}\\ x^{(k+1)}=Bx^{(k)}+f,k=0,1,2,\ldots, \end{cases} {x(0),初始向量,x(k+1)=Bx(k)+f,k=0,1,2,,
其中 B = I − ( D − L ) − 1 A = ( D − L ) − 1 U ≡ G , f = ( D − L ) − 1 b . B=I-(D-L)^{-1}A=(D-L)^{-1}U\equiv G,f=(D-L)^{-1}b. B=I(DL)1A=(DL)1UG,f=(DL)1b.
G = ( D − L ) − 1 U 为 解 A x = b G=(D-L)^{-1}U为解Ax=b G=(DL)1UAx=b的高斯-赛德尔迭代法的迭代矩阵.

4.逐次超松弛迭代法(SOR)

选取分裂矩阵 M M M为带参数的下三角矩阵 M = 1 ω ( D − ω L ) , M=\frac{1}{\omega }(D-\omega L), M=ω1(DωL),
其中 ω > 0 \omega >0 ω>0为可选择的松弛因子.于是可以构造一个迭代矩阵
L ω ≡ I − ω ( D − ω L ) − 1 A = ( D − ω L ) − 1 ( ( 1 − ω ) D + ω U ) . L_{\omega}\equiv I-\omega(D-\omega L)^{-1}A=(D-\omega L)^{-1}((1-\omega)D+\omega U). LωIω(DωL)1A=(DωL)1((1ω)D+ωU).
从而得到解 A x = b Ax=b Ax=b的逐次超松弛迭代法(successive over relaxation method,简称SOR方法).
A x = b Ax=b Ax=b的SOR方法为
{ x ( 0 ) , 初始向量, x ( k + 1 ) = L ω x ( k ) + f , k = 0 , 1 , … , \begin{cases} x^{(0)},\text{初始向量,}\\ x^{(k+1)}=L_{\omega}x^{(k)}+f,k=0,1,\ldots, \end{cases} {x(0),初始向量,x(k+1)=Lωx(k)+f,k=0,1,,
其中 L ω = ( D − ω L ) − 1 ( ( 1 − ω ) D + ω U ) , f = ω ( D − ω L ) − 1 b . L_{\omega}=(D-\omega L)^{-1}((1-\omega)D+\omega U),f=\omega (D-\omega L)^{-1}b. Lω=(DωL)1((1ω)D+ωU),f=ω(DωL)1b.

5.Python实现三种迭代法

import numpy as np
from scipy.linalg import eigvals, inv

def vector_norm(vector: np.ndarray, p=None):
    """
    计算向量的p-范数
    :param vector: 实向量或者复向量
    :param p: 指定类型的范数,默认是oo范数
    :return: 指定向量范数和p值
    """
    if p is None:
        return abs(vector).max(), p
    elif p >= 1:
        return np.power(np.sum(np.power(abs(vector), p)), 1 / p), p
    else:
        raise Exception("error,p must be an integer , greater than  or equal to 1")


def jacobi(coefficient_matrix: np.ndarray,
           right_hand_side_vector: np.ndarray,
           initial_vector: np.ndarray, epsilon=1e-4):
    d = np.diag(np.diag(coefficient_matrix))
    l = -np.tril(coefficient_matrix, k=-1)
    u = -np.triu(coefficient_matrix, k=1)
    jacobi_matrix = inv(d) @ (l + u)
    if spectral_radius(jacobi_matrix) < 1:
        f = inv(d) @ right_hand_side_vector
        x_1 = initial_vector
        x_2 = jacobi_matrix @ x_1 + f
        iteration_count = 1
        while 1:
            norm, _ = vector_norm(x_2 - x_1)
            if norm < epsilon:
                return x_2, iteration_count
            x_1 = x_2
            x_2 = jacobi_matrix @ x_1 + f
            iteration_count += 1
    raise Exception("jacobi iteration is not convergent")


def gauss_seidel(coefficient_matrix: np.ndarray,
                 right_hand_side_vector: np.ndarray,
                 initial_vector: np.ndarray, epsilon=1e-4):
    d = np.diag(np.diag(coefficient_matrix))
    l = -np.tril(coefficient_matrix, k=-1)
    u = -np.triu(coefficient_matrix, k=1)
    gauss_seidel_matrix = inv(d - l) @ u
    if spectral_radius(gauss_seidel_matrix) < 1:
        f = inv(d - l) @ right_hand_side_vector
        x_1 = initial_vector
        x_2 = gauss_seidel_matrix @ x_1 + f
        iteration_count = 1
        while 1:
            norm, _ = vector_norm(x_2 - x_1)
            if norm < epsilon:
                return x_2, iteration_count
            x_1 = x_2
            x_2 = gauss_seidel_matrix @ x_1 + f
            iteration_count += 1
    raise Exception("jacobi iteration is not convergent")


def successive_over_relaxation(coefficient_matrix: np.ndarray,
                               right_hand_side_vector: np.ndarray,
                               initial_vector: np.ndarray,
                               true_solution: np.ndarray, omega=1.0, epsilon=5e-6):
    d = np.diag(np.diag(coefficient_matrix))
    l = -np.tril(coefficient_matrix, k=-1)
    u = -np.triu(coefficient_matrix, k=1)
    l_omega = inv(d - omega * l) @ ((1 - omega) * d + omega * u)
    if spectral_radius(l_omega) < 1:
        f = omega * inv(d - omega * l) @ right_hand_side_vector
        x = l_omega @ initial_vector + f
        iteration_count = 1
        while 1:
            norm, _ = vector_norm(true_solution - x)
            if norm < epsilon:
                return x, iteration_count
            x = l_omega @ x + f
            iteration_count += 1
    raise Exception("jacobi iteration is not convergent")


def hilbert_matrix(order: int):
    hilbert = np.zeros((order, order))
    for i in range(order):
        for j in range(order):
            hilbert[i, j] = 1 / (i + j + 1)
    return hilbert


def spectral_radius(square_matrix: np.ndarray):
    if square_matrix.shape[0] == square_matrix.shape[1]:
        return abs(eigvals(square_matrix)).max()
    raise Exception("\n{} is not a square matrix".format(square_matrix))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值