Mathematica中的符号条件期望

时间:2011-03-23 16:03:07

标签: wolfram-mathematica

我想实现条件期望运算符。我将使用大写epsilon E来表示运算符。我期望至少以下输入(下划线表示下标)

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]]

];       

1 个答案:

答案 0 :(得分:3)

我想我可以让你接近你想要的东西;不过,我不打算这么做,因为它可能很棘手,但我会指出你正确的方向。

首先,使用下标来表示不同的变量在Mathematica中很棘手,因为它将E 0 解释为Subscript[E,0]E并保留Subscript。 (正如Sjoerd所说,E = 2.718...。)要让Mathematica将<anything> <something> 识别为一个独特的符号,您需要通过{{1}加载Notations包}}。然后使用Notations Palette,<<Notations` Symbolize。 (请注意,如果不使用调色板正确设置代码,请不要尝试这样做,否则可能无效。)

根据需要对所有变量进行符号化后,需要设置相应的转换规则。前两个是最简单的,输入

Subscript[E,0]

规则3和4:

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

这些是容易的,接下来的三个需要不同类型的关联,SetSetDelayed都不会在这里工作,因为被评估的外部符号是E_0[x_Plus]:=Distribute[E_0[x]] E_0[x_Times]:=Distribute[E_0[x], Times] ,你可以不要将新规则与Protected关联起来。但是,有两种方法可以将这些表达式与内部符号相关联:UpSet (^=)(或UpSetDelayed (^:=))或TagSet (/:)。我更喜欢使用Dt,因为它更明确,但要么应该有效。

规则5和6:

TagSet

这也会让你接近规则7,但是在规则3和规则4的同时添加它会导致递归限制错误,因为它来回反弹并试图弄清楚如何评估它。相反,用

替换规则3和4
E_0 /: Dt[ E_0[ x_ ], y_ ] := E_0[ Dt[x,y] ]

这对递归有明确的限制。就规则7而言,你得到了这个

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

这是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]] 规则和规则4的结果。要让Dt不要分发E_0D,请将其作为练习。


修改: 我想就您提供的解决方案代码发表一些意见。首先,巧妙地使用布尔来停止递归,它适用于您的Dt。不过,我建议对您的产品分发进行一些更改。首先,我使用Notation而不是条件(x__Times),因为它更容易阅读,我相信(但尚未测试)它可能更快,即处理它的开销更少。其次,将/; Head[x] == Times替换为Table,其中List @@ x,称为Apply,将@@替换为Times,再次更容易阅读和写作。对于List的定义,请考虑使用Complement;我不知道它是否更快,但我更喜欢为这类事物设置理论结构。最后,除非您需要变量为reevaluated whenever it is used,否则请勿使用SetDelayedn),请使用:=Set)。通过使用=,m被评估两次,v被评估3次!

优点和缺点: 这样做的主要原因是易用性和可读性。通过定义自己的对象及其行为,您可以为自己提供很大的灵活性并简化代码。仅此一点就值得。但是,我过去一直很难做到这一点,这样的设置可能是不安全的,我建议进行彻底的测试。其次,通过添加这些额外的层,您可能会减慢代码速度,因此如果要在关键任务应用程序中使用它,请务必小心。此外,每次使用时都必须包含:=,调色板在某些时候会变得很烦人。虽然可以通过在加载Notation包之前设置Notation来处理调色板。