Mathematica 绘图中多个函数的检测和样式设置

发布于 2024-10-31 11:42:22 字数 421 浏览 1 评论 0原文

这个问题让我开始思考 Mathematica 如何检测正在绘制的多个函数。我发现我实在是看不懂这个流程。

考虑:

Plot[{1, Sequence[2, 3], 4}, {x, 0, 1}, PlotRange -> {0, 5}]

在此处输入图像描述

我可以理解 Plot 最初在列表中找到三个元素,但它如何“知道”将 23 设置为相同的样式呢?就好像有关于这两个元素来自起始列表的哪一部分的记忆。这是如何运作的?

This question started me thinking about how Mathematica detects multiple functions being plotted. I find that I really do not understand the process.

Consider:

Plot[{1, Sequence[2, 3], 4}, {x, 0, 1}, PlotRange -> {0, 5}]

enter image description here

I can understand that Plot finds three elements in the list initially, but how does it "know" to style 2 and 3 the same? It is as though there is a memory of what part of the starting list those two elements came from. How does this work?

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

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

发布评论

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

评论(2

等你爱我 2024-11-07 11:42:22

好吧,它知道存在三个参数:

In[13]:= Function[x, Length[Unevaluated[x]], HoldAll][{1, 
  Sequence[2, 3], 4}]

Out[13]= 3

如果允许 x 求值,那么

In[14]:= Function[x, Length[x], HoldAll][{1, Sequence[2, 3], 4}]

Out[14]= 4

编辑:人们会更好地看到它:

In[15]:= Hold[{1, Sequence[2, 3], 4}]

Out[15]= Hold[{1, Sequence[2, 3], 4}]

换句话说,序列的扁平化需要求值器。

编辑2:我显然错过了提出的真正问题,现在将尝试回答它。

一旦 Plot 确定了参数的数量,它就会构建 {{ style1, Line ..}, {style2, Line..}, ... }。在 {1,Sequence[2,3],4} 的情况下,我们得到以下结构:

In[23]:= Cases[
  Plot[{1, Sequence[2, 3], 4}, {x, 0, 1}, 
   PlotRange -> {0, 5}], {_Hue, __Line}, 
  Infinity] /. {x_Line :> Line, _Hue -> Hue}

Out[23]= {{Hue, Line}, {Hue, Line, Line}, {Hue, Line}}

当绘制 {1,{2,3},4} 时,我们得到不同的结构:

In[24]:= Cases[
  Plot[{1, List[2, 3], 4}, {x, 0, 1}, 
   PlotRange -> {0, 5}], {_Hue, __Line}, 
  Infinity] /. {x_Line :> Line, _Hue -> Hue}

Out[24]= {{Hue, Line}, {Hue, Line}, {Hue, Line}, {Hue, Line}}

因为列表会被展平,只是不使用评估者。因此,正如您所看到的,出现相同颜色的标记是因为 Sequence[2,3] 被视为黑盒函数,它返回两个元素的列表:

In[25]:= g[x_?NumberQ] := {2, 3}

In[26]:= Cases[
  Plot[{1, g[x], 4}, {x, 0, 1}, PlotRange -> {0, 5}], {_Hue, __Line}, 
  Infinity] /. {x_Line :> Line, _Hue -> Hue}

Out[26]= {{Hue, Line}, {Hue, Line, Line}, {Hue, Line}}

我试图构建一个顶级实现来构建这样的结构,但必须与评估者对抗。例如:

In[28]:= Thread /@ Function[x,
   Thread[{Hold @@ {Range[Length[Unevaluated[x]]]}, Hold[x]}, Hold]
   , HoldAll][{1, Sequence[2, 3], 4}]

Out[28]= Hold[Thread[{{1, 2, 3}, {1, Sequence[2, 3], 4}}]]

现在我们必须评估线程而不评估其参数,这将给出
{{1, 1}, {2, Sequence[2,3]}, {3, 4}},其中列表的第一个元素是标签,后面的一个元素是要采样的函数。

希望这有帮助。

Well, it knows that there three arguments just so:

In[13]:= Function[x, Length[Unevaluated[x]], HoldAll][{1, 
  Sequence[2, 3], 4}]

Out[13]= 3

If x is allowed to evaluate, then

In[14]:= Function[x, Length[x], HoldAll][{1, Sequence[2, 3], 4}]

Out[14]= 4

EDIT: One sees it better with:

In[15]:= Hold[{1, Sequence[2, 3], 4}]

Out[15]= Hold[{1, Sequence[2, 3], 4}]

in other words, flattening of Sequence requires evaluator.

EDIT 2: I clearly missed the real question posed and will try to answer it now.

Once Plot determines the number of argument it builds {{ style1, Line ..}, {style2, Line..}, ... }. In the case of {1,Sequence[2,3],4} we get the following structure:

In[23]:= Cases[
  Plot[{1, Sequence[2, 3], 4}, {x, 0, 1}, 
   PlotRange -> {0, 5}], {_Hue, __Line}, 
  Infinity] /. {x_Line :> Line, _Hue -> Hue}

Out[23]= {{Hue, Line}, {Hue, Line, Line}, {Hue, Line}}

When plotting {1,{2,3},4} we get a different structure:

In[24]:= Cases[
  Plot[{1, List[2, 3], 4}, {x, 0, 1}, 
   PlotRange -> {0, 5}], {_Hue, __Line}, 
  Infinity] /. {x_Line :> Line, _Hue -> Hue}

Out[24]= {{Hue, Line}, {Hue, Line}, {Hue, Line}, {Hue, Line}}

because lists would be flattened, just not using the evaluator. So as you see the tagging in the same color occurs because Sequence[2,3] is treated as a black-box function which returns a list of two elements:

In[25]:= g[x_?NumberQ] := {2, 3}

In[26]:= Cases[
  Plot[{1, g[x], 4}, {x, 0, 1}, PlotRange -> {0, 5}], {_Hue, __Line}, 
  Infinity] /. {x_Line :> Line, _Hue -> Hue}

Out[26]= {{Hue, Line}, {Hue, Line, Line}, {Hue, Line}}

I was trying to build a top-level implementation which would build such a structure, but one has to fight the evaluator. For example:

In[28]:= Thread /@ Function[x,
   Thread[{Hold @@ {Range[Length[Unevaluated[x]]]}, Hold[x]}, Hold]
   , HoldAll][{1, Sequence[2, 3], 4}]

Out[28]= Hold[Thread[{{1, 2, 3}, {1, Sequence[2, 3], 4}}]]

Now we have to evaluate the Thread without evaluating its arguments, which would give
{{1, 1}, {2, Sequence[2,3]}, {3, 4}}, where the first element of the list is a tag, and the subsequent once are functions to be sampled.

Hope this helps.

ま柒月 2024-11-07 11:42:22

想象一个产生此输出的过程并不难。我没有额外的证据证明这确实发生了,但可以合理地假设 Plot 循环遍历传递给它的函数列表,并将每个函数与一个样式相关联。然后,在为绘图变量设置值后,继续评估它们中的每一个。通常,每个“函数”(传递给 Plot 的列表中的元素)都会返回一个实数。然而,从版本 6 开始,Mathematica 也可以处理返回数字列表的内容,但其缺陷是它对完整列表使用相同的样式。版本 5 会对返回列表的函数引发错误。

It's not that difficult to imagine a process which results in this output. I don't have additional proof that this is indeed what happens, but it is reasonable to assume that Plot loops through the list of functions that were passed to it, and associates a style with each. Then it proceeds to evaluate each of them after setting a value to the plot variable. Normally each "function" (element in the list passed to Plot) would return a real number. However, since version 6, Mathematica can handle those that return lists of numbers too, with the flaw that it uses the same styling for the complete list. Version 5 would throw an error for functions that returned lists.

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