画了一个简陋的曼德勃罗集

时间:2024-07-11 16:54:49

原文画了一个简陋的曼德勃罗集 - 知乎 (zhihu.com)

前两天看妈咪叔科普曼德勃罗集的视频:

【分形与混沌2】最有魅力的几何图形——曼德勃罗集与朱利亚集 天使与魔鬼共存_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili​www.bilibili.com/video/av79113074​编辑

虽然看过很多次曼德勃罗集的图形,但是之前一直没有去了解这个究竟是什么。看了视频觉得挺神奇的。这个集合的定义超级简单,只需要一个二次迭代公式:

????????+1=????????2+????,????0=0,????∈????

曼德勃罗集就是所有使数列 ????0,????1,...???????? 收敛的 ???? 的集合。 ????0,????1,...???????? 可能收敛到一个或多个复平面上的点,而且收敛到的点数和 ???? 所在的区域有关。

正好最近养病不想干什么费脑子的事情,于是就想着自己动手画一画。现在没有MATLAB用了,只能重新捡起了好久没有用的Matplotlib用Python写了一下。

不会写Python的人写的Python在这里:

https://github.com/myc24601/mandelbrot/tree/master​github.com/myc24601/mandelbrot/tree/master

我用了最简单粗暴的算法:对要画的每个点,扔到迭代公式里面看看数列收不收敛。一开始我尝试画3000x4000个点,我的15年小破本本艰难地跑了18分钟才计算完,Matplotlib又用了6分钟才把图画出来。不精确地记了一下时,算一个点大概在0.1ms这个量级。吓得我赶紧把绘图精度降了两个数量级(300x400)。跑出来的结果大概是下面这个样子:

动图封面

对于曼德勃罗集外面的点,生成的序列是发散的(Matplotlib在我的本本上实在太慢了,在显示第一个发散序列之前有一个漫长的停顿,我都已经把鼠标挪到集合里面了。只能将就着看)。对于中间大圆区域内的点,所有数列最后会收敛在一个点上;在左边那个第二大圆内的点,数列会收敛在两个点上......妈咪叔的视频里有更加详细的介绍,而且视频里看上去是Mathematica作的图,比我这个不知道高到哪里去了。

最后吐槽:NumPy和Matplotlib的设计真的是非常的不直观,对小白用户一点都不友好,一段时间不用的话就得重新熟悉一下基本概念(一定是它们设计的反人类不是我记性不好,嗯......)。本来我就是想悠闲地画个图散散心,结果折腾得无比心累。所以有钱的话还是买个MATLAB吧,反正学生版家庭版一年也不花多少钱,买不了吃亏买不了上当。MATLAB R2020a还有几个月就要上市了,大家期待一下呗。

P.S. 强行给MATLAB加戏只是为了能把我这篇小破短文发到MATLAB专栏orz。但是2020a还是非常值得期待的!

P.P.S. 经评论提醒,MATLAB有一个GPU加速画曼德勃罗集的例子:

Illustrating Three Approaches to GPU Computing: The Mandelbrot Set​www.mathworks.com/help/parallel-computing/examples/illustrating-three-approaches-to-gpu-computing-the-mandelbrot-set.html​编辑

用MATLAB的Parallel Computing Toolbox只需要把普通array替换成gpuArray,其他的code基本不用改。讲真,这才是科学计算工具应该有的样子。