Переопределить некоммутативное умножение в Mathematica - PullRequest
7 голосов
/ 17 февраля 2011

Mathematicas NonCommulativeMultiply (**) не упрощает такие термины, как

a**0=0**a=0  
a**1=1**a=a  

или

a**a=a^2.  

Я хотел бы переопределить **, чтобы сделать это.Я использовал NCAlgebra для этого, но мне нужны ReplaceRepeated (//.) И NCAlgebra, как говорится в их документации, специально нарушает эту функциональность в Mathematica.

Могут ли некоторые показать мне, как очистить атрибуты ** и переопределить это умножение, сделать то же самое, что и при обычном, плюс работать с 1 и 0. Мне действительно не нужно умножение, чтобы иметь дело с a**a, но было бы неплохо, если бы это было достаточно просто.Главное, что мне нужно **, чтобы иметь дело с 1 и 0.

Ответы [ 3 ]

7 голосов
/ 17 февраля 2011

Нижеследующее работает только в том случае, если вы удалите атрибут Flat из NonCommulativeMultiply (Что я и сделал по ошибке во время тестирования ... ошибка новичка!)

Самое простое, что нужно сделать, это

Unprotect[NonCommutativeMultiply];
NonCommutativeMultiply[a___, 1, b___] := a ** b
NonCommutativeMultiply[___, 0, ___] := 0
NonCommutativeMultiply[a_] := a
Protect[NonCommutativeMultiply];

Требуется окончательное выражение, чтобы a**1 упрощалось до a вместо NonCommutativeMultiply[a]. Вам также может понадобиться NonCommutativeMultiply[]:=1, чтобы такие выражения, как 1**1, упростились должным образом (*). Единственная проблема со всем этим, для больших выражений, шаблон проверяется на все, и это становится очень медленным.

Приведенные выше два определения для 0 и 1 можно объединить и обобщить до

NonCommutativeMultiply[a___, n_?NumericQ, b___] := n a ** b

, который исключает любые числовые термины внутри выражения. Но это еще больше замедляет работу в больших выражениях, поскольку каждый член проверяется на предмет числовости.

Чтобы упростить a**a до a^2, вам нужно что-то вроде

NonCommutativeMultiply[a___, b_, b_, c___] := a ** b^2 ** c

или более обычно

NonCommutativeMultiply[a___, b_^n_., b_^m_., c___] := a ** b^(n + m) ** c

(*) Обратите внимание, что это только потому, что порядок по умолчанию, в который Mathematica помещает DownValues, не обязательно является лучшим в этом случае. Измените порядок так, чтобы NonCommutativeMultiply[a_] предшествовал a___ ** n_?NumericQ ** b___, тогда правила NonCommutativeMultiply[] не были сгенерированы правилами, и вам не понадобится этот последний шаблон (если вы не создадите NonCommutativeMultiply[] другим способом).

1 голос
/ 17 июля 2011

Трюк с

Unprotect[NonCommutativeMultiply];
....
Protect[NonCommutativeMultiply];

очень хорош!Я потратил 10 часов, пытаясь решить проблему с NonCommutativeMultiply (как сгладить выражения, которые включали и nc, и обычное умножение, например a**b**(c*d*(e**f)), но более сложное), но я не думал о внесении изменений в NonCommutativeMultiply.Спасибо!

1 голос
/ 17 февраля 2011

Ладно, написание правил, которые хорошо сочетаются с атрибутами NonCommutativeMultiply, иногда доставляет неудобства.Вот альтернативный метод, который вводит помощника NCM, который не имеет правил и атрибутов NonCommutativeMultiply, связанных с ним.

Следующий код также включает в себя последнюю пару ваших вопросов. (1) (2)

Unprotect[NonCommutativeMultiply];
Clear[NonCommutativeMultiply]
(* Factor out numerics -- could generalize to some ScalarQ *)
nc:NonCommutativeMultiply[a__]/;MemberQ[{a},_?NumericQ]:=NCMFactorNumericQ[NCM[a]]/.NCM->NonCommutativeMultiply
(* Simplify Powers *)
b___**a_^n_.**a_^m_.**c___:=NCM[b,a^(n+m),c]/.NCM->NonCommutativeMultiply
(* Expand Brackets *)
nc:NonCommutativeMultiply[a___,b_Plus,c___]:=Distribute[NCM[a,b,c]]/.NCM->NonCommutativeMultiply
(* Sort Subscripts *)
c___**Subscript[a_, i_]**Subscript[b_, j_]**d___/;i>j:=c**Subscript[b, j]**Subscript[a, i]**d
Protect[NonCommutativeMultiply];

Unprotect[NCM];
Clear[NCM]
NCMFactorNumericQ[nc_NCM]:=With[{pos=Position[nc,_?NumericQ,1]},Times@@Extract[nc,pos]  Delete[nc,pos]]
NCM[a_]:=a
NCM[]:=1
Protect[NCM];

Обратите внимание, что NCMFactorNumericQ быстр, потому что работает за один проход, но с ним связано правило nc:NonCommutativeMultiply[a__]/;MemberQ[{a},_?NumericQ] медленный, потому что атрибут Flat означает, что он выполняет глупое количество проверок, используя NumericQ.Если вам действительно нужна большая скорость и большие выражения, вам следует просто вручную применить подпрограммы Sort и Factor, чтобы Mathematica выполняла меньше проверок шаблонов.

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