Mathematica 表达式开头的非交换乘法和负系数

发布于 2024-10-17 21:18:13 字数 1314 浏览 2 评论 0原文

在一些非常友善的 stackoverflow 贡献者这篇文章的帮助下,我有了以下新内容Mathematica 中 NonCommutativeMultiply (**) 的定义:

取消保护[非交换乘法];
ClearAll[非交换乘法]
非对易乘法[] := 1
非对易乘法[___, 0, ___] := 0
NonCommutativeMultiply[a___, 1, b___] := a ** b
NonCommutativeMultiply[a___, i_Integer, b___] := i*a ** b
非交换乘法[a_] := a
c___ ** 下标[a_, i_] ** 下标[b_, j_] ** d___ /;我> j :=
c ** 下标[b, j] ** 下标[a, i] ** d
SetAttributes[NonCommutativeMultiply, {OneIdentity, Flat}]
Protect[NonCommutativeMultiply];

这个乘法很棒,但是,它不处理表达式开头的负值,即
a**b**c + (-q)**c**a
应该简化为
a**b**c - q**c**a
但它不会。

在我的乘法中,变量q(以及任何整数定标器)是可交换的;我仍在尝试编写一个 SetCommutative 函数,但没有成功。我并不迫切需要 SetCommutative,它就好了。

如果我能够将所有 q's 拉到每个表达式的开头,也会很有帮助,即:
a**b**c + a**b**q**c**a
应简化为:
a**b**c + q**a**b**c**a
同样,结合这两个问题:
a**b**c + a**c**(-q)**b
应简化为:
a**b**c - q**a**c**b

目前,我想弄清楚如何处理表达式开头的这些负变量,以及如何将 q's(-q)'s 拉到前面,如上所述。我尝试使用 ReplaceRepeated (\\.) 来处理这里提到的两个问题,但到目前为止我还没有成功。

欢迎所有想法,谢谢...

With the help of some very gracious stackoverflow contributors in this post, I have the following new definition for NonCommutativeMultiply (**) in Mathematica:


Unprotect[NonCommutativeMultiply];
ClearAll[NonCommutativeMultiply]
NonCommutativeMultiply[] := 1
NonCommutativeMultiply[___, 0, ___] := 0
NonCommutativeMultiply[a___, 1, b___] := a ** b
NonCommutativeMultiply[a___, i_Integer, b___] := i*a ** b
NonCommutativeMultiply[a_] := a
c___ ** Subscript[a_, i_] ** Subscript[b_, j_] ** d___ /; i > j :=
c ** Subscript[b, j] ** Subscript[a, i] ** d
SetAttributes[NonCommutativeMultiply, {OneIdentity, Flat}]
Protect[NonCommutativeMultiply];

This multiplication is great, however, it does not deal with negative values at the beginning of an expression, i.e.,
a**b**c + (-q)**c**a
should simplify to
a**b**c - q**c**a
and it will not.

In my multiplication, the variable q (and any integer scaler) is commutative; I am still trying to write a SetCommutative function, without success. I am not in desperate need of SetCommutative, it would just be nice.

It would also be helpful if I were able to pull all of the q's to the beginning of each expression, i.e.,:
a**b**c + a**b**q**c**a
should simplify to:
a**b**c + q**a**b**c**a
and similarly, combining these two issues:
a**b**c + a**c**(-q)**b
should simplify to:
a**b**c - q**a**c**b

At the current time, I would like to figure out how to deal with these negative variables at the beginning of an expression and how to pull the q's and (-q)'s to the front as above. I have tried to deal with the two issues mentioned here using ReplaceRepeated (\\.), but so far I have had no success.

All ideas are welcome, thanks...

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

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

发布评论

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

评论(2

迷乱花海 2024-10-24 21:18:13

这样做的关键是要认识到 Mathematica 将 ab 表示为 a+((-1)*b),正如您

In[1]= FullForm[a-b]
Out[2]= Plus[a,Times[-1,b]]

在问题的第一部分中看到的那样,您所要做的就是添加此规则:

NonCommutativeMultiply[Times[-1, a_], b__] := - a ** b

或者您甚至可以从任何位置捕获符号:

NonCommutativeMultiply[a___, Times[-1, b_], c___] := - a ** b ** c

更新 -- 第 2 部分。 将标量置于前面的一般问题是模式 _Integer当前规则中的 只会发现明显是整数的东西。它甚至不会发现 qAssuming[{Element[q, Integers]}, a**q**b] 这样的结构中的整数。
为了实现这一点,您需要检查假设,将这个过程放入全局转换表中可能会非常昂贵。相反,我会编写一个可以手动应用的转换函数(并且可能从全局表中删除当前规则)。像这样的东西可能会起作用:

NCMScalarReduce[e_] := e //.  {
    NonCommutativeMultiply[a___, i_ /; Simplify@Element[i, Reals],b___] 
    :> i a ** b
}

上面使用的规则使用 Simplify 显式查询假设,您可以通过分配给 $Asminations 进行全局设置,也可以使用 Assuming< 进行本地设置/code>:

Assuming[{q \[Element] Reals},
  NCMScalarReduce[c ** (-q) ** c]] 

返回-qc**c

华泰

The key to doing this is to realize that Mathematica represents a-b as a+((-1)*b), as you can see from

In[1]= FullForm[a-b]
Out[2]= Plus[a,Times[-1,b]]

For the first part of your question, all you have to do is add this rule:

NonCommutativeMultiply[Times[-1, a_], b__] := - a ** b

or you can even catch the sign from any position:

NonCommutativeMultiply[a___, Times[-1, b_], c___] := - a ** b ** c

Update -- part 2. The general problem with getting scalars to front is that the pattern _Integer in your current rule will only spot things that are manifestly integers. It wont even spot that q is an integer in a construction like Assuming[{Element[q, Integers]}, a**q**b].
To achieve this, you need to examine assumptions, a process that is probably to expensive to be put in the global transformation table. Instead I would write a transformation function that I could apply manually (and maybe remove the current rule form the global table). Something like this might work:

NCMScalarReduce[e_] := e //.  {
    NonCommutativeMultiply[a___, i_ /; Simplify@Element[i, Reals],b___] 
    :> i a ** b
}

The rule used above uses Simplify to explicitly query assumptions, which you can set globally by assigning to $Assumptions or locally by using Assuming:

Assuming[{q \[Element] Reals},
  NCMScalarReduce[c ** (-q) ** c]] 

returns -q c**c.

HTH

深居我梦 2024-10-24 21:18:13

只是一个快速回答,重复上一个问题的一些评论。
您可以删除几个定义并使用作用于 Times[i,c] 的规则来解决此问题的所有部分,其中 i 是可交换的,并且 c 的默认值为 Sequence[]

Unprotect[NonCommutativeMultiply];
ClearAll[NonCommutativeMultiply]
NonCommutativeMultiply[] := 1
NonCommutativeMultiply[a___, (i:(_Integer|q))(c_:Sequence[]), b___] := i a**Switch[c, 1, Unevaluated[Sequence[]], _, c]**b
NonCommutativeMultiply[a_] := a
c___**Subscript[a_, i_]**Subscript[b_, j_] ** d___ /; i > j := c**Subscript[b, j]**Subscript[a, i]**d
SetAttributes[NonCommutativeMultiply, {OneIdentity, Flat}]
Protect[NonCommutativeMultiply];

这将按预期工作

In[]:= a**b**q**(-c)**3**(2 a)**q
Out[]= -6 q^2 a**b**c**a

。请注意,您可以泛化 (_Integer|q) 以处理更通用的可交换对象。

Just a quick answer that repeats some of the comments from the previous question.
You can remove a couple of the definitions and solve all of the parts of this question using the rule that acts on Times[i,c] where i is commutative and c has the default of Sequence[]

Unprotect[NonCommutativeMultiply];
ClearAll[NonCommutativeMultiply]
NonCommutativeMultiply[] := 1
NonCommutativeMultiply[a___, (i:(_Integer|q))(c_:Sequence[]), b___] := i a**Switch[c, 1, Unevaluated[Sequence[]], _, c]**b
NonCommutativeMultiply[a_] := a
c___**Subscript[a_, i_]**Subscript[b_, j_] ** d___ /; i > j := c**Subscript[b, j]**Subscript[a, i]**d
SetAttributes[NonCommutativeMultiply, {OneIdentity, Flat}]
Protect[NonCommutativeMultiply];

This then works as expected

In[]:= a**b**q**(-c)**3**(2 a)**q
Out[]= -6 q^2 a**b**c**a

Note that you can generalize (_Integer|q) to work on more general commutative objects.

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