重新定义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**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[] 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 。 如果你真的想要更快的速度和更大的表达式,那么你应该手动应用SortFactor例程,以便Mathematica减少模式检查。


诀窍

Unprotect[NonCommutativeMultiply];
....
Protect[NonCommutativeMultiply];

非常好! 我花了10个小时试图解决NonCommutativeMultiply一个问题(如何将涉及nc和正常乘法的表达式变成a**b**(c*d*(e**f))但更复杂)不要考虑修改NonCommutativeMultiply本身。 谢谢!

链接地址: http://www.djcxy.com/p/35587.html

上一篇: Redefine Noncommutative Multiplication in Mathematica

下一篇: Convenient way to add inline formatting to usage Messages