内部lambda如何在这个RK4 ODE求解器中使用外部lambda函数?蟒蛇

时间:2017-11-02 01:47:19

标签: python python-3.x lambda ode nested-function

我在搜索中找到了以下代码来改进我的数值分析代码:

from math import sqrt

def RK4(f):
    return lambda t, y, dt: (
        lambda dy1: (
            lambda dy2: (
                lambda dy3: (
                    lambda dy4: (dy1 + 2 * dy2 + 2 * dy3 + dy4) / 6
                )(dt * f(t + dt, y + dy3))
            )(dt * f(t + dt / 2, y + dy2 / 2))
        )(dt * f(t + dt / 2, y + dy1 / 2))
    )(dt * f(t, y))

def theory(t): 
    return (t**2 + 4)**2 / 16

dy = RK4(lambda t, y: t * sqrt(y))

t, y, dt = 0., 1., .1
while t <= 10:
    if abs(round(t) - t) < 1e-5:
        print("y(%2.1f)\t= %4.6f \t error: %4.6g" % (t, y, abs(y - theory(t))))
    t, y = t + dt, y + dy(t, y, dt)

现在,程序运行正常,可以看到程序的整体算法。但我无法理解lambda嵌套是如何工作的。如果我理解正确dyN中的RK4是内部定义的函数,因为这个ODE求解方法需要它们。但我不知道内部lambda在定义中如何使用外部lambda。也许我没有正确理解lambda语法。

1 个答案:

答案 0 :(得分:2)

这里发生的是定义并立即调用lambda函数。首先,要认识到以下只是计算y

的平方的复杂方法
( lambda x:
    x**2
)( y )

嵌套反过来围绕这样的构造包裹另一个lambda以修改其参数。同样,以下是计算w正弦平方的复杂方法,即(math.sin(w))**2

( lambda z: (
        lambda x: x**2
    )(math.sin(z))
) (w)

因此,阅读本文的方法是将步骤从下到上应用于彼此。

使用普通函数和没有嵌套调用的示例编写lambda - 构造,它变为:

def step_5(f,dy1,dy2,dy3,dy4):
    return (dy1 + 2 * dy2 + 2 * dy3 + dy4) / 6

def step_4(f,dy1,dy2,dy3):
    return step_5( dy1,dy2,dy3, dt * f(t + dt, y + dy3) )

def step_3(f,dy1,dy2):
    return step_4( dy1,dy2, dt * f(t + dt / 2, y + dy2 / 2) )

def step_2(f,dy1):
    return step_3( dy1, dt * f(t + dt / 2, y + dy1 / 2))

def RK4(f):
    return step_2( dt * f(t, y) )

从那里开始,只需要一个可读写的Runge-Kutta方法只需很短的一步。