Wolfram mathematica 在Mathematica中重新定义非交换乘法

Wolfram mathematica 在Mathematica中重新定义非交换乘法,wolfram-mathematica,Wolfram Mathematica,Mathematics非对易乘法(**)不会简化以下术语 a**0=0**a=0 a**1=1**a=a 或 为此,我想重新定义**。我曾使用NCAlgebra来实现这一点,但我需要替换(//)和NCAlgebra,正如他们的文档所述,特别破坏了mathematica中的这一功能 可以告诉我如何清除***的属性并重新定义这个乘法吗?做与正常情况相同的事情,再加上处理1和0。我真的不需要乘法来处理a**a,但如果它足够简单,那就好了。我需要**来处理1和0 仅当删除非对易乘法的平坦属性时

Mathematics非对易乘法(**)不会简化以下术语

a**0=0**a=0  
a**1=1**a=a  

为此,我想重新定义
**
。我曾使用NCAlgebra来实现这一点,但我需要替换(//)和NCAlgebra,正如他们的文档所述,特别破坏了mathematica中的这一功能


可以告诉我如何清除
***
的属性并重新定义这个乘法吗?做与正常情况相同的事情,再加上处理1和0。我真的不需要乘法来处理
a**a
,但如果它足够简单,那就好了。我需要
**
来处理1和0

仅当删除非对易乘法的平坦属性时,以下选项才有效 (这是我在测试中犯的错误……一个新手错误!)

最简单的办法就是

Unprotect[NonCommutativeMultiply];
NonCommutativeMultiply[a___, 1, b___] := a ** b
NonCommutativeMultiply[___, 0, ___] := 0
NonCommutativeMultiply[a_] := a
Protect[NonCommutativeMultiply];
需要最终表达式,以便
a**1
简化为
a
,而不是
非对易乘法[a]
。您可能还需要
noncompativemultiply[]:=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
放入的默认顺序在这种情况下不一定是最好的。更改顺序,使
非对易乘法[a\u]
出现在
非对易乘法[]
之前,然后
非对易乘法[]
将不会由规则生成,并且您不需要最后一个模式(除非您以其他方式生成
非对易乘法[]
),编写能够很好地处理
非对易乘法的属性的规则有时是件麻烦事。这里有一个替代方法,它引入了一个helper
NCM
,它没有与之关联的
noncompativemultiply
规则和属性

下面的代码还包含了最后两个问题。

请注意,
NCMFactorNumericQ
是快速的,因为它在一个过程中工作,但是与之相关的规则是
nc:noncommunivemultiply[a_u;]/;MemberQ[{a},?NumericQ]
速度很慢,因为Flat属性意味着它使用
NumericQ
执行大量愚蠢的检查。 如果您真的想要更快的速度和更大的表达式,那么您应该手动应用
排序
因子
例程,以便Mathematica进行更少的模式检查

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

非常好!我花了10个小时试图解决
非对易乘法
(如何展平包含n.c.和正常乘法的表达式,如
a**b**(c*d*(e**f))
,但更复杂),但我没有想到修改
非对易乘法
本身。谢谢

顺便说一句:我的纸和笔记本现在都用完了。因为我有非常大的表达式,所以你会看到我不得不在如何简化
非对易乘法
表达式方面做出艰难的决定。即使在那时,我也不得不握着mma的手进行一些计算,否则它们永远不会终止。@Simon,优化肯定也是我关心的问题。我想知道,如果我所需要做的就是将0和1添加到**,那么速度会慢多少。谢谢你的帮助,我现在就查一下试卷。我也会尝试这段代码并报告任何问题。@Simon,我尝试了上面的定义,它返回“$IterationLimit::itlim:Iteration limit of 4096 Oversed.>>”,输出为Hold[1**1**1….1**1]。@Cantormath:Damn。。。我意外地运行了一个
ClearAll[noncommunivemultiply]
,删除了Flat和OneIdentity属性。我的规则与Flat属性的相互作用导致了问题…@Cantormath:问题是您需要贪婪的模式匹配,
\uuu\n**uuuuuu\uu
构造提供给您,这样您就可以在一个步骤中将术语移到非对易乘法之外。请注意,“*”用作on so。可以使用反斜杠(\)转义文本“*”,或者(如果合适)使用反勾号(`)将文本标记为代码(对于内联代码),或者使用四个空格缩进行,从而获得文本“*”。如果您单击问题的“编辑”链接,您可以检查问题源以查看其执行情况。通过单击编辑器工具栏中的橙色问号,您可以了解有关标记语言(称为Markdown)的更多信息。@Simon,我想我有一个我喜欢的乘法定义。我没有使用(*简化权限)和(展开括号),稍后我将应用它们。我注意到(简化幂*),如果你说用**将许多项之和的相同表达式相乘,它将表达式平方(^2),而不是用非对易乘法相乘。同样,这不是一个问题,因为我没有使用它。我遇到的一个问题是表达式开头的负变量。我得到的是
c+(-q)**a
而不是
c-q**a
@Simon,所以我想我有一个我喜欢的乘法定义。我没有使用
(简化权限)
(展开括号)
,稍后我将应用它们。我注意到关于
(简化幂)
,如果你说用
**
将许多项之和的相同表达式相乘,它将
(^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];
Unprotect[NonCommutativeMultiply];
....
Protect[NonCommutativeMultiply];