曼德博集合中的形状

4

迷人而可爱的曼德布洛集合环和卷是由浮点计算不精确导致的吗?

我编写了各种曼德布洛集合实现,例如动态缩放和回放。有些使用定点算术,有些使用FPU。

我看到了这个问题,它表明每个芽都是数学上平滑的形状,并且周围还有更小的芽。

海马形状等等的游行是否是计算机浮点算术限制的副作用,而不是真正的曼德布洛集合?

海马形状?由Spektre添加:

Sea horse?

我一直想说的是,无论是定点还是固定精度浮点算术,都不能保留迭代步骤的真实结果。Mandelbrot集的有趣部分在边界附近,在这个区域中,迭代坐标可以在循环近重复中摇摆数千次,最终“逃脱”。我的问题是:算术是否会以导致这些模式的方式失败?据我理解,完美的Mandelbrot集实际上是无限排列的平滑形状芽。评论者说,算术越好,著名的海马等形状就越好,当不良实现产生模糊图像时,可以看到这一点。但这只加强了我的问题:算术越精确,算术失败的精度和规律性就越高,直到坐标变化时出现不连续性,并以稍微不同的方式进行失败。
无论如何,这里有一个C函数,它使用x87 FPU迭代一个点。该代码并不新,可以利用平方之间的差异来改进它,这仍然是我古老的“待办事项”清单上的任务。
int MAXRAD = 4;
int K_LIMIT = 5000;
double REAL8, IMAG8;

int iterate (void)
// calculate Mandelbrot iterations of REAL8, IMAG8
// return iterations
{
int iters;

    __asm {

        FILD    DWORD PTR MAXRAD       ;MAX R^2
        FLD     QWORD PTR IMAG8        ;INIT Y VALUE
        FLD     QWORD PTR REAL8        ;INIT X VALUE

        FLD     ST(1)     ;WORKING Y = IMAG
        FLD     ST(1)     ;WORKING X = REAL

        MOV     ECX,DWORD PTR K_LIMIT
        MOV     BX,0100h  ;MASK FOR C0 FLAG

        ALIGN 4
    MLOOPB:               ;ITERATE      ST0  ST1  ST2  ST3  ST4  ST5  ST6  ST7
                          ;             X    Y    REAL IMAG 4.0
        FLD     ST(0)     ;PUSH X       X    X    Y    REAL IMAG 4.0
        FMUL    ST(1),ST  ;X * X        X    X^2  Y    REAL IMAG 4.0
        FMUL    ST,ST(2)  ;X * Y        XY   X^2  Y    REAL IMAG 4.0
        FADD    ST,ST(0)  ;2 * XY       2XY  X^2  Y    REAL IMAG 4.0
        FADD    ST,ST(4)  ;2XY+IMAG     Y'   X^2  Y    REAL IMAG 4.0
        FXCH    ST(2)     ;Y', Y        Y    X^2  Y'   REAL IMAG 4.0
        FMUL    ST,ST(0)  ;Y * Y        Y^2  X^2  Y'   REAL IMAG 4.0
        FLD     ST(0)     ;PUSH Y^2     Y^2  Y^2  X^2  Y'   REAL IMAG 4.0
        FADD    ST,ST(2)  ;Y^2 + X^2    R^2  Y^2  X^2  Y'   REAL IMAG 4.0
        FCOMP   ST(6)     ;TEST & POP   Y^2  X^2  Y'   REAL IMAG 4.0
        FNSTSW  AX        ;STATUS
        FSUB              ;X^2 - Y^2    ...  Y'   REAL IMAG 4.0
        FADD    ST,ST(2)  ;X'            X'  Y'   REAL IMAG 4.0
        TEST    AX,BX     ;CHECK C0
        LOOPNZ  MLOOPB    ;LOOP IF (ITERS > 0) and (RADIUS^2 < 4)

        FNINIT            ;INIT COPROCESSOR TO CLEAR STACK

        MOV     EAX,DWORD PTR K_LIMIT
        SUB     EAX,ECX   ;DONE, LOOP WAS COUNTED DOWNWARD
        MOV     DWORD PTR iters,EAX
    }

    return iters;
}

请注意,在迭代循环中没有内存加载/存储操作。
我还在StackExchange Mathematics上提出了这个问题here

3
你能发布一张Mandelbrot集合上海马形状的图片吗? - Ṃųỻịgǻňạcểơửṩ
在遭受一次负评之后,我想澄清:我不相信能够在不进行迭代的情况下生成Mandelbrot集合图片。所有我所见过的东西,比如计算一个点到M集合的距离,都需要迭代。由于浮点运算的精度有限,再加上大量迭代,计算结果可能并不准确,那么生成的图像又有多少真实性可言呢?特别是在M集合附近,函数值可能会在两个或更多吸引子点周围的大量迭代中动荡,之后才成功逃脱。 - Weather Vane
@WeatherVane 你能否展示你的代码(和可能存在的不准确之处),这样我就可以添加一个语言标签?我希望在这里给出更好的答案。 - S.S. Anne
@JL2210,你的悬赏是一个慷慨的提议,旨在吸引人们关注这个问题。你是指迭代一个点的代码吗?经过多次制作与其他人产生类似结果的版本后,我认为缩放每个点的坐标不会成为问题。我有很多版本可供使用。更好的版本使用手工编写寄存器的汇编语言,在两种情况下进行:a)固定点和b)使用FPU堆栈。所有代码都不是最近的,但我很快就会发布一些东西。 - Weather Vane
1
一个相对简单的测试你所拥有的代码的方法是使用FLDCW改变FPU的精度,以在24、53和64位精度之间进行切换。你可能还想在两个初始化加载后包含一个FADD ST(0),0,以便将加载的值四舍五入,因为FLD不受精度影响。 - 1201ProgramAlarm
显示剩余4条评论
1个回答

7

曼德博集合中看到的漩涡和海马形状、芽和其他令人惊叹的事物是真实存在的,不是计算舍入的结果。事实上,你的计算结果越准确,也就是四舍五入误差越小,计算出来的形状就会变得更加复杂。个人警告:编写曼德博集合的代码可能会让人上瘾!


4
这个问题并没有引起太多的兴趣。我接受你的答案,尽管我并不完全相信经过多次迭代后算术不会产生逐渐增加的误差,然后以一种产生模式的方式满足终止条件。总有一天,我会在一个非常小而且比较浅的区域上进行固定点算术测试,在每次迭代时扩展位数存储(也许在磁盘上),以避免失去任何有效数字。固定点很好,因为值始终在±4的范围内。 - Weather Vane
@WeatherVane:如果幅度变得非常小,它们可能会保持小(因此在集合内),因此固定绝对精度(定点)与固定相对精度(浮点数)相比更好。我优化过的第一个程序(通过修改gcc汇编输出)是我从杂志上打出来的C Mandelbrot程序,在我的Atari Mega4 STe(68020)上运行。 :) 它使用了定点整数。 - Peter Cordes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接