对于我的课堂作业,我正在编写使用循环的代码,利用Heron的方法找到平方根的估计值,同时还显示迭代和相对变化。
我有以下代码:
# Problem 1.
def square_root_for(a, x0, max_iter = 10, tol=1e-14):
""" (number, integer, number) -> float
Return an estimate of the square root of a number using the Heron's method.
>>> square_root_for(5, 5)
Iteration | Estimate | Relative Change
-------------------------------------------------
1 | 3.00000000000000 | 0.4000000000000000
2 | 2.33333333333333 | 0.2222222222222222
3 | 2.23809523809524 | 0.0408163265306123
4 | 2.23606889564336 | 0.0009053870529653
5 | 2.23606797749998 | 0.0000004106060359
6 | 2.23606797749979 | 0.0000000000000842
7 | 2.23606797749979 | 0.0000000000000000
2.23606797749979
"""
x = [x0]
x.append(a/x0)
print('Iteration | Estimate | Relative Change')
print('-------------------------------------------------')
for i in range(1,max_iter):
change = (abs(x[i] - x[i-1]) / x[i-1])
if change > tol:
x.append(1/2 * (x[i] + (a / x[i])))
else:
break
print('{} | {:.14f} | {:.16f}'.format(i, x[i], change))
return(x[i])
# Don't change or delete the 5 lines of code below.
a = 5
max_iter = 100
tol = 1e-15
x_final = square_root_for(a, a, max_iter, tol)
print('Final estimate using square_root_for is {0}'.format(x_final))
# Problem 2.
def square_root_while(a, x0, tol=1e-14):
""" (number, number, number) -> float
Return an estimate of the square root of a number using the Heron's method.
>>> square_root_while(5, 5)
Iteration | Estimate | Relative Change
-------------------------------------------------
1 | 3.00000000000000 | 0.4000000000000000
2 | 2.33333333333333 | 0.2222222222222222
3 | 2.23809523809524 | 0.0408163265306123
4 | 2.23606889564336 | 0.0009053870529653
5 | 2.23606797749998 | 0.0000004106060359
6 | 2.23606797749979 | 0.0000000000000842
7 | 2.23606797749979 | 0.0000000000000000
2.23606797749979
"""
x = [x0]
x.append(a/x0)
print('Iteration | Estimate | Relative Change')
print('-------------------------------------------------')
i = 1
while i < max_iter + 1:
change = (abs(x[i] - x[i-1]) / x[i-1])
if change > tol:
x.append(1/2 * (x[i] + (a / x[i])))
else:
break
print('{} | {:.14f} | {:.16f}'.format(i, x[i], change))
i += 1
return x[i]
# Don't change or delete the 4 lines of code below.
a = 5
tol = 1e-15
x_final = square_root_while(a, a, tol)
print('Final estimate using square_root_while is {0}'.format(x_final))
问题是我的输出不正确。正确的输出(如在文档字符串中所见)应该是:
Iteration | Estimate | Relative Change
-------------------------------------------------
1 | 3.00000000000000 | 0.4000000000000000
2 | 2.33333333333333 | 0.2222222222222222
3 | 2.23809523809524 | 0.0408163265306123
4 | 2.23606889564336 | 0.0009053870529653
5 | 2.23606797749998 | 0.0000004106060359
6 | 2.23606797749979 | 0.0000000000000842
7 | 2.23606797749979 | 0.0000000000000000
2.23606797749979
我的输出是:
Iteration | Estimate | Relative Change
-------------------------------------------------
1 | 1.00000000000000 | 0.8000000000000000
2 | 3.00000000000000 | 2.0000000000000000
3 | 2.33333333333333 | 0.2222222222222222
4 | 2.23809523809524 | 0.0408163265306123
5 | 2.23606889564336 | 0.0009053870529653
6 | 2.23606797749998 | 0.0000004106060359
7 | 2.23606797749979 | 0.0000000000000842
2.23606797749979
问题在输出的前两行,但我不知道我做错了什么。也许是数学方面的问题?一个学生问我的老师一个类似的问题,她说:"当你做第一个追加时,它和其他的追加有点不同。"我不确定这是否有帮助。如果有什么建议的话,我将不胜感激。
您需要对代码进行以下更改:
- 函数中的第二行应该是
x.append(0.5*(x0 + a/x0))
。你需要x和a/x的平均值(就像在其他迭代中一样)。 print
语句应该在if/else
块之前执行,以打印相对变化低于公差的最后一行。
尝试:
def square_root_for(a, x0, max_iter = 10, tol=1e-14):
x = [x0]
x.append(0.5*(x0 + a/x0))
print('Iteration | Estimate | Relative Change')
print('-------------------------------------------------')
for i in range(1, max_iter):
change = (abs(x[i] - x[i-1]) / x[i-1])
print('{} | {:.14f} | {:.16f}'.format(i, x[i], change))
if change > tol:
x.append(1/2 * (x[i] + (a / x[i])))
else:
break
return(x[i])
>>> square_root_for(5, 5, 100, 1e-15)
Iteration | Estimate | Relative Change
-------------------------------------------------
1 | 3.00000000000000 | 0.4000000000000000
2 | 2.33333333333333 | 0.2222222222222222
3 | 2.23809523809524 | 0.0408163265306123
4 | 2.23606889564336 | 0.0009053870529653
5 | 2.23606797749998 | 0.0000004106060359
6 | 2.23606797749979 | 0.0000000000000842
7 | 2.23606797749979 | 0.0000000000000000
Final estimate using square_root_for is 2.23606797749979
一般来说,如果你发现自己在猜测代码的顺序,你应该试着重写代码-现在,你应该明白每一行的意思,看看下面的:
def square_root_for(a, first_guess, max_iter=10, tol=1e-14):
print('Iteration | Estimate | Relative Change')
print('-------------------------------------------------')
# put a and the first guess in a list
guesses = [a, first_guess]
# loop for a maximum of max_iter times
for i in range(1, max_iter):
# add a new guess to the end of the list
guesses.append(1 / 2 * (guesses[i] + (a / guesses[i])))
# compute the relative change between the last guess [-1] and the one before [-2]
change = abs(guesses[-1] - guesses[-2]) / guesses[-2]
print('{} | {:.14f} | {:.16f}'.format(i, guesses[-1], change))
# stop if the change is at or below tol
if change <= tol:
break
# return the last guess in the list as the result
return guesses[-1]
返回相同的正确结果,但请注意,每一行做某事实际上更容易理解,因为它更字面地描述了自己。你几乎不需要注释。