在此 RK4 ODE 求解器中,内部 lambda 如何使用外部 lambda 函数? Python
How does the inner lambda use the outer lambda fuction in this RK4 ODE-solver? Python
我在搜索中找到了以下代码来改进我的数值分析代码:
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 嵌套是如何工作的。如果我理解正确,RK4
中的所有 dyN
都是内部定义的函数,因为此 ODE 求解方法需要它们。但我不知道内部 lambdas 如何在它们的定义中使用外部 lambdas。也许我没有正确理解 lambda 语法。
这里发生的是定义并立即调用 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) )
从那里,距离编写可读的龙格-库塔方法仅一小步。
我在搜索中找到了以下代码来改进我的数值分析代码:
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 嵌套是如何工作的。如果我理解正确,RK4
中的所有 dyN
都是内部定义的函数,因为此 ODE 求解方法需要它们。但我不知道内部 lambdas 如何在它们的定义中使用外部 lambdas。也许我没有正确理解 lambda 语法。
这里发生的是定义并立即调用 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) )
从那里,距离编写可读的龙格-库塔方法仅一小步。