2012-03-28 2 views
12

Double -> Double 함수를 사용하여 수학적 도함수를 반환하는 함수를 정의하려고합니다.하스켈의 함수의 동일성

der :: (Double -> Double) -> (Double -> Double) 
der f 
    | f == exp = exp 
    | otherwise = undefined 

을하지만 하스켈 ==Double -> Double에 값을 지원하지 않습니다 나는 다음과 같은 일을 시도했다. 하스켈에서 내가하려고하는 일이 불가능한가요?

+0

'f'(x) = (f (x + dx) - f (x))/dx' 또는 자동 차별화를 사용하여 수치 적으로 할 수 있습니다. 튜링 (Turing) - 완성 된 언어에 대한 일반적인 경우에 당신이하려는 것은 불가능합니다. –

답변

20

예, 하스켈에서 할 수있는 일은 불가능합니다. 일반적으로 두 함수가 가능한 모든 입력 값에 대해 동일한 지 여부를 결정합니다 (가능한 경우 모든 입력 값을 확인하지 않고). 정지 문제.

그러나 특정 경우에 Double을 시뮬레이트하는 (즉, 동일한 인스턴스가 있고 따라서 대신 사용할 수있는) 사용자 정의 유형을 사용하여 주위를 둘러 볼 수 있지만 숫자로 평가하는 대신, 함수가 수행하는 연산의 추상 표현을 구성합니다. Expr은 수학 함수 정의 f(x) = ...의 오른쪽을 나타냅니다.

diff X = Const 1 
diff (Const _) = Const 0 
diff (Plus a b) = Plus (diff a) (diff b) 
diff (Exp a) = Mult (diff a) (Exp a) 
... 

을 모두 갖는

fromFunction :: Floating a => (a -> a) -> Expr 
fromFunction f = f X 

toFunction :: Expr -> (Double -> Double) 
toFunction X = \x -> x 
toFunction (Const a) = const a 
toFunction (Plus a b) = \x -> (toFunction a x) + (toFunction b x) 
... 

또한 식을 차별화하는 기능 diff :: Expr -> Expr를 정의 할 수 있습니다 :

data Expr = X | Const Double | 
      Add Expr Expr | Mult Expr Expr | 
      Negate Expr | Inverse Expr | 
      Exp Expr | Log Expr | Sin Expr | ... 
     deriving (Show, Eq) 

instance Num Expr where 
    (+) = Add 
    (*) = Mult 
    ... 
instance Fractional Expr where 
    recip = Inverse 
    ... 
instance Floating Expr where 
    pi = Const pi 
    exp = Exp 
    log = Log 
    sin = Sin 
    ... 

그런 다음 기능과 Expr들 사이의 변환 변환 함수를 정의 할 수 있습니다 이러한 부분은 당신이 (일부) 기능을 구분할 수 있다는 것을 의미합니다.

f x = sin x + cos x * exp x 
f' = toFunction . diff . fromFunction $ f 

주의 사항 : Expr위한 완벽한 Eq 인스턴스를 정의

  • 이 일반적으로 작동하지 않습니다,
  • (이것은 기본적으로 이후는, 중단 문제에 해당 까다 롭습니다 두 함수가 같은지 질문)
  • 이 코드 중 실제로 테스트하지 않은 경우
  • 차이점 켜기 및 재구성은 런타임에 수행되므로 결과 함수는 매우 느릴 수 있습니다.
+2

일반적이기 때문에 단지 하나의'X'Comstructor 이상이 필요합니다. 실제로'Eq' 인스턴스는 까다 롭습니다. 한 번 시도했지만, 평등성 검사가 지나치게 시간이 지나면 끝내지 못했습니다. '∂/∂x (a + x)/sin x'이다. – leftaroundabout

+1

Expr 데이터 형식에 실제로 추가하는 함수에 따라 중단 문제와 같을 수도 있고 아닐 수도 있습니다. 경우에 따라 표현식을 정규화하고 해당 표현식이 동일한 지 확인할 수 있습니다. 또는 재 작성 시스템을 만들 수 있습니다 (이는 몇 가지 방식으로 일반 형식 계산과 동일합니다). toFunction을 사용하여 두 표현식이 평등한지 여부를 결정할 수 있습니다. – danr

11

함수 동등성은 확장 적이 지 않아야합니다. 즉, 모든 인수에 대해 동일한 결과를 제공하는 경우 두 함수가 동일하므로 함수를 동등하게 테스트 할 수 없습니다.

하지만 다른 유형을 사용하는 하스켈에서 파생 상품을 정의하는 다른 방법이 있습니다. 예 : Automatic Differentiation, simpler version of AD.

+0

+1 -하지만 파생 상품을 정의하는 다른 방법에 대한 세부 정보는 유용 할 것입니다. –

+0

숫자 차별화에 관심이 없습니다. –

+5

수치 차별화가 아니라 매우 다르다. 수치 적이거나 상징적 인 것이 아니라 세 번째 신비한 대안입니다. :) – augustss