Символическое условное ожидание в Mathematica - PullRequest
1 голос
/ 23 марта 2011

Я хочу реализовать оператор условного ожидания.Я буду использовать эпсилон 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 Ответ

3 голосов
/ 23 марта 2011

Я думаю, что смогу приблизить вас к тому, что вы хотите;Я не собираюсь делать все это, хотя это может быть сложно, но я укажу вам в правильном направлении.

Прежде всего, использование индексов для обозначения различных переменных является сложным в Mathematica, поскольку он интерпретирует E0 как Subscript[E,0], и оба E и Subscript зарезервированы,(Как сказал Шёрд, E = 2.718....) Чтобы Mathematica распознала <anything><something> как отдельный символ, вам необходимо загрузить пакет Notations через <<Notations`.Затем с помощью палитры обозначений Symbolize Subscript[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] + Plus@@( E_0 /@ {y} )
E_0[x_ y__ ] := E_0[x] Times@@( 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, чтобы не распределять по D и Dtоставлено в качестве упражнения.


Редактировать : Я хотел бы сделать несколько комментариев по предоставленному вами коду решения.Во-первых, умное использование логического значения для остановки рекурсии, и оно хорошо работает с вашим Notation.Я бы посоветовал несколько изменений в дистрибуции вашего продукта.Во-первых, я бы использовал x__Times вместо условия (/; Head[x] == Times), так как его легче читать, и я верю (но не проверял), что это может быть быстрее, то есть меньше накладных расходов на его обработку.Во-вторых, замените используемое вами Table на List @@ x, где @@, называемое Apply, заменяет Times на List, и его снова легче читать и писать.Для определения n рассмотрите возможность использования Complement;Я не знаю, быстрее ли это, но я предпочитаю теоретико-множественные конструкции для такого типа вещей.И, наконец, если вам не нужна переоценка переменной при ее использовании , не используйте SetDelayed (:=), используйте Set (=).Используя :=, m оценивается дважды, а v оценивается 3 раза!

"за" и "против" : Главными причинами этого являются простота использования и удобочитаемость.Определяя свои собственные объекты и их поведение, вы даете себе большую гибкость и упрощаете свой код.Уже одно это стоит того.Тем не менее, у меня были трудности с этим в прошлом, и такая установка может быть привередливой, и я бы рекомендовал провести тщательное тестирование.Во-вторых, добавляя эти дополнительные слои, вы можете замедлить ваш код, поэтому будьте осторожны, если он будет использоваться в критически важных приложениях.Кроме того, вы должны включать Notation каждый раз, когда вы используете его, и палитра станет раздражать в какой-то момент.Хотя с палитрой можно справиться, установив AutoLoadNotationPalette = False перед загрузкой пакета Notation.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...