2011-03-25 4 views
3

D과 차별화되는 연산자 f을 구현하고 싶습니다. Mathematica에서 D로 통근하는 함수를 정의하는 방법

Unprotect[D]; 
D[f[y___], x] := f[D[y, x]]; 
Protect[D]; 

D[f[Sin[x]], x] 
D[f[Sin[x]] + 1, x] 

불행하게도이 코드는 두 개의 다른 결과

을 생산
f[Cos[x]] (* as expected *) 
Cos[x] f´[Sin[x]] (* cannot explain *) 

내가 무슨 일하는 방법과 두 번째 표현식뿐만 아니라 f[Cos[x]]로 평가하도록 대체 규칙을 수정하는 것을 알고 싶습니다.

업데이트. Solution 1 다음 솔루션은 D 연산자를 다시 정의하는 작업을 수행하는 것 같습니다. (내 자신의 코드를 완전히 이해할 수는 없지만).

PartialDerivative[x_, x_] := 1; 

PartialDerivative[c_, x_] := 0 /; FreeQ[c, x]; 

PartialDerivative[f_ConditionalExpectation, x_] := 
    ConditionalExpectation[PartialDerivative[f, x]]; 

PartialDerivative[(f_)[g__], x_] := Module[{i, n, p}, 
     n = Length[SequenceHold[g]]; 
     Sum[ 
      p = ConstantArray[0, n]; p[[i]] = 1; 
      ((Derivative[##1][f] &) @@ p)[g]* 
       PartialDerivative[SequenceHold[g][[i]], x], {i, 1, n}]]; 

더 많은 경험을 가진 사람이 코드를 살펴보고이 접근 방식이 괜찮은지 알 수 있으면 감사하겠습니다.

답변

7

패턴은 의미 적으로가 아니라 구문 적으로 일치합니다. 내장 함수의 경우, 함수를 다시 정의하고 패턴이 일치하지 않으면 기본 제공 규칙 (정의)이 사용됩니다. 패턴이 일치하는지 또는 일치하지 않는지 확인하려면 FullForm이 유용 할 때가 많습니다. 이러한 방법으로, 우리가 볼 : 당신이 f를 때

In[26]:= FullForm[HoldForm[D[f[Sin[x]]+1,x]]] 
Out[26]//FullForm= HoldForm[D[Plus[f[Sin[x]],1],x]] 

귀하의 정의에만 유효 [_] 여기가 D[Plus[f[..],1],x]있는 동안, D 내부. 따라서 정의가 일치하지 않으면 내장이 사용됩니다. 이 경우에 적용 할 수있는 한 가지 방법은 다음과 같습니다.

Unprotect[D]; 
D[f[y___], x_] := f[D[y, x]]; 
D[HoldPattern[Plus[left___, a_f, right___]], x_] := 
    D[Plus[left], x] + D[a, x] + D[Plus[right], x]; 
Protect[D]; 

이제 예상대로 작동합니다. 그러나 IMO는 이러한 방식으로 D과 같은 내장 함수를 재정의하는 것은 좋지 않으므로 피해야합니다. 첫째, 위의 해결 방법은 강력하지 않을 수도 있으며 모든 경우에 적용되도록 더 많은 규칙을 추가 할 수 있습니다. 또한 일반적으로 내장 함수를 재정의하는 것을 피하는 것이 좋습니다 (일부 시스템 함수는 사용자가 재정의 한 함수를 사용할 수 있기 때문에 아주 미묘한 버그가 발생할 수 있으므로 한 가지 이유는 제어 할 수 없기 때문입니다) 그 위에). 대신 내 자신의 차별화 기능을 구현하고 싶습니다. 이것은 통합이 아니며 상대적으로 직관적이며 다른 시스템의 기능을 위험에 빠뜨리지 않습니다.

관련 문제