2009-09-29 120 views
4

我有一个微分算子,它对两个函数起作用。为了简化问题,让我们说,我的操作是Mathematica部分评估

A[F_,G_] := D[F,x] D[G,y] 

我希望能够,如果我知道楼定义一个微分算子AF,使得AF [G]等于A [F,G]。显而易见的方法是

AF[G_] := A[F,G] 

它工作没有任何问题。但我真正喜欢的是安排事情,以便当我用不同的参数G1,G2,...调用AF时,导数D [F,x]不会每次重新计算,而只会重新计算一次。此外,我希望AF的定义不依赖于A的特定形式,因为A是作为我的函数的参数传递的。

我已经阅读了Hold,HoldAll,Evaluate等方面的帮助,但是我不能把这些东西放在一起得到我想要的东西。我甚至不知道我在Mathematica中是否可能需要。

回答

4

由于你描述的问题,我没有看到一个简单的方法。你可以做的一件事是重新定义它以使它更容易,它将重新定义A,因此它的衍生品FG的函数。如果你有

A[{dFdx_,dFdy_}, {dGdx_,dGdy_}] := dFdx*dFdy 

你会在一个很好的位置,计算出你需要的F衍生品,然后在某种程度上这是一般相对于A,像这样定义AF

With[{ dFdx = D[F,x], dFdy = D[F,y] }, 
    AF[G_] := A[{dFdx, dFdy}, {D[G, x], D[G, y]}]] 

如图所示,您可以使用With将评估过的片段替换为SetDelayed表单的未评估右侧(使用“:=”定义)。但是,如果你不能做出这样的改变,事情就会变得多毛,并且你必须对A做出一些假设。

如果A是为它定义DownValues的象征,有一个简单的定义,那么你可以做你想要使用Hold,做规则替换,然后做一个ReleaseHold,像这样的部分评价:

ReleaseHold[ 
    Hold[AF[G_] := A[F, G]] /. DownValues[A] /. 
    HoldPattern[D[F, var_]] :> With[{eval = D[F, var]}, eval /; True]] 

第二个规则的With[...]位是强制的东西匹配Hold内的模式称为"Trott-Strzebonski method",这是模糊的,但像这样的任务是非常有用的评价一招。然而,这种方式确实会限制你的界面,也就是说你不能通过一个纯函数来传递A,而且如果这个技巧更复杂,这个技巧可能也不起作用。如果您可以设法指定您的差异表格是实际衍生工具的函数,我强烈建议您这样做。

编辑:我想到了这样做的一个更普遍和强大的方式。然后

诀窍是暂时抑制的使用BlockD(衍生物操作者)的定义,所以在A定义的衍生物保持未计算,然后使用规则替换中的值来替代的F衍生物而在纯函数都包裹起来,以获得名替换正确的,就像这样:

With[{fRules = 
{HoldPattern[D[F, x]] :> Evaluate[D[F, x]]}}, 
    Block[{D}, 
    With[{fn = Function[G, Evaluate[A[F, G] /. fRules]]}, 
     AF[G_] := fn[G]]]] 
+0

谢谢!这工作完美。尽管考虑到有多个变量x,y等的可能性,但我做了一些非必要的更改。因此,我使用的代码是AF = With [{fRules = {HoldPattern [D [F, x []]:>评估[D [F,x]]}},块[{D},函数[G,评估[A [F,G] /。 fRules]]]]; – cefstat 2009-09-29 15:22:16

0

难道你们就不能只是做:

A[F_] := With[{DF = D[F, x]}, Function[{G}, DF D[G, y]]] 

类似于F#中的实际函数式编程语言中的咖喱,您可以在其中编写:

let a f = 
    let df = d f x 
    fun g -> df * d g y 
+0

如果知道'A'并提前以'F'和'G'的衍生函数的形式进行投射,这可以很好地工作。但如果不是这样,则需要延迟评估“G”的衍生产品,同时强制评估“F”的衍生产品,这需要额外的步骤。 – Pillsy 2010-04-23 03:19:26