“升值"是什么意思在 Mathematica 中意味着什么以及何时使用它们? [英] What does "upvalue" mean in Mathematica and when to use them?

查看:47
本文介绍了“升值"是什么意思在 Mathematica 中意味着什么以及何时使用它们?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对我来说,g/: f[g[x_]] := h[x] 只是冗长的 f[g[x_]] := h[x].你能举一个必须使用 /: 的例子吗?

To me, g /: f[g[x_]] := h[x] is just verbose equivalent of f[g[x_]] := h[x]. Can you raise an example that you have to use /:?

推荐答案

其实,g/: f[g[x_]] := h[x] 并不等同于 f[g[x_]] := h[x].后者将定义与 f 相关联,而 TagSet (/:) 和 UpSet(^= 及其延迟版本, ^:=) 将定义与g.这是一个至关重要的区别,可以通过一个简单的例子来说明.假设您想要一组遵守模 5 加法的变量,即 6 + 7 mod 5 = 3.因此,我们希望任何带有 Head mod 的东西都能正确运行.最初,我们认为

Actually, g /: f[g[x_]] := h[x] is not equivalent to f[g[x_]] := h[x]. The latter associates the definition with f, while TagSet (/:) and UpSet (^= and its delayed version, ^:=) associate the definition with g. This is a crucial difference and can be illustrated by a simple example. Let's say you want to have a set of variables that obey modulo 5 addition, i.e. 6 + 7 mod 5 = 3. So, we want anything with Head mod to behave correctly. Initially, we'd think that

a_mod + b_mod := mod@Mod[a + b, 5]

会起作用.但是,它会产生错误

would work. But, it generates the error

SetDelayed::write : Tag Plus in a_mod + b_mod is Protected.

我们可以删除Unprotect Plus,然后我们的定义就可以工作了,但这可能会导致其他定义出现问题,并且随着Plus 积累更多的定义,它会变慢.或者,我们可以通过 TagSet

We could remove Unprotect Plus and our definition would then work, but this may cause problems with other definitions and as Plus accumulates more definitions, it would slow down. Alternatively, we can associate the addition property with the mod object itself via TagSet

mod /: mod[a_] + mod[b_] := mod @ Mod[a + b, 5]

UpSetDelayed

mod[a_] + mod[b_] ^:= mod @ Mod[a + b, 5]

设置 upvalue 有点从概念的角度来看更正确,因为 mod 是具有不同属性的那个.

Setting an upvalue is somewhat more correct from a conceptual point of view since mod is the one with the different property.

有几个问题需要注意.首先upvalue机制只能扫描一层,即Plus[a_mod, b_mod]没问题,但是Exp[Plus[a_mod, b_mod]]会报错.这可能需要您使用中间类型获得创意.其次,从编码的角度来看,UpSetDelayed 更容易编写,但有时对于与哪个 Head 相关联的 upvalue 存在一些歧义.TagSet 通过显式命名适当的 Head 来处理这个问题,总的来说,与 UpSet 相比,我更喜欢使用它.

There are a couple of issues to be aware of. First, the upvalue mechanism can only scan one level deep, i.e. Plus[a_mod, b_mod] is fine, but Exp[Plus[a_mod, b_mod]] will throw an error. This may require you to get creative with an intermediate type. Secondly, from a coding perspective UpSetDelayed is easier to write, but occasionally there is some ambiguity as to which Head is the upvalue associated with. TagSet handles that by explicitly naming the appropriate Head, and in general, it is what I tend to prefer over UpSet.

Mathematica 的一些运算符没有任何与其相关的行为,因此它们不受保护.对于这些运算符,您可以根据需要定义函数.例如,我定义了

Some of Mathematica's operators do not have any behavior associated with them, so they're not protected. For these operators, you can define functions as you wish. For instance, I've defined

a_ \[CircleTimes] b_ := KroneckerProduct[a,b]
a_ \[CircleTimes] b_ \[CircleTimes] c__ := a \[CircleTimes] ( b \[CircleTimes] c )

a_ \[CirclePlus] b__ := BlockDiagonal[{a,b}]

为我经常使用的矩阵运算提供方便的速记符号.

to provide convenient shorthand notations for matrix operations that I use a lot.

我上面的例子有点做作,但有很多次UpValues 派上了用场.例如,我发现我需要一个符号形式来表示复杂的统一根在乘法和幂运算下表现得很好.

My example above was a little contrived, but there are a number of times UpValues have come in handy. For example, I found that I needed a symbolic form for the complex roots of unity that behaved appropriately under multiplication and exponentiation.

示例:一个简单而有用的示例是将 Symbol 标记为 Real:

Example: A straightforward and useful example is marking a Symbol as Real:

makeReal[a__Symbol] := (
     # /: Element[#, Reals] := True; 
     # /: Im[#] := 0; 
     # /: Re[#] := #;
     # /: Abs[#] := Sign[#] #;
     # /: Arg[#] := Piecewise[{{0, Sign[#] >= 0}, {Pi, Sign[#] < 0}}]
   ) & /@ List[a]

注意将 TagSet 用作 Element[ a, Reals ] ^:= True 会产生歧义.aReals 会附加什么规则?此外,如果我们想要一个正实数,我们可以设置 Arg[#]:=0 这允许 Simplify 像预期的那样表现,例如简化[Sqrt[a^2]] == a.

Note the use of TagSet as Element[ a, Reals ] ^:= True would be ambiguous. What would the rule be attached to a or Reals? Also, if we wanted a positive real number, we could set Arg[#]:=0 which allows Simplify to behave as expected, e.g. Simplify[Sqrt[a^2]] == a.

这篇关于“升值"是什么意思在 Mathematica 中意味着什么以及何时使用它们?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆