Python 用于改进euler';使用预测-校正方法的s方法

Python 用于改进euler';使用预测-校正方法的s方法,python,Python,我正在尝试学习Python,我想回顾一下一些古老的数学知识,看看我是否能用数值方法编写一个程序来求解ODE,这会很有趣。我能够为Euler的方法设计一个程序,没有太多麻烦,但现在我正在尝试修改它,使它使用预测-校正方法,并且似乎不能正确地得到它 欧拉法: def f(x,y): return (0.2*x*y) def eulers(x,y,h,xfinal): print(y) iters = int((xfinal-x)/h) for i in range(1,iters+

我正在尝试学习Python,我想回顾一下一些古老的数学知识,看看我是否能用数值方法编写一个程序来求解ODE,这会很有趣。我能够为Euler的方法设计一个程序,没有太多麻烦,但现在我正在尝试修改它,使它使用预测-校正方法,并且似乎不能正确地得到它

欧拉法:

def f(x,y):
  return (0.2*x*y)

def eulers(x,y,h,xfinal):
  print(y)
  iters = int((xfinal-x)/h)
  for i in range(1,iters+1):
    y = y + h*(f(x,y))
    print(y)

print(eulers(1,1,0.05,1.5))
改进的Euler方法(到目前为止我一直在尝试):

我正在使用的教科书指出,改进的方法使用公式Yn+1=Yn+h*(f(Xn,Yn)+f(Xn+1,^Yn+1^))/2,其中^Yn+1^是原始Euler方法中使用的公式(Yn+1=Yn+h*f(Xn,Yn)。由于预测-校正方法的每次迭代都需要两次计算,我尝试了以下两种方法:

for i in range(0,iters):
  f1 = yA[i] + h*(f(xA[i],yA[i]))
  yA[i+1] = yA[i] + h*( (f(xA[i],yA[i]) + f(xA[i+1],f1) )/ 2 )

但这两种方法似乎都不起作用。我最终得到了相同的数字,就好像我要用原始的Euler方法运行程序一样(就好像我刚刚运行了:

for i in range(0,iters):
  yA[i+1] = yA[i] + h*(f(xA[i],yA[i]))

有什么想法吗?谢谢。

小调:
range(0,iters)
只是
range(iters)
。此外,您似乎在将
yA
复制到末尾的列表中,但这样做效率很低。您可以调用
newlist=yA.tolist()
(因为它是一个numpy数组)。但您也可以打印数组:
print(yA)
。至于您的实际问题:暂时忘记效率,尝试同时计算“
Y hat
”和
Y
并行;一个是原始的Euler,另一个是基于这个Euler的,完全按照定义。你仍然得到相同的结果吗?问题可能是你一直在根据之前的修正值计算“未修正”的Y hat。我不确定我是否完全理解你的意思,但我计算了Y(在本例中为Yhat)使用原始的Euler方法(带有改进方法的代码),它给了我正确的近似值。我尝试将改进方法的“Yhat”定义为“f1”,认为使用“yA[I+1]'对于for循环的两行来说都是问题所在,但这一更改似乎没有任何区别。抱歉,我现在意识到循环工作正常。我在程序开始时查看了函数,没有注意到练习中使用的问题中的一些小细节。不过感谢您的帮助。小提示:
range(0,iters)
只是
range(iters)
。此外,您似乎在将
yA
复制到末尾的列表中,但这样做效率很低。您可以调用
newlist=yA.tolist()
(因为它是一个numpy数组)。但您也可以打印数组:
print(yA)
。至于你的实际问题:暂时忘记效率,试着并行计算“
Y hat
”和
Y
;一个是原始的Euler,另一个是基于另一个Euler,完全按照定义。你仍然得到相同的结果吗?问题可能是你一直在计算“未修正的”我不确定我是否完全理解你的意思,但我使用原始的Euler方法(使用改进方法的代码)计算了Y(在本例中为Yhat),它给出了正确的近似值。我尝试将改进方法的“Yhat”定义为“f1”,认为使用“yA[I+1]'对于for循环的两行来说都是问题所在,但这一更改似乎没有任何区别。抱歉,我现在意识到循环工作正常。我在程序开始时查看了函数,没有注意到我在练习中使用的问题中的一些小细节。不过感谢您的帮助。
for i in range(0,iters):
  yA[i+1] = yA[i] + h*(f(xA[i],yA[i]))
  yA[i+1] = yA[i] + h*( (f(xA[i],yA[i]) + f(xA[i+1],yA[i+1]) )/ 2 )
for i in range(0,iters):
  yA[i+1] = yA[i] + h*(f(xA[i],yA[i]))