python - 在python中为割线方法编写循环时遇到问题
问题描述
我最近开始学习 python,我的课程中的一个问题是编程割线方法。我无法重新分配循环中的变量。
无论我如何编写 while 语句,我都会得到除以零的错误。我假设这是因为我的代码使循环成为当前 x_1=x_0 并计算 f(x_1)-f(x_0),而不是将旧的 x_1 用于 x_0。我的尝试:
G = 6.6741*10**-11
r_e = 6371000
r_m = 1737100
M_e = 5.9722*10**24
M_m = 7.3420*10**22
R = 3.8440*10**8
w = 2.6617*10**-6
def f(x):
return (G*M_e)/x**2 - (G*M_m)/(R-x)**2 - w**2 * x
x_0=2*10**8
x_1=2.2*10**8
i=1
while i<=10 or 0.99 < x_1/x_0 <1.01:
x_1=float(x_1-f(x_1)*(x_1-x_0)/(f(x_1)-f(x_0)))
i = i+1
x_0=x_1
print (x_1)
错误:
runfile('//myfiles/vj284/dos/python/Coursework q1.py',
wdir='//myfiles/vj284/dos/python')
Traceback (most recent call last):
File "<ipython-input-2-b33827a1b929>", line 1, in <module>
runfile('//myfiles/vj284/dos/python/Coursework q1.py',
wdir='//myfiles/vj284/dos/python')
File "C:\Program Files\Anaconda3\lib\site-
packages\spyder\utils\site\sitecustomize.py", line 705, in runfile
execfile(filename, namespace)
File "C:\Program Files\Anaconda3\lib\site-
packages\spyder\utils\site\sitecustomize.py", line 102, in execfile
exec(compile(f.read(), filename, 'exec'), namespace)
File "//myfiles/vj284/dos/python/Coursework q1.py", line 20, in <module>
x_1=float(x_1-f(x_1)*(x_1-x_0)/(f(x_1)-f(x_0)))
ZeroDivisionError: float division by zero
解决方案
我假设这是因为我的代码使循环成为当前
x_1=x_0
和计算f(x_1)-f(x_0)
,而不是使用旧x_1
的 forx_0
。
没有。这是因为你在循环中的最后一行x_0 = x_1
。你为什么要覆盖x_0
?还有,是y
为了什么?
编辑:由于您添加了文本版本,因此更容易修复您的代码。只需使用一个临时变量来保存“新”结果。另外,更改or
为and
AND 添加一个条件来检查收敛(如果方法收敛x_0
将与 相同x_1
,因此代码将由于除以零而崩溃):
i = 1
while i <= 10 and 0.99 < x_1/x_0 <1.01 and abs((x_1 - x_0) / x_1) > 1e-15: :
tmp = x_1 - f(x_1) * (x_1 - x_0) / (f(x_1) - f(x_0))
i = i + 1
x_0 = x_1
x_1 = tmp
不清楚为什么你有and 0.99 < x_1/x_0 <1.01
循环条件。我认为您应该将其删除:
i = 1
while i <= 10 and abs(x_1 - x_0) > 1e-15 * abs(x_1):
tmp = x_1 - f(x_1) * (x_1 - x_0) / (f(x_1) - f(x_0))
i = i + 1
x_0 = x_1
x_1 = tmp
最后一个编辑:为了避免需要临时变量,我将重写循环如下:
for _ in range(10):
if abs(x_1 - x_0) < 1e-15 * abs(x_1):
break
x_0, x_1 = x_1, x_1 - f(x_1) * (x_1 - x_0) / (f(x_1) - f(x_0))
此外,您可能应该检查函数值的接近性而不是其参数:通常,由于舍入错误,f(x_1)
可能等于f(x_0)
eventhough x_1 != x_0
。或者,您可能想要检查是否f(x_1) <= eps
表明已找到根。