Mathematica中表达式开始时的非交换乘法和负系数

时间:2011-02-18 06:31:37

标签: wolfram-mathematica

在一些非常优雅的stackoverflow贡献者in this post的帮助下,我在Mathematica中对NonCommutativeMultiply (**)有了以下新定义:

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 (\\.)处理这里提到的两个问题,但到目前为止我没有成功。

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

2 个答案:

答案 0 :(得分:3)

这样做的关键是要认识到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

答案 1 :(得分:2)

快速回答重复上一个问题的一些评论。 您可以使用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)

请注意,您可以概括{{1}}以处理更一般的可交换对象。