from math import sin
def euler(f, x0, t0, h, N):
t = t0
x = x0
while t <= N:
t += h
x += [h * x for x in f(t, x)]
print(x)
def f(t, x):
vv = [-x[0]**3 - x[0] + sin(t)]
return vv
这是我的代码。 f
是一个函数,x0
是t0
时的初始条件,t0
是初始时间,h
是步长,{{1}是步数。当我输入N
时
我得>>>euler(f, [0.], 0., 1., 10)
这是不正确的。
我知道我的列表理解陈述遗漏了一些内容,但我无法确切地指出我所遗漏的内容,因为我不知道它是如何返回这些值的。前2个值是正确的,然后,它会错误地计算剩余值。
当我应该得到
[0.0, 0.8414709848078965, 0.9092974268256817, 0.1411200080598672, -0.7568024953079282, -0.9589242746631385, -0.27941549819892586, 0.6569865987187891, 0.9893582466233818, 0.4121184852417566, -0.5440211108893698]
使用此代码:
0.0
0.8414709848078965
0.313474190234726
0.11031613198378529
-0.758145003910546
-0.5231547727660838
-0.1362327890906342
0.6595149938422956
0.7024955870270317
0.06543687806493725
答案 0 :(得分:2)
试试这个:
from math import sin
def euler(f, x0list, t0, h, N):
t = t0
xlist = x0list
while t < N*h:
klist = f(t,xlist)
xlist = [x+h * k for x,k in zip(xlist,klist)]
t += h
print t,xlist
def f(t, xlist):
return [ -x**3 - x + sin(t) for x in xlist ]
euler(f, [0.,-0.1,0.1], 0., 1., 10)
这假定您要并行评估多个轨迹。
x
和斜率k
,它再次取决于x
。因此,您还需要在f
中进行列表评估。 zip
对构建迭代器,将关联的状态和斜率配对在一起,以计算下一个状态。 zip
的方法是让函数f
返回一对(x,k)
对。当然,您也可以避免所有这些并迭代euler
的评估,其中只计算一条轨迹。
答案 1 :(得分:0)
如果你想要的是一个将轨迹作为列表返回的函数,你可以使用yield
提供的列表生成器模式:
def euler(f, x, t, h, N):
yield x # report the initial point as the first sample
for k in range(N):
x += h*f(t,x)
t += h
yield x
def f(t, x):
return -x**3 - x + sin(t)
x0, t0, tf = 0.0, 0.0, 10.0
N = 10
h = (tf-t0)/N
for x in euler(f, x0, t0, h, N):
print x
for k,x in enumerate(euler(f, x0, t0, h, N)):
print "%3d %15.8f %20.16f" % (k, t0+k*h, x)
使用“tlist
in - xlist
out”形式使方法调用更加灵活,使用类似
def eulerfix(f, tlist, x):
yield x
for t, tnext in zip(tlist, tlist[1:]):
x = x + (tnext-t)*f(t,x)
yield x
def f(t, x):
return -x**3 - x + sin(t)
x0, t0, tf = 0.0, 0.0, 10.0
N = 10
t = [ t0 + k*(tf-t0)/N for k in range(N+1) ]
for k,x in enumerate( eulerfix(f, t, x0) ):
print "%3d %15.8f %20.16f" % (k, t[k], x)