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

发布于 2024-10-18 02:05:56 字数 441 浏览 4 评论 0原文

Mathematicas NonCommutativeMultiply (**) 不会简化类似

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

a**a=a^2.  

我想重新定义 ** 之类的术语来执行此操作。我使用 NCAlgebra 来执行此操作,但我需要 ReplaceRepeated (//.) 和 NCAlgebra,正如他们的文档所述,专门破坏了 mathematica 中的此功能。

有人可以告诉我如何清除 ** 的属性并重新定义此乘法,执行与正常情况相同的操作,并处理 1 和 0。我真的不需要乘法来处理 a**a,但是如果足够简单就好了。主要是我需要 ** 来处理 1 和 0。

Mathematicas NonCommutativeMultiply (**) does not simplify terms like

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

or

a**a=a^2.  

I would like to redefine ** to do this. I was using NCAlgebra to do this but I need ReplaceRepeated (//.) and NCAlgebra, as their documentation says, specifically breaks this functionality in mathematica.

Can some show me how to Clear the attributes of ** and redefine this multiplication do the same things it would normal do plus dealing with 1 and 0. I really do not need the multiplication to deal with a**a, but It would be nice if it is simple enough. The main thing I need ** to deal with 1 and 0.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

仙气飘飘 2024-10-25 02:05:56

仅当您删除 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 放置其 < 的默认顺序在这种情况下,code>DownValues 不一定是最好的。更改顺序,使 NonCommutativeMultiply[a_] 出现在 a___ ** n_?NumericQ ** b___ 之前,则不会生成 NonCommutativeMultiply[]按照规则,您不需要最后一个模式(除非您以其他方式生成 NonCommutativeMultiply[])。

The below only works if you remove the Flat attribute of NonCommutativeMultiply
(Which is something I did by mistake during testing... a rookie mistake!)

The simplest thing to do is

Unprotect[NonCommutativeMultiply];
NonCommutativeMultiply[a___, 1, b___] := a ** b
NonCommutativeMultiply[___, 0, ___] := 0
NonCommutativeMultiply[a_] := a
Protect[NonCommutativeMultiply];

The final expression is needed so that a**1 simplifies to a instead of NonCommutativeMultiply[a]. You might also need NonCommutativeMultiply[]:=1 so that expressions like 1**1 simplify properly (*).
The only problem with all of this, is for large expressions, the pattern is checked against everything and this gets really slow.

The above two definitions for 0 and 1 can be combined and generalized to

NonCommutativeMultiply[a___, n_?NumericQ, b___] := n a ** b

which factors out any numerical terms inside the expression.
But this slows down things even more in large expressions, since each term is checked to see if its numerical.

To simplify your a**a to a^2, you need something like

NonCommutativeMultiply[a___, b_, b_, c___] := a ** b^2 ** c

or more generally

NonCommutativeMultiply[a___, b_^n_., b_^m_., c___] := a ** b^(n + m) ** c

(*) Note that this is only because the default order that Mathematica puts its DownValues in is not necessarily the best in this case. Change the order so that NonCommutativeMultiply[a_] comes before a___ ** n_?NumericQ ** b___ then NonCommutativeMultiply[] won't be generated by the rules, and you won't need that last pattern (unless you produce NonCommutativeMultiply[] some other way).

迷雾森÷林ヴ 2024-10-25 02:05:56

好吧,编写与 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 属性意味着它使用 NumericQ 进行大量愚蠢的检查。
如果您确实想要更快的速度并拥有较大的表达式,那么您应该手动应用 SortFactor 例程,以便 Mathematica 执行更少的模式检查。

OK, writing rules that play nice with the attributes of NonCommutativeMultiply is sometimes a hassle. Here's an alternate method which introduces a helper NCM that does not have the rules and attributes of NonCommutativeMultiply associated with it.

The following code also incorporates the last couple of your questions.
(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];

Note that NCMFactorNumericQ is fast because it works in a single pass, but the rule associated with it nc:NonCommutativeMultiply[a__]/;MemberQ[{a},_?NumericQ] is slow, because the Flat attribute means that it does a stupid number of checks using NumericQ.
If you really want more speed and have large expressions, then you should just manually apply the Sort and Factor routines, so that Mathematica does less pattern checks.

甜味超标? 2024-10-25 02:05:56

搭配的技巧

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

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

The trick with

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

is very good! I spent 10 hours trying to solve a problem with NonCommutativeMultiply (how to flatten expressions that involved both n.c. and normal multiplication like a**b**(c*d*(e**f)) but more complicated) but I didn't think of amending NonCommutativeMultiply itself. Thanks!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文