单步线性定常迭代法

本文介绍了如何使用Python的numpy库实现非奇异线性代数方程组的Jacobi和Gauss-Seidel迭代法。这两种方法分别通过分解矩阵并迭代更新解向量来求解问题,其中Gauss-Seidel法因考虑了前一步的更新而可能更快收敛。代码示例展示了输入矩阵和向量,以及判断迭代收敛的条件。
摘要由CSDN通过智能技术生成

求解非奇异线性代数方程组                      Ax=b

1.Jacobi迭代法

令        A = D - L - U

其中D中的对角线元素与A相等,其余为零。L中元素的行数大于列数时和A对应元素相同,其余为零。U中元素的行数小于列数时和A对应元素相同,其余为零。则方程组可以写成 x = B*x + g,其中B = D(逆)*(L+U),g = D(逆)*b。若在右边给定初始向量,则可以计算一个新的向量,以此类推,即为Jacobi迭代法。以下为其代码:

import numpy as np
print("解非奇异线性方程组‘Ax=b’")
print("请输入非奇异矩阵的行标(n):")
n = int(input())
print("请输入非奇异矩阵(A)(一行一行的输入):")
A = np.array([([float(0) for i in range(n)]) for j in range(n)])
for i in range(n):
    for j in range(n):
        A[i][j] = float(input())
print("请输入向量b:")
b = np.array([([0]) for i in range(n)])
for i in range(n):
    b[i][0] = float(input())
D = np.array([([float(0) for i in range(n)]) for j in range(n)])
for i in range(n):
    D[i][i] = A[i][i]
L = np.array([([float(0) for i in range(n)]) for j in range(n)])
for i in range(n):
    for j in range(n):
        if i > j:
            L[i][j] = -A[i][j]
U = np.array([([float(0) for i in range(n)]) for j in range(n)])
for i in range(n):
    for j in range(n):
        if i < j:
            U[i][j] = -A[i][j]
Dn = np.linalg.inv(D)                               # Dn是D的逆
M = Dn@(L+U)
t, T = np.linalg.eig(M)         # t是特征值,T是特征向量
for i in range(n):
    if abs(t[i]) > 1:
        print("迭代法不收敛")
g = Dn@b
print("请输入向量x(任取解作为初始值):")
x = np.array([([float(0)]) for i in range(n)])
k = int(0)
while k < 1:
    x = M@x + g
    r = A@x - b
    num = float(0)
    for i in range(n):
        num = num + abs(r[i])
    if num < 0.0001:        # 判断迭代完成的条件
        k = 1
print(x)

2.Gauss-Seidel迭代法

注意到Jacobi迭代法中各个分量的计算顺序是没有关系。现在,在计算x(k)用x(k-1)的各个分量计算,但当计算x(k)的第二分量时,由于x(k)的第一个分量已经算出,则用它来代替x(k-1)的第一个分量,其余分量不变。类似的,来计算其它分量,则这种迭代格式为Gauss-Seidel迭代法,简称G-S迭代法。与Jacobi迭代法相比,G-S迭代法编写程序时储存量会更少。同Jacobi迭代法的计量相同,G-S迭代法可以写成 x(k) = (D-L)(逆)*U*x(k-1) + (D-L)(逆)*b。以下为其代码:

import numpy as np
print("解非奇异线性方程组‘Ax=b’")
print("请输入非奇异矩阵的行标(n):")
n = int(input())
print("请输入非奇异矩阵(A)(一行一行的输入):")
A = np.array([([float(0) for i in range(n)]) for j in range(n)])
for i in range(n):
    for j in range(n):
        A[i][j] = float(input())
print("请输入向量b:")
b = np.array([([0]) for i in range(n)])
for i in range(n):
    b[i][0] = float(input())
D = np.array([([float(0) for i in range(n)]) for j in range(n)])
for i in range(n):
    D[i][i] = A[i][i]
L = np.array([([float(0) for i in range(n)]) for j in range(n)])
for i in range(n):
    for j in range(n):
        if i > j:
            L[i][j] = -A[i][j]
U = np.array([([float(0) for i in range(n)]) for j in range(n)])
for i in range(n):
    for j in range(n):
        if i < j:
            U[i][j] = -A[i][j]
Dn = np.linalg.inv(D - L)                               # Dn是D-L的逆
M = Dn@U
g = Dn@b
x = np.array([([float(0)]) for i in range(n)])
k = int(0)
while k < 1:
    x = M@x + g
    r = A@x - b
    num = float(0)
    for i in range(n):
        num = num + abs(r[i])
    if num < 0.0001:        # 判断迭代完成的条件(在一定的误差内)
        k = 1
print(x)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值