我正在尝试解决以下问题。
这是我编写的代码
import numpy as np
import math
sum = 4
while sum <= 13:
b = 10**(-sum)
x = (math.sqrt(9+b)-3)/(b)
print(x)
sum +=1
给出以下结果
0.16666620370475727
0.1666666203714584
0.1666666618049817
0.1666666671340522
0.1666666804567285
0.1666666804567285
0.1666666804567285
0.1666666804567285
0.16653345369377348
0.16431300764452317
我不确定我的代码是否正确。当我将n
的13插入Wolfram的原始方程式时,我得到了一些不同。我认为随着距离13越来越近,它将接近0.1666666。
我又如何从中制作图表?我想这将是观察结果的最好方法。
答案 0 :(得分:3)
这是与情节一起的完整解决方案。说明:np.logspace(4, 13, 10)
将x
的值创建为10 ^(4),10 ^(5),10 ^(6)... 10 ^(13)。您将其输出取反值,以得到所需的x点为10 ^(-4),10 ^(-5),10 ^(-6)... 10 ^(-13)。然后,您可以遍历这些x值并求解方程式。将每个x的输出值保存在列表中,然后将其绘制出来。
还有其他矢量化方法,而无需创建循环。但这应该可以帮助您入门。
import numpy as np
import math
import matplotlib.pyplot as plt
xmesh = 1./np.logspace(4, 13, 10)
result = []
for x in xmesh:
elem = (math.sqrt(9+x)-3)/(x) # removed 'b' because xmesh is already inverse
result.append(elem) # Adds each element to the list for later plotting
plt.semilogx(xmesh, result, '-bo') # Uses a logarithmic x-axis
plt.gca().invert_xaxis() # Inverts the x-axis because you want it so as per comments
plt.xlabel('1/x', fontsize=16)
plt.ylabel('y', fontsize=16)
plt.show()
输出
使用您的代码
以下是如何在无需大量修改的情况下使用您的代码使其工作
import numpy as np
import math
import matplotlib.pyplot as plt
sum = 4
xmesh = 1./np.logspace(4, 13, 10)
result = []
while sum <= 13:
b = 10**(-sum)
x = (math.sqrt(9+b)-3)/(b)
result.append(x)
sum +=1
plt.semilogx(xmesh, result, '-bo')
plt.gca().invert_xaxis()
plt.xlabel('1/x', fontsize=16)
plt.ylabel('y', fontsize=16)
plt.show()
矢量化方法
import numpy as np
xmesh = 1./np.logspace(4, 13, 10)
result = (np.sqrt(9+xmesh)-3)/(xmesh) # No need to loop. Used `np.sqrt`
plt.semilogx(xmesh, result, '-bo')
plt.gca().invert_xaxis()
答案 1 :(得分:0)
我不确定我的代码是否正确。
您的代码正确。
您看到的是浮数有限精度的结果。
(sqrt(9+x)-3)/x
的 x→0
的限制是 1/6
,而对于 x
您具有接近 1/6
但不同的值
当 x
变得非常小时,分子受math.sqrt
结果的舍入的影响,因此收敛到极限值。< / p>
对于 x 的较小值,可以使用二项式近似来近似分子(9 + x)^ 0.5-3 = 3 *(1 + x / 9)^ 0.5-3≈3 *(1 + x / 18)-3 = 3 + x / 6-3 = x / 6,让我们看看使用Python发生了什么
>>> for n in range(7,16):
... x = 10**(-n)
... print('%2d %10e %s %15e %15e'%(n, x, repr(sqrt(9+x)), sqrt(9+x)-3, x/6))
...
7 1.000000e-07 3.0000000166666667 1.666667e-08 1.666667e-08
8 1.000000e-08 3.000000001666667 1.666667e-09 1.666667e-09
9 1.000000e-09 3.0000000001666667 1.666667e-10 1.666667e-10
10 1.000000e-10 3.0000000000166667 1.666667e-11 1.666667e-11
11 1.000000e-11 3.0000000000016667 1.666667e-12 1.666667e-12
12 1.000000e-12 3.0000000000001665 1.665335e-13 1.666667e-13
13 1.000000e-13 3.0000000000000164 1.643130e-14 1.666667e-14
14 1.000000e-14 3.0000000000000018 1.776357e-15 1.666667e-15
15 1.000000e-15 3.0000000000000004 4.440892e-16 1.666667e-16
我使用repr(...)
来显示平方根结果中的有效数字,您会看到不同的并发现象①用于表示 x / 6的有效数字的数量正在减少,②在计算平方根时会失去精度,并且③当您从基本正确的结果(3+δ)
中减去3时,这些 small 效应会被抵消效应放大。 / p>
我又如何从中制作图表?我想这将是观察结果的最好方法。
如您所见,不必绘制结果图表即可了解问题所在!!!
当您认识到四舍五入引起的不稳定后,要做的是解决问题的最后一部分,
是否有更好的方法来评估此表达式?