列表理解乘法不是预期的

时间:2016-11-11 09:27:52

标签: python python-3.x math list-comprehension

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是一个函数,x0t0时的初始条件,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

2 个答案:

答案 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)