Wolfram mathematica 在Mathematica中如何定义与D通勤的函数

Wolfram mathematica 在Mathematica中如何定义与D通勤的函数,wolfram-mathematica,Wolfram Mathematica,我想实现一个操作符f,它与微分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]] 更新。解

我想实现一个操作符
f
,它与微分
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]]

更新。解决方案1下面的解决方案似乎完成了重新定义
D
操作符的工作(尽管我还远没有完全理解自己的代码)


如果更有经验的人能看看代码,告诉我这种方法是否正确,我将不胜感激。

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

In[26]:= FullForm[HoldForm[D[f[Sin[x]]+1,x]]]
Out[26]//FullForm= HoldForm[D[Plus[f[Sin[x]],1],x]]
您的定义只有在
D
中有f[u]时才有效,而在这里有
D[Plus[f[…],1],x]
。因此,您的定义不匹配,然后使用内置的。这里有一种方法可以扩展它以涵盖这种情况:

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
,是一种糟糕的做法,应该避免。首先,上述解决方案可能也不健壮,您可能会发现自己添加了更多的规则以使其在所有情况下都能工作。另外,一般来说,如果可以的话,最好避免重新定义内置函数(一个原因是这样做可能会导致一些非常微妙的错误,因为其他一些系统函数可能会使用您重新定义的函数,并且您无法控制它)。相反,我将实现自己的差异化功能。这不是集成,它相对简单,并且不会危及任何其他系统的功能

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