2012-04-29 4 views
1

ODE 해결자를 작성하여 Python을 배우기 시작합니다. 하나 또는 여러 변수 입력 함수를 투명하게 처리하고 싶습니다.수치 형식을 단일 값 시퀀스로 투명하게 처리 (또는 그 반대)

def euler(h, t, y, f): 
    return (y + h*f for y,f in zip(y,f(t,y))) 

가 지금은 두 가지 기능이 같은 f1f2을 정의 : (명백하게)

을 발생하는
def f1(t,y): 
    return -2*t*y 

def f2(t,y): 
    x, y = y #is rebinding usually ok, or confusing? 
    return (x - t*y, y + x/t) 

내가 그들을 테스트

는, 그건 다음은 오일러의 방법의 한 단계 내 코드입니다
>>> list(euler(0.01, 1, (1,2), f2)) 
[0.99, 2.03] 
>>> list(euler(0.01, 1, 1, f1)) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 2, in euler 
TypeError: zip argument #1 must support iteration 

주어진 함수가 하나 이상의 변수에서 작동하지만 솔라리스가 멋진 방법을 찾지 못했다면 솔버가 투명하게 처리되기를 바랍니다. 내가 찾은 방법이

import operator as op 
def euler(h, t, y, f): 
    if op.isNumberType(y): 
     return (y + h*f(t,y),) 
    return (y + h*f for y,f in zip(y,f(t,y))) 

했다하지만 지금은 float를 통과하고이 반복 가능한, 그래서 list(euler(...))는 suceed 수 돌아왔다. 그러나 예를 들어 f(t,euler(...))과 같이 전화 할 수 없습니다.

프리미엄 유형으로 싱글 톤 시퀀스를 처리하거나 무한 검사없이 싱글 톤 시퀀스로 프리미티브를 처리 할 수있는 방법이 있습니까? "끝없는 확인"이란 말은 몇 군데를 점검하고 코드 전체를 점검하지 않고 말입니다. 아니면 그냥 그것을 빨아 f(t,y) 숫자 대신 시퀀스를 기대해야합니까?

도움을 주셔서 감사 드리며 코딩 관련 팁도 환영합니다!

답변

1

f (t, y)는 시퀀스 만 사용하면 매우 쉽습니다.

def euler(h, t, y, f): 
    return (y + h*v for y,v in zip(y,f(t,y))) 

def f1(t,status): 
    x, = status 
    return -2*t*x, 

def f2(t,status): 
    x, y = status 
    return x - t*y, y + x/t 


print list(euler(0.01, 1, (1,2), f2)) 
print list(euler(0.01, 1, (1,), f1)) 
+0

당신의 대답은 내 것과 어떻게 다른가요? – Abhijit

+0

f1에 x 다음에 쉼표가 있습니다. – HYRY

+0

@ HYRY가 가장 좋아하는 점은 그들의 용도가 유사하다는 점입니다. 답장을 보내 주셔서 감사합니다. –

1

오일러 기능에서 TypeError를 잡아 목록에 캡슐화하고 다시 시도하여 복구 할 수 있습니다.

+0

'try ... catch'가'if'보다 선호됩니까? Java에서 (예, "Java는 Python이 아닙니다") 예외적 인 조건에서만 예외를 사용하는 것이 가장 좋습니다. –

+0

예, 자세한 내용은 "duck-typing"을보십시오. –

1

한 가지 가능한 솔루션은

def euler(h, t, y, f): 
    if isinstance(y,collections.Iterable): 
     return (y + h*f for y,f in zip(y,f(t,y))) 
    else: 
     return (y+h*f(t,y),) 

또 다른 해결책은

def f1(t,y): 
    return (-2*t*y[0],) 

로 한 차원 함수를 작성하고 다음과 같은 방식으로

에 오일러를 호출하는 것입니다 다음과 같은 방식으로 오일러 함수를 작성하는 것입니다
list(euler(0.01, 1, (1,), f1)) 
관련 문제