如何在 Mathematica 中定义与 D 交换的函数 [英] How to define a function that commutes with D in Mathematica

查看:21
本文介绍了如何在 Mathematica 中定义与 D 交换的函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现一个运算符 f 与微分 D 交换.

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 *)

我想知道发生了什么,以及如何修复替换规则,使第二个表达式的计算结果也为 f[Cos[x]].

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.

更新.解决方案 1 以下解决方案似乎完成了重新定义 D 运算符的工作(尽管我离完全理解我自己的代码还差得很远).

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.

推荐答案

模式在语法上匹配,而不是语义上匹配.对于内置函数,如果您重新定义它们,并且如果您的模式不匹配,则使用内置规则(定义).要查看模式是否匹配或不匹配的原因,FullForm 通常很有用.这样,我们看到:

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]]

你的定义只有在 D 中有 f[_] 时才有效,而这里有 D[Plus[f[..],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];

现在它将按预期工作.但是请注意,IMO 以这种方式重新定义诸如 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.

这篇关于如何在 Mathematica 中定义与 D 交换的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆