2017-11-02 2 views
1

나는 수치 분석을 위해 내 코드를 개선하기 위해 내 검색에 다음 코드를 발견이 RK4 ODE-solver에서 내부 람다는 외부 람다 펑션을 어떻게 사용합니까? 파이썬

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) 

지금, 프로그램이 잘 작동하고 프로그램의 전체적인 알고리즘을 볼 수 있습니다. 그러나 나는 람다 중첩이 어떻게 작동 하는지를 이해할 수 없다. 내가 올바르게 이해하면 RK4에있는 dyN은이 ODE 해결 방법에 필요한대로 내부에 정의 된 함수입니다. 그러나 나는 어떻게 내부 람다가 자신의 정의에 외부 람다를 사용하는지 모르겠다. 아마 나는 람다 문법을 정확하게 이해하지 못한다.

+0

[Understanding Python lambdas] (https://stackoverflow.com/questions/32928543/understanding-python-lambdas)의 가능한 복제본 – LutzL

답변

2

여기서 일어나는 일은 람다 함수가 정의되어 즉시 호출된다는 것입니다. 먼저, 다음은 y의 제곱을 계산 단지 복잡한 방법이라는 것을 깨닫게 :

(lambda x: 
    x**2 
)(y) 

차례로 중첩 통과

이 인수를 수정하는 이러한 구조의 주위에 다른 lambda를 랩합니다. 다시, 다음은

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

(math.sin(w))**2 그래서,이 글을 읽을 수있는 방법은 서로 아래쪽에서 위쪽으로 단계를 적용하는 것입니다, w의 사인, 즉의 제곱을 계산하는 복잡한 방법이 될 것입니다.

정상적인 기능을 중첩 호출없이 예에서 lambda -construction 작성, 그것은된다 :

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

거기에서, 그것은 판독 가능 기록 룽게 - 쿠타 방법에 짧은 단계입니다.

관련 문제