GaussSeidel迭代 Jacobi迭代及其收敛性

迭代法求解线性方程组

目的是对于一个可逆矩阵 A A A,利用迭代法求解

A x = b . Ax=b. Ax=b.

G a u s s S e i d e l Gauss Seidel GaussSeidel J a c o b i Jacobi Jacobi 都是将 A A A 矩阵分成 D + L + U D+L+U D+L+U 矩阵的形式,构造出 x = G x + d x=Gx+d x=Gx+d的迭代矩阵,来迭代求解出 x x x,理想情况下当 x = = G x + d x==Gx+d x==Gx+d 时算法收敛,且此时 x = A − 1 b x= \def\foo{A^{-1}} \foo b x=A1b。其中 D L U D L U DLU 分别为 A A A 矩阵的对角线矩阵,下三角矩阵和上三角矩阵。

在上述中介绍到两种方法都是通过定义迭代矩阵 x = G x + d x=Gx+d x=Gx+d 来求解 x x x 的。因此接下来分别介绍,GaussSeidel 和Jacobi分别时怎样定义迭代矩阵的。

G a u s s S e i d e l GaussSeidel GaussSeidel

公式推导

矩阵形式

A = D + L + U A = D + L + U A=D+L+U
A x = b Ax=b Ax=b
( D + L + U ) x = b (D+L+U)x=b (D+L+U)x=b
( D + L ) x = − U x + b (D+L)x = -Ux+b (D+L)x=Ux+b
x = − ( D + L ) − 1 U x + ( D + L ) − 1 b x = -\def\foo{{(D+L)}^{-1}}\foo Ux + \def\foo{{(D+L)}^{-1}}\foo b x=(D+L)1Ux+(D+L)1b
   ⟹    x = G x + d \implies x = Gx +d x=Gx+d
由上述推导可知,在 G a u s s S e i d e l GaussSeidel GaussSeidel G = − ( D + L ) − 1 U G=-\def\foo{{(D+L)}^{-1}}\foo U G=(D+L)1U d = ( D + L ) − 1 b d= \def\foo{{(D+L)}^{-1}}\foo b d=(D+L)1b

非矩阵形式

x i k = 1 a i i ( b − ∑ 0 < j < i a i j x j k − ∑ j > i a i j x j k − 1 ) ) x_{i}^{k} = \frac{1}{a_{ii}} (b- \sum_{0<j<i} {a_{ij} x_{j}^{k}}-\sum_{j>i} {a_{ij} x_{j}^{k-1}}) ) xik=aii1(b0<j<iaijxjkj>iaijxjk1))
其中 x i k x_{i}^{k} xik 代表 x x x 的第 i i i个分量在第 k k k次迭代中的结果

代码示例

使用非矩阵形式实现在稀疏矩阵csr_matrix下实现的 G a u s s S e i d e l GaussSeidel GaussSeidel

# A csr_matrix 
import sys
import copy
import numpy as np
import networkx as nx
from scipy.sparse import spdiags, tril, triu, coo_matrix, csr_matrix

def gauss_seidel(A, b, x0 = None, maxiter=20):
    # x0 = spsolve(A, b)
    if x0 is None:
        x0 =  np.array( [0.0]*A.shape[0]  )
    
    for _ in range(maxiter):
        n, _, indptr, indices, data = A.shape[0], A.nnz, A.indptr, A.indices, A.data
        for row in range(n):
            aii, sumi = 0.0, 0.0
            for j in range(indptr[row], indptr[row+1]):
                if row == indices[j]:
                    aii = 1.0/data[j]
                else:
                    sumi += data[j] * x0[ indices[j] ]
            x0[row] = (aii * (b[row] - sumi) )
    return x0
if __name__ == '__main__':  
    A = csr_matrix(([10,-2,-1, -2,10,-1, -1,-2,5], ([0,0,0,1,1,1,2,2,2], [0,1,2,0,1,2,0,1,2]) ) , shape=(3,3), dtype=np.float32)
    x = np.ones(A.shape[0])
    b = A.dot(x)
    xk = gauss_seidel(A, b)
    print(x)
    print(xk)

输出如下
在这里插入图片描述

J a c o b i Jacobi Jacobi

公式推导

矩阵形式

A = D + L + U A = D + L + U A=D+L+U
A x = b Ax=b Ax=b
( D + L + U ) x = b (D+L+U)x=b (D+L+U)x=b
D x = − ( L + U ) x + b Dx = -(L+U)x+b Dx=L+U)x+b
x = − D − 1 ( L + U ) x + D − 1 b x = -\def\foo{D^{-1}}\foo (L+U)x + \def\foo{D^{-1}}\foo b x=D1(L+U)x+D1b
   ⟹    x = G x + d \implies x = Gx +d x=Gx+d
由上述推导可知,在Jacobi中 G = − D − 1 ( L + U ) G=-\def\foo{D^{-1}}\foo (L+U) G=D1(L+U) d = D − 1 b d= \def\foo{D^{-1}}\foo b d=D1b

非矩阵形式

x i k = 1 a i i ( b − ∑ j ! = i a i j x j k − 1 ) x_{i}^{k}= \frac{1}{a_{ii}}(b-\sum_{j!=i} {a_{ij} x_{j}^{k-1}}) xik=aii1(bj!=iaijxjk1)

代码示例

使用矩阵形式实现在稀疏矩阵csr_matrix下实现的 J a c o b i Jacobi Jacobi

# A csr_matrix
import sys
import copy
import numpy as np
from scipy.sparse import spdiags, tril, triu, coo_matrix, csr_matrix
def jacobi(A, b, x0 = None, maxiter=20):
    if x0 is None:
        x0 =  np.array( [0.0]*A.shape[0]  )

    D = spdiags(A.diagonal(), np.array([0]), A.shape[0], A.shape[1]) # default with <class 'scipy.sparse.dia.dia_matrix'> 

    L = tril(A) - D
    U = triu(A) - D 

    dia = generate_dia_inv(D)
    B = -( dia ).dot(L+U)
    f = ( dia ).dot(b)

    for _ in range(maxiter):
        x0 = B.dot(x0) + f
    return x0
def generate_dia_inv(mat):
    res_dia = mat.diagonal()
    res_dia = 1.0/res_dia
    res_mat = csr_matrix((res_dia.shape[0], res_dia.shape[0]))
    res_mat.setdiag(res_dia)
    return res_mat
if __name__ == '__main__':  
    A = csr_matrix(([10,-2,-1, -2,10,-1, -1,-2,5], ([0,0,0,1,1,1,2,2,2], [0,1,2,0,1,2,0,1,2]) ) , shape=(3,3), dtype=np.float32)
    x = np.ones(A.shape[0])
    b = A.dot(x)
    xk = jacobi(A, b)
    print(x)
    print(xk)

输出如下
在这里插入图片描述

收敛性

因为两种方法的根本思想是一致的,都是通过迭代公式 x = G x + d x = Gx +d x=Gx+d 来求解 x x x。所以直接通过此迭代公式来看两种方法收敛的条件。
令误差向量 e i = x i − x \def\foo{e^{i}}\foo = \def\foo{x^{i}}\foo-x ei=xix,其中 x x x A x = b Ax=b Ax=b的精确解, e i \def\foo{e^{i}}\foo ei G a u s s S e i d e l GaussSeidel GaussSeidel或者 J a c o c i Jacoci Jacoci i i i次迭代所求解。

收敛性证明
由于 x i = G x i − 1 + d \def\foo{x^{i}}\foo = G\def\foo{x^{i-1}}\foo+d xi=Gxi1+d
x = G x + d x = Gx+d x=Gx+d
所以有, e i = G e i − 1 \def\foo{e^{i}}\foo = G\def\foo{e^{i-1}}\foo ei=Gei1
e i − 1 = G e i − 2 \def\foo{e^{i-1}}\foo = G\def\foo{e^{i-2}}\foo ei1=Gei2
. . . ... ...
因此, e i = G i e 0 \def\foo{e^{i}}\foo = \def\foo{G^{i}}\foo\def\foo{e^{0}}\foo ei=Gie0
当迭代法收敛时,就意味着 lim ⁡ i → ∞ e i → 0 \lim\limits_{i\rarr\infin}\def\foo{e^{i}}\foo\rarr0 ilimei0
由特征值和特征向量的定义可知 G ζ i = λ i ζ i G\zeta_i=\lambda_i\zeta_i Gζi=λiζi,且特征向量之间线性无关
因此 e 0 = Σ δ k ζ k \def\foo{e^{0}}\foo=\Sigma\delta_k\zeta_k e0=Σδkζk, 可以这样表示,且 δ k \delta_k δk是定值
e 1 = G e 0 = G ∑ δ k ζ k = ∑ δ k G ζ k = ∑ δ k λ k ζ k \def\foo{e^{1}}\foo = \def\foo{G}\foo\def\foo{e^{0}}\foo = G \sum\delta_k\zeta_k = \sum\delta_kG \zeta_k = \sum\delta_k \lambda_k \zeta_k e1=Ge0=Gδkζk=δkGζk=δkλkζk,由 G ζ i = λ i ζ i G\zeta_i=\lambda_i\zeta_i Gζi=λiζi得。
e 2 = ∑ δ k λ k 2 ζ k \def\foo{e^{2}}\foo= \sum\delta_k \lambda_k^{2} \zeta_k e2=δkλk2ζk , e 3 = ∑ δ k λ k 3 ζ k \def\foo{e^{3}}\foo= \sum\delta_k \lambda_k^{3} \zeta_k e3=δkλk3ζk
那么 lim ⁡ i → ∞ e i = lim ⁡ i → ∞ ∑ λ k i δ k ζ k \lim\limits_{i\rarr\infin}\def\foo{e^{i}}\foo =\lim\limits_{i\rarr\infin} \sum \lambda_k^{i} \delta_k\zeta_k ilimei=ilimλkiδkζk
其中 δ k ζ k \delta_k\zeta_k δkζk是定值
则当 a b s ( λ k ) > 1    ⟹    lim ⁡ i → ∞ e i → ∞ abs(\lambda_k) > 1 \implies\lim\limits_{i\rarr\infin}\def\foo{e^{i}}\foo\rarr\infin abs(λk)>1ilimei
a b s ( λ k ) < 1    ⟹    lim ⁡ i → ∞ e i → 0 abs(\lambda_k) < 1 \implies\lim\limits_{i\rarr\infin}\def\foo{e^{i}}\foo\rarr0 abs(λk)<1ilimei0
综上,当迭代矩阵 G G G的所有特征值 a b s ( λ k ) < 1 abs(\lambda_k) < 1 abs(λk)<1时, 该迭代方法收敛。
  • 10
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值