重新定义Mathematica中的非交换乘法

时间:2011-02-17 00:30:08

标签: wolfram-mathematica

Mathematicas NonCommutativeMultiply(**)不简化像

这样的术语
a**0=0**a=0  
a**1=1**a=a  

a**a=a^2.  

我想重新定义**来执行此操作。我正在使用NCAlgebra来做这个,但我需要ReplaceRepeated(//。)和NCAlgebra,正如他们的文档所说,在mathematica中特别打破了这个功能。

有些人可以告诉我如何清除**的属性并重新定义这个乘法做同样的事情,加上处理1和0.我真的不需要乘法来处理{{1但是如果它足够简单就好了。我需要a**a来处理1和0。

3 个答案:

答案 0 :(得分:7)

以下内容仅在删除NonCommutativeMultiply的Flat属性时才有效 (这是我在测试过程中误做的事情......一个新手的错误!)

最简单的事情是

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**aa^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 :(得分:1)

好吧,编写与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属性意味着它使用{{进行了大量的检查1}}。 如果你真的想要更快的速度并拥有大表达式,那么你应该只需手动应用NumericQSort例程,这样Mathematica就可以减少模式检查。

答案 2 :(得分:1)

的诀窍
Unprotect[NonCommutativeMultiply];
....
Protect[NonCommutativeMultiply];

非常好!我花了10个小时尝试用NonCommutativeMultiply来解决问题(如何压缩涉及nc和正常乘法的表达式,如a**b**(c*d*(e**f)),但更复杂)但我没想到修改NonCommutativeMultiply本身。谢谢!