我正在做这个:
最后,我按照以下方式绘制点(这里是问题的真正关键):
ClearAll[matrix];
matrix[p_,q_,nu_:0]:=Module[{sigma},
sigma=p/q;
N@SparseArray[
{{m_,m_}\[Rule]2Cos[2\[Pi]*m*p/q+nu],{i_,j_}/;
Abs[i-j]\[Equal]1\[Rule]1},{q,q}]]
ClearAll[attachsigma]
attachsigma[sigma_,lst_]:={sigma,#}&/@lst
然后执行
fracs = Table[p/q, {q, 2, 30}, {p, 2, q}] // Flatten // DeleteDuplicates;
pq = {Numerator@#, Denominator@#} & /@ fracs;
(ens = Eigenvalues[#] & /@
Normal /@ (matrix[#[[1]], #[[2]]] & /@ pq);) // Timing
pts = Flatten[#, 1] &@MapThread[attachsigma, {fracs, ens}];
最后,我按照以下方式绘制点(这里是问题的真正关键):
plot = ListPlot[pts,
PlotMarkers \[Rule] Graphics[{PointSize[Tiny], Point[{0, 0}]}]]
在我的电脑上,计算所有点大约需要2.6秒,但绘图需要大约25秒。如果我像这样绘制它:
ListPlot[pts]
如果不使用 PlotMarkers
,绘图几乎是瞬间完成的(只有5256个点)。因此,PlotMarkers
会严重拖慢绘图速度。
请问,
a)为什么会这样?我有些模糊地理解了一下,类比于如果给 Sort
提供自定义排序函数时会发生的情况。
b)更重要的是,如何避免这种减速?我正在尝试创建具有更多点的图形,所以它们非常缓慢;此外,我正在创建很多这样的图形(实际上是电影)。
一种解决方法是不绘制所有点,但随着参数的变化,找出应该包含哪些点和不包含哪些点变得不容易(如果我只需要这一个框架,则这当然可以工作)。因此,我希望在不删除点的情况下加快绘图速度。
编辑:在 Sjoerd 的提示下回答:
ListPlot[pts] /. Point[List[x___]] \[RuleDelayed] {PointSize[Tiny], Point[List[x]]}
瞬间生成正确的东西。这只是通过手动将Graphics
结构中的Points
替换为较小的点。
现在可以将fracs = Table[p/q, {q, 2, 30}, {p, 2, q}] // Flatten // DeleteDuplicates
中表格的上限增加到80左右,以获得更多的点(这个东西是Hofstadter蝴蝶,是一个分形):
FullForm
显示这确实是它们的表示方式。不过你有什么加速的建议吗?例如,如果我能选择正确的smth
,那么ListPlot[pts] /. Point[List[x___]] :> smth
可以起作用,但是 mma 中的图形不是我的强项... - aclListPlot
一般是一样快的。太好了。 - acl