本次将通过一个具体实例来实现一下这两种方法的过程
例题:
1.共同部分
import numpy as np
#输入部分
A = np.array([[10.0, -2, -1], [-2, 10, -1], [-1, -2, 5]])
B = np.array([3.0, 15, 10])
x0 = np.array([0.0, 0, 0]) #x0,我的理解是一个相对于x延后更新的数组,用于前后更新误差检验
x = np.array([0.0, 0, 0])
print(x[0])
times = 0 #迭代次数
一.雅克比迭代法
#让i从0循环到最后一个解,每一次更新一个x[i],最后循环完毕得到的最新一组解,再通过误差分析检测是否合适
#j循环的目的在于temp,通过temp的更新(见公式)
while True:
for i in range(3): #这里的3,指的是行A数,相对应一组解中有几个解
temp = 0
for j in range(3): #这里的3,指的是A列数
if i != j:
temp += x0[j] * A[i][j]
x[i] = (B[i] - temp) / A[i][i]
#误差分析部分:
calTemp = max(abs(x - x0))
times += 1
if calTemp < 1e-6:
break
else:
x0 = x.copy() #如果误差过大,让x0=x,进行下一次循环
print(times)
print(x)
output:
16
[ 0.99999984 1.99999984 2.99999974]
二.高斯赛德尔迭代法
与雅克比迭代法不同之处在于,高斯赛德尔迭代法中,一次完整的i循环中,每一次循环得到的更新值,应用到本次循环中的接下来的循环
while True:
for i in range(3):
temp = 0
for j in range(3):
if i < j: #与雅克比迭代法不同之处 #将x0[j]和x[j]放在哪个语句那里很重要!!!
temp += x0[j] * A[i][j] #此时我需要计算x[i],需要得到temp(与j有关),当i>j,就可以使用更新过的x数组的值,i<j,就用没有更新过的,那么就是x0数组
elif i > j:
temp += x[j] * A[i][j]
x[i] = (B[i] - temp) / A[i][i]
calTemp = max(abs(x - x0))
times += 1
if calTemp < 1e-6:
break
else:
x0 = x.copy()
print(times)
print(x)
output:
9
[ 0.99999989 1.99999995 2.99999996]
Notes:
1.双循环中的第二个循环,用于更新得到temp变量
通过循环来更新temp变量的思想我认为值得思考
2.x0 = x.copy()
一开始,我采用的是x0 = x1,但是容易忽视的是,这样的话,x0 和x1指向的是同一个内存,之后,无论是x0,还是x1改变,两个数组都会改变,这就违背我的原意了
B = np.array([3.0, 15, 10])
C = B
B[2] = 1
print(B)
print(C)
output:
[ 3. 15. 1.]
[ 3. 15. 1.]
所以copy函数是很好的选择