2011-03-23 57 views
1

我想實現條件期望運算符。我將使用資本epsilon E來表示運營商。我期望至少下列輸入(下劃線表示下標)Mathematica中的符號條件期望

E_2[a] 
E_2[x_1] 
E_2[x_1 + y_5] 
E_1[3 a + b - 4 + 2 x_] 
E_6[x_5 x_7] 
E_t[x_t] 
E_t[3 x_{t - 1} x_{t + 2}] 

以產生以下輸出上述

a 
x_1 
E_2[y_5] + x_1 
-4 + 3 a + b + 2 E_2[x_5] 
E_6[x_7] x_5 
x_t 
3 E_t[x_{t + 2}] x_{t - 1} 

這些實施例不應我需要產生唯一的輸入/輸出對,而是服務作爲我喜歡的語法的測試和說明。

我有這麼多。 ce表示條件期望,其第三個組成部分是「期望傳播」是否已完成(否則無限遞歸發生在產品規則中),mv代表可測量變量。

Notation[Subscript[E, t_][y_] ==> ce[y_, t_, False]]; 
Notation[Subscript[E, t_][y_] <== ce[y_, t_, _]]; 

Notation[Subscript[x_, t_] <==> mv[x_, t_]]; 

(* Atomic Elements and Measurable Variables *) 
ce[x_, t_, _] := x /; (AtomQ[x] || Head[x] === mv && 0 <= t - x[[2]]); 

(* Distribution over Addition *) 
ce[x_ + y__, t_, s_] := ce[x, t, s] + Plus @@ (ce[#, t, s] & /@ {y}); 

(* Distribution over Product *) 
ce[x__Times, t_, False] := Module[{v, m, n}, 

    (* All Variables in the Product *) 
    v = List @@ x; 

    (* Measurable Among Them *) 
    m = Select[v, AtomQ[#] || Head[#] === mv && 0 <= t - #[[2]] &]; 

    (* The Rest is not Measurable *) 
    n = Complement[v, m]; 

    Times[Times @@ m, ce[Times @@ n, t, True]] 

];  
+2

我不認爲這一切都會很有意義。如果你想讓函數定義給出上面的輸出給出上面的輸入,你可以將第一個框設置爲第二個。 'Subscript [E,0] [a] = a','Subscript [E,0] [Subscript [x,0]] = Subscript [x,0]'等等,你的例子可以工作,但它不會概括。 PS E是保留字(自然對數的基礎)。 – 2011-03-23 16:50:13

+1

下劃線用於模式匹配......不要在符號名稱 – 2011-03-23 17:50:57

+1

@belisarius中使用它,但是他確實提到他將它用作'Subscript'的縮寫。 – rcollyer 2011-03-23 18:01:48

回答

3

我想我可以讓你接近你想要的東西;儘管如此,我不打算這麼做,因爲這可能會非常棘手,但我會指出你朝着正確的方向發展。

首先,使用下標來表示不同的變量是在數學棘手,因爲它解釋E0作爲Subscript[E,0]和兩個ESubscript被保留。 (正如Sjoerd所說,E = 2.718...。)要讓Mathematica識別<anything><something>作爲一個獨特的符號,您需要通過<<Notations`加載Notations包。然後使用Notations Palette,SymbolizeSubscript[E,0]。 (作爲一個小心點,不要試圖在沒有使用調色板的情況下正確設置代碼,否則它可能無法正常工作。)

一旦所有變量都符號化,根據需要,您需要設置適當的轉換規則。前兩個是最簡單的,進入

E_0[a] = a 
E_0[x_0] = x_0 

第3和4:

E_0[x_Plus]:=Distribute[E_0[x]] 
E_0[x_Times]:=Distribute[E_0[x], Times] 

那些是容易的,未來三年需要不同類型的關聯,既不Set也不SetDelayed將在這裏上班正在評估的外部符號是Dt,並且您無法將新規則與它關聯,因爲它是Protected。但是,有兩種方法可將這些表達式與內部符號相關聯:UpSet (^=)(或UpSetDelayed (^:=))或TagSet (/:)。我更喜歡使用TagSet,因爲它更明確,但是應該可以工作。

第5和6:

E_0 /: Dt[ E_0[ x_ ], y_ ] := E_0[ Dt[x,y] ] 

這也將讓你接近第7條,但它反彈來回試圖找出如何增加這個靠規則3和4導致遞歸限制錯誤評估它。相反,將規則3和4替換爲

E_0[x_ + y__]:= E_0[x] + [email protected]@(E_0 /@ {y}) 
E_0[x_ y__ ] := E_0[x] [email protected]@(E_0 /@ {y}) 

這對遞歸有明確的限制。至於第7條規則而言,你得到這個

E_0[D[x_1[t_1,q_0], t_1]] E_0[Dt[t_1, y_0]] 
+ E_0[D[x_1[t_1,q_0], q_0]] E_0[Dt[q_0,y]] 

這是Dt規則的結果和規則4.要獲得E_0不超過DDt分發留作練習。


編輯: 我想就您所提供的解決方案代碼幾點意見。首先,巧妙地使用布爾值來停止遞歸,並且它適用於您的Notation。不過,我建議您對產品分發進行一些更改。首先,我使用x__Times而不是條件(/; Head[x] == Times),因爲它更容易閱讀,我相信(但沒有測試過)它可能更快,即處理它的開銷更小。其次,將Table替換爲List @@ x,其中@@,稱爲Apply,用List替換Times,並且它再次更易於讀取和寫入。對於您定義的n,請考慮使用Complement;我不知道它是否更快,但我傾向於爲這種類型的東西設置理論構造。最後,除非您需要變量爲reevaluated whenever it is used,否則請勿使用SetDelayed:=),請使用Set=)。通過使用:=,m被評估兩次,v被評估3次!

優點和缺點: 這樣做的主要原因是易用性和可讀性。通過定義您自己的對象以及它們的行爲方式,您爲自己提供了很大的靈活性並簡化了代碼。僅憑這一點就值得。但是,過去我很難做到這一點,而且這樣的設置可能會很難,我建議進行徹底的測試。其次,通過添加這些額外的圖層,您可能會減慢代碼速度,因此如果要在關鍵任務應用程序中使用此代碼,請小心。此外,每次使用它時都必須包含Notation,並且調色板在某些時候會變得令人討厭。雖然在加載Notation包之前可以通過設置AutoLoadNotationPalette = False來處理調色板。