Python 欧拉';不同步长的s方法。如何更改算法的代码以考虑步长的不同值?

Python 欧拉';不同步长的s方法。如何更改算法的代码以考虑步长的不同值?,python,for-loop,matplotlib,integration,numerical-methods,Python,For Loop,Matplotlib,Integration,Numerical Methods,我有一个数值微分方程问题的算法,叫做Euler方法。本质上,欧拉方法近似于微分方程的解。我的函数适用于单个步长(valueh),但我正在尝试更改代码,以允许我循环3个不同的值h(通过将h从单个值更改为可能的值列表)。然而,我编写的函数没有充分地循环我的值。我是python新手,以前使用过R。有人能告诉我如何正确地执行此操作吗 对于步长h的单个值,我的代码是: from math import exp # exponential function dy = lambda x,y: x*y f =

我有一个数值微分方程问题的算法,叫做Euler方法。本质上,欧拉方法近似于微分方程的解。我的函数适用于单个步长(value
h
),但我正在尝试更改代码,以允许我循环3个不同的值h(通过将
h
从单个值更改为可能的值列表)。然而,我编写的函数没有充分地循环我的值。我是python新手,以前使用过R。有人能告诉我如何正确地执行此操作吗

对于步长h的单个值,我的代码是:

from math import exp # exponential function

dy = lambda x,y: x*y
f = lambda x: exp(x**2/2) # analytical solution function

x = 0 # Intial value X_0
xn = 2 # Final Value
y = 1 # value of y(x0)
h = 0.2 # stepsize
n = int((xn-x)/h)

print ('x \t\t y (Euler h={}) \t y (analytical)'.format(h))
print ('%f \t %f \t %f'% (x,y,f(x)))
for i in range(n):
    y += dy(x, y)*h
    x += h
    print ('%f \t %f \t %f'% (x,y,f(x)))


x        y (Euler h=0.5) y (analytical)
0.000000     1.000000    1.000000
0.500000     1.000000    1.133148
1.000000     1.250000    1.648721
1.500000     1.875000    3.080217
2.000000     3.281250    7.389056
我想将h更改为
h=[0.01,0.2,0.5]
,然后创建显示不同步长值下解析解和Euler方法解的绘图

如果这是一个简单的问题,我再次道歉。我是python编程新手,经常犯一些错误,下面是我迄今为止最好的尝试。我还没有将x值存储到容器中,因为我的函数没有在h值上循环。我试图编写一个嵌套的for循环,其中外部循环在h值上循环,存储值并将其绘制为一行,然后迭代到h的第二个值并执行相同的操作,最后可以将值放置在单个绘图上

# Improved to allow plotting different values
import matplotlib.pyplot as plt 
import numpy as np
from math import exp # exponential function

dy = lambda x,y: x*y
f = lambda x: exp(x**2/2) # analytical solution function
x = 0
xn = 2
y = 1
# Container for step sizes
h = [0.5,0.2,0.1]

# Container to store the x values at each stepsize
# X =np.zeros((3,))

print ('x \t\t y (Euler) \t y (analytical)')
print ('%f \t %f \t %f'% (x,y,f(x)))
for j in range(0,len(h),1):
    n = int((xn-x)/h[j])
    for i in range(n):
        y += dy(x, y)*h[j]
        x += h[j]
        print ('%f \t %f \t %f'% (x,y,f(x)))
    plt.plot(x,y)

plt.show()


x        y (Euler)   y (analytical)
0.000000     1.000000    1.000000
0.500000     1.000000    1.133148
1.000000     1.250000    1.648721
1.500000     1.875000    3.080217
2.000000     3.281250    7.389056


因此,问题是真正尝试为不同的步长创建Euler方法,即“如何更改函数以循环列表并使用matplotlib打印结果”

您犯了一个小错误,如果要打印结果,需要将结果存储在容器中。我稍微重写了你的代码。我首先给你完整的代码,然后再讨论你的代码出了什么问题。也许你自己能发现错误。我还添加了解析解的计算和其他一些小的改进,这应该是您喜欢的。下面是代码:

导入matplotlib.pyplot作为plt
将numpy作为np导入
从数学导入exp#指数函数
dy=λx,y:x*y
f=lambda x:exp(x**2/2)#解析解函数
x_final=2
#解析解
x_a=np.arange(0,x_最终,0.01)
y_a=np.0(len(x_a))
对于范围内的i(len(x_a)):
y_a[i]=f(x_a[i])
plt.绘图(x_a,y_a,label=“分析”)
#步长容器
h=[0.5,0.2,0.1]
对于范围内的j(len(h)):
x=0
y=1
打印(“h=“+str(h[j]))
打印(“x\t\t y(欧拉)\t y(分析)”)
打印(“%f\t%f\t%f”%(x,y,f(x)))
n=int((x_final-x)/h[j])
x_n=np.零(n+1)
y_n=np.零(n+1)
x_n[0]=x
y_n[0]=y
对于范围(n)中的i:
y+=dy(x,y)*h[j]
x+=h[j]
打印(“%f\t%f\t%f”%(x,y,f(x)))
x_n[i+1]=x
y_n[i+1]=y
plt.plot(x_n,y_n,“x-”,label=“h=”+str(h[j]))
plt.xlabel(“x”)
plt.ylabel(“y”)
plt.legend()
plt.show()
这将在我的计算机上绘制以下内容:

请注意,我将变量
xn
重命名为
xu final
,以避免与我引入的变量名称混淆。如前所述,您需要将每个x和y值存储在一个容器中。为此我使用了NumPy数组,但也可以使用列表。这个

n=int((x_final-x)/h[j])
x_n=np.零(n+1)
y_n=np.零(n+1)
x_n[0]=x
y_n[0]=y
只创建两个零数组,其大小等于子步数+1。然后我将第一个值设置为等于初始值。这必须在循环
h
内,因为每个h的子步数
n
不同

i
-循环结束时,我只需将当前
x
y
值写入数组中的正确位置

范围(n)内的i的
:
y+=dy(x,y)*h[j]
x+=h[j]
打印(“%f\t%f\t%f”%(x,y,f(x)))
x_n[i+1]=x
y_n[i+1]=y
使用
x
y
调用
plt.plot
,只绘制一个点,因为它们是sclars,而不是调用
plt.plot
,您需要将数组传递给函数:

plt.plot(x_n,y_n,“x-”,label=“h=”+str(h[j]))
我还添加了一个将显示在图例中的标签,并将线型更改为
“x-”

您犯了一个错误,导致您的
i
循环仅对第一个
h
执行,即您没有将
x
y
重置为初始值。因此,在第一次运行外循环之后,您的
n
始终是
0

当然,您可以优化一些事情,比如使用

h_列表中h的
:
...

这将比总是使用
h[j]
而不仅仅是
h
更具可读性,但我认为现在这已经足够了

您需要为x和y值创建一个列表,并在每个步骤中附加当前值。当您为不同的h开始新的迭代时,不要忘记重置列表。