This问题开始让我思考Mathematica如何检测绘制的多个函数。我发现我真的不明白这个过程。
考虑:
Plot[{1, Sequence[2, 3], 4}, {x, 0, 1}, PlotRange -> {0, 5}]
我可以理解Plot
最初会在列表中找到三个元素,但它如何“知道”样式2
和3
相同?就好像存在这两个元素来自哪个起始列表部分的记忆。这是如何工作的?
答案 0 :(得分:9)
嗯,它知道有三个参数:
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}},其中列表的第一个元素是标记,后面的一个是要采样的函数。
希望这有帮助。
答案 1 :(得分:8)
想象一个导致这个输出的过程并不难。我没有额外的证据证明这确实发生了什么,但是假设Plot
遍历传递给它的函数列表并将样式与每个函数相关联是合理的。然后在将值设置为绘图变量之后继续评估它们中的每一个。通常,每个“函数”(传递给Plot
的列表中的元素)将返回实数。但是,从版本6开始,Mathematica也可以处理返回数字列表的那些,其缺陷是它使用完整列表的相同样式。版本5会为返回列表的函数抛出错误。