重新定义Mathematica中的非交换乘法
Mathematicas NonCommutativeMultiply(**)不会简化像这样的术语
a**0=0**a=0
a**1=1**a=a
要么
a**a=a^2.
我想重新定义**
来做到这一点。 我使用NC代数来做到这一点,但我需要ReplaceRepeated(//。)和NCAlgebra,正如他们的文档所述,它专门在mathematica中打破了这个功能。
有些人可以告诉我如何清除**
的属性,并重新定义这个乘法做与通常一样的事情,加上处理1和0.我真的不需要乘法来处理a**a
,但它会是很好,如果它够简单。 我需要的最主要的**
处理1和0。
如果你删除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[]
some另一种方式)。
好的,编写NonCommutativeMultiply
属性的NonCommutativeMultiply
有时是一件麻烦事。 下面是一个备用方法,它引入了一个辅助NCM
,该辅助NCM
没有NonCommutativeMultiply
关联的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属性意味着它会执行一个愚蠢的使用NumericQ
进行检查的NumericQ
。 如果你真的想要更快的速度和更大的表达式,那么你应该手动应用Sort
和Factor
例程,以便Mathematica减少模式检查。
诀窍
Unprotect[NonCommutativeMultiply];
....
Protect[NonCommutativeMultiply];
非常好! 我花了10个小时试图解决NonCommutativeMultiply
一个问题(如何将涉及nc和正常乘法的表达式变成a**b**(c*d*(e**f))
但更复杂)不要考虑修改NonCommutativeMultiply
本身。 谢谢!
上一篇: Redefine Noncommutative Multiplication in Mathematica
下一篇: Convenient way to add inline formatting to usage Messages