use*_*407 3 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]
Run Code Online (Sandbox Code Playgroud)
不幸的是,这段代码会产生两种不同
f[Cos[x]] (* as expected *)
Cos[x] f´[Sin[x]] (* cannot explain *)
Run Code Online (Sandbox Code Playgroud)
我想知道,发生了什么,以及如何修复替换规则,以便第二个表达式也可以评估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}]];
Run Code Online (Sandbox Code Playgroud)
如果有经验的人可以查看代码并告诉我这种方法是否正常,我将不胜感激.
模式在语法上匹配,而不是语义匹配.对于内置函数,如果重新定义它们,并且如果模式不匹配,则使用内置规则(定义).要查看模式是否匹配或不匹配的原因,FullForm通常很有用.通过这种方式,我们看到:
In[26]:= FullForm[HoldForm[D[f[Sin[x]]+1,x]]]
Out[26]//FullForm= HoldForm[D[Plus[f[Sin[x]],1],x]]
Run Code Online (Sandbox Code Playgroud)
你的定义只有当你在里面有f [ _ ] 时才有效D,而你在这里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];
Run Code Online (Sandbox Code Playgroud)
现在它将按预期工作.但请注意,IMO D以这种方式重新定义内置函数是一种不好的做法,应该避免.首先,上述解决方案可能也不健壮,您可能会发现自己添加了更多规则,以使其适用于所有情况.此外,通常情况下,最好避免重新定义内置函数(如果可以的话)(一个原因是这样做可能会导致一些非常微妙的错误,因为其他一些系统函数可能会使用您重新定义的函数,并且您无法控制超过它).我会改为实现自己的差异化功能.这不是集成,它相对简单,您不会将任何其他系统的功能置于危险之中.
| 归档时间: |
|
| 查看次数: |
594 次 |
| 最近记录: |