Mathematica 表达式开头的非交换乘法和负系数

Can*_*ath 4 wolfram-mathematica

在这篇文章中一些非常友善的 stackoverflow 贡献者的帮助下,我NonCommutativeMultiply (**)在 Mathematica 中 得到了以下新定义:

Unprotect[NonCommutativeMultiply];
ClearAll[NonCommutativeMultiply]
NonCommutativeMultiply[] := 1
NonCommutativeMultiply[___, 0, ___] := 0
NonCommutativeMultiply[a___, 1, b___] := a ** b
NonCommutativeMultiply[a___, i_Integer, b___] := i*a ** 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];

这种乘法很棒,但是,它不处理表达式开头的负值,即
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 (\\.),但到目前为止我还没有成功。

欢迎所有想法,谢谢...

Jan*_*nus 5

做到这一点的关键是要认识到 Mathematica 表示a-ba+((-1)*b),正如您可以从

In[1]= FullForm[a-b]
Out[2]= Plus[a,Times[-1,b]]
Run Code Online (Sandbox Code Playgroud)

对于问题的第一部分,您所要做的就是添加以下规则:

NonCommutativeMultiply[Times[-1, a_], b__] := - a ** b
Run Code Online (Sandbox Code Playgroud)

或者你甚至可以从任何位置捕捉标志:

NonCommutativeMultiply[a___, Times[-1, b_], c___] := - a ** b ** c
Run Code Online (Sandbox Code Playgroud)

更新——第 2 部分。将标量放在前面的一般问题是当前规则中的模式_Integer只会发现明显是整数的东西。它甚至不会发现它q是像 这样的结构中的整数Assuming[{Element[q, Integers]}, a**q**b]
为了实现这一点,您需要检查假设,将这个过程放入全局转换表中可能会非常昂贵。相反,我会编写一个可以手动应用的转换函数(并且可能从全局表中删除当前规则)。像这样的事情可能会起作用:

NCMScalarReduce[e_] := e //.  {
    NonCommutativeMultiply[a___, i_ /; Simplify@Element[i, Reals],b___] 
    :> i a ** b
}
Run Code Online (Sandbox Code Playgroud)

上面使用的规则Simplify用于显式查询假设,您可以通过分配到全局设置$Assumptions或使用本地设置Assuming

Assuming[{q \[Element] Reals},
  NCMScalarReduce[c ** (-q) ** c]] 
Run Code Online (Sandbox Code Playgroud)

返回-q c**c

华泰