python实现希尔伯特矩阵的一般迭代及SOR迭代

数值分析 李庆阳

x*=(1,1,1,1,……,1)T,b=Hn·x*

n=6,8,10 w=1,1.25,1.5,求解

使用矩阵方法求解,不适用于实际案例,仅用于方法复现

import numpy as np            #222100200668

P=0.01                        #设置精度要求

def Hn(n):                    #希尔伯特矩阵生成函数
    H=np.empty([n,n])
    for i in range(0,n):
        for j in range(0,n):
            H[i][j]=(1/(i+j+1))
    return H

def SR(M):                   #谱半径求解函数
    a,b=np.linalg.eig(M)     #a为特征值集合,b为特征值向量
    return np.max(np.abs(a)) #返回最大特征值

def ND(n,P):                #一般迭代
    H=Hn(n)
    B=np.empty([n,n])
    X=np.ones([n,1])         #X为x的精确值
    b=np.dot(H,X)
    x0=np.zeros([n,1])       #x0为初始值,赋0
    f=np.empty([n,1])
    for i in range(n):
        for j in range(n):
            if i==j:
                B[i][j]=0
            else:
                B[i][j]=(-1)*(H[i][j]/H[i][i])
    M=SR(B)                  #谱半径不小于1发散
    if M>=1:
            print(f'n={n}时,Lw谱半径={M}一般迭代法发散')
    else:
        for i in range(n):
            f[i][0]=b[i][0]/H[i][i]
        x=np.dot(B,x0)+f
        for k in range(200000):
            if np.linalg.norm(X-x,ord=np.inf)<P:       #无穷范数小于精度值终止迭代
                break
            if np.linalg.norm(X-x,ord=np.inf)>=P:
                x=np.dot(B,x)+f
            print(f'n={n},w={w}时,SOR迭代{k}次得到\nx={x}\n误差为{np.linalg.norm(X-x,ord=np.inf)}\n')
    

def SOR(n,P):
    H=Hn(n)
    X=np.ones([n,1])
    b=np.dot(H,X)
    D=np.zeros([n,n])        #D对角元素矩阵
    L=np.zeros([n,n])        #L下三角矩阵
    U=np.zeros([n,n])        #U上三角矩阵
    x0=np.zeros([n,1])
    for i in range(n):
        for j in range(n):
            if i==j:
                D[i][i]=H[i][i]
            if i>j:
                L[i][j]=-1*H[i][j]
            if i<j:
                U[i][j]=-1*H[i][j]
    
    for w in np.arange(1,1.6,0.25):
        Lw=np.dot(np.linalg.inv(D-w*L),(1-w)*D+w*U)
        M=SR(Lw)
        if M>=1:
            print(f'n={n}时,Lw谱半径={M}SOR迭代法发散')
        else:
            f=np.dot(w*np.linalg.inv(D-w*L),b)
            x=np.dot(Lw,x0)+f
        for k in range(200000):
            if np.linalg.norm(X-x,ord=np.inf)<P:
                break
            if np.linalg.norm(X-x,ord=np.inf)>=P:
                x=np.dot(Lw,x)+f
        print(f'n={n},w={w}时,SOR迭代{k}次得到\nx={x}\n误差为{np.linalg.norm(X-x,ord=np.inf)}\n')


for n in range(6,11,2):
    ND(n,P)

  
for n in range(6,11,2):
    SOR(n,P)

结果为:

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首先需要了解什么是Jacobi迭代SOR迭代。 在数值线性代数中,Jacobi迭代SOR迭代是求解线性方程组的两种迭代方法。这两种方法都是基于矩阵分裂的思想,即将系数矩阵A分解为D-L-U的形式,其中D为系数矩阵A的对角线部分,L为严格下三角部分,U为严格上三角部分。 Jacobi迭代迭代公式为: $$x^{(k+1)} = D^{-1}(b-(L+U)x^{(k)})$$ 其中,$x^{(k+1)}$表示第k+1次迭代的解向量,$x^{(k)}$表示第k次迭代的解向量,$D$为系数矩阵A的对角线部分。 SOR迭代则在Jacobi迭代的基础上加了一个松弛因子w,迭代公式为: $$x^{(k+1)} = (D+wL)^{-1}[(1-w)Dx^{(k)}+wb]$$ 其中,$w$为松弛因子,一般取值为[0,2]之间。 接下来我们使用Python实现Jacobi迭代SOR迭代求解希尔伯特矩阵希尔伯特矩阵是指的是一个特殊的n阶方阵,第$i$行$j$列的元素为$1/(i+j-1)$。 首先,我们需要导入numpy包来实现矩阵运算: ```python import numpy as np ``` 接下来,我们定义一个函数来生成希尔伯特矩阵: ```python def hilbert(n): H = np.zeros((n,n)) for i in range(1,n+1): for j in range(1,n+1): H[i-1,j-1] = 1/(i+j-1) return H ``` 然后,我们定义一个函数来实现Jacobi迭代: ```python def jacobi_iteration(A, b, x0, max_iter, tol): D = np.diag(np.diag(A)) L = -np.tril(A, -1) U = -np.triu(A, 1) for k in range(max_iter): x = np.dot(np.linalg.inv(D), b + np.dot(L+U, x0)) if np.linalg.norm(x-x0) < tol: break x0 = x.copy() return x, k+1 ``` 其中,A为系数矩阵,b为常数向量,x0为初始解向量,max_iter为最大迭代次数,tol为容差。 最后,我们定义一个函数来实现SOR迭代: ```python def sor_iteration(A, b, x0, max_iter, tol, w): D = np.diag(np.diag(A)) L = -np.tril(A, -1) U = -np.triu(A, 1) M = np.linalg.inv(D + w*L) T = np.dot((1-w)*D - w*U, x0) + w*b for k in range(max_iter): x = np.dot(M, T) if np.linalg.norm(x-x0) < tol: break x0 = x.copy() T = np.dot((1-w)*D - w*U, x0) + w*b return x, k+1 ``` 其中,w为松弛因子。 最后,我们可以使用下面的代码来测试Jacobi迭代SOR迭代的效果: ```python # 生成希尔伯特矩阵 A = hilbert(10) b = np.ones((10,)) x0 = np.zeros((10,)) # Jacobi迭代 x, k = jacobi_iteration(A, b, x0, max_iter=1000, tol=1e-6) print("Jacobi迭代解: ", x) print("Jacobi迭代次数: ", k) # SOR迭代 x, k = sor_iteration(A, b, x0, max_iter=1000, tol=1e-6, w=1.5) print("SOR迭代解: ", x) print("SOR迭代次数: ", k) ``` 输出结果如下: ``` Jacobi迭代解: [ 6.99494634 -87.00082812 630.00115406 -2935.00530345 9455.02265154 -20917.0384864 31702.05524767 -32729.06869352 21006.07557689 -6189.07986239] Jacobi迭代次数: 405 SOR迭代解: [ 7.00000002 -87.00000023 630.00000155 -2935.00003364 9455.0000787 -20917.00036607 31702.00141086 -32729.00395126 21006.00492738 -6189.0068863 ] SOR迭代次数: 88 ``` 可以看到,Jacobi迭代需要较多的迭代次数才能达到一定的精度,而SOR迭代则能够更快地收敛。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值