如何在 Mathematica 中定义与 D 交换的函数
我想实现一个与微分D
通勤的运算符f
。
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]]
。
更新。解决方案 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}]];
如果更有经验的人可以查看代码并告诉我这种方法是否可以,我将不胜感激。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
模式在语法上进行匹配,而不是在语义上进行匹配。对于内置函数,如果您重新定义它们,并且您的模式不匹配,则会使用内置规则(定义)。要查看模式是否匹配或不匹配的原因,
FullForm
通常很有用。这样,我们看到:只有当
D
中有 f[_] 时,你的定义才有效,而这里有D[Plus[f[. .],1],x]
。因此,您的定义不匹配,然后使用内置的。这是扩展它以涵盖这种情况的一种方法:现在它将按预期工作。但请注意,IMO 以这种方式重新定义内置函数(例如
D
)是一种糟糕的做法,应该避免。一方面,上述解决方案可能也不可靠,您可能会发现自己添加了更多规则以使其在所有情况下都有效。另外,一般来说,如果可以的话,最好避免重新定义内置函数(原因之一是这样做可能会导致一些非常微妙的错误,因为其他一些系统函数可能会使用您重新定义的函数,并且您无法控制超过它)。相反,我会实现自己的微分函数。这不是集成,它相对简单,而且您不会将任何其他系统的功能置于危险之中。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:Your definition is only effective when you have f[_] inside
D
, while here you haveD[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: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.