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。
答案 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**a
到a^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
相关联的规则和属性。
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}}。
如果你真的想要更快的速度并拥有大表达式,那么你应该只需手动应用NumericQ
和Sort
例程,这样Mathematica就可以减少模式检查。
答案 2 :(得分:1)
的诀窍
Unprotect[NonCommutativeMultiply];
....
Protect[NonCommutativeMultiply];
非常好!我花了10个小时尝试用NonCommutativeMultiply
来解决问题(如何压缩涉及nc和正常乘法的表达式,如a**b**(c*d*(e**f))
,但更复杂)但我没想到修改NonCommutativeMultiply
本身。谢谢!