问题
I'd like to implement an operator f
that commutes with differentiation D
.
Unprotect[D];
D[f[y___], x] := f[D[y, x]];
Protect[D];
D[f[Sin[x]], x]
D[f[Sin[x]] + 1, x]
Unfortunately this code produces two different results
f[Cos[x]] (* as expected *)
Cos[x] f´[Sin[x]] (* cannot explain *)
I'd like to know, what's going on, and how to fix the replacement rule such that the second expression evaluates to f[Cos[x]]
as well.
Update. Solution 1 The following solution seems to do the job of redefining the D
operator (although I'm nowhere near understanding completely my own code).
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}]];
I would appreciate if someone more experienced could take a look at the code and tell me whether this approach is alright.
回答1:
Patterns are matched syntactically, not semantically. For built-in functions, if you redefine them, and if your patterns are not matched, built-in rules (definitions) are used. To see whether or not the pattern will match or why it did not match, FullForm
is often useful. In this way, we see:
In[26]:= FullForm[HoldForm[D[f[Sin[x]]+1,x]]]
Out[26]//FullForm= HoldForm[D[Plus[f[Sin[x]],1],x]]
Your definition is only effective when you have f[_] inside D
, while here you have D[Plus[f[..],1],x]
. Thus, your definition does not match, and then the built-in is used. Here is one way to extend it to cover this case:
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];
Now it will work as expected. Note however that IMO redefining built-in functions such as D
in this manner is a poor practice and should be avoided. For one thing, the above solution is probably not robust either, and you may find yourself adding many more rules to make it work in all cases. Also, generally, it is better to avoid redefining built-in functions if you can (one reason is that doing so may result in some very subtle bugs, since some other system functions may use the one that you redefined, and you have no control over it). I'd instead implement my own differentiation function. This is not integration, it is relatively straightforward to do and you don't put any other system's functionality in danger.
来源:https://stackoverflow.com/questions/5430229/how-to-define-a-function-that-commutes-with-d-in-mathematica