Некоммутативное умножение и отрицательные коэффициенты в начале выражения в Mathematica - PullRequest
3 голосов
/ 18 февраля 2011

С помощью некоторых очень любезных авторов стека и потоков в этом посте , у меня есть следующее новое определение для NonCommutativeMultiply (**) в Mathematica:

Unprotect[NonCommutativeMultiply];<br> ClearAll[NonCommutativeMultiply]<br> NonCommutativeMultiply[] := 1<br> NonCommutativeMultiply[___, 0, ___] := 0<br> NonCommutativeMultiply[a___, 1, b___] := a ** b<br> NonCommutativeMultiply[a___, i_Integer, b___] := i*a ** b<br> NonCommutativeMultiply[a_] := a<br> c___ ** Subscript[a_, i_] ** Subscript[b_, j_] ** d___ /; i > j :=<br> c ** Subscript[b, j] ** Subscript[a, i] ** d<br> SetAttributes[NonCommutativeMultiply, {OneIdentity, Flat}]<br> Protect[NonCommutativeMultiply];

Это умножение велико, однако оно не имеет дело с отрицательными значениями в начале выражения, т. Е.
a**b**c + (-q)**c**a
следует упростить до
a**b**c - q**c**a
и не будет.

В моем умножении переменная q (и любой целочисленный скалер) является коммутативной; Я все еще пытаюсь написать функцию SetCommutative, но безуспешно. Я не отчаянно нуждаюсь в SetCommutative, это было бы просто замечательно.

Было бы также полезно, если бы я мог вытянуть все q's в начало каждого выражения, т.е.:
a**b**c + a**b**q**c**a
следует упростить до:
a**b**c + q**a**b**c**a
и аналогично, объединяя эти две проблемы:
a**b**c + a**c**(-q)**b
следует упростить до:
a**b**c - q**a**c**b

В настоящее время я хотел бы выяснить, как обращаться с этими отрицательными переменными в начале выражения и как вытянуть q's и (-q)'s на передний план, как указано выше. Я попытался решить две проблемы, упомянутые здесь, используя ReplaceRepeated (\\.), но до сих пор не добился успеха.

Все идеи приветствуются, спасибо ...

Ответы [ 2 ]

3 голосов
/ 18 февраля 2011

Ключом к этому является осознание того, что Mathematica представляет a-b как a+((-1)*b), как вы можете видеть из

In[1]= FullForm[a-b]
Out[2]= Plus[a,Times[-1,b]]

Для первой части вашего вопроса все, что вам нужно сделать, этодобавьте это правило:

NonCommutativeMultiply[Times[-1, a_], b__] := - a ** b

или вы даже можете поймать знак из любой позиции:

NonCommutativeMultiply[a___, Times[-1, b_], c___] := - a ** b ** c

Обновление - часть 2. Общая проблема с получениемСкаляры на передний план - это то, что шаблон _Integer в вашем текущем правиле будет определять только те вещи, которые явно целые.Он даже не заметит, что q является целым числом в конструкции, подобной Assuming[{Element[q, Integers]}, a**q**b].
. Чтобы достичь этого, вам необходимо изучить предположения, процесс, который, вероятно, стоит дорого поместить в таблицу глобальных преобразований.Вместо этого я написал бы функцию преобразования, которую я мог бы применить вручную (и, возможно, удалить текущее правило из глобальной таблицы).Примерно так может сработать:

NCMScalarReduce[e_] := e //.  {
    NonCommutativeMultiply[a___, i_ /; Simplify@Element[i, Reals],b___] 
    :> i a ** b
}

Используемое выше правило использует Simplify для явного запроса допущений, которые можно установить глобально, назначив $Assumptions или локально, используя Assuming:

Assuming[{q \[Element] Reals},
  NCMScalarReduce[c ** (-q) ** c]] 

возвращает -q c**c.

HTH

2 голосов
/ 18 февраля 2011

Просто быстрый ответ, повторяющий некоторые комментарии из предыдущего вопроса.Вы можете удалить пару определений и решить все части этого вопроса, используя правило, действующее на Times[i,c], где i является коммутативным, а c имеет значение по умолчанию Sequence[]

Unprotect[NonCommutativeMultiply];
ClearAll[NonCommutativeMultiply]
NonCommutativeMultiply[] := 1
NonCommutativeMultiply[a___, (i:(_Integer|q))(c_:Sequence[]), b___] := i a**Switch[c, 1, Unevaluated[Sequence[]], _, c]**b
NonCommutativeMultiply[a_] := a
c___**Subscript[a_, i_]**Subscript[b_, j_] ** d___ /; i > j := c**Subscript[b, j]**Subscript[a, i]**d
SetAttributes[NonCommutativeMultiply, {OneIdentity, Flat}]
Protect[NonCommutativeMultiply];

Это тогда работает как ожидалось

In[]:= a**b**q**(-c)**3**(2 a)**q
Out[]= -6 q^2 a**b**c**a

Обратите внимание, что вы можете обобщить (_Integer|q) для работы с более общими коммутативными объектами.

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