我有一个问题,在代码中,h = 0.1表示一个小错误,h = 0.01和h = 0.001。我不明白为什么?,但是当h = 0.0001时,错误再次减少。
谢谢!
def f(x,y):
return 2*x**2-4*x+y
def RK4(x0,y0):
while x0 < b:
k1 = h*f(x0,y0)
k2 = h*f(x0+0.5*h,y0+0.5*k1)
k3 = h*f(x0+0.5*h,y0+0.5*k2)
k4 = h*f(x0+h,y0+k3)
y0+=(k1+2*k2+2*k3+k4)/6
x0+=h
return y0
b=3
h=0.001
print(RK4(1,0.7182818))
答案 0 :(得分:0)
请同时打印最后x0
,您将看到迭代永远不会停在b
。 h
的浮点表示和x0
h
的增加很少是精确的,因此迭代本身不会“命中”b
的值,它会停在少于b+h
。
h returned x returned y
------------------------------------------------
0.1 (3.0000000000000018, 2.0855312227119374)
0.01 (3.0099999999999794, 2.1671997121516187)
0.001 (3.0009999999997796, 2.093630295729702 )
0.0001 (3.000000000002, 2.08553671291036 )
1e-05 (3.0000000000131024, 2.0855367130274134)
您可以通过先验计算步数或纠正最后一步来纠正此问题
def f(x,y):
return 2*x**2-4*x+y
def RK4(x0,y0,xf,h):
while x0 < xf:
if x0+h > xf: h=xf-x0
k1 = h*f(x0,y0)
k2 = h*f(x0+0.5*h,y0+0.5*k1)
k3 = h*f(x0+0.5*h,y0+0.5*k2)
k4 = h*f(x0+h,y0+k3)
y0+=(k1+2*k2+2*k3+k4)/6
x0+=h
return x0,y0
b=3
for k in range (1,6): h=10**-k; print h, RK4(1,0.7182818,b,h)
给出了期望的结果
h returned (x, y)
-----------------------------------
0.1 (3.0, 2.0855312227119236)
0.01 (3.0, 2.0855367122312707)
0.001 (3.0, 2.085536712901802 )
0.0001 (3.0, 2.0855367128941893)
1e-05 (3.0, 2.0855367129214737)
正如宣布的那样,您可以预先计算步数[{1}},并确保N
。为了那个替换
N*h=xf-x0
带
while x0 < xf:
if x0+h > xf: h=xf-x0
您仍然可以在 Dx = float(xf-x0); N = int(0.5+Dx/h); h = Dx/N
for _ in range(N):
,
x0