2009-09-29 121 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