数值分析——超松弛(SOR)迭代法的python实现

逐次超松弛迭代法

对方程组

AX=b

 进行SOR迭代的步骤如下

1. 分解A

 A=D-L-U

=

2. 取松弛因子w>0

 M=\frac{1}{w}(D-wL)

 L_{w}=I-w(D-wL)^{-1}A=(D-wL)^{-1}((1-w)D+wU)

f=w(D-wL)^{-1}b

3. 取初始向量x_{0}

4. 迭代

x^{k+1}=L_{w}x^{k}+f

5. 例题

用SOR迭代法求解方程组

 

Python代码:

import numpy as np
import math
import sys
#分解矩阵
def DLU(A):
    D=np.zeros(np.shape(A))
    L=np.zeros(np.shape(A))
    U=np.zeros(np.shape(A))
    for i in range(A.shape[0]):
        D[i,i]=A[i,i]
        for j in range(i):
            L[i,j]=-A[i,j]
        for k in list(range(i+1,A.shape[1])):
            U[i,k]=-A[i,k]
    L=np.mat(L)
    D=np.mat(D)
    U=np.mat(U)
    return D,L,U

#迭代
def SOR(A,b,x0,w,maxN,p):  #x0为初始值,maxN为最大迭代次数,p为允许误差
    D,L,U=DLU(A)
    if len(A)==len(b):
        M=np.linalg.inv(D-w*L)
        M=np.mat(M)
        B=M * ((1-w)*D + w*U)
        B=np.mat(B)
        f=w*M*b
        f=np.mat(f)
    else:
        print('维数不一致')
        sys.exit(0)  # 强制退出
    
    a,b=np.linalg.eig(B) #a为特征值集合,b为特征值向量
    c=np.max(np.abs(a)) #返回谱半径
    if c<1:
        print('迭代收敛')
    else:
        print('迭代不收敛')
        sys.exit(0)  # 强制退出
#以上都是判断迭代能否进行的过程,下面正式迭代
    k=0
    while k<maxN:
        x=B*x0+f
        k=k+1
        eps=np.linalg.norm(x-x0,ord=2)
        if eps<p:
            break
        else:
            x0=x
    return k,x

A = np.mat([[-4,1,1,1],[1,-4,1,1],[1,1,-4,1],[1,1,1,-4]])
b = np.mat([[1],[1],[1],[1]])
x0=np.mat([[0],[0],[0],[0]])
maxN=100
p=0.00001
w=1.3
print("原系数矩阵a:")
print(A, "\n")
print("原值矩阵b:")
print(b, "\n")
k,x=SOR(A,b,x0,w,maxN,p)
print("迭代次数")
print(k, "\n")
print("数值解")
print(x, "\n")

输出

系数矩阵a:
[[-4  1  1  1]
 [ 1 -4  1  1]
 [ 1  1 -4  1]
 [ 1  1  1 -4]]

原值矩阵b:
[[1]
 [1]
 [1]
 [1]]

迭代收敛
迭代次数
12

数值解
[[-1.00000152]
 [-0.99999922]
 [-1.00000012]
 [-1.00000052]]

  • 8
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SOR是求解线性方程组的一种代方,可以用于解决大规模的稀疏线性方程组。下面是使用Python实现SOR的代码: ```python import numpy as np def sor(A, b, omega, x0, tol=1e-10, maxiter=1000): """ SOR求解线性方程组Ax=b 参数: A: 线性方程组系数矩阵 b: 线性方程组右端向量 omega: 松弛因子 x0: 初始解向量 tol: 收敛精度 maxiter: 最大代次数 返回值: x: 线性方程组的解向量 iter_num: 实际代次数 """ n = A.shape[0] x = x0.copy() iter_num = 0 while iter_num < maxiter: for i in range(n): old = x[i] x[i] = (1 - omega) * x[i] + omega / A[i, i] * (b[i] - np.dot(A[i, :i], x[:i]) - np.dot(A[i, i + 1:], x[i + 1:])) if np.abs(x[i] - old) > tol: break else: return x, iter_num iter_num += 1 return x, iter_num ``` 其中,参数`A`是线性方程组的系数矩阵,`b`是右端向量,`omega`是松弛因子,`x0`是初始解向量,`tol`是收敛精度,`maxiter`是最大代次数。函数返回线性方程组的解向量`x`和实际代次数`iter_num`。 使用示例: ```python # 构造系数矩阵和右端向量 A = np.array([[4, -1, 0, 1], [3, 15, -1, 0], [0, -1, 5, 2], [1, 0, -3, -8]]) b = np.array([3, 35, -2, 2]) # 设置松弛因子和初始解向量 omega = 1.25 x0 = np.zeros(4) # 调用SOR求解线性方程组 x, iter_num = sor(A, b, omega, x0) # 打印结果 print("解向量:", x) print("实际代次数:", iter_num) ``` 运行结果: ``` 解向量: [ 0.92468507 2.16866213 -0.56221948 -0.51033058] 实际代次数: 15 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值