gpt4 book ai didi

wolfram-mathematica - Times 和 NonCommutativeMultiply,自动处理差值

转载 作者:行者123 更新时间:2023-12-04 08:05:40 25 4
gpt4 key购买 nike

我有一些应该是非交换的符号,但我不想在构造方程时记住哪些表达式具有这种行为。

我曾想过使用 MakeExpression 对原始框进行操作,并在适当的时候自动将乘法提升为非交换乘法(例如,当某些符号是非交换对象时)。

我想知道是否有人对这种配置有任何经验。

这是我到目前为止所得到的:

(* Detect whether a set of row boxes represents a multiplication *)

Clear[isRowBoxMultiply];
isRowBoxMultiply[x_RowBox] := (Print["rowbox: ", x];
Head[ToExpression[x]] === Times)
isRowBoxMultiply[x___] := (Print["non-rowbox: ", x]; False)

(* Hook into the expression maker, so that we can capture any \
expression of the form F[x___], to see how it is composed of boxes, \
and return true or false on that basis *)

MakeExpression[
RowBox[List["F", "[", x___, "]"]], _] := (HoldComplete[
isRowBoxMultiply[x]])

(* Test a number of expressions to see whether they are automatically \
detected as multiplies or not. *)
F[a]
F[a b]
F[a*b]
F[a - b]
F[3 x]
F[x^2]
F[e f*g ** h*i j]

Clear[MakeExpression]

这似乎正确识别乘法语句的表达式:
During evaluation of In[561]:= non-rowbox: a
Out[565]= False

During evaluation of In[561]:= rowbox: RowBox[{a,b}]
Out[566]= True

During evaluation of In[561]:= rowbox: RowBox[{a,*,b}]
Out[567]= True

During evaluation of In[561]:= rowbox: RowBox[{a,-,b}]
Out[568]= False

During evaluation of In[561]:= rowbox: RowBox[{3,x}]
Out[569]= True

During evaluation of In[561]:= non-rowbox: SuperscriptBox[x,2]
Out[570]= False

During evaluation of In[561]:= rowbox: RowBox[{e,f,*,RowBox[{g,**,h}],*,i,j}]
Out[571]= True

所以,看起来我可以有条件地重写底层表达式的框并不是不可能的;但如何可靠地做到这一点?

取表达式 RowBox[{"e","f","*",RowBox[{"g","**","h"}],"*","i","j"}] ,这需要重写为 RowBox[{"e","**","f","**",RowBox[{"g","**","h"}],"**","i","**","j"}]这似乎是与模式匹配器和规则集有关的重要操作。

我会很感激那些对我更有经验的人的任何建议。

我试图找到一种方法来做到这一点,而不会改变乘法的默认行为和顺序。

谢谢! :)

最佳答案

这不是对您的问题的最直接回答,但对于许多目的而言,与直接使用盒子一样低级工作可能是一种矫枉过正。这是另一种选择:让 Mathematica 解析器解析您的代码,然后进行更改。这是一种可能性:

ClearAll[withNoncommutativeMultiply];
SetAttributes[withNoncommutativeMultiply, HoldAll];
withNoncommutativeMultiply[code_] :=
Internal`InheritedBlock[{Times},
Unprotect[Times];
Times = NonCommutativeMultiply;
Protect[Times];
code];

这将取代 Times动态使用 NonCommutativeMultiply ,并避免了您提到的错综复杂。通过使用 Internal`InheritedBlock ,我对 Times做了修改局部于内部执行的代码 withNoncommutativeMultiply .

您现在可以使用 $Pre 自动应用此功能:
$Pre  = withNoncommutativeMultiply;

现在,例如:
In[36]:= 
F[a]
F[a b]
F[a*b]
F[a-b]
F[3 x]
F[x^2]
F[e f*g**h*i j]

Out[36]= F[a]
Out[37]= F[a**b]
Out[38]= F[a**b]
Out[39]= F[a+(-1)**b]
Out[40]= F[3**x]
Out[41]= F[x^2]
Out[42]= F[e**f**g**h**i**j]

当然,使用 $Pre以这种方式几乎不合适,因为在您的所有代码中,乘法都将被非交换乘法替换 - 我用它作为说明。您可以对 Times 进行更复杂的重新定义。 ,因此这仅适用于某些符号。

这是一个基于词法而不是动态范围的更安全的替代方案:
ClearAll[withNoncommutativeMultiplyLex];
SetAttributes[withNoncommutativeMultiplyLex, HoldAll];
withNoncommutativeMultiplyLex[code_] :=
With @@ Append[
Hold[{Times = NonCommutativeMultiply}],
Unevaluated[code]]

您可以以同样的方式使用它,但仅限于 Times 的那些实例代码中明确存在的将被替换。同样,这只是原理的说明,您可以根据需要对其进行扩展或专门化。而不是 With ,它在专门化/添加特殊情况的能力方面相当有限,可以使用具有相似语义的替换规则。

关于wolfram-mathematica - Times 和 NonCommutativeMultiply,自动处理差值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8366806/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com