我在搜索中找到了以下代码来改进我的数值分析代码:
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语法。
答案 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方法只需很短的一步。