Wolfram mathematica Mathematica中向量值黑箱函数的绘图风格

Wolfram mathematica Mathematica中向量值黑箱函数的绘图风格,wolfram-mathematica,Wolfram Mathematica,假设我写了一个黑箱函数,它对一个昂贵的复数函数进行数值计算,然后返回实部和虚部 fun[x_?InexactNumberQ] := Module[{f = Sin[x]}, {Re[f], Im[f]}] 然后我可以像往常一样在Plot中使用它,但是Plot不能识别函数返回一对,并且两条曲线的颜色相同。如何告诉Mathematica指定的函数总是返回一个固定长度的向量?或者如何设计这个情节 编辑:鉴于试图回答该问题,我认为只有将样式设置作为所获得图形的后处理,才能避免双重重新估价。最有可能的

假设我写了一个黑箱函数,它对一个昂贵的复数函数进行数值计算,然后返回实部和虚部

fun[x_?InexactNumberQ] := Module[{f = Sin[x]}, {Re[f], Im[f]}]
然后我可以像往常一样在Plot中使用它,但是Plot不能识别函数返回一对,并且两条曲线的颜色相同。如何告诉Mathematica指定的函数总是返回一个固定长度的向量?或者如何设计这个情节

编辑:鉴于试图回答该问题,我认为只有将样式设置作为所获得图形的后处理,才能避免双重重新估价。最有可能的是,以下内容并不可靠,但似乎对我的示例有效:

gr = Plot[fun[x + I], {x, -1, 1}, ImageSize -> 250];
k = 1;
{gr, gr /. {el_Line :> {ColorData[1][k++], el}}}
一种可能性是:

Plot[{#[[1]], #[[2]]}, {x, -1, 1}, PlotStyle -> {{Red}, {Blue}}] &@ fun[x + I]  

编辑

如果您的函数不是真正的平滑(即几乎线性!),那么您无法做很多事情来防止双重求值过程,因为由于Plot[]网格探索算法的性质,它无论如何都会发生(某种程度上)

例如:

fun[x_?InexactNumberQ] := Module[{f = Sin[3  x]}, {Re[f], Im[f]}];
Plot[{#[[1]], #[[2]]}, {x, -1, 1}, Mesh -> All, 
   PlotStyle -> {{Red}, {Blue}}] &@fun[x + I]  

如果实际应用可能,一种方法是允许
fun
除了数字之外,还接受符号输入,然后
绘图
中对其进行评估:

fun2[x_] := Module[{f = Sin[x]}, {Re[f], Im[f]}]

Plot[Evaluate[fun2[x + I]], {x, -1, 1}]

这与您进行评估的效果相同:

Plot[{-Im[Sinh[1 - I x]], Re[Sinh[1 - I x]]}, {x, -1, 1}]

如果你的函数计算起来很昂贵,我认为没有一个好的解决方案。Plot只会确认有多条曲线需要设置样式,如果您给它一个明确的函数列表作为参数,或者给它一个可以计算为值列表的函数

您可能不想执行@belisarius建议的操作的原因是它会计算函数两次(速度是原来的两倍)


但是,您可以使用memonization来避免这种情况(即f[x_3;]:=f[x]=…构造),并使用他的解决方案。但是如果你使用实值函数,这会很快填满你的记忆。为了防止出现这种情况,您可能想尝试一下我写的关于只缓存有限数量的值的内容,以避免填满内存:

如果在fun中插入Sow,并在绘图中使用Reap,可以看出,对于x的某些值,函数会被计算两次。但我不明白为什么。让fun[x#不精确数字q]:=模块[{f=Sin[x]},Sow[x];{Re[f],Im[f]}然后(收获[Plot[{f#[[1]],{x,-1,1},PlotStyle->{Red},{Blue}和@fun[x+I][-1,1]//Tally][All,2]//Tally给出了{2,78},1,197的节省空间。@sashp}。我错过了你的“昂贵功能”声明。你可以使用备忘录,虽然这似乎可以避免一些重复。不过,这很俗气,除非你费心将全局变量本地化。fun[x#?incactnumberq]:=Module[{f=Sin[x]},Sow[x];tagagroun=Im[f];Re[f]]g[x]:=tagagroun pts=reau[Plot[[1]],g[[2]]},{x,-1,1},PlotStyle->{Red},{Blue}}和{fun[x+I],tagagroun}[[2,1]];虽然不是对我的问题的直接回答,但您的分析表明,在不覆盖自动细分的情况下,我可以避免的不必要的评估太多了。接受。我不能这样做的原因是,实际函数是由数值积分定义的,没有闭合形式。如果实部和虚部没有“有趣点”,缓存将更有用。Plot将尝试探索每个部分的要点。我会更新我的答案。我不认为有任何记录在案的方法可以做到这一点。我试着运行
Trace[Plot[{Sin[x],Cos[x]},{x,-1,1}],TraceInternal->True]
来找出Mma确定行数和分配颜色/样式的位置,但这并没有让事情变得更清楚。也许其他人能更好地理解输出。