2011-03-23 355 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来处理调色板。