Wolfram mathematica Mathematica中表达式开头的非对易乘法和负系数

Wolfram mathematica Mathematica中表达式开头的非对易乘法和负系数,wolfram-mathematica,Wolfram Mathematica,在一些非常友好的stackoverflow贡献者的帮助下,我在Mathematica中对非对易乘法(**)有了以下新定义: 取消保护[非交换乘法] ClearAll[非交换乘法] 非对易乘法[]:=1 非对易乘法[\uuuuuuuuuuu,0,\uuuuuuuuuu]:=0 非对易乘法[a_uuuu,1,b_uuuu]:=a**b 非对易乘法[a_uuuu,i_整数,b_uuu]:=i*a**b 非对易乘法[a_z]:=a 下标,下标,下标,下标;i>j:= c**下标[b,j]**下标[a,

在一些非常友好的stackoverflow贡献者的帮助下,我在Mathematica中对
非对易乘法(**)
有了以下新定义:


取消保护[非交换乘法]
ClearAll[非交换乘法]
非对易乘法[]:=1
非对易乘法[\uuuuuuuuuuu,0,\uuuuuuuuuu]:=0
非对易乘法[a_uuuu,1,b_uuuu]:=a**b
非对易乘法[a_uuuu,i_整数,b_uuu]:=i*a**b
非对易乘法[a_z]:=a
下标,下标,下标,下标;i>j:=
c**下标[b,j]**下标[a,i]**d
SetAttributes[NoncommutiveMultiply,{OneIdentity,Flat}]
保护[非交换乘法]

这种乘法非常好,但是它不处理表达式开头的负值,即
a**b**c+(-q)**c**a

应简化为
a**b**c-q**c**a

而且不会

在我的乘法中,变量
q
(和任何整数定标器)是可交换的;我仍在尝试编写一个
setcommunicative
函数,但没有成功。我并不迫切需要
setcommunicative
,那就好了

如果我能够将所有的
q
拉到每个表达式的开头,也会很有帮助,例如:
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
(-q)
拉到前面,如上所述。我曾尝试使用
ReplaceRepeated(\\)
来处理这里提到的两个问题,但迄今为止我没有成功


欢迎所有想法,谢谢……

实现这一点的关键是要认识到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部分。将标量放在前面的一般问题是,当前规则中的模式
\u Integer
只会发现明显是整数的东西。它甚至不会发现
q
在类似
的构造中是一个整数,假设[{Element[q,Integers]},a**q**b]

要实现这一点,您需要检查假设,这一过程要放入全局转换表可能会非常昂贵。相反,我将编写一个可以手动应用的转换函数(并可能从全局表中删除当前规则)。类似的方法可能会奏效:

NCMScalarReduce[e_] := e //.  {
    NonCommutativeMultiply[a___, i_ /; Simplify@Element[i, Reals],b___] 
    :> i a ** b
}
上面使用的规则使用
Simplify
显式查询假设,您可以通过分配给
$assemptions
全局设置假设,也可以使用
assemption
本地设置假设:

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


HTH

这只是一个简单的回答,重复了上一个问题中的一些评论。 您可以删除一些定义,并使用作用于
时间[i,c]
的规则来解决此问题的所有部分,其中
i
是可交换的,
c
具有默认的
序列[]

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)
进行泛化,以处理更一般的交换对象

对于SET交换部分,我建议您看看我在前面的问题中提到的grassmanOps包。在那里,他们将变量定义为“费米子”(反交换)和“玻色子”(交换),并对非交换乘法进行了修改,以检查这种分级,并将所有玻色子变量放在前面。